[gnome-maps/wip/contacts: 13/14] Add shim c lib libmapsc



commit 0f2b2645bd092c00bfcfbd3e652fdc52650ff47d
Author: Jonas Danielsson <jonas threetimestwo org>
Date:   Thu Dec 4 03:05:37 2014 -0500

    Add shim c lib libmapsc
    
    This library will be introspectable and provide 'must-have'
    functionality to Maps that we cannot get through regular bindings.
    
    To start out with it contains functionality to interface with the
    Folks library to retrive contacts data.

 Makefile.am                 |    2 +-
 configure.ac                |   12 ++
 lib/Makefile.am             |   41 ++++++
 lib/mapsc-contact-address.c |  285 +++++++++++++++++++++++++++++++++++++++++++
 lib/mapsc-contact-address.h |   50 ++++++++
 lib/mapsc-contact.c         |  216 ++++++++++++++++++++++++++++++++
 lib/mapsc-contact.h         |   53 ++++++++
 lib/mapsc-contacts.c        |  241 ++++++++++++++++++++++++++++++++++++
 lib/mapsc-contacts.h        |   70 +++++++++++
 9 files changed, 969 insertions(+), 1 deletions(-)
---
diff --git a/Makefile.am b/Makefile.am
index ce68989..8f53c8f 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,3 +1,3 @@
 ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS}
 
-SUBDIRS = src data po
+SUBDIRS = lib src data po
diff --git a/configure.ac b/configure.ac
index c4fb258..03b029f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -32,6 +32,15 @@ PKG_CHECK_MODULES(GNOME_MAPS, [
     gobject-introspection-1.0    >= $GOBJECT_INTROSPECTION_MIN_VERSION
 ])
 
+FOLKS_MIN_VERSION=0.10.0
+GEE_MIN_VERSION=0.16.0
+
+PKG_CHECK_MODULES(MAPSC, [
+    gee-0.8                      >= $GEE_MIN_VERSION
+    folks                        >= $FOLKS_MIN_VERSION
+])
+AC_SUBST(MAPSC_CFLAGS)
+AC_SUBST(MAPSC_LIBS)
 
 # no stupid static libraries
 AM_DISABLE_STATIC
@@ -47,8 +56,11 @@ AC_SUBST(GJS_CONSOLE)
 GLIB_COMPILE_RESOURCES=`$PKG_CONFIG --variable glib_compile_resources gio-2.0`
 AC_SUBST(GLIB_COMPILE_RESOURCES)
 
