Javier Jardón has proposed merging lp:~jjardon/indicator-datetime/update_map into lp:indicator-datetime.
Requested reviews: Indicator Applet Developers (indicator-applet-developers) Related bugs: Bug #754275 in Indicator Date and Time: "Time zones map is wrong" https://bugs.launchpad.net/indicator-datetime/+bug/754275 For more details, see: https://code.launchpad.net/~jjardon/indicator-datetime/update_map/+merge/76144 -- https://code.launchpad.net/~jjardon/indicator-datetime/update_map/+merge/76144 Your team ayatana-commits is subscribed to branch lp:indicator-datetime.
=== modified file 'libmap/Makefile.am' --- libmap/Makefile.am 2011-02-23 18:28:53 +0000 +++ libmap/Makefile.am 2011-09-20 04:43:25 +0000 @@ -16,6 +16,7 @@ data/timezone_12.png \ data/timezone_12.75.png \ data/timezone_13.png \ + data/timezone_14.png \ data/timezone_-2.png \ data/timezone_2.png \ data/timezone_-3.png \ @@ -38,6 +39,7 @@ data/timezone_7.png \ data/timezone_-8.png \ data/timezone_8.png \ + data/timezone_8.75.png \ data/timezone_-9.png \ data/timezone_9.png \ data/timezone_-9.5.png \ @@ -55,7 +57,7 @@ noinst_PROGRAMS = test-timezone -test_timezone_SOURCES = test-timezone.c tz.c tz.h +test_timezone_SOURCES = test-timezone.c tz.c tz.h cc-timezone-map.h cc-timezone-map.c test_timezone_LDADD = $(LIBMAP_LIBS) test_timezone_CFLAGS = $(LIBMAP_CFLAGS) === modified file 'libmap/cc-timezone-map.c' --- libmap/cc-timezone-map.c 2011-06-29 13:10:25 +0000 +++ libmap/cc-timezone-map.c 2011-09-20 04:43:25 +0000 @@ -25,6 +25,7 @@ #include "cc-timezone-map.h" #include <math.h> +#include <string.h> #include "tz.h" G_DEFINE_TYPE (CcTimezoneMap, cc_timezone_map, GTK_TYPE_WIDGET) @@ -50,10 +51,10 @@ GdkPixbuf *background; GdkPixbuf *color_map; GdkPixbuf *olsen_map; - + guchar *visible_map_pixels; gint visible_map_rowstride; - + gint olsen_map_channels; guchar *olsen_map_pixels; gint olsen_map_rowstride; @@ -64,7 +65,6 @@ TzDB *tzdb; TzLocation *location; - GHashTable *alias_db; }; enum @@ -570,12 +570,6 @@ priv->visible_map_rowstride = 0; } - if (priv->alias_db) - { - g_hash_table_destroy (priv->alias_db); - priv->alias_db = NULL; - } - if (priv->watermark) { g_free (priv->watermark); @@ -686,11 +680,10 @@ window = gdk_window_new (gtk_widget_get_parent_window (widget), &attr, GDK_WA_X | GDK_WA_Y); - gdk_window_set_user_data (window, widget); - cursor = gdk_cursor_new (GDK_HAND2); gdk_window_set_cursor (window, cursor); + gdk_window_set_user_data (window, widget); gtk_widget_set_window (widget, window); } @@ -739,23 +732,26 @@ CcTimezoneMapPrivate *priv = CC_TIMEZONE_MAP (widget)->priv; GdkPixbuf *hilight, *orig_hilight, *pin; GtkAllocation alloc; + GtkStateFlags state; + GtkStyleContext *context; + GdkRGBA rgba; gchar *file; GError *err = NULL; gdouble pointx, pointy; gdouble alpha = 1.0; - GtkStyle *style; char buf[16]; gtk_widget_get_allocation (widget, &alloc); - style = gtk_widget_get_style (widget); + state = gtk_widget_get_state_flags (widget); /* Check if insensitive */ - if (gtk_widget_get_state (widget) == GTK_STATE_INSENSITIVE) + if (state & GTK_STATE_FLAG_INSENSITIVE) alpha = 0.5; /* paint background */ - gdk_cairo_set_source_color (cr, &style->bg[gtk_widget_get_state (widget)]); + gtk_style_context_get_color (context, state, &rgba); + gdk_cairo_set_source_rgba (cr, &rgba); cairo_paint (cr); gdk_cairo_set_source_pixbuf (cr, priv->background, 0, 0); cairo_paint_with_alpha (cr, alpha); @@ -773,10 +769,6 @@ cairo_stroke(cr); } - if (!priv->location) { - return TRUE; - } - /* paint hilight */ file = g_strdup_printf (DATADIR "/timezone_%s.png", g_ascii_formatd (buf, sizeof (buf), @@ -813,16 +805,23 @@ g_clear_error (&err); } - pointx = convert_longtitude_to_x (priv->location->longitude, alloc.width); - pointy = convert_latitude_to_y (priv->location->latitude, alloc.height); - - if (pointy > alloc.height) - pointy = alloc.height; + if (priv->location) + { + pointx = convert_longtitude_to_x (priv->location->longitude, alloc.width); + pointy = convert_latitude_to_y (priv->location->latitude, alloc.height); + + if (pointy > alloc.height) + pointy = alloc.height; + + if (pin) + { + gdk_cairo_set_source_pixbuf (cr, pin, pointx - 8, pointy - 14); + cairo_paint_with_alpha (cr, alpha); + } + } if (pin) { - gdk_cairo_set_source_pixbuf (cr, pin, pointx - 8, pointy - 14); - cairo_paint_with_alpha (cr, alpha); g_object_unref (pin); } @@ -964,6 +963,7 @@ { TzLocation * loc = get_loc_for_xy (widget, event->x, event->y); set_location (CC_TIMEZONE_MAP (widget), loc); + return TRUE; } @@ -975,57 +975,6 @@ } static void -load_backward_tz (CcTimezoneMap *self) -{ - GError *error = NULL; - char **lines, *contents; - guint i; - - self->priv->alias_db = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); - - if (g_file_get_contents (GNOMECC_DATA_DIR "/datetime/backward", &contents, NULL, &error) == FALSE) - { - g_warning ("Failed to load 'backward' file: %s", error->message); - return; - } - lines = g_strsplit (contents, "\n", -1); - g_free (contents); - for (i = 0; lines[i] != NULL; i++) - { - char **items; - guint j; - char *real, *alias; - - if (g_ascii_strncasecmp (lines[i], "Link\t", 5) != 0) - continue; - - items = g_strsplit (lines[i], "\t", -1); - real = NULL; - alias = NULL; - /* Skip the "Link<tab>" part */ - for (j = 1; items[j] != NULL; j++) - { - if (items[j][0] == '\0') - continue; - if (real == NULL) - { - real = items[j]; - continue; - } - alias = items[j]; - break; - } - - if (real == NULL || alias == NULL) - g_warning ("Could not parse line: %s", lines[i]); - - g_hash_table_insert (self->priv->alias_db, g_strdup (alias), g_strdup (real)); - g_strfreev (items); - } - g_strfreev (lines); -} - -static void cc_timezone_map_init (CcTimezoneMap *self) { CcTimezoneMapPrivate *priv; @@ -1070,8 +1019,6 @@ NULL); g_signal_connect (self, "state-flags-changed", G_CALLBACK (state_flags_changed), NULL); - - load_backward_tz (self); } CcTimezoneMap * @@ -1080,17 +1027,19 @@ return g_object_new (CC_TYPE_TIMEZONE_MAP, NULL); } -void +gboolean cc_timezone_map_set_timezone (CcTimezoneMap *map, const gchar *timezone) { GPtrArray *locations; guint i; char *real_tz; + gboolean ret; - real_tz = g_hash_table_lookup (map->priv->alias_db, timezone); + real_tz = tz_info_get_clean_name (map->priv->tzdb, timezone); locations = tz_get_locations (map->priv->tzdb); + ret = FALSE; for (i = 0; i < locations->len; i++) { @@ -1099,18 +1048,17 @@ if (!g_strcmp0 (loc->zone, real_tz ? real_tz : timezone)) { set_location (map, loc); + ret = TRUE; break; } } - gtk_widget_queue_draw (GTK_WIDGET (map)); -} - -void -cc_timezone_map_set_coords (CcTimezoneMap *map, gdouble lon, gdouble lat) -{ - const gchar * zone = cc_timezone_map_get_timezone_at_coords (map, lon, lat); - cc_timezone_map_set_timezone (map, zone); + if (ret) + gtk_widget_queue_draw (GTK_WIDGET (map)); + + g_free (real_tz); + + return ret; } const gchar * === modified file 'libmap/cc-timezone-map.h' --- libmap/cc-timezone-map.h 2011-02-23 21:26:49 +0000 +++ libmap/cc-timezone-map.h 2011-09-20 04:43:25 +0000 @@ -72,10 +72,8 @@ void cc_timezone_map_set_watermark (CcTimezoneMap * map, const gchar * watermark); -void cc_timezone_map_set_timezone (CcTimezoneMap *map, - const gchar *timezone); -void cc_timezone_map_set_coords (CcTimezoneMap *map, - gdouble lon, gdouble lat); +gboolean cc_timezone_map_set_timezone (CcTimezoneMap *map, + const gchar *timezone); const gchar * cc_timezone_map_get_timezone_at_coords (CcTimezoneMap *map, gdouble lon, gdouble lat); TzLocation * cc_timezone_map_get_location (CcTimezoneMap *map); === modified file 'libmap/data/cc.png' Binary files libmap/data/cc.png 2011-02-22 16:20:34 +0000 and libmap/data/cc.png 2011-09-20 04:43:25 +0000 differ === modified file 'libmap/data/timezone_-11.png' Binary files libmap/data/timezone_-11.png 2011-02-22 16:20:34 +0000 and libmap/data/timezone_-11.png 2011-09-20 04:43:25 +0000 differ === modified file 'libmap/data/timezone_8.png' Binary files libmap/data/timezone_8.png 2011-02-22 16:20:34 +0000 and libmap/data/timezone_8.png 2011-09-20 04:43:25 +0000 differ === modified file 'libmap/test-timezone.c' --- libmap/test-timezone.c 2011-02-25 16:41:56 +0000 +++ libmap/test-timezone.c 2011-09-20 04:43:25 +0000 @@ -1,56 +1,101 @@ -#include <config.h> -#include <locale.h> - -#include "tz.h" +#include <gtk/gtk.h> +#include "cc-timezone-map.h" + +#define TZ_DIR "/usr/share/zoneinfo/" + +static GList * +get_timezone_list (GList *tzs, + const char *top_path, + const char *subpath) +{ + GDir *dir; + char *fullpath; + const char *name; + + if (subpath == NULL) + fullpath = g_strdup (top_path); + else + fullpath = g_build_filename (top_path, subpath, NULL); + dir = g_dir_open (fullpath, 0, NULL); + if (dir == NULL) { + g_warning ("Could not open %s", fullpath); + return NULL; + } + while ((name = g_dir_read_name (dir)) != NULL) { + char *path; + + if (g_str_has_suffix (name, ".tab")) + continue; + + if (subpath != NULL) + path = g_build_filename (top_path, subpath, name, NULL); + else + path = g_build_filename (top_path, name, NULL); + if (g_file_test (path, G_FILE_TEST_IS_DIR)) { + if (subpath == NULL) { + tzs = get_timezone_list (tzs, top_path, name); + } else { + char *new_subpath; + new_subpath = g_strdup_printf ("%s/%s", subpath, name); + tzs = get_timezone_list (tzs, top_path, new_subpath); + g_free (new_subpath); + } + } else if (g_file_test (path, G_FILE_TEST_IS_REGULAR)) { + if (subpath == NULL) + tzs = g_list_prepend (tzs, g_strdup (name)); + else { + char *tz; + tz = g_strdup_printf ("%s/%s", subpath, name); + tzs = g_list_prepend (tzs, tz); + } + } + g_free (path); + } + g_dir_close (dir); + + return tzs; +} int main (int argc, char **argv) { - TzDB *db; - GPtrArray *locs; - guint i; - char *pixmap_dir; - int retval = 0; - - setlocale (LC_ALL, ""); - - if (argc == 2) { - pixmap_dir = g_strdup (argv[1]); - } else if (argc == 1) { - pixmap_dir = g_strdup ("data/"); - } else { - g_message ("Usage: %s [PIXMAP DIRECTORY]", argv[0]); - return 1; - } - - db = tz_load_db (); - locs = tz_get_locations (db); - for (i = 0; i < locs->len ; i++) { - TzLocation *loc = locs->pdata[i]; - TzInfo *info; - char *filename, *path; - gdouble selected_offset; - char buf[16]; - - info = tz_info_from_location (loc); - selected_offset = tz_location_get_utc_offset (loc) - / (60.0*60.0) + ((info->daylight) ? -1.0 : 0.0); - - filename = g_strdup_printf ("timezone_%s.png", - g_ascii_formatd (buf, sizeof (buf), - "%g", selected_offset)); - path = g_build_filename (pixmap_dir, filename, NULL); - - if (g_file_test (path, G_FILE_TEST_IS_REGULAR) == FALSE) { - g_message ("File '%s' missing for zone '%s'", filename, loc->zone); - retval = 1; + CcTimezoneMap *map; + TzDB *tz_db; + GList *tzs, *l; + GHashTable *ht; + int ret = 0; + + gtk_init (&argc, &argv); + + ht = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); + map = cc_timezone_map_new (); + tz_db = tz_load_db (); + tzs = get_timezone_list (NULL, TZ_DIR, NULL); + for (l = tzs; l != NULL; l = l->next) { + char *timezone = l->data; + char *clean_tz; + + clean_tz = tz_info_get_clean_name (tz_db, timezone); + + if (cc_timezone_map_set_timezone (map, clean_tz) == FALSE) { + if (g_hash_table_lookup (ht, clean_tz) == NULL) { + if (g_strcmp0 (clean_tz, timezone) == 0) + g_print ("Failed to locate timezone '%s'\n", timezone); + else + g_print ("Failed to locate timezone '%s' (original name: '%s')\n", clean_tz, timezone); + g_hash_table_insert (ht, g_strdup (clean_tz), GINT_TO_POINTER (TRUE)); + } + /* We don't warn for those two, we'll just fallback + * in the panel code */ + if (!g_str_equal (clean_tz, "posixrules") && + !g_str_equal (clean_tz, "Factory")) + ret = 1; } - - g_free (filename); - g_free (path); - tz_info_free (info); + g_free (timezone); + g_free (clean_tz); } - tz_db_free (db); - g_free (pixmap_dir); + g_list_free (tzs); + tz_db_free (tz_db); + g_hash_table_destroy (ht); - return retval; + return ret; } === modified file 'libmap/tz.c' --- libmap/tz.c 2011-02-23 18:28:53 +0000 +++ libmap/tz.c 2011-09-20 04:43:25 +0000 @@ -39,7 +39,7 @@ static int compare_country_names (const void *a, const void *b); static void sort_locations_by_country (GPtrArray *locations); static gchar * tz_data_file_get (void); - +static void load_backward_tz (TzDB *tz_db); /* ---------------- * * Public interface * @@ -124,9 +124,12 @@ sort_locations_by_country (tz_db->locations); g_free (tz_data_file); - + + /* Load up the hashtable of backward links */ + load_backward_tz (tz_db); + return tz_db; -} +} static void tz_location_free (TzLocation *loc) @@ -143,58 +146,10 @@ { g_ptr_array_foreach (db->locations, (GFunc) tz_location_free, NULL); g_ptr_array_free (db->locations, TRUE); + g_hash_table_destroy (db->backward); g_free (db); } -static gint -sort_locations (TzLocation *a, - TzLocation *b) -{ - if (a->dist > b->dist) - return 1; - - if (a->dist < b->dist) - return -1; - - return 0; -} - -static gdouble -convert_longtitude_to_x (gdouble longitude, gint map_width) -{ - const gdouble xdeg_offset = -6; - gdouble x; - - x = (map_width * (180.0 + longitude) / 360.0) - + (map_width * xdeg_offset / 180.0); - - return x; -} - -static gdouble -radians (gdouble degrees) -{ - return (degrees / 360.0) * G_PI * 2; -} - -static gdouble -convert_latitude_to_y (gdouble latitude, gdouble map_height) -{ - gdouble bottom_lat = -59; - gdouble top_lat = 81; - gdouble top_per, y, full_range, top_offset, map_range; - - top_per = top_lat / 180.0; - y = 1.25 * log (tan (G_PI_4 + 0.4 * radians (latitude))); - full_range = 4.6068250867599998; - top_offset = full_range * top_per; - map_range = fabs (1.25 * log (tan (G_PI_4 + 0.4 * radians (bottom_lat))) - top_offset); - y = fabs (y - top_offset); - y = y / map_range; - y = y * map_height; - return y; -} - GPtrArray * tz_get_locations (TzDB *db) { @@ -242,47 +197,18 @@ return offset; } -gint -tz_location_set_locally (TzLocation *loc) -{ - time_t curtime; - struct tm *curzone; - gboolean is_dst = FALSE; - gint correction = 0; - - g_return_val_if_fail (loc != NULL, 0); - g_return_val_if_fail (loc->zone != NULL, 0); - - curtime = time (NULL); - curzone = localtime (&curtime); - is_dst = curzone->tm_isdst; - - setenv ("TZ", loc->zone, 1); -#if 0 - curtime = time (NULL); - curzone = localtime (&curtime); - - if (!is_dst && curzone->tm_isdst) { - correction = (60 * 60); - } - else if (is_dst && !curzone->tm_isdst) { - correction = 0; - } -#endif - - return correction; -} - TzInfo * tz_info_from_location (TzLocation *loc) { TzInfo *tzinfo; time_t curtime; struct tm *curzone; + gchar *tz_env_value; g_return_val_if_fail (loc != NULL, NULL); g_return_val_if_fail (loc->zone != NULL, NULL); + tz_env_value = g_strdup (getenv ("TZ")); setenv ("TZ", loc->zone, 1); #if 0 @@ -311,6 +237,13 @@ #endif tzinfo->daylight = curzone->tm_isdst; + + if (tz_env_value) + setenv ("TZ", tz_env_value, 1); + else + unsetenv ("TZ"); + + g_free (tz_env_value); return tzinfo; } @@ -326,6 +259,99 @@ g_free (tzinfo); } +struct { + const char *orig; + const char *dest; +} aliases[] = { + { "Asia/Istanbul", "Europe/Istanbul" }, /* Istanbul is in both Europe and Asia */ + { "Europe/Nicosia", "Asia/Nicosia" }, /* Ditto */ + { "EET", "Europe/Istanbul" }, /* Same tz as the 2 above */ + { "HST", "Pacific/Honolulu" }, + { "WET", "Europe/Brussels" }, /* Other name for the mainland Europe tz */ + { "CET", "Europe/Brussels" }, /* ditto */ + { "MET", "Europe/Brussels" }, + { "Etc/Zulu", "Etc/GMT" }, + { "Etc/UTC", "Etc/GMT" }, + { "GMT", "Etc/GMT" }, + { "Greenwich", "Etc/GMT" }, + { "Etc/UCT", "Etc/GMT" }, + { "Etc/GMT0", "Etc/GMT" }, + { "Etc/GMT+0", "Etc/GMT" }, + { "Etc/GMT-0", "Etc/GMT" }, + { "Etc/Universal", "Etc/GMT" }, + { "PST8PDT", "America/Los_Angeles" }, /* Other name for the Atlantic tz */ + { "EST", "America/New_York" }, /* Other name for the Eastern tz */ + { "EST5EDT", "America/New_York" }, /* ditto */ + { "CST6CDT", "America/Chicago" }, /* Other name for the Central tz */ + { "MST", "America/Denver" }, /* Other name for the mountain tz */ + { "MST7MDT", "America/Denver" }, /* ditto */ +}; + +static gboolean +compare_timezones (const char *a, + const char *b) +{ + if (g_str_equal (a, b)) + return TRUE; + if (strchr (b, '/') == NULL) { + char *prefixed; + + prefixed = g_strdup_printf ("/%s", b); + if (g_str_has_suffix (a, prefixed)) { + g_free (prefixed); + return TRUE; + } + g_free (prefixed); + } + + return FALSE; +} + +char * +tz_info_get_clean_name (TzDB *tz_db, + const char *tz) +{ + char *ret; + const char *timezone; + guint i; + gboolean replaced; + + /* Remove useless prefixes */ + if (g_str_has_prefix (tz, "right/")) + tz = tz + strlen ("right/"); + else if (g_str_has_prefix (tz, "posix/")) + tz = tz + strlen ("posix/"); + + /* Here start the crazies */ + replaced = FALSE; + + for (i = 0; i < G_N_ELEMENTS (aliases); i++) { + if (compare_timezones (tz, aliases[i].orig)) { + replaced = TRUE; + timezone = aliases[i].dest; + break; + } + } + + /* Try again! */ + if (!replaced) { + /* Ignore crazy solar times from the '80s */ + if (g_str_has_prefix (tz, "Asia/Riyadh") || + g_str_has_prefix (tz, "Mideast/Riyadh")) { + timezone = "Asia/Riyadh"; + replaced = TRUE; + } + } + + if (!replaced) + timezone = tz; + + ret = g_hash_table_lookup (tz_db->backward, timezone); + if (ret == NULL) + return g_strdup (timezone); + return g_strdup (ret); +} + /* ----------------- * * Private functions * * ----------------- */ @@ -397,3 +423,60 @@ qsort (locations->pdata, locations->len, sizeof (gpointer), compare_country_names); } + +static void +load_backward_tz (TzDB *tz_db) +{ + GError *error = NULL; + char **lines, *contents; + guint i; + + tz_db->backward = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); + + if (g_file_get_contents (GNOMECC_DATA_DIR "/datetime/backward", &contents, NULL, &error) == FALSE) + { + g_warning ("Failed to load 'backward' file: %s", error->message); + return; + } + lines = g_strsplit (contents, "\n", -1); + g_free (contents); + for (i = 0; lines[i] != NULL; i++) + { + char **items; + guint j; + char *real, *alias; + + if (g_ascii_strncasecmp (lines[i], "Link\t", 5) != 0) + continue; + + items = g_strsplit (lines[i], "\t", -1); + real = NULL; + alias = NULL; + /* Skip the "Link<tab>" part */ + for (j = 1; items[j] != NULL; j++) + { + if (items[j][0] == '\0') + continue; + if (real == NULL) + { + real = items[j]; + continue; + } + alias = items[j]; + break; + } + + if (real == NULL || alias == NULL) + g_warning ("Could not parse line: %s", lines[i]); + + /* We don't need more than one name for it */ + if (g_str_equal (real, "Etc/UTC") || + g_str_equal (real, "Etc/UCT")) + real = "Etc/GMT"; + + g_hash_table_insert (tz_db->backward, g_strdup (alias), g_strdup (real)); + g_strfreev (items); + } + g_strfreev (lines); +} + === modified file 'libmap/tz.h' --- libmap/tz.h 2011-02-22 16:20:34 +0000 +++ libmap/tz.h 2011-09-20 04:43:25 +0000 @@ -41,7 +41,8 @@ struct _TzDB { - GPtrArray *locations; + GPtrArray *locations; + GHashTable *backward; }; struct _TzLocation @@ -72,6 +73,8 @@ TzDB *tz_load_db (void); void tz_db_free (TzDB *db); +char * tz_info_get_clean_name (TzDB *tz_db, + const char *tz); GPtrArray *tz_get_locations (TzDB *db); void tz_location_get_position (TzLocation *loc, double *longitude, double *latitude);
_______________________________________________ Mailing list: https://launchpad.net/~ayatana-commits Post to : ayatana-commits@lists.launchpad.net Unsubscribe : https://launchpad.net/~ayatana-commits More help : https://help.launchpad.net/ListHelp