Merge lp:~jjardon/indicator-datetime/update_map into lp:indicator-datetime/0.3

Proposed by Javier Jardón on 2011-09-20
Status: Rejected
Rejected by: Charles Kerr on 2012-02-15
Proposed branch: lp:~jjardon/indicator-datetime/update_map
Merge into: lp:indicator-datetime/0.3
Diff against target: 853 lines (+343/-228)
6 files modified
libmap/Makefile.am (+3/-1)
libmap/cc-timezone-map.c (+44/-89)
libmap/cc-timezone-map.h (+2/-4)
libmap/test-timezone.c (+94/-49)
libmap/tz.c (+196/-84)
libmap/tz.h (+4/-1)
To merge this branch: bzr merge lp:~jjardon/indicator-datetime/update_map
Reviewer Review Type Date Requested Status
Charles Kerr (community) 2011-09-20 Disapprove on 2012-02-15
Review via email: mp+76144@code.launchpad.net
To post a comment you must log in.
140. By Javier Jardón on 2011-09-20

Handle GMT offsets as timezones

Charles Kerr (charlesk) wrote :

indicator-datetime uses an external dependency for this now (libtimezonemap), so we're no longer bundling libmap.

I appreciate you taking the time to make this patch. I think the code reviewers need to do a better job of handling these reviews in a timely manner so that conflicting patches like this have less chance of occurring.

The patch looks fine, but since it's now moot I'm going to pass on it.

review: Disapprove

Unmerged revisions

140. By Javier Jardón on 2011-09-20

Handle GMT offsets as timezones

139. By Javier Jardón on 2011-09-20

libmap/Makefile.am: Add two missing timezone files

138. By Javier Jardón on 2011-09-20

libmap: Use GtkStyleContext instead deprecated GtkStyle

137. By Javier Jardón on 2011-09-20

libmap: sync cc-timezone-map code against upstream

136. By Javier Jardón on 2011-09-19

libmap: Update tz utilities

135. By Javier Jardón on 2011-09-19