+GOBJECT_INTROSPECTION_CHECK([0.6.3])
+
 AC_CONFIG_FILES([
     Makefile
+    lib/Makefile
     src/Makefile
     data/Makefile
     data/org.gnome.Maps.desktop.in
diff --git a/lib/Makefile.am b/lib/Makefile.am
new file mode 100644
index 0000000..34a6c5c
--- /dev/null
+++ b/lib/Makefile.am
@@ -0,0 +1,41 @@
+lib_LTLIBRARIES = libmapsc.la
+
+libmapsc_headers_public = mapsc-contacts.h mapsc-contact.h mapsc-contact-address.h
+libmapsc_sources = mapsc-contacts.c mapsc-contact.c mapsc-contact-address.c
+libmapsc_la_SOURCES = $(libmapsc_sources) $(libmapsc_headers_public)
+libmapsc_la_LIBADD = $(MAPSC_LIBS)
+
+AM_CPPFLAGS =          \
+       $(MAPSC_CFLAGS) \
+       -I$(top_srcdir)
+
+if HAVE_INTROSPECTION
+
+-include $(INTROSPECTION_MAKEFILE)
+INTROSPECTION_GIRS =
+INTROSPECTION_SCANNER_ARGS = --warn-all
+INTROSPECTION_COMPILER_ARGS =
+
+MapsC-1.0.gir: libmapsc.la
+MapsC_1_0_gir_NAMESPACE = MapsC
+MapsC_1_0_gir_INCLUDES = GLib-2.0 GObject-2.0
+MapsC_1_0_gir_PACKAGES = gobject-2.0
+MapsC_1_0_gir_FILES = $(libmapsc_la_SOURCES)
+MapsC_1_0_gir_CFLAGS = $(MAPSC_CFLAGS) -I$(top_srcdir) -I$(top_builddir)
+MapsC_1_0_gir_LIBS = libmapsc.la
+MapsC_1_0_gir_SCANNERFLAGS = \
+       --symbol-prefix=mapsc \
+       --identifier-prefix=MapsC \
+       --pkg-export=mapsc-1.0 \
+MapsContacts_1_0_gir_FILES = $(introspection_files)
+INTROSPECTION_GIRS += MapsC-1.0.gir
+
+girdir = $(datadir)/gir-1.0
+gir_DATA = $(INTROSPECTION_GIRS)
+
+typelibdir = $(libdir)/girepository-1.0
+typelib_DATA = $(INTROSPECTION_GIRS:.gir=.typelib)
+
+CLEANFILES = $(gir_DATA) $(typelib_DATA)
+
+endif
diff --git a/lib/mapsc-contact-address.c b/lib/mapsc-contact-address.c
new file mode 100644
index 0000000..a058d6f
--- /dev/null
+++ b/lib/mapsc-contact-address.c
@@ -0,0 +1,285 @@
+/* -*- Mode: JS2; indent-tabs-mode: nil; js2-basic-offset: 4 -*- */
+/* vim: set et ts=4 sw=4: */
+/*
+ * GNOME Maps is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * GNOME Maps is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with GNOME Maps; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * Author: Jonas Danielsson <jonas threetimestwo org>
+ */
+
+
+#include <folks/folks.h>
+#include "mapsc-contact.h"
+
+struct _MapsCContactAddressPrivate {
+  char *type;
+  char *phone;
+  char *country;
+  char *region;
+  char *locality;
+  char *postal_code;
+  char *street;
+};
+
+enum {
+  PROP_0,
+
+  PROP_TYPE,
+  PROP_PHONE,
+  PROP_COUNTRY,
+  PROP_REGION,
+  PROP_LOCALITY,
+  PROP_POSTAL_CODE,
+  PROP_STREET,
+};
+
+static void
+mapsc_contact_address_set_property (GObject      *object,
+                                    guint         property_id,
+                                    const GValue *value,
+                                    GParamSpec   *pspec)
+{
+  MapsCContactAddress *contact = MAPSC_CONTACT_ADDRESS (object);
+
+  switch (property_id) {
+  case PROP_TYPE:
+    g_free (contact->priv->type);
+    contact->priv->type = g_value_dup_string (value);
+    break;
+
+  case PROP_PHONE:
+    g_free (contact->priv->phone);
+    contact->priv->phone = g_value_dup_string (value);
+    break;
+
+  case PROP_COUNTRY:
+    g_free (contact->priv->country);
+    contact->priv->country = g_value_dup_string (value);
+    break;
+
+  case PROP_REGION:
+    g_free (contact->priv->region);
+    contact->priv->region = g_value_dup_string (value);
+    break;
+
+  case PROP_LOCALITY:
+    g_free (contact->priv->locality);
+    contact->priv->locality = g_value_dup_string (value);
+    break;
+
+  case PROP_POSTAL_CODE:
+    g_free (contact->priv->postal_code);
+    contact->priv->postal_code = g_value_dup_string (value);
+    break;
+
+  case PROP_STREET:
+    g_free (contact->priv->street);
+    contact->priv->street = g_value_dup_string (value);
+    break;
+
+  default:
+    G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+    break;
+  }
+}
+
+static void
+mapsc_contact_address_get_property (GObject    *object,
+                                    guint       property_id,
+                                    GValue     *value,
+                                    GParamSpec *pspec)
+{
+  MapsCContactAddress *contact = MAPSC_CONTACT_ADDRESS (object);
+
+  switch (property_id) {
+  case PROP_TYPE:
+    g_value_set_string (value,
+                        contact->priv->type);
+    break;
+
+  case PROP_PHONE:
+    g_value_set_string (value,
+                        contact->priv->phone);
+    break;
+
+  case PROP_COUNTRY:
+    g_value_set_string (value,
+                        contact->priv->country);
+    break;
+
+  case PROP_REGION:
+    g_value_set_string (value,
+                        contact->priv->region);
+    break;
+
+  case PROP_LOCALITY:
+    g_value_set_string (value,
+                        contact->priv->locality);
+    break;
+
+  case PROP_POSTAL_CODE:
+    g_value_set_string (value,
+                        contact->priv->postal_code);
+    break;
+
+  case PROP_STREET:
+    g_value_set_string (value,
+                        contact->priv->street);
+    break;
+
+  default:
+    G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+    break;
+  }
+}
+
+G_DEFINE_TYPE_WITH_PRIVATE (MapsCContactAddress, mapsc_contact_address, G_TYPE_OBJECT)
+
+static void
+mapsc_contact_address_dispose (GObject *object)
+{
+  MapsCContactAddress *contact = (MapsCContactAddress *) object;
+
+  g_clear_pointer (&contact->priv->type, g_free);
+  g_clear_pointer (&contact->priv->phone, g_free);
+  g_clear_pointer (&contact->priv->country, g_free);
+  g_clear_pointer (&contact->priv->street, g_free);
+  g_clear_pointer (&contact->priv->region, g_free);
+  g_clear_pointer (&contact->priv->postal_code, g_free);
+  g_clear_pointer (&contact->priv->locality, g_free);
+
+  G_OBJECT_CLASS (mapsc_contact_address_parent_class)->dispose (object);
+}
+
+static void
+mapsc_contact_address_class_init (MapsCContactAddressClass *klass)
+{
+  GObjectClass *mapsc_class = G_OBJECT_CLASS (klass);
+  GParamSpec *pspec;
+
+  mapsc_class->dispose = mapsc_contact_address_dispose;
+  mapsc_class->get_property = mapsc_contact_address_get_property;
+  mapsc_class->set_property = mapsc_contact_address_set_property;
+
+  /**
+   * MapsCContactAddress:type:
+   *
+   * The type of the contact.
+   */
+  pspec = g_param_spec_string ("type",
+                               "Type",
+                               "Type",
+                               NULL,
+                               G_PARAM_READWRITE |
+                               G_PARAM_STATIC_STRINGS);
+  g_object_class_install_property (mapsc_class, PROP_TYPE, pspec);
+
+  /**
+   * MapsCContactAddress:phone:
+   *
+   * The phone number of the contact.
+   */
+  pspec = g_param_spec_string ("phone",
+                               "Phone",
+                               "Phone number",
+                               NULL,
+                               G_PARAM_READWRITE |
+                               G_PARAM_STATIC_STRINGS);
+  g_object_class_install_property (mapsc_class, PROP_PHONE, pspec);
+
+  /**
+   * MapsCContactAddress:country:
+   *
+   * The country of the contact.
+   */
+  pspec = g_param_spec_string ("country",
+                               "Country",
+                               "Country",
+                               NULL,
+                               G_PARAM_READWRITE |
+                               G_PARAM_STATIC_STRINGS);
+  g_object_class_install_property (mapsc_class, PROP_COUNTRY, pspec);
+
+  /**
+   * MapsCContactAddress:region:
+   *
+   * The region of the contact.
+   */
+  pspec = g_param_spec_string ("region",
+                               "Region",
+                               "Region",
+                               NULL,
+                               G_PARAM_READWRITE |
+                               G_PARAM_STATIC_STRINGS);
+  g_object_class_install_property (mapsc_class, PROP_REGION, pspec);
+
+  /**
+   * MapsCContactAddress:locality:
+   *
+   * The locality of the contact.
+   */
+  pspec = g_param_spec_string ("locality",
+                               "Locality",
+                               "Locality",
+                               NULL,
+                               G_PARAM_READWRITE |
+                               G_PARAM_STATIC_STRINGS);
+  g_object_class_install_property (mapsc_class, PROP_LOCALITY, pspec);
+
+  /**
+   * MapsCContactAddress:postal-code:
+   *
+   * The postal code of the contact.
+   */
+  pspec = g_param_spec_string ("postal-code",
+                               "Postal code",
+                               "Postal code",
+                               NULL,
+                               G_PARAM_READWRITE |
+                               G_PARAM_STATIC_STRINGS);
+  g_object_class_install_property (mapsc_class, PROP_POSTAL_CODE, pspec);
+
+  /**
+   * MapsCContactAddress:street:
+   *
+   * The street of the contact.
+   */
+  pspec = g_param_spec_string ("street",
+                               "Street",
+                               "Street",
+                               NULL,
+                               G_PARAM_READWRITE |
+                               G_PARAM_STATIC_STRINGS);
+  g_object_class_install_property (mapsc_class, PROP_STREET, pspec);
+}
+
+static void
+mapsc_contact_address_init (MapsCContactAddress *contact)
+{
+  contact->priv = mapsc_contact_address_get_instance_private (contact);
+
+  contact->priv->type = NULL;
+  contact->priv->phone = NULL;
+  contact->priv->country = NULL;
+  contact->priv->street = NULL;
+  contact->priv->region = NULL;
+  contact->priv->postal_code = NULL;
+  contact->priv->locality = NULL;
+}
+
+MapsCContactAddress *
+mapsc_contact_address_new ()
+{
+  return g_object_new (MAPSC_TYPE_CONTACT_ADDRESS, NULL);
+}
diff --git a/lib/mapsc-contact-address.h b/lib/mapsc-contact-address.h
new file mode 100644
index 0000000..b4ecae7
--- /dev/null
+++ b/lib/mapsc-contact-address.h
@@ -0,0 +1,50 @@
+/* -*- Mode: JS2; indent-tabs-mode: nil; js2-basic-offset: 4 -*- */
+/* vim: set et ts=4 sw=4: */
+/*
+ * GNOME Maps is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * GNOME Maps is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with GNOME Maps; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * Author: Jonas Danielsson <jonas threetimestwo org>
+ */
+#ifndef __MAPSC_CONTACT_ADDRESS_H__
+#define __MAPSC_CONTACT_ADDRESS_H__
+
+#include <glib-object.h>
+
+#define MAPSC_TYPE_CONTACT_ADDRESS            (mapsc_contact_address_get_type ())
+#define MAPSC_CONTACT_ADDRESS(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), 
MAPSC_TYPE_CONTACT_ADDRESS, MapsCContactAddress))
+#define MAPSC_IS_CONTACT_ADDRESS(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), 
MAPSC_TYPE_CONTACT_ADDRESS))
+#define MAPSC_CONTACT_ADDRESS_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), MAPSC_TYPE_CONTACT_ADDRESS, 
MapsCContactAddressClass))
+#define MAPSC_IS_CONTACT_ADDRESS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MAPSC_TYPE_CONTACT_ADDRESS))
+#define MAPSC_CONTACT_ADDRESS_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), MAPSC_TYPE_CONTACT_ADDRESS, 
MapsCContactAddressClass))
+
+typedef struct _MapsCContactAddress MapsCContactAddress;
+typedef struct _MapsCContactAddressClass MapsCContactAddressClass;
+typedef struct _MapsCContactAddressPrivate MapsCContactAddressPrivate;
+
+struct _MapsCContactAddress {
+  GObject parent_instance;
+  MapsCContactAddressPrivate *priv;
+
+};
+
+struct _MapsCContactAddressClass {
+  GObjectClass parent_class;
+};
+
+GType mapsc_contact_address_get_type (void);
+
+MapsCContactAddress *mapsc_contact_address_new  (void);
+
+#endif
diff --git a/lib/mapsc-contact.c b/lib/mapsc-contact.c
new file mode 100644
index 0000000..54f3796
--- /dev/null
+++ b/lib/mapsc-contact.c
@@ -0,0 +1,216 @@
+/* -*- Mode: JS2; indent-tabs-mode: nil; js2-basic-offset: 4 -*- */
+/* vim: set et ts=4 sw=4: */
+/*
+ * GNOME Maps is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * GNOME Maps is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with GNOME Maps; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * Author: Jonas Danielsson <jonas threetimestwo org>
+ */
+
+
+#include <folks/folks.h>
+#include "mapsc-contact.h"
+
+
+struct _MapsCContactPrivate {
+  char *name;
+  char *id;
+
+  GLoadableIcon *icon;
+  GList *addresses;
+};
+
+enum {
+  PROP_0,
+
+  PROP_NAME,
+  PROP_ICON,
+  PROP_ID
+};
+
+static void
+mapsc_contact_set_property (GObject      *object,
+                            guint         property_id,
+                            const GValue *value,
+                            GParamSpec   *pspec)
+{
+        MapsCContact *contact = MAPSC_CONTACT (object);
+
+        switch (property_id) {
+        case PROP_NAME:
+          g_free (contact->priv->name);
+          contact->priv->name = g_value_dup_string (value);
+          break;
+
+        case PROP_ICON:
+          if (contact->priv->icon)
+            g_object_unref (contact->priv->icon);
+          contact->priv->icon = g_value_dup_object (value);
+          break;
+
+        case PROP_ID:
+          g_free (contact->priv->id);
+          contact->priv->id = g_value_dup_string (value);
+          break;
+
+        default:
+          G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+          break;
+        }
+}
+
+static void
+mapsc_contact_get_property (GObject    *object,
+                            guint       property_id,
+                            GValue     *value,
+                            GParamSpec *pspec)
+{
+        MapsCContact *contact = MAPSC_CONTACT (object);
+
+        switch (property_id) {
+        case PROP_NAME:
+          g_value_set_string (value,
+                              contact->priv->name);
+                break;
+
+        case PROP_ICON:
+          g_value_set_object (value,
+                              contact->priv->icon);
+                break;
+
+        case PROP_ID:
+          g_value_set_string (value,
+                              contact->priv->id);
+          break;
+
+        default:
+          G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+          break;
+        }
+}
+
+G_DEFINE_TYPE_WITH_PRIVATE (MapsCContact, mapsc_contact, G_TYPE_OBJECT)
+
+static void
+mapsc_contact_dispose (GObject *object)
+{
+  MapsCContact *contact = (MapsCContact *) object;
+
+  g_clear_pointer (&contact->priv->name, g_free);
+  g_clear_pointer (&contact->priv->id, g_free);
+  g_clear_object (&contact->priv->icon);
+  g_list_free_full (contact->priv->addresses, g_object_unref);
+
+  G_OBJECT_CLASS (mapsc_contact_parent_class)->dispose (object);
+}
+
+static void
+mapsc_contact_class_init (MapsCContactClass *klass)
+{
+  GObjectClass *mapsc_class = G_OBJECT_CLASS (klass);
+  GParamSpec *pspec;
+
+  mapsc_class->dispose = mapsc_contact_dispose;
+  mapsc_class->get_property = mapsc_contact_get_property;
+  mapsc_class->set_property = mapsc_contact_set_property;
+
+  /**
+   * MapsCContact:name:
+   *
+   * The name of the contact.
+   */
+  pspec = g_param_spec_string ("name",
+                               "Name",
+                               "Name",
+                               NULL,
+                               G_PARAM_READWRITE |
+                               G_PARAM_STATIC_STRINGS);
+  g_object_class_install_property (mapsc_class, PROP_NAME, pspec);
+
+  /**
+   * MapsCContact:id:
+   *
+   * The unique id of the contact.
+   */
+  pspec = g_param_spec_string ("id",
+                               "ID",
+                               "ID",
+                               NULL,
+                               G_PARAM_READWRITE |
+                               G_PARAM_STATIC_STRINGS);
+  g_object_class_install_property (mapsc_class, PROP_ID, pspec);
+
+  /**
+   * MapsCContact:icon:
+   *
+   * The icon of the contact.
+   */
+  pspec = g_param_spec_object ("icon",
+                               "Icon",
+                               "An icon representing the contact",
+                               G_TYPE_ICON,
+                               G_PARAM_READWRITE |
+                               G_PARAM_STATIC_STRINGS);
+  g_object_class_install_property (mapsc_class, PROP_ICON, pspec);
+}
+
+static void
+mapsc_contact_init (MapsCContact *contact)
+{
+  contact->priv = mapsc_contact_get_instance_private (contact);
+
+  contact->priv->name = NULL;
+  contact->priv->id = NULL;
+  contact->priv->icon = NULL;
+  contact->priv->addresses = NULL;
+}
+
+/**
+ * mapsc_contact_add_address:
+ * @contact: A #MapsCContact object
+ * @address: A #MapsCContactAddress object
+ *
+ **/
+void
+mapsc_contact_add_address (MapsCContact *contact,
+                           MapsCContactAddress *address)
+{
+  g_return_if_fail (contact != NULL);
+  g_return_if_fail (MAPSC_IS_CONTACT (contact));
+  g_return_if_fail (address != NULL);
+  g_return_if_fail (MAPSC_IS_CONTACT_ADDRESS (address));
+
+  contact->priv->addresses = g_list_prepend (contact->priv->addresses, address);
+}
+
+/**
+ * mapsc_contact_get_addresses:
+ * @contact: A #MapsCContact object
+ *
+ * Returns: (element-type MapsCContactAddress) (transfer container): a list of #MapsCContactAddress
+ **/
+GList *
+mapsc_contact_get_addresses (MapsCContact *contact)
+{
+  g_return_if_fail (contact != NULL);
+  g_return_if_fail (MAPSC_IS_CONTACT (contact));
+
+  return contact->priv->addresses;
+}
+
+MapsCContact *
+mapsc_contact_new ()
+{
+  return g_object_new (MAPSC_TYPE_CONTACT, NULL);
+}
diff --git a/lib/mapsc-contact.h b/lib/mapsc-contact.h
new file mode 100644
index 0000000..b15de82
--- /dev/null
+++ b/lib/mapsc-contact.h
@@ -0,0 +1,53 @@
+/* -*- Mode: JS2; indent-tabs-mode: nil; js2-basic-offset: 4 -*- */
+/* vim: set et ts=4 sw=4: */
+/*
+ * GNOME Maps is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * GNOME Maps is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with GNOME Maps; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * Author: Jonas Danielsson <jonas threetimestwo org>
+ */
+#ifndef __MAPSC_CONTACT_H__
+#define __MAPSC_CONTACT_H__
+
+#include <glib-object.h>
+#include "mapsc-contact-address.h"
+
+#define MAPSC_TYPE_CONTACT            (mapsc_contact_get_type ())
+#define MAPSC_CONTACT(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), MAPSC_TYPE_CONTACT, MapsCContact))
+#define MAPSC_IS_CONTACT(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MAPSC_TYPE_CONTACT))
+#define MAPSC_CONTACT_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), MAPSC_TYPE_CONTACT, 
MapsCContactClass))
+#define MAPSC_IS_CONTACT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MAPSC_TYPE_CONTACT))
+#define MAPSC_CONTACT_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), MAPSC_TYPE_CONTACT, 
MapsCContactClass))
+
+typedef struct _MapsCContact MapsCContact;
+typedef struct _MapsCContactClass MapsCContactClass;
+typedef struct _MapsCContactPrivate MapsCContactPrivate;
+
+struct _MapsCContact {
+  GObject parent_instance;
+  MapsCContactPrivate *priv;
+
+};
+
+struct _MapsCContactClass {
+  GObjectClass parent_class;
+};
+
+GType mapsc_contact_get_type (void);
+
+MapsCContact *mapsc_contact_new    (void);
+void mapsc_contact_add_address     (MapsCContact *contact,
+                                    MapsCContactAddress *address);
+GList *mapsc_contact_get_addresses (MapsCContact *contact);
+#endif
diff --git a/lib/mapsc-contacts.c b/lib/mapsc-contacts.c
new file mode 100644
index 0000000..574b2d9
--- /dev/null
+++ b/lib/mapsc-contacts.c
@@ -0,0 +1,241 @@
+/* -*- Mode: JS2; indent-tabs-mode: nil; js2-basic-offset: 4 -*- */
+/* vim: set et ts=4 sw=4: */
+/*
+ * GNOME Maps is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * GNOME Maps is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with GNOME Maps; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * Author: Jonas Danielsson <jonas threetimestwo org>
+ */
+
+
+#include <folks/folks.h>
+
+#include "mapsc-contacts.h"
+#include "mapsc-contact.h"
+
+struct _MapsCContactsPrivate {
+  GList *list;
+  FolksIndividualAggregator *aggregator;
+  MapsCContactsLoadCallback load_callback;
+};
+
+G_DEFINE_TYPE_WITH_PRIVATE (MapsCContacts, mapsc_contacts, G_TYPE_OBJECT)
+
+static void
+mapsc_contacts_dispose (GObject *object)
+{
+  MapsCContacts *contacts = (MapsCContacts *) object;
+
+  g_list_free (contacts->priv->list);
+  g_object_unref (contacts->priv->aggregator);
+
+  G_OBJECT_CLASS (mapsc_contacts_parent_class)->dispose (object);
+}
+
+static void
+mapsc_contacts_class_init (MapsCContactsClass *klass)
+{
+  GObjectClass *mapsc_class = G_OBJECT_CLASS (klass);
+  GParamSpec *pspec;
+
+  mapsc_class->dispose = mapsc_contacts_dispose;
+}
+
+static void
+mapsc_contacts_init (MapsCContacts *contacts)
+{
+  contacts->priv = mapsc_contacts_get_instance_private (contacts);
+  contacts->priv->list = NULL;
+  contacts->priv->load_callback = NULL;
+}
+
+static MapsCContact *
+get_contact (FolksIndividual *individual)
+{
+  MapsCContact *contact;
+  GLoadableIcon *avatar;
+  GeeCollection *set;
+  GeeIterator *iter;
+
+  g_object_get (G_OBJECT (individual), "postal-addresses", &set, NULL);
+  iter = gee_iterable_iterator (GEE_ITERABLE (set));
+
+  if (!gee_iterator_has_next (iter))
+    return NULL;
+
+  contact = mapsc_contact_new ();
+
+  g_object_set (G_OBJECT (contact), "name",
+                folks_individual_get_display_name (individual));
+  g_object_set (G_OBJECT (contact), "id",
+                folks_individual_get_id (individual));
+
+  g_object_get (G_OBJECT (individual), "avatar",
+                &avatar);
+  g_object_set (G_OBJECT (contact), "icon",
+                avatar);
+
+  while (gee_iterator_has_next (iter)) {
+    MapsCContactAddress *contact_address;
+    FolksPostalAddress *address;
+    FolksAbstractFieldDetails *details;
+    GeeCollection *values;
+    GeeIterator *values_iter;
+
+    gee_iterator_next (iter);
+    details = gee_iterator_get (iter);
+    address = (FolksPostalAddress *) folks_abstract_field_details_get_value (details);
+    contact_address = mapsc_contact_address_new ();
+
+    values = gee_multi_map_get_values (folks_abstract_field_details_get_parameters (details));
+    values_iter = gee_iterable_iterator (GEE_ITERABLE (values));
+    if (gee_iterator_has_next (values_iter)) {
+      char *type;
+
+      gee_iterator_next (values_iter);
+      type = gee_iterator_get (values_iter);
+      g_object_set (G_OBJECT (contact_address), "type", type, NULL);
+    }
+
+    g_object_set (G_OBJECT (contact_address), "country",
+                  folks_postal_address_get_country (address), NULL);
+    g_object_set (G_OBJECT (contact_address), "region",
+                  folks_postal_address_get_region (address), NULL);
+    g_object_set (G_OBJECT (contact_address), "locality",
+                  folks_postal_address_get_locality (address), NULL);
+    g_object_set (G_OBJECT (contact_address), "postal-code",
+                  folks_postal_address_get_postal_code (address), NULL);
+    g_object_set (G_OBJECT (contact_address), "street",
+                  folks_postal_address_get_street (address), NULL);
+
+    mapsc_contact_add_address (contact, contact_address);
+  }
+
+  return contact;
+}
+
+static void
+aggregator_quiescent_notify (FolksIndividualAggregator *aggregator,
+                             GParamSpec                *pspec,
+                             MapsCContacts             *contacts)
+{
+  GeeMap *map;
+  GeeMapIterator *iter;
+
+  map = folks_individual_aggregator_get_individuals (aggregator);
+  iter = gee_map_map_iterator (map);
+
+  while (gee_map_iterator_has_next (iter)) {
+    MapsCContact *contact;
+
+    gee_map_iterator_next (iter);
+    contact = get_contact (gee_map_iterator_get_value (iter));
+    if (contact)
+      contacts->priv->list = g_list_prepend (contacts->priv->list, contact);
+  }
+
+  contacts->priv->load_callback (contacts);
+}
+
+static void
+aggregator_prepare (FolksIndividualAggregator *aggregator,
+                    GAsyncResult              *res,
+                    gpointer                   user_data)
+{
+  folks_individual_aggregator_prepare_finish (aggregator, res, NULL);
+}
+
+MapsCContacts *
+mapsc_contacts_new ()
+{
+  return g_object_new (MAPSC_TYPE_CONTACTS, NULL);
+}
+
+static void
+mapsc_contacts_lookup_cb (FolksIndividualAggregator *aggregator,
+                          GAsyncResult *res,
+                          MapsCContactsLookupCallback callback)
+{
+  FolksIndividual *individual;
+
+  individual = folks_individual_aggregator_look_up_individual_finish (aggregator,
+                                                                      res,
+                                                                      NULL);
+  if (individual != NULL) {
+    MapsCContact *contact = get_contact (individual);
+    callback (contact);
+  } else {
+    callback (NULL);
+  }
+}
+
+/**
+ * mapsc_contacts_lookup:
+ * @contacts: A #MapsCContacts object
+ * @callback: (scope async): A #MapsCContactsLookupCallback function
+ *
+ **/
+void
+mapsc_contacts_lookup (MapsCContacts *contacts,
+                       const char * id,
+                       MapsCContactsLookupCallback callback)
+{
+  folks_individual_aggregator_look_up_individual (contacts->priv->aggregator,
+                                                  id,
+                                                  mapsc_contacts_lookup_cb,
+                                                  callback);
+}
+
+/**
+ * mapsc_contacts_load:
+ * @contacts: A #MapsCContacts object
+ * @callback: (scope async): A #MapsCContactsLoadCallback function
+ *
+ * Load contacts from available backends.
+ *
+ **/
+void
+mapsc_contacts_load (MapsCContacts            *contacts,
+                     MapsCContactsLoadCallback callback)
+{
+  g_return_if_fail (contacts != NULL);
+  g_return_if_fail (MAPSC_IS_CONTACTS (contacts));
+
+  contacts->priv->load_callback = callback;
+  contacts->priv->aggregator = folks_individual_aggregator_dup ();
+
+  g_signal_connect (G_OBJECT (contacts->priv->aggregator),
+                    "notify::is-quiescent",
+                    G_CALLBACK (aggregator_quiescent_notify),
+                    contacts);
+
+  folks_individual_aggregator_prepare (contacts->priv->aggregator,
+                                       (GAsyncReadyCallback) aggregator_prepare,
+                                       NULL);
+}
+
+/**
+ * mapsc_contacts_get_list:
+ * @contacts: A #MapsCContacts object
+ *
+ * Returns: (element-type MapsCContact) (transfer container): a list of #MapsCContact,
+ **/
+GList *
+mapsc_contacts_get_list (MapsCContacts *contacts)
+{
+  g_return_if_fail (contacts != NULL);
+  g_return_if_fail (MAPSC_IS_CONTACTS (contacts));
+
+  return contacts->priv->list;
+}
diff --git a/lib/mapsc-contacts.h b/lib/mapsc-contacts.h
new file mode 100644
index 0000000..0497478
--- /dev/null
+++ b/lib/mapsc-contacts.h
@@ -0,0 +1,70 @@
+/* -*- Mode: JS2; indent-tabs-mode: nil; js2-basic-offset: 4 -*- */
+/* vim: set et ts=4 sw=4: */
+/*
+ * GNOME Maps is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * GNOME Maps is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with GNOME Maps; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * Author: Jonas Danielsson <jonas threetimestwo org>
+ */
+
+#ifndef __MAPSC_CONTACTS_H__
+#define __MAPSC_CONTACTS_H__
+
+#include <glib-object.h>
+#include "mapsc-contact.h"
+
+#define MAPSC_TYPE_CONTACTS            (mapsc_contacts_get_type ())
+#define MAPSC_CONTACTS(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), MAPSC_TYPE_CONTACTS, 
MapsCContacts))
+#define MAPSC_IS_CONTACTS(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MAPSC_TYPE_CONTACTS))
+#define MAPSC_CONTACTS_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), MAPSC_TYPE_CONTACTS, 
MapsCContactsClass))
+#define MAPSC_IS_CONTACTS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MAPSC_TYPE_CONTACTS))
+#define MAPSC_CONTACTS_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), MAPSC_TYPE_CONTACTS, 
MapsCContactsClass))
+
+typedef struct _MapsCContacts MapsCContacts;
+typedef struct _MapsCContactsClass MapsCContactsClass;
+typedef struct _MapsCContactsPrivate MapsCContactsPrivate;
+
+/**
+ * MapsCContactsLoadCallback:
+ * @contacts: The #MapsCContacts object
+ **/
+typedef void (*MapsCContactsLoadCallback) (MapsCContacts *contacts);
+
+/**
+ * MapsCContactsLookupCallback:
+ * @contact: A #MapsCContact object
+ **/
+typedef void (*MapsCContactsLookupCallback) (MapsCContact *contact);
+
+struct _MapsCContacts {
+  GObject parent_instance;
+  MapsCContactsPrivate *priv;
+
+};
+
+struct _MapsCContactsClass {
+  GObjectClass parent_class;
+};
+
+GType mapsc_contacts_get_type (void);
+
+MapsCContacts *mapsc_contacts_new  (void);
+void mapsc_contacts_load           (MapsCContacts *contacts,
+                                    MapsCContactsLoadCallback callback);
+void mapsc_contacts_lookup         (MapsCContacts *contacts,
+                                    const char *id,
+                                    MapsCContactsLookupCallback callback);
+GList *mapsc_contacts_get_list     (MapsCContacts *contacts);
+
+#endif


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]