[gnome-maps/wip/contacts: 4/4] wipwip



commit 36dd06a17fbeec88187dc8d3d3ce9aad410f3232
Author: Jonas Danielsson <jonas threetimestwo org>
Date:   Wed Dec 10 07:00:39 2014 -0500

    wipwip

 configure.ac                |    2 +
 lib/mapsc-contact-address.c |   51 ++++++++++++++++++
 lib/mapsc-contact-address.h |    7 ++-
 lib/mapsc-contact.c         |  121 +++++++++++++++++++++++++++++++++++++++++++
 lib/mapsc-contact.h         |    8 +++
 lib/mapsc-contacts.c        |    4 +-
 src/application.js          |   43 ++++++++++-----
 src/geocodeService.js       |    1 +
 src/mapView.js              |    7 ++-
 9 files changed, 224 insertions(+), 20 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 794c972..5ecaec1 100644
--- a/configure.ac
+++ b/configure.ac
@@ -37,10 +37,12 @@ PKG_CHECK_MODULES(GNOME_MAPS, [
 
 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)
diff --git a/lib/mapsc-contact-address.c b/lib/mapsc-contact-address.c
index a058d6f..6fc8df7 100644
--- a/lib/mapsc-contact-address.c
+++ b/lib/mapsc-contact-address.c
@@ -30,6 +30,9 @@ struct _MapsCContactAddressPrivate {
   char *locality;
   char *postal_code;
   char *street;
+
+  double latitude;
+  double longitude;
 };
 
 enum {
@@ -276,6 +279,54 @@ mapsc_contact_address_init (MapsCContactAddress *contact)
   contact->priv->region = NULL;
   contact->priv->postal_code = NULL;
   contact->priv->locality = NULL;
+  contact->priv->latitude = -G_MAXDOUBLE;
+  contact->priv->longitude = -G_MAXDOUBLE;
+}
+
+/**
+ * mapsc_contact_address_set_location:
+ * @address: A #MapsCContactAddress object
+ * @latitude: The latitude of the address
+ * @longitude: The longitude of the address
+ * 
+ **/
+void
+mapsc_contact_address_set_location (MapsCContactAddress *address,
+                                    double               latitude,
+                                    double               longitude)
+{
+  g_return_if_fail (address != NULL);
+  g_return_if_fail (MAPSC_IS_CONTACT_ADDRESS (address));
+
+  address->priv->latitude = latitude;
+  address->priv->longitude = longitude;
+}
+
+/**
+ * mapsc_contact_address_get_location:
+ * @address: A #MapsCContactAddress object
+ * @latitude: (out): The latitude of the address
+ * @longitude: (out): The latitude of the address
+ * 
+ * Returns: %TRUE if @address have a location.
+ **/
+gboolean
+mapsc_contact_address_get_location (MapsCContactAddress *address,
+                                    double              *latitude,
+                                    double              *longitude)
+{
+  g_return_if_fail (address != NULL);
+  g_return_if_fail (MAPSC_IS_CONTACT_ADDRESS (address));
+
+  if (address->priv->latitude == -G_MAXDOUBLE ||
+      address->priv->longitude == -G_MAXDOUBLE) {
+    return FALSE;
+  }
+
+  *latitude = address->priv->latitude;
+  *longitude = address->priv->longitude;
+
+  return TRUE;
 }
 
 MapsCContactAddress *
diff --git a/lib/mapsc-contact-address.h b/lib/mapsc-contact-address.h
index b4ecae7..bb0244e 100644
--- a/lib/mapsc-contact-address.h
+++ b/lib/mapsc-contact-address.h
@@ -46,5 +46,10 @@ struct _MapsCContactAddressClass {
 GType mapsc_contact_address_get_type (void);
 
 MapsCContactAddress *mapsc_contact_address_new  (void);
-
+void mapsc_contact_address_set_location         (MapsCContactAddress *address,
+                                                 double               latitude,
+                                                 double               longitude);
+gboolean mapsc_contact_address_get_location     (MapsCContactAddress *address,
+                                                 double              *latitude,
+                                                 double              *longitude);
 #endif
diff --git a/lib/mapsc-contact.c b/lib/mapsc-contact.c
index 54f3796..fb23d37 100644
--- a/lib/mapsc-contact.c
+++ b/lib/mapsc-contact.c
@@ -20,6 +20,8 @@
 
 
 #include <folks/folks.h>
+#include <geocode-glib/geocode-glib.h>
+
 #include "mapsc-contact.h"
 
 
@@ -29,8 +31,20 @@ struct _MapsCContactPrivate {
 
   GLoadableIcon *icon;
   GList *addresses;
+
+  GMutex geocode_mutex;
+  guint geocode_counter;
+  guint geocodes_to_perform;
 };
 
+typedef struct {
+  MapsCContactAddress *address;
+  MapsCContact *contact;
+  MapsCContactGeocodeCallback callback;
+
+  GHashTable *params;
+} GeocodeData;
+
 enum {
   PROP_0,
 
@@ -174,6 +188,8 @@ mapsc_contact_init (MapsCContact *contact)
   contact->priv->id = NULL;
   contact->priv->icon = NULL;
   contact->priv->addresses = NULL;
+  
+  g_mutex_init (&contact->priv->geocode_mutex);
 }
 
 /**
@@ -209,6 +225,111 @@ mapsc_contact_get_addresses (MapsCContact *contact)
   return contact->priv->addresses;
 }
 
+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);
+
+    mapsc_contact_address_set_location (data->address,
+                                        geocode_location_get_latitude (location),
+                                        geocode_location_get_longitude (location));
+  }
+
+  
+  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->addresses);
+
+  for (l = contact->priv->addresses; l != NULL; l = l->next) {
+    MapsCContactAddress *address = l->data;
+    char *street;
+    char *locality;
+    char *county;
+    char *country;
+    GeocodeData *data;
+
+    data = g_slice_new (GeocodeData);
+    data->contact = contact;
+    data->address = l->data;
+    data->callback = callback;
+    data->params = g_hash_table_new_full (g_str_hash,
+                                          g_str_equal,
+                                          g_free,
+                                          g_free);
+
+    g_object_get (G_OBJECT (address), "street", &street);
+    add_attribute (data->params, "street", street);
+    
+    g_object_get (G_OBJECT (address), "locality", &locality);
+    add_attribute (data->params, "locality", locality);
+
+    g_object_get (G_OBJECT (address), "region", &county);
+    add_attribute (data->params, "region", county);
+
+    g_object_get (G_OBJECT (address), "country", &country);
+    add_attribute (data->params, "country", country);
+
+    forward = geocode_forward_new_for_params (data->params);
+    geocode_forward_search_async (forward,
+                                  NULL,
+                                  (GAsyncReadyCallback) on_geocode_search_async,
+                                  data);
+  }
+}
+
 MapsCContact *
 mapsc_contact_new ()
 {
diff --git a/lib/mapsc-contact.h b/lib/mapsc-contact.h
index b15de82..50363b8 100644
--- a/lib/mapsc-contact.h
+++ b/lib/mapsc-contact.h
@@ -34,6 +34,12 @@ 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;
@@ -50,4 +56,6 @@ MapsCContact *mapsc_contact_new    (void);
 void mapsc_contact_add_address     (MapsCContact *contact,
                                     MapsCContactAddress *address);
 GList *mapsc_contact_get_addresses (MapsCContact *contact);
+void mapsc_contact_geocode (MapsCContact *contact,
+                            MapsCContactGeocodeCallback callback);
 #endif
diff --git a/lib/mapsc-contacts.c b/lib/mapsc-contacts.c
index 844ae0e..7bc8d6a 100644
--- a/lib/mapsc-contacts.c
+++ b/lib/mapsc-contacts.c
@@ -146,8 +146,8 @@ get_contact (FolksIndividual *individual)
     details = gee_iterator_get (iter);
     address = (FolksPostalAddress *) folks_abstract_field_details_get_value (details);
 
-    g_object_get (G_OBJECT (address), "id", &id);
-
+    g_print ("id: %s\n", folks_abstract_field_details_get_id (details));
+    
     values = gee_multi_map_get_values (folks_abstract_field_details_get_parameters (details));
     values_iter = gee_iterable_iterator (GEE_ITERABLE (values));
     if (!values_iter)
diff --git a/src/application.js b/src/application.js
index decc8bb..50aec6c 100644
--- a/src/application.js
+++ b/src/application.js
@@ -21,6 +21,7 @@
  *         Zeeshan Ali (Khattak) <zeeshanak gnome org>
  */
 
+const Geocode = imports.gi.GeocodeGlib;
 const GLib = imports.gi.GLib;
 const GObject = imports.gi.GObject;
 const Gettext = imports.gettext;
@@ -108,20 +109,34 @@ const Application = new Lang.Class({
 
         let contactArray = [];
         contacts.lookup(parameter.deep_unpack(), (function(contact) {
-            contact.get_addresses().forEach(function(address) {
-                contactArray.push(new Contact.Contact({ name: contact.name,
-                                                        id: contact.id,
-                                                        icon: contact.icon,
-                                                        type: address.type,
-                                                        street_address: address.street,
-                                                        county: address.region,
-                                                        town: address.locality,
-                                                        postal_code: address.postal_code,
-                                                        country: address.country
-                                                      }));
-            });
-
-            this._mainWindow.mapView.showContact(contactArray);
+            contact.geocode((function() {
+                
+                contact.get_addresses().forEach(function(address) {
+                    let [status, latitude, longitude] = address.get_location();
+
+                    if (!status) {
+                        log ('no location');
+                        return;
+                    }
+                    
+                    let location = new Geocode.Location({ latitude: latitude,
+                                                          longitude: longitude });
+
+                    contactArray.push(new Contact.Contact({ name: contact.name,
+                                                            id: contact.id,
+                                                            icon: contact.icon,
+                                                            type: address.type,
+                                                            street_address: address.street,
+                                                            county: address.region,
+                                                            town: address.locality,
+                                                            postal_code: address.postal_code,
+                                                            country: address.country,
+                                                            location: location
+                                                          }));
+                });
+                
+                this._mainWindow.mapView.showContact(contactArray);
+            }).bind(this));
         }).bind(this));
     },
 
diff --git a/src/geocodeService.js b/src/geocodeService.js
index e5e1df1..ec23d57 100644
--- a/src/geocodeService.js
+++ b/src/geocodeService.js
@@ -22,6 +22,7 @@
  */
 
 const Geocode = imports.gi.GeocodeGlib;
+const GObject = imports.gi.GObject;
 const Lang = imports.lang;
 
 const Application = imports.application;
diff --git a/src/mapView.js b/src/mapView.js
index 0ac0cc6..ec8105e 100644
--- a/src/mapView.js
+++ b/src/mapView.js
@@ -194,15 +194,16 @@ const MapView = new Lang.Class({
 
     showContact: function(contacts) {
         this._searchResultLayer.remove_all();
-        contacts.forEach(function(contact) {
+        contacts.forEach((function(contact) {
             let marker = new SearchResultMarker.SearchResultMarker({ place: contact,
                                                                      mapView: this });
             this._searchResultLayer.add_marker(marker);
-        });
+        }).bind(this));
 
         if (contacts.length > 0) {
+            this.view.zoom_level = this.view.max_zoom_level - 2;
             let bbox = this._searchResultLayer.get_bounding_box();
-            this.view.ensure_visible(bbox, true);
+            this.view.ensure_visible(bbox, false);
         }
     },
 


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