[libgweather] gweather-location: fix localization of matches in the location entry



commit ca3c22b8fed221e07770266d70a802209a691d5f
Author: Giovanni Campagna <gcampagna src gnome org>
Date:   Sun Jun 15 15:41:11 2014 +0200

    gweather-location: fix localization of matches in the location entry
    
    We need to keep both the English and the local variant of the sort
    name in the location and in the model, to be able to match on both.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=726897

 libgweather/gweather-location.c |   77 +++++++++++++-----------------
 libgweather/location-entry.c    |  101 +++++++++++++++++++++++----------------
 libgweather/weather-priv.h      |    2 +-
 libgweather/weather-yrno.c      |    6 +-
 4 files changed, 96 insertions(+), 90 deletions(-)
---
diff --git a/libgweather/gweather-location.c b/libgweather/gweather-location.c
index ac9f8c4..2eabdad 100644
--- a/libgweather/gweather-location.c
+++ b/libgweather/gweather-location.c
@@ -89,7 +89,7 @@ sort_locations_by_name (gconstpointer a, gconstpointer b)
     GWeatherLocation *loc_a = *(GWeatherLocation **)a;
     GWeatherLocation *loc_b = *(GWeatherLocation **)b;
 
-    return g_utf8_collate (loc_a->sort_name, loc_b->sort_name);
+    return g_utf8_collate (loc_a->local_sort_name, loc_b->local_sort_name);
 }
  
 static int
@@ -156,14 +156,26 @@ location_new_from_xml (GWeatherParser *parser, GWeatherLocationLevel level,
        }
 
        tagname = (const char *) xmlTextReaderConstName (parser->xml);
