diff options
author | Benjamin Berg <bberg@redhat.com> | 2020-04-30 12:06:52 +0200 |
---|---|---|
committer | Bastien Nocera <hadess@hadess.net> | 2021-01-11 20:31:52 +0100 |
commit | a221531edfce5904bcf533e236baa7c048fc8af5 (patch) | |
tree | ebafd751b709e227cedfd6f889a0f736cb014042 | |
parent | a446007d4f40ac6b4628a298bf5a74bcbf5597d5 (diff) | |
download | libgweather-a221531edfce5904bcf533e236baa7c048fc8af5.tar.gz |
location-entry: Sort locations in drop-down
The order of locations as returned by GWeatherLocation used to be sorted
by the localised name. However, that requires quite a lot of resources
and is not needed in many usecases.
As such, sort the resulting tree model by location name. Note that this
actually changes the behaviour slightly as Countries were grouped by
region before and are now all sorted by name.
To do so, add a new column that allows direct comparison for sorting
purposes. Note that this cannot be the same as the compare name, because
order needs to be reversed for sorting but must remain the same for
matching.
-rw-r--r-- | libgweather/gweather-location-entry.c | 45 |
1 files changed, 40 insertions, 5 deletions
diff --git a/libgweather/gweather-location-entry.c b/libgweather/gweather-location-entry.c index f8071aa..1514144 100644 --- a/libgweather/gweather-location-entry.c +++ b/libgweather/gweather-location-entry.c @@ -70,6 +70,7 @@ static void set_location_internal (GWeatherLocationEntry *entry, static void fill_location_entry_model (GtkListStore *store, GWeatherLocation *loc, const char *parent_display_name, + const char *parent_sort_local_name, const char *parent_compare_local_name, const char *parent_compare_english_name, gboolean show_named_timezones); @@ -78,6 +79,7 @@ enum LOC { LOC_GWEATHER_LOCATION_ENTRY_COL_DISPLAY_NAME = 0, LOC_GWEATHER_LOCATION_ENTRY_COL_LOCATION, + LOC_GWEATHER_LOCATION_ENTRY_COL_LOCAL_SORT_NAME, LOC_GWEATHER_LOCATION_ENTRY_COL_LOCAL_COMPARE_NAME, LOC_GWEATHER_LOCATION_ENTRY_COL_ENGLISH_COMPARE_NAME, LOC_GWEATHER_LOCATION_ENTRY_NUM_COLUMNS @@ -87,6 +89,7 @@ enum PLACE { PLACE_GWEATHER_LOCATION_ENTRY_COL_DISPLAY_NAME = 0, PLACE_GWEATHER_LOCATION_ENTRY_COL_PLACE, + PLACE_GWEATHER_LOCATION_ENTRY_COL_LOCAL_SORT_NAME, PLACE_GWEATHER_LOCATION_ENTRY_COL_LOCAL_COMPARE_NAME }; @@ -165,6 +168,25 @@ dispose (GObject *object) G_OBJECT_CLASS (gweather_location_entry_parent_class)->dispose (object); } +static int +tree_compare_local_name (GtkTreeModel *model, + GtkTreeIter *a, + GtkTreeIter *b, + gpointer user_data) +{ + g_autofree gchar *name_a = NULL, *name_b = NULL; + + gtk_tree_model_get (model, a, + LOC_GWEATHER_LOCATION_ENTRY_COL_LOCAL_SORT_NAME, &name_a, + -1); + gtk_tree_model_get (model, b, + LOC_GWEATHER_LOCATION_ENTRY_COL_LOCAL_SORT_NAME, &name_b, + -1); + + return g_utf8_collate (name_a, name_b); +} + + static void constructed (GObject *object) { @@ -177,8 +199,10 @@ constructed (GObject *object) if (!entry->priv->top) entry->priv->top = gweather_location_get_world (); - store = gtk_list_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, NULL, entry->priv->show_named_timezones); + store = gtk_list_store_new (5, G_TYPE_STRING, GWEATHER_TYPE_LOCATION, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING); + gtk_tree_sortable_set_default_sort_func (GTK_TREE_SORTABLE (store), + tree_compare_local_name, NULL, NULL); + fill_location_entry_model (store, entry->priv->top, NULL, NULL, NULL, NULL, entry->priv->show_named_timezones); entry->priv->model = GTK_TREE_MODEL (store); completion = gtk_entry_get_completion (GTK_ENTRY (entry)); @@ -485,12 +509,13 @@ gweather_location_entry_set_city (GWeatherLocationEntry *entry, static void fill_location_entry_model (GtkListStore *store, GWeatherLocation *loc, const char *parent_display_name, + const char *parent_sort_local_name, const char *parent_compare_local_name, const char *parent_compare_english_name, gboolean show_named_timezones) { g_autoptr(GWeatherLocation) child = NULL; - char *display_name, *local_compare_name, *english_compare_name; + char *display_name, *local_sort_name, *local_compare_name, *english_compare_name; switch (gweather_location_get_level (loc)) { case GWEATHER_LOCATION_WORLD: @@ -501,6 +526,7 @@ fill_location_entry_model (GtkListStore *store, GWeatherLocation *loc, while ((child = gweather_location_next_child (loc, child))) fill_location_entry_model (store, child, parent_display_name, + parent_sort_local_name, parent_compare_local_name, parent_compare_english_name, show_named_timezones); @@ -512,6 +538,7 @@ fill_location_entry_model (GtkListStore *store, GWeatherLocation *loc, fill_location_entry_model (store, child, gweather_location_get_name (loc), gweather_location_get_sort_name (loc), + gweather_location_get_sort_name (loc), gweather_location_get_english_sort_name (loc), show_named_timezones); break; @@ -523,12 +550,13 @@ fill_location_entry_model (GtkListStore *store, GWeatherLocation *loc, * You shouldn't need to translate this string unless the language has a different comma. */ display_name = g_strdup_printf (_("%s, %s"), gweather_location_get_name (loc), parent_display_name); + local_sort_name = g_strdup_printf ("%s, %s", parent_sort_local_name, gweather_location_get_sort_name (loc)); local_compare_name = g_strdup_printf ("%s, %s", gweather_location_get_sort_name (loc), parent_compare_local_name); english_compare_name = g_strdup_printf ("%s, %s", gweather_location_get_english_sort_name (loc), parent_compare_english_name); while ((child = gweather_location_next_child (loc, child))) fill_location_entry_model (store, child, - display_name, local_compare_name, english_compare_name, + display_name, local_sort_name, local_compare_name, english_compare_name, show_named_timezones); g_free (display_name); @@ -551,6 +579,8 @@ fill_location_entry_model (GtkListStore *store, GWeatherLocation *loc, */ display_name = g_strdup_printf (_("%s, %s"), gweather_location_get_name (loc), parent_display_name); + local_sort_name = g_strdup_printf ("%s, %s", + parent_sort_local_name, gweather_location_get_sort_name (loc)); local_compare_name = g_strdup_printf ("%s, %s", gweather_location_get_sort_name (loc), parent_compare_local_name); english_compare_name = g_strdup_printf ("%s, %s", @@ -559,6 +589,7 @@ fill_location_entry_model (GtkListStore *store, GWeatherLocation *loc, gtk_list_store_insert_with_values (store, NULL, -1, LOC_GWEATHER_LOCATION_ENTRY_COL_LOCATION, loc, LOC_GWEATHER_LOCATION_ENTRY_COL_DISPLAY_NAME, display_name, + LOC_GWEATHER_LOCATION_ENTRY_COL_LOCAL_SORT_NAME, local_sort_name, LOC_GWEATHER_LOCATION_ENTRY_COL_LOCAL_COMPARE_NAME, local_compare_name, LOC_GWEATHER_LOCATION_ENTRY_COL_ENGLISH_COMPARE_NAME, english_compare_name, -1); @@ -573,6 +604,7 @@ fill_location_entry_model (GtkListStore *store, GWeatherLocation *loc, gtk_list_store_insert_with_values (store, NULL, -1, LOC_GWEATHER_LOCATION_ENTRY_COL_LOCATION, loc, LOC_GWEATHER_LOCATION_ENTRY_COL_DISPLAY_NAME, gweather_location_get_name (loc), + LOC_GWEATHER_LOCATION_ENTRY_COL_LOCAL_SORT_NAME, gweather_location_get_sort_name (loc), LOC_GWEATHER_LOCATION_ENTRY_COL_LOCAL_COMPARE_NAME, gweather_location_get_sort_name (loc), LOC_GWEATHER_LOCATION_ENTRY_COL_ENGLISH_COMPARE_NAME, gweather_location_get_english_sort_name (loc), -1); @@ -757,6 +789,7 @@ fill_store (gpointer data, gpointer user_data) gtk_list_store_insert_with_values (user_data, NULL, -1, PLACE_GWEATHER_LOCATION_ENTRY_COL_PLACE, place, PLACE_GWEATHER_LOCATION_ENTRY_COL_DISPLAY_NAME, display_name, + PLACE_GWEATHER_LOCATION_ENTRY_COL_LOCAL_SORT_NAME, compare_name, PLACE_GWEATHER_LOCATION_ENTRY_COL_LOCAL_COMPARE_NAME, compare_name, -1); @@ -791,7 +824,9 @@ _got_places (GObject *source_object, } completion = gtk_entry_get_completion (user_data); - store = gtk_list_store_new (4, G_TYPE_STRING, GEOCODE_TYPE_PLACE, G_TYPE_STRING, G_TYPE_STRING); + store = gtk_list_store_new (5, G_TYPE_STRING, GEOCODE_TYPE_PLACE, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING); + gtk_tree_sortable_set_default_sort_func (GTK_TREE_SORTABLE (store), + tree_compare_local_name, NULL, NULL); g_list_foreach (places, fill_store, store); g_list_free (places); gtk_entry_completion_set_match_func (completion, new_matcher, NULL, NULL); |