From b4a4c9682ca2413175386ad36d06fc4e1032badc Mon Sep 17 00:00:00 2001 From: Michael Terry Date: Wed, 23 Feb 2011 13:28:53 -0500 Subject: grab timezone names from geomaps; flesh out support for timezone completion in main map and locations dialog; show times in locations dialog --- libmap/Makefile.am | 1 + libmap/Makefile.in | 1 + libmap/README | 2 +- libmap/cc-timezone-map.c | 466 ++++++++++++++++++++++++++++++++++++++++++++++- libmap/cc-timezone-map.h | 4 + libmap/tz.c | 49 +++++ 6 files changed, 512 insertions(+), 11 deletions(-) (limited to 'libmap') diff --git a/libmap/Makefile.am b/libmap/Makefile.am index 0cdeb34..a10b835 100644 --- a/libmap/Makefile.am +++ b/libmap/Makefile.am @@ -2,6 +2,7 @@ uidir = $(pkgdatadir)/libmap/ui dist_ui_DATA = \ data/bg.png \ data/cc.png \ + data/olsen_map.png \ data/pin.png \ data/timezone_0.png \ data/timezone_-10.png \ diff --git a/libmap/Makefile.in b/libmap/Makefile.in index b4ae6df..dd552a4 100644 --- a/libmap/Makefile.in +++ b/libmap/Makefile.in @@ -285,6 +285,7 @@ uidir = $(pkgdatadir)/libmap/ui dist_ui_DATA = \ data/bg.png \ data/cc.png \ + data/olsen_map.png \ data/pin.png \ data/timezone_0.png \ data/timezone_-10.png \ diff --git a/libmap/README b/libmap/README index 70d6f6c..c83c6d8 100644 --- a/libmap/README +++ b/libmap/README @@ -2,4 +2,4 @@ This static library is a copied version of the code in GNOME 3.0's control cente Ideally in the future, we can have all three packages using the same code. But for now, for time reasons (hah), it's just a copy. -To update this copy, put newer versions of the code and data files in place; then fix up any GTK3-isms. +To update this copy, put newer versions of the code and data files in place; then fix up any GTK3-isms and add cc_timezone_map_set_coords and friends. diff --git a/libmap/cc-timezone-map.c b/libmap/cc-timezone-map.c index 960a049..7647925 100644 --- a/libmap/cc-timezone-map.c +++ b/libmap/cc-timezone-map.c @@ -1,5 +1,6 @@ /* * Copyright (C) 2010 Intel, Inc + * Copyright (C) 2011 Canonical Ltd. * * Portions from Ubiquity, Copyright (C) 2009 Canonical Ltd. * Written by Evan Dandrea @@ -48,10 +49,15 @@ struct _CcTimezoneMapPrivate 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; + gdouble selected_offset; TzDB *tzdb; @@ -111,6 +117,388 @@ static CcTimezoneMapOffset color_codes[] = {-100, 0, 0, 0, 0 } }; +static const gchar * olsen_map_timezones[] = { + "Africa/Abidjan", + "Africa/Accra", + "Africa/Addis_Ababa", + "Africa/Algiers", + "Africa/Asmara", + "Africa/Bamako", + "Africa/Bangui", + "Africa/Banjul", + "Africa/Bissau", + "Africa/Blantyre", + "Africa/Brazzaville", + "Africa/Bujumbura", + "Africa/Cairo", + "Africa/Casablanca", + "Africa/Conakry", + "Africa/Dakar", + "Africa/Dar_es_Salaam", + "Africa/Djibouti", + "Africa/Douala", + "Africa/El_Aaiun", + "Africa/Freetown", + "Africa/Gaborone", + "Africa/Harare", + "Africa/Johannesburg", + "Africa/Kampala", + "Africa/Khartoum", + "Africa/Kigali", + "Africa/Kinshasa", + "Africa/Lagos", + "Africa/Libreville", + "Africa/Lome", + "Africa/Luanda", + "Africa/Lubumbashi", + "Africa/Lusaka", + "Africa/Malabo", + "Africa/Maputo", + "Africa/Maseru", + "Africa/Mbabane", + "Africa/Mogadishu", + "Africa/Monrovia", + "Africa/Nairobi", + "Africa/Ndjamena", + "Africa/Niamey", + "Africa/Nouakchott", + "Africa/Ouagadougou", + "Africa/Porto-Novo", + "Africa/Sao_Tome", + "Africa/Tripoli", + "Africa/Tunis", + "Africa/Windhoek", + "America/Adak", + "America/Anguilla", + "America/Antigua", + "America/Araguaina", + "America/Argentina/Buenos_Aires", + "America/Argentina/Catamarca", + "America/Argentina/Cordoba", + "America/Argentina/Jujuy", + "America/Argentina/La_Rioja", + "America/Argentina/Mendoza", + "America/Argentina/Rio_Gallegos", + "America/Argentina/San_Juan", + "America/Argentina/San_Luis", + "America/Argentina/Tucuman", + "America/Argentina/Ushuaia", + "America/Aruba", + "America/Asuncion", + "America/Atikokan", + "America/Bahia", + "America/Barbados", + "America/Belem", + "America/Belize", + "America/Blanc-Sablon", + "America/Boa_Vista", + "America/Bogota", + "America/Boise", + "America/Cambridge_Bay", + "America/Campo_Grande", + "America/Cancun", + "America/Caracas", + "America/Cayenne", + "America/Cayman", + "America/Chicago", + "America/Chihuahua", + "America/Coral_Harbour", + "America/Costa_Rica", + "America/Cuiaba", + "America/Curacao", + "America/Dawson", + "America/Dawson_Creek", + "America/Denver", + "America/Dominica", + "America/Edmonton", + "America/Eirunepe", + "America/El_Salvador", + "America/Fortaleza", + "America/Glace_Bay", + "America/Goose_Bay", + "America/Grand_Turk", + "America/Grenada", + "America/Guadeloupe", + "America/Guatemala", + "America/Guayaquil", + "America/Guyana", + "America/Halifax", + "America/Havana", + "America/Hermosillo", + "America/Indiana/Indianapolis", + "America/Indiana/Knox", + "America/Indiana/Marengo", + "America/Indiana/Petersburg", + "America/Indiana/Vevay", + "America/Indiana/Vincennes", + "America/Indiana/Winamac", + "America/Inuvik", + "America/Iqaluit", + "America/Jamaica", + "America/Juneau", + "America/Kentucky/Louisville", + "America/Kentucky/Monticello", + "America/La_Paz", + "America/Lima", + "America/Los_Angeles", + "America/Maceio", + "America/Managua", + "America/Manaus", + "America/Marigot", + "America/Martinique", + "America/Mazatlan", + "America/Menominee", + "America/Merida", + "America/Mexico_City", + "America/Miquelon", + "America/Moncton", + "America/Monterrey", + "America/Montevideo", + "America/Montreal", + "America/Montserrat", + "America/Nassau", + "America/New_York", + "America/Nipigon", + "America/Noronha", + "America/North_Dakota/Center", + "America/North_Dakota/Salem", + "America/Panama", + "America/Pangnirtung", + "America/Paramaribo", + "America/Phoenix", + "America/Port-au-Prince", + "America/Port_of_Spain", + "America/Porto_Velho", + "America/Puerto_Rico", + "America/Rainy_River", + "America/Rankin_Inlet", + "America/Recife", + "America/Regina", + "America/Resolute", + "America/Rio_Branco", + "America/Santarem", + "America/Santiago", + "America/Santo_Domingo", + "America/Sao_Paulo", + "America/St_Barthelemy", + "America/St_Johns", + "America/St_Kitts", + "America/St_Lucia", + "America/St_Thomas", + "America/St_Vincent", + "America/Tegucigalpa", + "America/Thunder_Bay", + "America/Tijuana", + "America/Toronto", + "America/Tortola", + "America/Vancouver", + "America/Whitehorse", + "America/Winnipeg", + "America/Yellowknife", + "Ameriica/Swift_Current", + "Arctic/Longyearbyen", + "Asia/Aden", + "Asia/Almaty", + "Asia/Amman", + "Asia/Anadyr", + "Asia/Aqtau", + "Asia/Aqtobe", + "Asia/Ashgabat", + "Asia/Baghdad", + "Asia/Bahrain", + "Asia/Baku", + "Asia/Bangkok", + "Asia/Beirut", + "Asia/Bishkek", + "Asia/Brunei", + "Asia/Choibalsan", + "Asia/Chongqing", + "Asia/Colombo", + "Asia/Damascus", + "Asia/Dhaka", + "Asia/Dili", + "Asia/Dubai", + "Asia/Dushanbe", + "Asia/Gaza", + "Asia/Harbin", + "Asia/Ho_Chi_Minh", + "Asia/Hong_Kong", + "Asia/Hovd", + "Asia/Irkutsk", + "Asia/Jakarta", + "Asia/Jayapura", + "Asia/Jerusalem", + "Asia/Kabul", + "Asia/Kamchatka", + "Asia/Karachi", + "Asia/Kashgar", + "Asia/Katmandu", + "Asia/Kolkata", + "Asia/Krasnoyarsk", + "Asia/Kuala_Lumpur", + "Asia/Kuching", + "Asia/Kuwait", + "Asia/Macau", + "Asia/Magadan", + "Asia/Makassar", + "Asia/Manila", + "Asia/Muscat", + "Asia/Nicosia", + "Asia/Novosibirsk", + "Asia/Omsk", + "Asia/Oral", + "Asia/Phnom_Penh", + "Asia/Pontianak", + "Asia/Pyongyang", + "Asia/Qatar", + "Asia/Qyzylorda", + "Asia/Rangoon", + "Asia/Riyadh", + "Asia/Sakhalin", + "Asia/Samarkand", + "Asia/Seoul", + "Asia/Shanghai", + "Asia/Singapore", + "Asia/Taipei", + "Asia/Tashkent", + "Asia/Tbilisi", + "Asia/Tehran", + "Asia/Thimphu", + "Asia/Tokyo", + "Asia/Ulaanbaatar", + "Asia/Urumqi", + "Asia/Vientiane", + "Asia/Vladivostok", + "Asia/Yakutsk", + "Asia/Yekaterinburg", + "Asia/Yerevan", + "Atlantic/Azores", + "Atlantic/Bermuda", + "Atlantic/Canary", + "Atlantic/Cape_Verde", + "Atlantic/Faroe", + "Atlantic/Madeira", + "Atlantic/Reykjavik", + "Atlantic/South_Georgia", + "Atlantic/St_Helena", + "Atlantic/Stanley", + "Australia/Adelaide", + "Australia/Brisbane", + "Australia/Broken_Hill", + "Australia/Currie", + "Australia/Darwin", + "Australia/Eucla", + "Australia/Hobart", + "Australia/Lindeman", + "Australia/Lord_Howe", + "Australia/Melbourne", + "Australia/Perth", + "Australia/Sydney", + "Europe/Amsterdam", + "Europe/Andorra", + "Europe/Athens", + "Europe/Belgrade", + "Europe/Berlin", + "Europe/Bratislava", + "Europe/Brussels", + "Europe/Bucharest", + "Europe/Budapest", + "Europe/Chisinau", + "Europe/Copenhagen", + "Europe/Dublin", + "Europe/Gibraltar", + "Europe/Guernsey", + "Europe/Helsinki", + "Europe/Isle_of_Man", + "Europe/Istanbul", + "Europe/Jersey", + "Europe/Kaliningrad", + "Europe/Kiev", + "Europe/Lisbon", + "Europe/Ljubljana", + "Europe/London", + "Europe/Luxembourg", + "Europe/Madrid", + "Europe/Malta", + "Europe/Marienhamn", + "Europe/Minsk", + "Europe/Monaco", + "Europe/Moscow", + "Europe/Oslo", + "Europe/Paris", + "Europe/Podgorica", + "Europe/Prague", + "Europe/Riga", + "Europe/Rome", + "Europe/Samara", + "Europe/San_Marino", + "Europe/Sarajevo", + "Europe/Simferopol", + "Europe/Skopje", + "Europe/Sofia", + "Europe/Stockholm", + "Europe/Tallinn", + "Europe/Tirane", + "Europe/Uzhgorod", + "Europe/Vaduz", + "Europe/Vatican", + "Europe/Vienna", + "Europe/Vilnius", + "Europe/Volgograd", + "Europe/Warsaw", + "Europe/Zagreb", + "Europe/Zaporozhye", + "Europe/Zurich", + "Indian/Antananarivo", + "Indian/Chagos", + "Indian/Christmas", + "Indian/Cocos", + "Indian/Comoro", + "Indian/Kerguelen", + "Indian/Mahe", + "Indian/Maldives", + "Indian/Mauritius", + "Indian/Mayotte", + "Indian/Reunion", + "Pacific/Apia", + "Pacific/Auckland", + "Pacific/Chatham", + "Pacific/Easter", + "Pacific/Efate", + "Pacific/Enderbury", + "Pacific/Fakaofo", + "Pacific/Fiji", + "Pacific/Funafuti", + "Pacific/Galapagos", + "Pacific/Gambier", + "Pacific/Guadalcanal", + "Pacific/Guam", + "Pacific/Honolulu", + "Pacific/Johnston", + "Pacific/Kiritimati", + "Pacific/Kosrae", + "Pacific/Kwajalein", + "Pacific/Majuro", + "Pacific/Marquesas", + "Pacific/Midway", + "Pacific/Nauru", + "Pacific/Niue", + "Pacific/Norfolk", + "Pacific/Noumea", + "Pacific/Pago_Pago", + "Pacific/Palau", + "Pacific/Pitcairn", + "Pacific/Ponape", + "Pacific/Port_Moresby", + "Pacific/Rarotonga", + "Pacific/Saipan", + "Pacific/Tahiti", + "Pacific/Tarawa", + "Pacific/Tongatapu", + "Pacific/Truk", + "Pacific/Wake", + "Pacific/Wallis" +}; static void cc_timezone_map_get_property (GObject *object, @@ -155,6 +543,16 @@ cc_timezone_map_dispose (GObject *object) priv->orig_color_map = NULL; } + if (priv->olsen_map) + { + g_object_unref (priv->olsen_map); + priv->olsen_map = NULL; + + priv->olsen_map_channels = 0; + priv->olsen_map_pixels = NULL; + priv->olsen_map_rowstride = 0; + } + if (priv->background) { g_object_unref (priv->background); @@ -513,12 +911,10 @@ set_location (CcTimezoneMap *map, tz_info_free (info); } -static gboolean -button_press_event (GtkWidget *widget, - GdkEventButton *event) +static TzLocation * +get_loc_for_xy (GtkWidget * widget, gint x, gint y) { CcTimezoneMapPrivate *priv = CC_TIMEZONE_MAP (widget)->priv; - gint x, y; guchar r, g, b, a; guchar *pixels; gint rowstride; @@ -529,10 +925,6 @@ button_press_event (GtkWidget *widget, GList *distances = NULL; GtkAllocation alloc; - x = event->x; - y = event->y; - - rowstride = priv->visible_map_rowstride; pixels = priv->visible_map_pixels; @@ -578,11 +970,19 @@ button_press_event (GtkWidget *widget, } distances = g_list_sort (distances, (GCompareFunc) sort_locations); - - set_location (CC_TIMEZONE_MAP (widget), (TzLocation*) distances->data); + TzLocation * loc = (TzLocation*) distances->data; g_list_free (distances); + return loc; +} + +static gboolean +button_press_event (GtkWidget *widget, + GdkEventButton *event) +{ + TzLocation * loc = get_loc_for_xy (widget, event->x, event->y); + set_location (CC_TIMEZONE_MAP (widget), loc); return TRUE; } @@ -664,6 +1064,18 @@ cc_timezone_map_init (CcTimezoneMap *self) g_clear_error (&err); } + priv->olsen_map = gdk_pixbuf_new_from_file (DATADIR "/olsen_map.png", + &err); + if (!priv->olsen_map) + { + g_warning ("Could not load olsen map: %s", + (err) ? err->message : "Unknown error"); + g_clear_error (&err); + } + priv->olsen_map_channels = gdk_pixbuf_get_n_channels (priv->olsen_map); + priv->olsen_map_pixels = gdk_pixbuf_get_pixels (priv->olsen_map); + priv->olsen_map_rowstride = gdk_pixbuf_get_rowstride (priv->olsen_map); + priv->tzdb = tz_load_db (); g_signal_connect (self, "button-press-event", G_CALLBACK (button_press_event), @@ -704,6 +1116,40 @@ cc_timezone_map_set_timezone (CcTimezoneMap *map, 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); +} + +const gchar * +cc_timezone_map_get_timezone_at_coords (CcTimezoneMap *map, gdouble lon, gdouble lat) +{ + gint x = (int)(2048.0 / 360.0 * (180.0 + lon)); + gint y = (int)(1024.0 / 180.0 * (90.0 - lat)); + gint offset = map->priv->olsen_map_rowstride * y + x * map->priv->olsen_map_channels; + guchar color0 = map->priv->olsen_map_pixels[offset]; + guchar color1 = map->priv->olsen_map_pixels[offset + 1]; + gint zone = ((color0 & 248) << 1) + ((color1 >>4) & 15); + + const gchar * city = NULL; + if (zone < G_N_ELEMENTS(olsen_map_timezones)) + city = olsen_map_timezones[zone]; + + if (city != NULL) { + return city; + } + else { + GtkAllocation alloc; + gtk_widget_get_allocation (GTK_WIDGET (map), &alloc); + x = convert_longtitude_to_x(lon, alloc.width); + y = convert_latitude_to_y(lat, alloc.height); + TzLocation * loc = get_loc_for_xy(GTK_WIDGET (map), x, y); + return loc->zone; + } +} + TzLocation * cc_timezone_map_get_location (CcTimezoneMap *map) { diff --git a/libmap/cc-timezone-map.h b/libmap/cc-timezone-map.h index 3c57b27..8de986d 100644 --- a/libmap/cc-timezone-map.h +++ b/libmap/cc-timezone-map.h @@ -72,6 +72,10 @@ CcTimezoneMap *cc_timezone_map_new (void); void cc_timezone_map_set_timezone (CcTimezoneMap *map, const gchar *timezone); +void cc_timezone_map_set_coords (CcTimezoneMap *map, + gdouble lon, gdouble lat); +const gchar * cc_timezone_map_get_timezone_at_coords (CcTimezoneMap *map, + gdouble lon, gdouble lat); TzLocation * cc_timezone_map_get_location (CcTimezoneMap *map); G_END_DECLS diff --git a/libmap/tz.c b/libmap/tz.c index 3e6c8ae..b77a8ef 100644 --- a/libmap/tz.c +++ b/libmap/tz.c @@ -146,6 +146,55 @@ tz_db_free (TzDB *db) 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) { -- cgit v1.2.3