158 lines
4.4 KiB
Diff
158 lines
4.4 KiB
Diff
|
From 4c87463e3b663b413c3be899bb15891aa7f0ee43 Mon Sep 17 00:00:00 2001
|
||
|
From: David Shea <dshea@redhat.com>
|
||
|
Date: Tue, 28 Jun 2016 13:49:14 -0400
|
||
|
Subject: [PATCH 18/24] Improve the location selected when setting the timezone
|
||
|
by name.
|
||
|
|
||
|
When setting the timezone from a name (e.g., Australia/Brisbane), try to
|
||
|
find the city that matches the timezone name. That way, in our example,
|
||
|
the pin will appear on Brisbane and not just some random city in eastern
|
||
|
Australia.
|
||
|
|
||
|
In addition, when cc_timezone_map_set_timezone is called for an unknown
|
||
|
timezone, set the offset highlight based on glib's view of timezones
|
||
|
(since this may be a low-population timezone without city data) and
|
||
|
unset the location.
|
||
|
---
|
||
|
src/cc-timezone-map.c | 103 ++++++++++++++++++++++++++++++++++++++++++++++++--
|
||
|
1 file changed, 100 insertions(+), 3 deletions(-)
|
||
|
|
||
|
diff --git a/src/cc-timezone-map.c b/src/cc-timezone-map.c
|
||
|
index 11b14ea..5e4c210 100644
|
||
|
--- a/src/cc-timezone-map.c
|
||
|
+++ b/src/cc-timezone-map.c
|
||
|
@@ -28,6 +28,7 @@
|
||
|
#include <math.h>
|
||
|
#include "tz.h"
|
||
|
#include <librsvg/rsvg.h>
|
||
|
+#include <string.h>
|
||
|
|
||
|
G_DEFINE_TYPE (CcTimezoneMap, cc_timezone_map, GTK_TYPE_WIDGET)
|
||
|
|
||
|
@@ -817,10 +818,42 @@ cc_timezone_map_set_timezone (CcTimezoneMap *map,
|
||
|
const gchar *timezone)
|
||
|
{
|
||
|
GPtrArray *locations;
|
||
|
+ GList *zone_locations = NULL;
|
||
|
+ GList *location_node = NULL;
|
||
|
guint i;
|
||
|
- char *real_tz;
|
||
|
+ const char *real_tz;
|
||
|
+ const char *tz_city_start;
|
||
|
+ char *tz_city;
|
||
|
+ char *tmp;
|
||
|
+ gboolean found_location = FALSE;
|
||
|
|
||
|
real_tz = g_hash_table_lookup (map->priv->alias_db, timezone);
|
||
|
+ if (!real_tz)
|
||
|
+ real_tz = timezone;
|
||
|
+
|
||
|
+ tz_city_start = strrchr (timezone, '/');
|
||
|
+ if (tz_city_start)
|
||
|
+ {
|
||
|
+ /* Move to the first character after the / */
|
||
|
+ tz_city_start++;
|
||
|
+ }
|
||
|
+ else
|
||
|
+ {
|
||
|
+ tz_city_start = real_tz;
|
||
|
+ }
|
||
|
+
|
||
|
+ tz_city = g_strdup(tz_city_start);
|
||
|
+
|
||
|
+ /* Replace the underscores with spaces */
|
||
|
+ tmp = tz_city;
|
||
|
+ while (*tmp != '\0')
|
||
|
+ {
|
||
|
+ if (*tmp == '_')
|
||
|
+ {
|
||
|
+ *tmp = ' ';
|
||
|
+ }
|
||
|
+ tmp++;
|
||
|
+ }
|
||
|
|
||
|
locations = tz_get_locations (map->priv->tzdb);
|
||
|
|
||
|
@@ -828,12 +861,76 @@ cc_timezone_map_set_timezone (CcTimezoneMap *map,
|
||
|
{
|
||
|
CcTimezoneLocation *loc = locations->pdata[i];
|
||
|
|
||
|
- if (!g_strcmp0 (cc_timezone_location_get_zone(loc), real_tz ? real_tz : timezone))
|
||
|
+ if (!g_strcmp0 (cc_timezone_location_get_zone (loc), real_tz))
|
||
|
{
|
||
|
- set_location (map, loc);
|
||
|
+ zone_locations = g_list_prepend (zone_locations, loc);
|
||
|
+ }
|
||
|
+ }
|
||
|
+
|
||
|
+ /* No location found. Use GLib to set the highlight. g_time_zone_new always
|
||
|
+ * returns a GTimeZone, so invalid zones will just be offset 0.
|
||
|
+ */
|
||
|
+ if (zone_locations == NULL)
|
||
|
+ {
|
||
|
+ CcTimezoneLocation *test_location = cc_timezone_location_new ();
|
||
|
+ gdouble offset;
|
||
|
+
|
||
|
+ cc_timezone_location_set_zone (test_location, real_tz);
|
||
|
+ offset = get_location_offset (test_location);
|
||
|
+ g_object_unref (test_location);
|
||
|
+
|
||
|
+ set_location (map, NULL);
|
||
|
+ cc_timezone_map_set_selected_offset (map, offset);
|
||
|
+
|
||
|
+ return;
|
||
|
+ }
|
||
|
+
|
||
|
+ /* Look for a location with a name that either starts or ends with the name
|
||
|
+ * of the zone
|
||
|
+ */
|
||
|
+ location_node = zone_locations;
|
||
|
+ while (location_node != NULL)
|
||
|
+ {
|
||
|
+ const gchar *name = cc_timezone_location_get_en_name (location_node->data);
|
||
|
+ if (!strncmp (name, tz_city, strlen (tz_city)) ||
|
||
|
+ ((strlen(name) > strlen(tz_city)) &&
|
||
|
+ !strncmp (name + (strlen(name) - strlen(tz_city)), tz_city, strlen (tz_city))))
|
||
|
+ {
|
||
|
+ set_location (map, location_node->data);
|
||
|
+ found_location = TRUE;
|
||
|
break;
|
||
|
}
|
||
|
+
|
||
|
+ location_node = location_node->next;
|
||
|
}
|
||
|
+
|
||
|
+ /* If that didn't work, try by state */
|
||
|
+ if (!found_location)
|
||
|
+ {
|
||
|
+ location_node = zone_locations;
|
||
|
+ while (location_node != NULL)
|
||
|
+ {
|
||
|
+ const gchar *state = cc_timezone_location_get_state (location_node->data);
|
||
|
+
|
||
|
+ if ((state != NULL) &&
|
||
|
+ !strncmp (state, tz_city, strlen (tz_city)))
|
||
|
+ {
|
||
|
+ set_location (map, location_node->data);
|
||
|
+ found_location = TRUE;
|
||
|
+ break;
|
||
|
+ }
|
||
|
+
|
||
|
+ location_node = location_node->next;
|
||
|
+ }
|
||
|
+ }
|
||
|
+
|
||
|
+ /* If nothing matched, just use the first location */
|
||
|
+ if (!found_location)
|
||
|
+ {
|
||
|
+ set_location (map, zone_locations->data);
|
||
|
+ }
|
||
|
+
|
||
|
+ g_list_free (zone_locations);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
--
|
||
|
2.5.5
|
||
|
|