libmap: Update maps with upstream

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'libmap/Makefile.am'
2--- libmap/Makefile.am 2011-02-23 18:28:53 +0000
3+++ libmap/Makefile.am 2011-09-21 00:00:29 +0000
4@@ -16,6 +16,7 @@
5 data/timezone_12.png \
6 data/timezone_12.75.png \
7 data/timezone_13.png \
8+ data/timezone_14.png \
9 data/timezone_-2.png \
10 data/timezone_2.png \
11 data/timezone_-3.png \
12@@ -38,6 +39,7 @@
13 data/timezone_7.png \
14 data/timezone_-8.png \
15 data/timezone_8.png \
16+ data/timezone_8.75.png \
17 data/timezone_-9.png \
18 data/timezone_9.png \
19 data/timezone_-9.5.png \
20@@ -55,7 +57,7 @@
21
22 noinst_PROGRAMS = test-timezone
23
24-test_timezone_SOURCES = test-timezone.c tz.c tz.h
25+test_timezone_SOURCES = test-timezone.c tz.c tz.h cc-timezone-map.h cc-timezone-map.c
26 test_timezone_LDADD = $(LIBMAP_LIBS)
27 test_timezone_CFLAGS = $(LIBMAP_CFLAGS)
28
29
30=== modified file 'libmap/cc-timezone-map.c'
31--- libmap/cc-timezone-map.c 2011-06-29 13:10:25 +0000
32+++ libmap/cc-timezone-map.c 2011-09-21 00:00:29 +0000
33@@ -25,6 +25,7 @@
34
35 #include "cc-timezone-map.h"
36 #include <math.h>
37+#include <string.h>
38 #include "tz.h"
39
40 G_DEFINE_TYPE (CcTimezoneMap, cc_timezone_map, GTK_TYPE_WIDGET)
41@@ -50,10 +51,10 @@
42 GdkPixbuf *background;
43 GdkPixbuf *color_map;
44 GdkPixbuf *olsen_map;
45-
46+
47 guchar *visible_map_pixels;
48 gint visible_map_rowstride;
49-
50+
51 gint olsen_map_channels;
52 guchar *olsen_map_pixels;
53 gint olsen_map_rowstride;
54@@ -64,7 +65,6 @@
55
56 TzDB *tzdb;
57 TzLocation *location;
58- GHashTable *alias_db;
59 };
60
61 enum
62@@ -570,12 +570,6 @@
63 priv->visible_map_rowstride = 0;
64 }
65
66- if (priv->alias_db)
67- {
68- g_hash_table_destroy (priv->alias_db);
69- priv->alias_db = NULL;
70- }
71-
72 if (priv->watermark)
73 {
74 g_free (priv->watermark);
75@@ -686,11 +680,10 @@
76 window = gdk_window_new (gtk_widget_get_parent_window (widget), &attr,
77 GDK_WA_X | GDK_WA_Y);
78
79- gdk_window_set_user_data (window, widget);
80-
81 cursor = gdk_cursor_new (GDK_HAND2);
82 gdk_window_set_cursor (window, cursor);
83
84+ gdk_window_set_user_data (window, widget);
85 gtk_widget_set_window (widget, window);
86 }
87
88@@ -739,23 +732,26 @@
89 CcTimezoneMapPrivate *priv = CC_TIMEZONE_MAP (widget)->priv;
90 GdkPixbuf *hilight, *orig_hilight, *pin;
91 GtkAllocation alloc;
92+ GtkStateFlags state;
93+ GtkStyleContext *context;
94+ GdkRGBA rgba;
95 gchar *file;
96 GError *err = NULL;
97 gdouble pointx, pointy;
98 gdouble alpha = 1.0;
99- GtkStyle *style;
100 char buf[16];
101
102 gtk_widget_get_allocation (widget, &alloc);
103
104- style = gtk_widget_get_style (widget);
105+ state = gtk_widget_get_state_flags (widget);
106
107 /* Check if insensitive */
108- if (gtk_widget_get_state (widget) == GTK_STATE_INSENSITIVE)
109+ if (state & GTK_STATE_FLAG_INSENSITIVE)
110 alpha = 0.5;
111
112 /* paint background */
113- gdk_cairo_set_source_color (cr, &style->bg[gtk_widget_get_state (widget)]);
114+ gtk_style_context_get_color (context, state, &rgba);
115+ gdk_cairo_set_source_rgba (cr, &rgba);
116 cairo_paint (cr);
117 gdk_cairo_set_source_pixbuf (cr, priv->background, 0, 0);
118 cairo_paint_with_alpha (cr, alpha);
119@@ -773,10 +769,6 @@
120 cairo_stroke(cr);
121 }
122
123- if (!priv->location) {
124- return TRUE;
125- }
126-
127 /* paint hilight */
128 file = g_strdup_printf (DATADIR "/timezone_%s.png",
129 g_ascii_formatd (buf, sizeof (buf),
130@@ -804,6 +796,13 @@
131 g_object_unref (orig_hilight);
132 }
133
134+ /* Don't draw the pin for non-geographical locations */
135+ if (priv->location &&
136+ g_str_has_prefix (priv->location->zone, "Etc/"))
137+ {
138+ return TRUE;
139+ }
140+
141 /* load pin icon */
142 pin = gdk_pixbuf_new_from_file (DATADIR "/pin.png", &err);
143
144@@ -813,16 +812,23 @@
145 g_clear_error (&err);
146 }
147
148- pointx = convert_longtitude_to_x (priv->location->longitude, alloc.width);
149- pointy = convert_latitude_to_y (priv->location->latitude, alloc.height);
150-
151- if (pointy > alloc.height)
152- pointy = alloc.height;
153+ if (priv->location)
154+ {
155+ pointx = convert_longtitude_to_x (priv->location->longitude, alloc.width);
156+ pointy = convert_latitude_to_y (priv->location->latitude, alloc.height);
157+
158+ if (pointy > alloc.height)
159+ pointy = alloc.height;
160+
161+ if (pin)
162+ {
163+ gdk_cairo_set_source_pixbuf (cr, pin, pointx - 8, pointy - 14);
164+ cairo_paint_with_alpha (cr, alpha);
165+ }
166+ }
167
168 if (pin)
169 {
170- gdk_cairo_set_source_pixbuf (cr, pin, pointx - 8, pointy - 14);
171- cairo_paint_with_alpha (cr, alpha);
172 g_object_unref (pin);
173 }
174
175@@ -964,6 +970,7 @@
176 {
177 TzLocation * loc = get_loc_for_xy (widget, event->x, event->y);
178 set_location (CC_TIMEZONE_MAP (widget), loc);
179+
180 return TRUE;
181 }
182
183@@ -975,57 +982,6 @@
184 }
185
186 static void
187-load_backward_tz (CcTimezoneMap *self)
188-{
189- GError *error = NULL;
190- char **lines, *contents;
191- guint i;
192-
193- self->priv->alias_db = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
194-
195- if (g_file_get_contents (GNOMECC_DATA_DIR "/datetime/backward", &contents, NULL, &error) == FALSE)
196- {
197- g_warning ("Failed to load 'backward' file: %s", error->message);
198- return;
199- }
200- lines = g_strsplit (contents, "\n", -1);
201- g_free (contents);
202- for (i = 0; lines[i] != NULL; i++)
203- {
204- char **items;
205- guint j;
206- char *real, *alias;
207-
208- if (g_ascii_strncasecmp (lines[i], "Link\t", 5) != 0)
209- continue;
210-
211- items = g_strsplit (lines[i], "\t", -1);
212- real = NULL;
213- alias = NULL;
214- /* Skip the "Link<tab>" part */
215- for (j = 1; items[j] != NULL; j++)
216- {
217- if (items[j][0] == '\0')
218- continue;
219- if (real == NULL)
220- {
221- real = items[j];
222- continue;
223- }
224- alias = items[j];
225- break;
226- }
227-
228- if (real == NULL || alias == NULL)
229- g_warning ("Could not parse line: %s", lines[i]);
230-
231- g_hash_table_insert (self->priv->alias_db, g_strdup (alias), g_strdup (real));
232- g_strfreev (items);
233- }
234- g_strfreev (lines);
235-}
236-
237-static void
238 cc_timezone_map_init (CcTimezoneMap *self)
239 {
240 CcTimezoneMapPrivate *priv;
241@@ -1070,8 +1026,6 @@
242 NULL);
243 g_signal_connect (self, "state-flags-changed", G_CALLBACK (state_flags_changed),
244 NULL);
245-
246- load_backward_tz (self);
247 }
248
249 CcTimezoneMap *
250@@ -1080,17 +1034,19 @@
251 return g_object_new (CC_TYPE_TIMEZONE_MAP, NULL);
252 }
253
254-void
255+gboolean
256 cc_timezone_map_set_timezone (CcTimezoneMap *map,
257 const gchar *timezone)
258 {
259 GPtrArray *locations;
260 guint i;
261 char *real_tz;
262+ gboolean ret;
263
264- real_tz = g_hash_table_lookup (map->priv->alias_db, timezone);
265+ real_tz = tz_info_get_clean_name (map->priv->tzdb, timezone);
266
267 locations = tz_get_locations (map->priv->tzdb);
268+ ret = FALSE;
269
270 for (i = 0; i < locations->len; i++)
271 {
272@@ -1099,18 +1055,17 @@
273 if (!g_strcmp0 (loc->zone, real_tz ? real_tz : timezone))
274 {
275 set_location (map, loc);
276+ ret = TRUE;
277 break;
278 }
279 }
280
281- gtk_widget_queue_draw (GTK_WIDGET (map));
282-}
283-
284-void
285-cc_timezone_map_set_coords (CcTimezoneMap *map, gdouble lon, gdouble lat)
286-{
287- const gchar * zone = cc_timezone_map_get_timezone_at_coords (map, lon, lat);
288- cc_timezone_map_set_timezone (map, zone);
289+ if (ret)
290+ gtk_widget_queue_draw (GTK_WIDGET (map));
291+
292+ g_free (real_tz);
293+
294+ return ret;
295 }
296
297 const gchar *
298
299=== modified file 'libmap/cc-timezone-map.h'
300--- libmap/cc-timezone-map.h 2011-02-23 21:26:49 +0000
301+++ libmap/cc-timezone-map.h 2011-09-21 00:00:29 +0000
302@@ -72,10 +72,8 @@
303
304 void cc_timezone_map_set_watermark (CcTimezoneMap * map,
305 const gchar * watermark);
306-void cc_timezone_map_set_timezone (CcTimezoneMap *map,
307- const gchar *timezone);
308-void cc_timezone_map_set_coords (CcTimezoneMap *map,
309- gdouble lon, gdouble lat);
310+gboolean cc_timezone_map_set_timezone (CcTimezoneMap *map,
311+ const gchar *timezone);
312 const gchar * cc_timezone_map_get_timezone_at_coords (CcTimezoneMap *map,
313 gdouble lon, gdouble lat);
314 TzLocation * cc_timezone_map_get_location (CcTimezoneMap *map);
315
316=== modified file 'libmap/data/cc.png'
317Binary files libmap/data/cc.png 2011-02-22 16:20:34 +0000 and libmap/data/cc.png 2011-09-21 00:00:29 +0000 differ
318=== modified file 'libmap/data/timezone_-11.png'
319Binary files libmap/data/timezone_-11.png 2011-02-22 16:20:34 +0000 and libmap/data/timezone_-11.png 2011-09-21 00:00:29 +0000 differ
320=== modified file 'libmap/data/timezone_8.png'
321Binary files libmap/data/timezone_8.png 2011-02-22 16:20:34 +0000 and libmap/data/timezone_8.png 2011-09-21 00:00:29 +0000 differ
322=== modified file 'libmap/test-timezone.c'
323--- libmap/test-timezone.c 2011-02-25 16:41:56 +0000
324+++ libmap/test-timezone.c 2011-09-21 00:00:29 +0000
325@@ -1,56 +1,101 @@
326-#include <config.h>
327-#include <locale.h>
328-
329-#include "tz.h"
330+#include <gtk/gtk.h>
331+#include "cc-timezone-map.h"
332+
333+#define TZ_DIR "/usr/share/zoneinfo/"
334+
335+static GList *
336+get_timezone_list (GList *tzs,
337+ const char *top_path,
338+ const char *subpath)
339+{
340+ GDir *dir;
341+ char *fullpath;
342+ const char *name;
343+
344+ if (subpath == NULL)
345+ fullpath = g_strdup (top_path);
346+ else
347+ fullpath = g_build_filename (top_path, subpath, NULL);
348+ dir = g_dir_open (fullpath, 0, NULL);
349+ if (dir == NULL) {
350+ g_warning ("Could not open %s", fullpath);
351+ return NULL;
352+ }
353+ while ((name = g_dir_read_name (dir)) != NULL) {
354+ char *path;
355+
356+ if (g_str_has_suffix (name, ".tab"))
357+ continue;
358+
359+ if (subpath != NULL)
360+ path = g_build_filename (top_path, subpath, name, NULL);
361+ else
362+ path = g_build_filename (top_path, name, NULL);
363+ if (g_file_test (path, G_FILE_TEST_IS_DIR)) {
364+ if (subpath == NULL) {
365+ tzs = get_timezone_list (tzs, top_path, name);
366+ } else {
367+ char *new_subpath;
368+ new_subpath = g_strdup_printf ("%s/%s", subpath, name);
369+ tzs = get_timezone_list (tzs, top_path, new_subpath);
370+ g_free (new_subpath);
371+ }
372+ } else if (g_file_test (path, G_FILE_TEST_IS_REGULAR)) {
373+ if (subpath == NULL)
374+ tzs = g_list_prepend (tzs, g_strdup (name));
375+ else {
376+ char *tz;
377+ tz = g_strdup_printf ("%s/%s", subpath, name);
378+ tzs = g_list_prepend (tzs, tz);
379+ }
380+ }
381+ g_free (path);
382+ }
383+ g_dir_close (dir);
384+
385+ return tzs;
386+}
387
388 int main (int argc, char **argv)
389 {
390- TzDB *db;
391- GPtrArray *locs;
392- guint i;
393- char *pixmap_dir;
394- int retval = 0;
395-
396- setlocale (LC_ALL, "");
397-
398- if (argc == 2) {
399- pixmap_dir = g_strdup (argv[1]);
400- } else if (argc == 1) {
401- pixmap_dir = g_strdup ("data/");
402- } else {
403- g_message ("Usage: %s [PIXMAP DIRECTORY]", argv[0]);
404- return 1;
405- }
406-
407- db = tz_load_db ();
408- locs = tz_get_locations (db);
409- for (i = 0; i < locs->len ; i++) {
410- TzLocation *loc = locs->pdata[i];
411- TzInfo *info;
412- char *filename, *path;
413- gdouble selected_offset;
414- char buf[16];
415-
416- info = tz_info_from_location (loc);
417- selected_offset = tz_location_get_utc_offset (loc)
418- / (60.0*60.0) + ((info->daylight) ? -1.0 : 0.0);
419-
420- filename = g_strdup_printf ("timezone_%s.png",
421- g_ascii_formatd (buf, sizeof (buf),
422- "%g", selected_offset));
423- path = g_build_filename (pixmap_dir, filename, NULL);
424-
425- if (g_file_test (path, G_FILE_TEST_IS_REGULAR) == FALSE) {
426- g_message ("File '%s' missing for zone '%s'", filename, loc->zone);
427- retval = 1;
428+ CcTimezoneMap *map;
429+ TzDB *tz_db;
430+ GList *tzs, *l;
431+ GHashTable *ht;
432+ int ret = 0;
433+
434+ gtk_init (&argc, &argv);
435+
436+ ht = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
437+ map = cc_timezone_map_new ();
438+ tz_db = tz_load_db ();
439+ tzs = get_timezone_list (NULL, TZ_DIR, NULL);
440+ for (l = tzs; l != NULL; l = l->next) {
441+ char *timezone = l->data;
442+ char *clean_tz;
443+
444+ clean_tz = tz_info_get_clean_name (tz_db, timezone);
445+
446+ if (cc_timezone_map_set_timezone (map, clean_tz) == FALSE) {
447+ if (g_hash_table_lookup (ht, clean_tz) == NULL) {
448+ if (g_strcmp0 (clean_tz, timezone) == 0)
449+ g_print ("Failed to locate timezone '%s'\n", timezone);
450+ else
451+ g_print ("Failed to locate timezone '%s' (original name: '%s')\n", clean_tz, timezone);
452+ g_hash_table_insert (ht, g_strdup (clean_tz), GINT_TO_POINTER (TRUE));
453+ }
454+ /* We don't warn for those two, we'll just fallback
455+ * in the panel code */
456+ if (!g_str_equal (clean_tz, "posixrules") &&
457+ !g_str_equal (clean_tz, "Factory"))
458+ ret = 1;
459 }
460-
461- g_free (filename);
462- g_free (path);
463- tz_info_free (info);
464+ g_free (timezone);
465+ g_free (clean_tz);
466 }
467- tz_db_free (db);
468- g_free (pixmap_dir);
469+ g_list_free (tzs);
470+ tz_db_free (tz_db);
471+ g_hash_table_destroy (ht);
472
473- return retval;
474+ return ret;
475 }
476
477=== modified file 'libmap/tz.c'
478--- libmap/tz.c 2011-02-23 18:28:53 +0000
479+++ libmap/tz.c 2011-09-21 00:00:29 +0000
480@@ -39,7 +39,7 @@
481 static int compare_country_names (const void *a, const void *b);
482 static void sort_locations_by_country (GPtrArray *locations);
483 static gchar * tz_data_file_get (void);
484-
485+static void load_backward_tz (TzDB *tz_db);
486
487 /* ---------------- *
488 * Public interface *
489@@ -51,6 +51,7 @@
490 TzDB *tz_db;
491 FILE *tzfile;
492 char buf[4096];
493+ gint i;
494
495 tz_data_file = tz_data_file_get ();
496 if (!tz_data_file) {
497@@ -119,14 +120,45 @@
498 }
499
500 fclose (tzfile);
501-
502+
503+ /* Add the Etc/GMT offsets, except Etc/GMT+12, which
504+ * is not inhabited, see:
505+ * http://en.wikipedia.org/wiki/GMT-12
506+ *
507+ * Are you confused about the above? So was I.
508+ *
509+ * From tzdata
510+ * We use POSIX-style signs in the Zone names and the output abbreviations,
511+ * even though this is the opposite of what many people expect.
512+ * POSIX has positive signs west of Greenwich, but many people expect
513+ * positive signs east of Greenwich.
514+ * etc.
515+ */
516+ for (i = -14; i <= 12; i++) {
517+ TzLocation *loc;
518+
519+ if (i == 12)
520+ continue;
521+
522+ loc = g_new0 (TzLocation, 1);
523+ if (i != 0)
524+ loc->zone = g_strdup_printf ("Etc/GMT%c%d", i < 0 ? '-' : '+', abs(i));
525+ else
526+ loc->zone = g_strdup ("Etc/GMT");
527+ loc->country = g_strdup ("XX");
528+ g_ptr_array_add (tz_db->locations, (gpointer) loc);
529+ }
530+
531 /* now sort by country */
532 sort_locations_by_country (tz_db->locations);
533
534 g_free (tz_data_file);
535-
536+
537+ /* Load up the hashtable of backward links */
538+ load_backward_tz (tz_db);
539+
540 return tz_db;
541-}
542+}
543
544 static void
545 tz_location_free (TzLocation *loc)
546@@ -143,58 +175,10 @@
547 {
548 g_ptr_array_foreach (db->locations, (GFunc) tz_location_free, NULL);
549 g_ptr_array_free (db->locations, TRUE);
550+ g_hash_table_destroy (db->backward);
551 g_free (db);
552 }
553
554-static gint
555-sort_locations (TzLocation *a,
556- TzLocation *b)
557-{
558- if (a->dist > b->dist)
559- return 1;
560-
561- if (a->dist < b->dist)
562- return -1;
563-
564- return 0;
565-}
566-
567-static gdouble
568-convert_longtitude_to_x (gdouble longitude, gint map_width)
569-{
570- const gdouble xdeg_offset = -6;
571- gdouble x;
572-
573- x = (map_width * (180.0 + longitude) / 360.0)
574- + (map_width * xdeg_offset / 180.0);
575-
576- return x;
577-}
578-
579-static gdouble
580-radians (gdouble degrees)
581-{
582- return (degrees / 360.0) * G_PI * 2;
583-}
584-
585-static gdouble
586-convert_latitude_to_y (gdouble latitude, gdouble map_height)
587-{
588- gdouble bottom_lat = -59;
589- gdouble top_lat = 81;
590- gdouble top_per, y, full_range, top_offset, map_range;
591-
592- top_per = top_lat / 180.0;
593- y = 1.25 * log (tan (G_PI_4 + 0.4 * radians (latitude)));
594- full_range = 4.6068250867599998;
595- top_offset = full_range * top_per;
596- map_range = fabs (1.25 * log (tan (G_PI_4 + 0.4 * radians (bottom_lat))) - top_offset);
597- y = fabs (y - top_offset);
598- y = y / map_range;
599- y = y * map_height;
600- return y;
601-}
602-
603 GPtrArray *
604 tz_get_locations (TzDB *db)
605 {
606@@ -242,47 +226,18 @@
607 return offset;
608 }
609
610-gint
611-tz_location_set_locally (TzLocation *loc)
612-{
613- time_t curtime;
614- struct tm *curzone;
615- gboolean is_dst = FALSE;
616- gint correction = 0;
617-
618- g_return_val_if_fail (loc != NULL, 0);
619- g_return_val_if_fail (loc->zone != NULL, 0);
620-
621- curtime = time (NULL);
622- curzone = localtime (&curtime);
623- is_dst = curzone->tm_isdst;
624-
625- setenv ("TZ", loc->zone, 1);
626-#if 0
627- curtime = time (NULL);
628- curzone = localtime (&curtime);
629-
630- if (!is_dst && curzone->tm_isdst) {
631- correction = (60 * 60);
632- }
633- else if (is_dst && !curzone->tm_isdst) {
634- correction = 0;
635- }
636-#endif
637-
638- return correction;
639-}
640-
641 TzInfo *
642 tz_info_from_location (TzLocation *loc)
643 {
644 TzInfo *tzinfo;
645 time_t curtime;
646 struct tm *curzone;
647+ gchar *tz_env_value;
648
649 g_return_val_if_fail (loc != NULL, NULL);
650 g_return_val_if_fail (loc->zone != NULL, NULL);
651
652+ tz_env_value = g_strdup (getenv ("TZ"));
653 setenv ("TZ", loc->zone, 1);
654
655 #if 0
656@@ -311,6 +266,13 @@
657 #endif
658
659 tzinfo->daylight = curzone->tm_isdst;
660+
661+ if (tz_env_value)
662+ setenv ("TZ", tz_env_value, 1);
663+ else
664+ unsetenv ("TZ");
665+
666+ g_free (tz_env_value);
667
668 return tzinfo;
669 }
670@@ -326,6 +288,99 @@
671 g_free (tzinfo);
672 }
673
674+struct {
675+ const char *orig;
676+ const char *dest;
677+} aliases[] = {
678+ { "Asia/Istanbul", "Europe/Istanbul" }, /* Istanbul is in both Europe and Asia */
679+ { "Europe/Nicosia", "Asia/Nicosia" }, /* Ditto */
680+ { "EET", "Europe/Istanbul" }, /* Same tz as the 2 above */
681+ { "HST", "Pacific/Honolulu" },
682+ { "WET", "Europe/Brussels" }, /* Other name for the mainland Europe tz */
683+ { "CET", "Europe/Brussels" }, /* ditto */
684+ { "MET", "Europe/Brussels" },
685+ { "Etc/Zulu", "Etc/GMT" },
686+ { "Etc/UTC", "Etc/GMT" },
687+ { "GMT", "Etc/GMT" },
688+ { "Greenwich", "Etc/GMT" },
689+ { "Etc/UCT", "Etc/GMT" },
690+ { "Etc/GMT0", "Etc/GMT" },
691+ { "Etc/GMT+0", "Etc/GMT" },
692+ { "Etc/GMT-0", "Etc/GMT" },
693+ { "Etc/Universal", "Etc/GMT" },
694+ { "PST8PDT", "America/Los_Angeles" }, /* Other name for the Atlantic tz */
695+ { "EST", "America/New_York" }, /* Other name for the Eastern tz */
696+ { "EST5EDT", "America/New_York" }, /* ditto */
697+ { "CST6CDT", "America/Chicago" }, /* Other name for the Central tz */
698+ { "MST", "America/Denver" }, /* Other name for the mountain tz */
699+ { "MST7MDT", "America/Denver" }, /* ditto */
700+};
701+
702+static gboolean
703+compare_timezones (const char *a,
704+ const char *b)
705+{
706+ if (g_str_equal (a, b))
707+ return TRUE;
708+ if (strchr (b, '/') == NULL) {
709+ char *prefixed;
710+
711+ prefixed = g_strdup_printf ("/%s", b);
712+ if (g_str_has_suffix (a, prefixed)) {
713+ g_free (prefixed);
714+ return TRUE;
715+ }
716+ g_free (prefixed);
717+ }
718+
719+ return FALSE;
720+}
721+
722+char *
723+tz_info_get_clean_name (TzDB *tz_db,
724+ const char *tz)
725+{
726+ char *ret;
727+ const char *timezone;
728+ guint i;
729+ gboolean replaced;
730+
731+ /* Remove useless prefixes */
732+ if (g_str_has_prefix (tz, "right/"))
733+ tz = tz + strlen ("right/");
734+ else if (g_str_has_prefix (tz, "posix/"))
735+ tz = tz + strlen ("posix/");
736+
737+ /* Here start the crazies */
738+ replaced = FALSE;
739+
740+ for (i = 0; i < G_N_ELEMENTS (aliases); i++) {
741+ if (compare_timezones (tz, aliases[i].orig)) {
742+ replaced = TRUE;
743+ timezone = aliases[i].dest;
744+ break;
745+ }
746+ }
747+
748+ /* Try again! */
749+ if (!replaced) {
750+ /* Ignore crazy solar times from the '80s */
751+ if (g_str_has_prefix (tz, "Asia/Riyadh") ||
752+ g_str_has_prefix (tz, "Mideast/Riyadh")) {
753+ timezone = "Asia/Riyadh";
754+ replaced = TRUE;
755+ }
756+ }
757+
758+ if (!replaced)
759+ timezone = tz;
760+
761+ ret = g_hash_table_lookup (tz_db->backward, timezone);
762+ if (ret == NULL)
763+ return g_strdup (timezone);
764+ return g_strdup (ret);
765+}
766+
767 /* ----------------- *
768 * Private functions *
769 * ----------------- */
770@@ -397,3 +452,60 @@
771 qsort (locations->pdata, locations->len, sizeof (gpointer),
772 compare_country_names);
773 }
774+
775+static void
776+load_backward_tz (TzDB *tz_db)
777+{
778+ GError *error = NULL;
779+ char **lines, *contents;
780+ guint i;
781+
782+ tz_db->backward = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
783+
784+ if (g_file_get_contents (GNOMECC_DATA_DIR "/datetime/backward", &contents, NULL, &error) == FALSE)
785+ {
786+ g_warning ("Failed to load 'backward' file: %s", error->message);
787+ return;
788+ }
789+ lines = g_strsplit (contents, "\n", -1);
790+ g_free (contents);
791+ for (i = 0; lines[i] != NULL; i++)
792+ {
793+ char **items;
794+ guint j;
795+ char *real, *alias;
796+
797+ if (g_ascii_strncasecmp (lines[i], "Link\t", 5) != 0)
798+ continue;
799+
800+ items = g_strsplit (lines[i], "\t", -1);
801+ real = NULL;
802+ alias = NULL;
803+ /* Skip the "Link<tab>" part */
804+ for (j = 1; items[j] != NULL; j++)
805+ {
806+ if (items[j][0] == '\0')
807+ continue;
808+ if (real == NULL)
809+ {
810+ real = items[j];
811+ continue;
812+ }
813+ alias = items[j];
814+ break;
815+ }
816+
817+ if (real == NULL || alias == NULL)
818+ g_warning ("Could not parse line: %s", lines[i]);
819+
820+ /* We don't need more than one name for it */
821+ if (g_str_equal (real, "Etc/UTC") ||
822+ g_str_equal (real, "Etc/UCT"))
823+ real = "Etc/GMT";
824+
825+ g_hash_table_insert (tz_db->backward, g_strdup (alias), g_strdup (real));
826+ g_strfreev (items);
827+ }
828+ g_strfreev (lines);
829+}
830+
831
832=== modified file 'libmap/tz.h'
833--- libmap/tz.h 2011-02-22 16:20:34 +0000
834+++ libmap/tz.h 2011-09-21 00:00:29 +0000
835@@ -41,7 +41,8 @@
836
837 struct _TzDB
838 {
839- GPtrArray *locations;
840+ GPtrArray *locations;
841+ GHashTable *backward;
842 };
843
844 struct _TzLocation
845@@ -72,6 +73,8 @@
846
847 TzDB *tz_load_db (void);
848 void tz_db_free (TzDB *db);
849+char * tz_info_get_clean_name (TzDB *tz_db,
850+ const char *tz);
851 GPtrArray *tz_get_locations (TzDB *db);
852 void tz_location_get_position (TzLocation *loc,
853 double *longitude, double *latitude);

Subscribers

People subscribed via source and target branches