From ca3c22b8fed221e07770266d70a802209a691d5f Mon Sep 17 00:00:00 2001
From: Giovanni Campagna <gcampagna@src.gnome.org>
Date: Sun, 15 Jun 2014 15:41:11 +0200
Subject: [PATCH] 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

Rebased to 3.10.2 by Mike Gorse <mgorse@suse.com>
---
diff -ur libgweather-3.10.2.orig/libgweather/gweather-location.c libgweather-3.10.2/libgweather/gweather-location.c
--- libgweather-3.10.2.orig/libgweather/gweather-location.c	2014-02-02 10:38:57.000000000 -0600
+++ libgweather-3.10.2/libgweather/gweather-location.c	2014-09-10 12:12:11.161993082 -0500
@@ -88,7 +88,7 @@
     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
@@ -155,14 +155,26 @@
 	}
 
 	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);
@@ -357,9 +369,11 @@
 
     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);
@@ -407,11 +421,6 @@
  *
  * 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 *
@@ -419,16 +428,7 @@
 {
     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);
 }
 
 /**
@@ -446,7 +446,7 @@
 gweather_location_get_sort_name (GWeatherLocation *loc)
 {
     g_return_val_if_fail (loc != NULL, NULL);
-    return loc->sort_name;
+    return loc->local_sort_name;
 }
 
 /**
@@ -721,26 +721,13 @@
 {
     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;
 }
@@ -780,7 +767,7 @@
 	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);
@@ -859,7 +846,7 @@
 
     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 &&
@@ -888,7 +875,7 @@
     const char *name;
     gboolean is_city;
 
-    name = location->name;
+    name = location->english_name;
 
     /* Normalize location to be a weather station or detached */
     if (location->level == GWEATHER_LOCATION_CITY) {
@@ -921,10 +908,12 @@
     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;
@@ -1009,7 +998,7 @@
 		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);
Only in libgweather-3.10.2/libgweather: gweather-location.c.orig
diff -ur libgweather-3.10.2.orig/libgweather/location-entry.c libgweather-3.10.2/libgweather/location-entry.c
--- libgweather-3.10.2.orig/libgweather/location-entry.c	2014-02-02 10:33:14.000000000 -0600
+++ libgweather-3.10.2/libgweather/location-entry.c	2014-09-10 12:12:11.162993082 -0500
@@ -70,8 +70,8 @@
 {
     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
 };
 
@@ -284,7 +284,7 @@
 	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;
@@ -450,10 +450,11 @@
 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;
 
@@ -469,7 +470,8 @@
 	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;
 
@@ -477,23 +479,26 @@
 	/* 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:
@@ -503,23 +508,26 @@
 	     */
 	    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;
@@ -532,21 +540,23 @@
 	 * 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:
@@ -566,7 +576,7 @@
 	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);
@@ -611,28 +621,19 @@
 }
 
 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)))
@@ -645,8 +646,24 @@
     }
 
     /* 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;
 }
 
Only in libgweather-3.10.2/libgweather: location-entry.c.orig
diff -ur libgweather-3.10.2.orig/libgweather/weather-priv.h libgweather-3.10.2/libgweather/weather-priv.h
--- libgweather-3.10.2.orig/libgweather/weather-priv.h	2014-02-02 10:38:57.000000000 -0600
+++ libgweather-3.10.2/libgweather/weather-priv.h	2014-09-10 12:12:11.162993082 -0500
@@ -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 -ur libgweather-3.10.2.orig/libgweather/weather-yrno.c libgweather-3.10.2/libgweather/weather-yrno.c
--- libgweather-3.10.2.orig/libgweather/weather-yrno.c	2014-02-02 10:38:57.000000000 -0600
+++ libgweather-3.10.2/libgweather/weather-yrno.c	2014-09-10 12:12:11.162993082 -0500
@@ -343,12 +343,12 @@
 
     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;
     }
 
