[gnome-maps/wip/contacts: 10/17] Add c shim library
- From: Jonas Danielsson <jonasdn src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-maps/wip/contacts: 10/17] Add c shim library
- Date: Tue, 16 Dec 2014 09:53:01 +0000 (UTC)
commit 794a96fd07dc2b12e8d5a707281ab35f61ec370e
Author: Jonas Danielsson <jonas threetimestwo org>
Date: Tue Dec 16 03:35:02 2014 -0500
Add c shim library
Makefile.am | 2 +-
configure.ac | 17 +++
lib/Makefile.am | 63 +++++++++
lib/mapsc-contact.c | 340 ++++++++++++++++++++++++++++++++++++++++++++++++++
lib/mapsc-contact.h | 61 +++++++++
lib/mapsc-contacts.c | 302 ++++++++++++++++++++++++++++++++++++++++++++
lib/mapsc-contacts.h | 76 +++++++++++
lib/mapsc.h | 9 ++
8 files changed, 869 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 b0f8fe2..4f4c02d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -22,6 +22,9 @@ AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE,"$GETTEXT_PACKAGE",[The name of the gettext d
IT_PROG_INTLTOOL(0.40.0)
PKG_PROG_PKG_CONFIG([0.22])
+GLIB_MKENUMS=`$PKG_CONFIG --variable=glib_mkenums glib-2.0`
+AC_SUBST(GLIB_MKENUMS)
+
GIO_MIN_VERSION=2.39.3
GJS_MIN_VERSION=1.39.0
GOBJECT_INTROSPECTION_MIN_VERSION=0.10.1
@@ -32,6 +35,17 @@ 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
+GEOCODE_MIN_VERSION=3.14
+
+PKG_CHECK_MODULES(MAPSC, [
+ gee-0.8 >= $GEE_MIN_VERSION
+ folks >= $FOLKS_MIN_VERSION
+ geocode-glib-1.0 >= $GEOCODE_MIN_VERSION
+])
+AC_SUBST(MAPSC_CFLAGS)
+AC_SUBST(MAPSC_LIBS)
# no stupid static libraries
AM_DISABLE_STATIC
@@ -47,8 +61,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..779a077
--- /dev/null
+++ b/lib/Makefile.am
@@ -0,0 +1,63 @@
+lib_LTLIBRARIES = libmapsc.la
+
+BUILT_SOURCES = \
+ mapsc-enum-types.c \
+ mapsc-enum-types.h
+
+libmapsc_headers_public = mapsc-contacts.h mapsc-contact.h
+libmapsc_sources = mapsc-contacts.c mapsc-contact.c
+libmapsc_la_SOURCES = $(libmapsc_sources) $(libmapsc_headers_public) $(BUILT_SOURCES)
+libmapsc_la_LIBADD = $(MAPSC_LIBS)
+
+AM_CPPFLAGS = \
+ $(MAPSC_CFLAGS) \
+ -I$(top_srcdir)
+
+mapsc-enum-types.h: $(libmapsc_headers_public)
+ $(AM_V_GEN) ($(GLIB_MKENUMS) \
+ --symbol-prefix mapsc \
+ --identifier-prefix MapsC \
+ --fhead "#ifndef __MAPSC_ENUM_TYPES_H__\n#define __MAPSC_ENUM_TYPES_H__\n\n#include
\"mapsc-contacts.h\"\n\nG_BEGIN_DECLS\n" \
+ --fprod "/* enumeratiobns from \"@filename \" */\n" \
+ --vhead "GType @enum_name _get_type (void) G_GNUC_CONST;\n#define MAPSC_TYPE_ ENUMSHORT@
(@enum_name _get_type())\n\n/**\n * SECTION:mapsc-enum-types\n * @short_description: Mapsc enumerated types\n
* @include: mapsc.h\n *\n * The enumerated types defined and used by libmapsc.\n **/" \
+ --ftail "G_END_DECLS\n\n#endif /* __MAPSC_ENUM_TYPES_H__ */" $^ > xgen-$(@F) \
+ && mv -f xgen-$(@F) $@)
+
+mapsc-enum-types.c: $(libmapsc_headers_public) mapsc-enum-types.h
+ $(AM_V_GEN) ($(GLIB_MKENUMS) \
+ --symbol-prefix mapsc \
+ --identifier-prefix MapsC \
+ --fhead "#include <mapsc-enum-types.h>" \
+ --fprod "\n/* enumerations from \"@filename \" */" \
+ --vhead "GType\n enum_name@_get_type (void)\n{\n static GType etype = 0;\n if (etype == 0)
{\n static const G Type@Value values[] = {" \
+ --vprod " { @VALUENAME@, \"@VALUENAME \", \"@valuenick \" }," \
+ --vtail " { 0, NULL, NULL }\n };\n etype = g_ type@_register_static (\"@EnumName
\", values);\n }\n return etype;\n}\n" $^ > xgen-$(@F) \
+ && mv -f xgen-$(@F) $@)
+
+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 GeocodeGlib-1.0
+MapsC_1_0_gir_PACKAGES = gobject-2.0 geocode-glib-1.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
+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) $(BUILT_SOURCES)
+endif
diff --git a/lib/mapsc-contact.c b/lib/mapsc-contact.c
new file mode 100644
index 0000000..f142570
--- /dev/null
+++ b/lib/mapsc-contact.c
@@ -0,0 +1,340 @@
+/* -*- 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 <geocode-glib/geocode-glib.h>
+
+#include "mapsc-contact.h"
+
+struct _MapsCContactPrivate {
+ char *name;
+ char *id;
+
+ GLoadableIcon *icon;
+ GList *places;
+
+ GMutex geocode_mutex;
+ guint geocode_counter;
+ guint geocodes_to_perform;
+};
+
+typedef struct {
+ GeocodePlace *place;
+ MapsCContact *contact;
+ MapsCContactGeocodeCallback callback;
+
+ GHashTable *params;
+} GeocodeData;
+
+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->places, 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->places = NULL;
+
+ g_mutex_init (&contact->priv->geocode_mutex);
+}
+
+/**
+ * mapsc_contact_add_address:
+ * @contact: A #MapsCContact object
+ * @place: A #GeocodePlace object
+ *
+ **/
+void
+mapsc_contact_add_place (MapsCContact *contact,
+ GeocodePlace *place)
+{
+ g_return_if_fail (contact != NULL);
+ g_return_if_fail (MAPSC_IS_CONTACT (contact));
+ g_return_if_fail (place != NULL);
+ g_return_if_fail (GEOCODE_IS_PLACE (place));
+
+ contact->priv->places = g_list_prepend (contact->priv->places, place);
+}
+
+/**
+ * mapsc_contact_get_places:
+ * @contact: A #MapsCContact object
+ *
+ * Returns: (element-type GeocodePlace) (transfer container): a list of #GeocodePlace
+ **/
+GList *
+mapsc_contact_get_places (MapsCContact *contact)
+{
+ g_return_if_fail (contact != NULL);
+ g_return_if_fail (MAPSC_IS_CONTACT (contact));
+
+ return contact->priv->places;
+}
+
+static void
+on_geocode_search_async (GeocodeForward *forward,
+ GAsyncResult *res,
+ GeocodeData *data)
+{
+ MapsCContact *contact;
+ GList *places;
+ gboolean call_callback = FALSE;
+
+ contact = data->contact;
+ places = geocode_forward_search_finish (forward, res, NULL);
+
+ if (places) {
+ GeocodePlace *place = g_list_nth_data (places, 0);
+ GeocodeLocation *location = geocode_place_get_location (place);
+ const char *street_address;
+
+ geocode_place_set_location (data->place, location);
+ g_object_set (G_OBJECT (data->place), "osm-type",
+ geocode_place_get_osm_type (place));
+ g_object_set (G_OBJECT (data->place), "osm-id",
+ geocode_place_get_osm_id (place));
+
+ street_address = geocode_place_get_street_address (place);
+ if (street_address) {
+ g_object_set (G_OBJECT (data->place), "street-address",
+ street_address);
+ } else {
+ g_object_set (G_OBJECT (data->place), "street-address",
+ geocode_place_get_street (place));
+
+ }
+ }
+
+ g_mutex_lock (&contact->priv->geocode_mutex);
+
+ contact->priv->geocode_counter++;
+ if (contact->priv->geocode_counter == contact->priv->geocodes_to_perform)
+ call_callback = TRUE;
+
+ g_mutex_unlock (&contact->priv->geocode_mutex);
+
+ g_hash_table_destroy (data->params);
+
+ if (call_callback)
+ data->callback (contact);
+}
+
+static void add_attribute (GHashTable *ht,
+ const char *key,
+ const char *s)
+{
+ GValue *value;
+ value = g_new0 (GValue, 1);
+ g_value_init (value, G_TYPE_STRING);
+ g_value_set_static_string (value, s);
+ g_hash_table_insert (ht, g_strdup (key), value);
+
+}
+
+/**
+ * mapsc_contact_geocode:
+ * @contact: A #MapsCContact object
+ * @callback: (scope async): A #MapsCContactGeocodeCallback function
+ *
+ **/
+void
+mapsc_contact_geocode (MapsCContact *contact,
+ MapsCContactGeocodeCallback callback)
+{
+ g_return_if_fail (contact != NULL);
+ g_return_if_fail (MAPSC_IS_CONTACT (contact));
+ g_return_if_fail (callback != NULL);
+
+ GeocodeForward *forward;
+ GList *l;
+
+ contact->priv->geocode_counter = 0;
+ contact->priv->geocodes_to_perform = g_list_length (contact->priv->places);
+
+ for (l = contact->priv->places; l != NULL; l = l->next) {
+ GeocodeData *data;
+
+ data = g_slice_new (GeocodeData);
+ data->contact = contact;
+ data->place = l->data;
+ data->callback = callback;
+ data->params = g_hash_table_new_full (g_str_hash,
+ g_str_equal,
+ g_free,
+ g_free);
+
+ add_attribute (data->params, "street",
+ geocode_place_get_street_address (data->place));
+ add_attribute (data->params, "locality",
+ geocode_place_get_town (data->place));
+ add_attribute (data->params, "region",
+ geocode_place_get_state (data->place));
+ add_attribute (data->params, "country",
+ geocode_place_get_country (data->place));
+
+ forward = geocode_forward_new_for_params (data->params);
+ geocode_forward_search_async (forward,
+ NULL,
+ (GAsyncReadyCallback) on_geocode_search_async,
+ data);
+ }
+}
+
+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..520e120
--- /dev/null
+++ b/lib/mapsc-contact.h
@@ -0,0 +1,61 @@
+/* -*- 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 <geocode-glib/geocode-glib.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;
+
+/**
+ * MapsCContactGeocodeCallback:
+ * @contact: A #MapsCContact object
+ **/
+typedef void (*MapsCContactGeocodeCallback) (MapsCContact *contact);
+
+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_place (MapsCContact *contact,
+ GeocodePlace *place);
+GList *mapsc_contact_get_places (MapsCContact *contact);
+void mapsc_contact_geocode (MapsCContact *contact,
+ MapsCContactGeocodeCallback callback);
+#endif
diff --git a/lib/mapsc-contacts.c b/lib/mapsc-contacts.c
new file mode 100644
index 0000000..0765dc4
--- /dev/null
+++ b/lib/mapsc-contacts.c
@@ -0,0 +1,302 @@
+/* -*- 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 <geocode-glib/geocode-glib.h>
+
+#include "mapsc-contacts.h"
+#include "mapsc-contact.h"
+#include "mapsc-enum-types.h"
+
+struct _MapsCContactsPrivate {
+ GList *list;
+ MapsCContactsState state;
+ FolksIndividualAggregator *aggregator;
+};
+
+enum {
+ PROP_0,
+
+ PROP_STATE
+};
+
+G_DEFINE_TYPE_WITH_PRIVATE (MapsCContacts, mapsc_contacts, G_TYPE_OBJECT)
+
+static void
+mapsc_contacts_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ MapsCContacts *contacts = MAPSC_CONTACTS (object);
+
+ switch (property_id) {
+ case PROP_STATE:
+ g_value_set_enum (value,
+ contacts->priv->state);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+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;
+ mapsc_class->get_property = mapsc_contacts_get_property;
+
+ /**
+ * MapsCContacts:state:
+ *
+ * The type of the contact.
+ */
+ pspec = g_param_spec_enum ("state",
+ "State",
+ "State",
+ MAPSC_TYPE_CONTACTS_STATE,
+ MAPSC_CONTACTS_STATE_INITIAL,
+ G_PARAM_READABLE |
+ G_PARAM_STATIC_STRINGS);
+ g_object_class_install_property (mapsc_class, PROP_STATE, pspec);
+
+}
+
+static void
+mapsc_contacts_init (MapsCContacts *contacts)
+{
+ contacts->priv = mapsc_contacts_get_instance_private (contacts);
+ contacts->priv->list = NULL;
+ contacts->priv->state = MAPSC_CONTACTS_STATE_INITIAL;
+}
+
+static MapsCContact *
+get_contact (FolksIndividual *individual)
+{
+ MapsCContact *contact;
+ GLoadableIcon *avatar;
+ GeeCollection *set;
+ GeeIterator *iter;
+
+ g_object_get (G_OBJECT (individual), "postal-addresses", &set, NULL);
+ if (!set)
+ return NULL;
+
+ iter = gee_iterable_iterator (GEE_ITERABLE (set));
+ if (!iter)
+ return NULL;
+
+ 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)) {
+ GeocodePlace *place;
+ FolksPostalAddress *addr;
+ FolksAbstractFieldDetails *details;
+ GeeCollection *values;
+ GeeMultiMap *map;
+ GeeIterator *values_iter;
+ char *name;
+ char *type = "Unknown";
+
+ gee_iterator_next (iter);
+ details = gee_iterator_get (iter);
+ addr = (FolksPostalAddress *) folks_abstract_field_details_get_value (details);
+
+ map = folks_abstract_field_details_get_parameters (details);
+ values = gee_multi_map_get_values (map);
+ values_iter = gee_iterable_iterator (GEE_ITERABLE (values));
+ if (!values_iter)
+ return NULL;
+
+ if (gee_iterator_has_next (values_iter)) {
+ gee_iterator_next (values_iter);
+ type = gee_iterator_get (values_iter);
+ }
+
+ name = g_strdup_printf ("%s (%s)",
+ folks_individual_get_display_name (individual),
+ type);
+ place = geocode_place_new (name, GEOCODE_PLACE_TYPE_UNKNOWN);
+ g_free (name);
+
+ geocode_place_set_country (place,
+ folks_postal_address_get_country (addr));
+ geocode_place_set_state (place,
+ folks_postal_address_get_region (addr));
+ geocode_place_set_postal_code (place,
+ folks_postal_address_get_postal_code (addr));
+ geocode_place_set_town (place,
+ folks_postal_address_get_locality (addr));
+ geocode_place_set_street_address (place,
+ folks_postal_address_get_street (addr));
+
+ mapsc_contact_add_place (contact, place);
+ }
+
+ return contact;
+}
+
+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,
+ (GAsyncReadyCallback) mapsc_contacts_lookup_cb,
+ callback);
+}
+
+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);
+ if (!iter)
+ return;
+
+ 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->state = MAPSC_CONTACTS_STATE_LOADED;
+ g_object_notify (G_OBJECT (contacts), "state");
+}
+
+static void
+aggregator_prepare (FolksIndividualAggregator *aggregator,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ folks_individual_aggregator_prepare_finish (aggregator, res, NULL);
+}
+
+/**
+ * mapsc_contacts_load:
+ * @contacts: A #MapsCContacts object
+ *
+ * Load contacts from available backends.
+ *
+ **/
+void
+mapsc_contacts_load (MapsCContacts *contacts)
+{
+ g_return_if_fail (contacts != NULL);
+ g_return_if_fail (MAPSC_IS_CONTACTS (contacts));
+
+ contacts->priv->aggregator = folks_individual_aggregator_dup ();
+
+ g_signal_connect (G_OBJECT (contacts->priv->aggregator),
+ "notify::is-quiescent",
+ G_CALLBACK (aggregator_quiescent_notify),
+ contacts);
+
+ contacts->priv->state = MAPSC_CONTACTS_STATE_LOADING;
+ g_object_notify (G_OBJECT (contacts), "state");
+
+ 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..5671261
--- /dev/null
+++ b/lib/mapsc-contacts.h
@@ -0,0 +1,76 @@
+/* -*- 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;
+
+/**
+ * MapsCContactsState:
+ * @MAPSC_CONTACTS_STATE_INITIAL: Initial state
+ * @MAPSC_CONTACTS_STATE_LOADING: Loading
+ * @MAPSC_CONTACTS_STATE_LOADED: Loaded
+ */
+typedef enum
+ {
+ MAPSC_CONTACTS_STATE_INITIAL,
+ MAPSC_CONTACTS_STATE_LOADING,
+ MAPSC_CONTACTS_STATE_LOADED,
+} MapsCContactsState;
+
+/**
+ * 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);
+void mapsc_contacts_lookup (MapsCContacts *contacts,
+ const char *id,
+ MapsCContactsLookupCallback callback);
+GList *mapsc_contacts_get_list (MapsCContacts *contacts);
+
+#endif
diff --git a/lib/mapsc.h b/lib/mapsc.h
new file mode 100644
index 0000000..8150c91
--- /dev/null
+++ b/lib/mapsc.h
@@ -0,0 +1,9 @@
+#ifndef __MAPSC_CONTACTS_H__
+#define __MAPSC_CONTACTS_H__
+
+#include <glib-object.h>
+#include "mapsc-contacts.h"
+#include "mapsc-contact.h"
+#include "mapsc-contact-address.h"
+
+#endif
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]