-       if (!strcmp (tagname, "name") && !loc->name) {
+       if (!strcmp (tagname, "name") && !loc->english_name) {
             loc->msgctxt = _gweather_parser_get_msgctxt_value (parser);
            value = _gweather_parser_get_value (parser);
            if (!value)
                goto error_out;
-           loc->name = value;
-           normalized = g_utf8_normalize (loc->name, -1, G_NORMALIZE_ALL);
-           loc->sort_name = g_utf8_casefold (normalized, -1);
+
+           loc->english_name = value;
+           if (loc->msgctxt) {
+               loc->local_name = g_strdup (g_dpgettext2 ("libgweather-locations",
+                                                         (char*) loc->msgctxt, value));
+           } else {
+               loc->local_name = g_strdup (g_dgettext ("libgweather-locations", value));
+           }
+
+           normalized = g_utf8_normalize (loc->local_name, -1, G_NORMALIZE_ALL);
+           loc->local_sort_name = g_utf8_casefold (normalized, -1);
+           g_free (normalized);
+
+           normalized = g_utf8_normalize (loc->english_name, -1, G_NORMALIZE_ALL);
+           loc->english_sort_name = g_utf8_casefold (normalized, -1);
            g_free (normalized);
        } else if (!strcmp (tagname, "iso-code") && !loc->country_code) {
            value = _gweather_parser_get_value (parser);
@@ -370,9 +382,11 @@ gweather_location_unref (GWeatherLocation *loc)
 
     g_return_if_fail (loc->level != GWEATHER_LOCATION_WORLD);
 
-    g_free (loc->name);
+    g_free (loc->english_name);
+    g_free (loc->local_name);
     g_free (loc->msgctxt);
-    g_free (loc->sort_name);
+    g_free (loc->local_sort_name);
+    g_free (loc->english_sort_name);
     g_free (loc->country_code);
     g_free (loc->tz_hint);
     g_free (loc->station_code);
@@ -422,11 +436,6 @@ gweather_location_get_type (void)
  *
  * Gets @loc's name, localized into the current language.
  *
- * Note that %GWEATHER_LOCATION_WEATHER_STATION nodes are not
- * localized, and so the name returned for those nodes will always be
- * in English, and should therefore not be displayed to the user.
- * (FIXME: should we just not return a name?)
- *
  * Return value: @loc's name
  **/
 const char *
@@ -434,16 +443,7 @@ gweather_location_get_name (GWeatherLocation *loc)
 {
     g_return_val_if_fail (loc != NULL, NULL);
 
-    const char *ret;
-
-    if (loc->msgctxt) {
-       ret = (const char*) g_dpgettext2 ("libgweather-locations",
-                                      (char*) loc->msgctxt, (char*) loc->name);
-    } else {
-       ret = (const char*) g_dgettext ("libgweather-locations", (char*) loc->name);
-    }
-
-    return g_strdup (ret);
+    return g_strdup (loc->local_name);
 }
 
 /**
@@ -461,7 +461,7 @@ const char *
 gweather_location_get_sort_name (GWeatherLocation *loc)
 {
     g_return_val_if_fail (loc != NULL, NULL);
-    return loc->sort_name;
+    return loc->local_sort_name;
 }
 
 /**
@@ -1033,26 +1033,13 @@ gweather_location_get_city_name (GWeatherLocation *loc)
 {
     g_return_val_if_fail (loc != NULL, NULL);
 
-    const char *ret;
-
     if (loc->level == GWEATHER_LOCATION_CITY ||
         loc->level == GWEATHER_LOCATION_DETACHED) {
-        if (loc->msgctxt) {
-            ret = (const char*) g_dpgettext2 ("libgweather-locations", (char*) loc->msgctxt, (char*) 
loc->name);
-        } else {
-            ret = (const char*) g_dgettext ("libgweather-locations", (char*) loc->name);
-        }
-
-        return g_strdup (ret);
+        return g_strdup (loc->local_name);
     } else if (loc->level == GWEATHER_LOCATION_WEATHER_STATION &&
                loc->parent &&
                loc->parent->level == GWEATHER_LOCATION_CITY) {
-        if (loc->parent->msgctxt) {
-            ret = (const char*) g_dpgettext2 ("libgweather-locations", (char*) loc->parent->msgctxt, (char*) 
loc->parent->name);
-        } else {
-            ret = (const char*) g_dgettext ("libgweather-locations", (char*) loc->parent->name);
-        }
-        return g_strdup (ret);
+        return g_strdup (loc->parent->local_name);
     } else
         return NULL;
 }
@@ -1092,7 +1079,7 @@ _gweather_location_update_weather_location (GWeatherLocation *gloc,
        l = l->parent;
     }
 
-    loc->name = g_strdup (gweather_location_get_name (gloc)),
+    loc->name = g_strdup (gloc->local_name),
     loc->code = g_strdup (code);
     loc->zone = g_strdup (zone);
     loc->yahoo_id = g_strdup (yahoo_id);
@@ -1171,7 +1158,7 @@ gweather_location_equal (GWeatherLocation *one,
 
     if (level == GWEATHER_LOCATION_ADM1 ||
        level == GWEATHER_LOCATION_ADM2) {
-       if (g_strcmp0 (one->sort_name, two->sort_name) != 0)
+       if (g_strcmp0 (one->english_sort_name, two->english_sort_name) != 0)
            return FALSE;
 
        return one->parent && two->parent &&
@@ -1202,7 +1189,7 @@ gweather_location_format_two_serialize (GWeatherLocation *location)
     GVariantBuilder latlon_builder;
     GVariantBuilder parent_latlon_builder;
 
-    name = location->name;
+    name = location->english_name;
 
     /* Normalize location to be a weather station or detached */
     if (location->level == GWEATHER_LOCATION_CITY) {
@@ -1238,10 +1225,12 @@ _gweather_location_new_detached (GWeatherLocation *nearest_station,
     self = g_slice_new0 (GWeatherLocation);
     self->ref_count = 1;
     self->level = GWEATHER_LOCATION_DETACHED;
-    self->name = g_strdup (name);
+    self->english_name = g_strdup (name);
+    self->local_name = g_strdup (name);
 
     normalized = g_utf8_normalize (name, -1, G_NORMALIZE_ALL);
-    self->sort_name = g_utf8_casefold (normalized, -1);
+    self->english_sort_name = g_utf8_casefold (normalized, -1);
+    self->local_sort_name = g_strdup (self->english_sort_name);
     g_free (normalized);
 
     self->parent = nearest_station;
@@ -1321,7 +1310,7 @@ gweather_location_common_deserialize (GWeatherLocation *world,
                continue;
            }
 
-           if (g_strcmp0 (name, city->name) == 0)
+           if (g_strcmp0 (name, city->english_name) == 0)
                found = gweather_location_ref (city);
            else
                found = _gweather_location_new_detached (ws, name, TRUE, latitude, longitude);
diff --git a/libgweather/location-entry.c b/libgweather/location-entry.c
index 7b85df8..cf9cf8e 100644
--- a/libgweather/location-entry.c
+++ b/libgweather/location-entry.c
@@ -70,8 +70,8 @@ enum
 {
     GWEATHER_LOCATION_ENTRY_COL_DISPLAY_NAME = 0,
     GWEATHER_LOCATION_ENTRY_COL_LOCATION,
-    GWEATHER_LOCATION_ENTRY_COL_COMPARE_NAME,
-    GWEATHER_LOCATION_ENTRY_COL_SORT_NAME,
+    GWEATHER_LOCATION_ENTRY_COL_LOCAL_COMPARE_NAME,
+    GWEATHER_LOCATION_ENTRY_COL_ENGLISH_COMPARE_NAME,
     GWEATHER_LOCATION_ENTRY_NUM_COLUMNS
 };
 
@@ -291,7 +291,7 @@ set_location_internal (GWeatherLocationEntry *entry,
        g_free (name);
     } else if (loc) {
        priv->location = gweather_location_ref (loc);
-       gtk_entry_set_text (GTK_ENTRY (entry), loc->name);
+       gtk_entry_set_text (GTK_ENTRY (entry), loc->local_name);
        priv->custom_text = TRUE;
     } else {
        priv->location = NULL;
@@ -457,10 +457,11 @@ gweather_location_entry_set_city (GWeatherLocationEntry *entry,
 static void
 fill_location_entry_model (GtkTreeStore *store, GWeatherLocation *loc,
                           const char *parent_display_name,
-                          const char *parent_compare_name)
+                          const char *parent_compare_local_name,
+                          const char *parent_compare_english_name)
 {
     GWeatherLocation **children;
-    char *display_name, *compare_name;
+    char *display_name, *local_compare_name, *english_compare_name;
     GtkTreeIter iter;
     int i;
 
@@ -476,7 +477,8 @@ fill_location_entry_model (GtkTreeStore *store, GWeatherLocation *loc,
        for (i = 0; children[i]; i++) {
            fill_location_entry_model (store, children[i],
                                       parent_display_name,
-                                      parent_compare_name);
+                                      parent_compare_local_name,
+                                      parent_compare_english_name);
        }
        break;
 
@@ -484,23 +486,26 @@ fill_location_entry_model (GtkTreeStore *store, GWeatherLocation *loc,
        /* Recurse, initializing the names to the country name */
        for (i = 0; children[i]; i++) {
            fill_location_entry_model (store, children[i],
-                                      gweather_location_get_name (loc),
-                                      gweather_location_get_sort_name (loc));
+                                      loc->local_name,
+                                      loc->local_sort_name,
+                                      loc->english_sort_name);
        }
        break;
 
     case GWEATHER_LOCATION_ADM1:
        /* Recurse, adding the ADM1 name to the country name */
-       display_name = g_strdup_printf ("%s, %s", gweather_location_get_name (loc), parent_display_name);
-       compare_name = g_strdup_printf ("%s, %s", gweather_location_get_sort_name (loc), parent_compare_name);
+       display_name = g_strdup_printf ("%s, %s", loc->local_name, parent_display_name);
+       local_compare_name = g_strdup_printf ("%s, %s", loc->local_sort_name, parent_compare_local_name);
+       english_compare_name = g_strdup_printf ("%s, %s", loc->english_sort_name, 
parent_compare_english_name);
 
        for (i = 0; children[i]; i++) {
            fill_location_entry_model (store, children[i],
-                                      display_name, compare_name);
+                                      display_name, local_compare_name, english_compare_name);
        }
 
        g_free (display_name);
-       g_free (compare_name);
+       g_free (local_compare_name);
+       g_free (english_compare_name);
        break;
 
     case GWEATHER_LOCATION_CITY:
@@ -510,23 +515,26 @@ fill_location_entry_model (GtkTreeStore *store, GWeatherLocation *loc,
             */
            for (i = 0; children[i]; i++) {
                display_name = g_strdup_printf ("%s (%s), %s",
-                                               gweather_location_get_name (loc),
-                                               gweather_location_get_name (children[i]),
+                                               loc->local_name, children[i]->local_name,
                                                parent_display_name);
-               compare_name = g_strdup_printf ("%s (%s), %s",
-                                               gweather_location_get_sort_name (loc),
-                                               gweather_location_get_sort_name (children[i]),
-                                               parent_compare_name);
+               local_compare_name = g_strdup_printf ("%s (%s), %s",
+                                                     loc->local_sort_name, children[i]->local_sort_name,
+                                                     parent_compare_local_name);
+               english_compare_name = g_strdup_printf ("%s (%s), %s",
+                                                       loc->english_sort_name, 
children[i]->english_sort_name,
+                                                       parent_compare_english_name);
 
                gtk_tree_store_append (store, &iter, NULL);
                gtk_tree_store_set (store, &iter,
                                    GWEATHER_LOCATION_ENTRY_COL_LOCATION, children[i],
                                    GWEATHER_LOCATION_ENTRY_COL_DISPLAY_NAME, display_name,
-                                   GWEATHER_LOCATION_ENTRY_COL_COMPARE_NAME, compare_name,
+                                   GWEATHER_LOCATION_ENTRY_COL_LOCAL_COMPARE_NAME, local_compare_name,
+                                   GWEATHER_LOCATION_ENTRY_COL_ENGLISH_COMPARE_NAME, english_compare_name,
                                    -1);
 
                g_free (display_name);
-               g_free (compare_name);
+               g_free (local_compare_name);
+               g_free (english_compare_name);
            }
 
            break;
@@ -539,21 +547,23 @@ fill_location_entry_model (GtkTreeStore *store, GWeatherLocation *loc,
         * child <location>.
         */
        display_name = g_strdup_printf ("%s, %s",
-                                       gweather_location_get_name (loc),
-                                       parent_display_name);
-       compare_name = g_strdup_printf ("%s, %s",
-                                       gweather_location_get_sort_name (loc),
-                                       parent_compare_name);
+                                       loc->local_name, parent_display_name);
+       local_compare_name = g_strdup_printf ("%s, %s",
+                                             loc->local_sort_name, parent_compare_local_name);
+       english_compare_name = g_strdup_printf ("%s, %s",
+                                               loc->english_sort_name, parent_compare_english_name);
 
        gtk_tree_store_append (store, &iter, NULL);
        gtk_tree_store_set (store, &iter,
                            GWEATHER_LOCATION_ENTRY_COL_LOCATION, loc,
                            GWEATHER_LOCATION_ENTRY_COL_DISPLAY_NAME, display_name,
-                           GWEATHER_LOCATION_ENTRY_COL_COMPARE_NAME, compare_name,
+                           GWEATHER_LOCATION_ENTRY_COL_LOCAL_COMPARE_NAME, local_compare_name,
+                           GWEATHER_LOCATION_ENTRY_COL_ENGLISH_COMPARE_NAME, english_compare_name,
                            -1);
 
        g_free (display_name);
-       g_free (compare_name);
+       g_free (local_compare_name);
+       g_free (english_compare_name);
        break;
 
     case GWEATHER_LOCATION_DETACHED:
@@ -573,7 +583,7 @@ gweather_location_entry_build_model (GWeatherLocationEntry *entry,
        entry->priv->top = gweather_location_ref (gweather_location_get_world ());
 
     store = gtk_tree_store_new (4, G_TYPE_STRING, GWEATHER_TYPE_LOCATION, G_TYPE_STRING, G_TYPE_STRING);
-    fill_location_entry_model (store, entry->priv->top, NULL, NULL);
+    fill_location_entry_model (store, entry->priv->top, NULL, NULL, NULL);
     gtk_entry_completion_set_model (gtk_entry_get_completion (GTK_ENTRY (entry)),
                                    GTK_TREE_MODEL (store));
     g_object_unref (store);
@@ -622,28 +632,19 @@ find_word (const char *full_name, const char *word, int word_len,
 }
 
 static gboolean
-matcher (GtkEntryCompletion *completion, const char *key,
-        GtkTreeIter *iter, gpointer user_data)
+match_compare_name (const char *key, const char *name)
 {
-    char *name, *name_mem;
-    gboolean is_first_word = TRUE, match;
+    gboolean is_first_word = TRUE;
     int len;
 
-    gtk_tree_model_get (gtk_entry_completion_get_model (completion), iter,
-                       GWEATHER_LOCATION_ENTRY_COL_COMPARE_NAME, &name_mem,
-                       -1);
-    name = name_mem;
-
     /* All but the last word in KEY must match a full word from NAME,
      * in order (but possibly skipping some words from NAME).
      */
     len = strcspn (key, " ");
     while (key[len]) {
        name = find_word (name, key, len, TRUE, is_first_word);
-       if (!name) {
-           g_free (name_mem);
+       if (!name)
            return FALSE;
-       }
 
        key += len;
        while (*key && !g_unichar_isalpha (g_utf8_get_char (key)))
@@ -656,8 +657,24 @@ matcher (GtkEntryCompletion *completion, const char *key,
     }
 
     /* The last word in KEY must match a prefix of a following word in NAME */
-    match = find_word (name, key, strlen (key), FALSE, is_first_word) != NULL;
-    g_free (name_mem);
+    return find_word (name, key, strlen (key), FALSE, is_first_word) != NULL;
+}
+
+static gboolean
+matcher (GtkEntryCompletion *completion, const char *key,
+        GtkTreeIter *iter, gpointer user_data)
+{
+    char *local_compare_name, *english_compare_name;
+    gboolean match;
+
+    gtk_tree_model_get (gtk_entry_completion_get_model (completion), iter,
+                       GWEATHER_LOCATION_ENTRY_COL_LOCAL_COMPARE_NAME, &local_compare_name,
+                       GWEATHER_LOCATION_ENTRY_COL_ENGLISH_COMPARE_NAME, &english_compare_name,
+                       -1);
+    match = match_compare_name (key, local_compare_name) || match_compare_name (key, english_compare_name);
+
+    g_free (local_compare_name);
+    g_free (english_compare_name);
     return match;
 }
 
diff --git a/libgweather/weather-priv.h b/libgweather/weather-priv.h
index 09c7e99..4bce917 100644
--- a/libgweather/weather-priv.h
+++ b/libgweather/weather-priv.h
@@ -38,7 +38,7 @@
 void        _gweather_gettext_init (void);
 
 struct _GWeatherLocation {
-    char *name, *msgctxt, *sort_name;
+    char *english_name, *local_name, *msgctxt, *local_sort_name, *english_sort_name;
     GWeatherLocation *parent, **children;
     GWeatherLocationLevel level;
     char *country_code, *tz_hint;
diff --git a/libgweather/weather-yrno.c b/libgweather/weather-yrno.c
index f7db931..93a2fb2 100644
--- a/libgweather/weather-yrno.c
+++ b/libgweather/weather-yrno.c
@@ -343,12 +343,12 @@ build_yrno_url_geonames (GWeatherLocation *glocation,
 
     while (glocation) {
        if (glocation->level == GWEATHER_LOCATION_CITY)
-           city_name = glocation->name;
+           city_name = glocation->english_name;
        if (glocation->level == GWEATHER_LOCATION_ADM1 ||
            glocation->level == GWEATHER_LOCATION_ADM2)
-           adm_division = glocation->name;
+           adm_division = glocation->english_name;
        if (glocation->level == GWEATHER_LOCATION_COUNTRY)
-           country = glocation->name;
+           country = glocation->english_name;
        glocation = glocation->parent;
     }
 


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