From a10f207618976b59a0cc43c01befbf67128c92a5 Mon Sep 17 00:00:00 2001 From: Michael Terry Date: Thu, 17 Feb 2011 14:30:43 -0500 Subject: first pass at preferences dialog --- configure.ac | 18 + data/Makefile.am | 3 + data/com.canonical.indicator.datetime.gschema.xml | 53 +- data/datetime-dialog.ui | 808 ++++++++++++++++++++++ src/Makefile.am | 20 +- src/datetime-prefs.c | 211 ++++++ src/datetime-service.c | 14 +- src/indicator-datetime.c | 31 +- src/settings-shared.h | 39 ++ src/utils.c | 45 ++ src/utils.h | 34 + 11 files changed, 1229 insertions(+), 47 deletions(-) create mode 100644 data/datetime-dialog.ui create mode 100644 src/datetime-prefs.c create mode 100644 src/settings-shared.h create mode 100644 src/utils.c create mode 100644 src/utils.h diff --git a/configure.ac b/configure.ac index 4f35d38..3cf45ef 100644 --- a/configure.ac +++ b/configure.ac @@ -64,6 +64,8 @@ EDS_REQUIRED_VERSION=2.30 ICAL_REQUIRED_VERSION=0.44 CAIRO_REQUIRED_VERSION=1.10 GDK_REQUIRED_VERSION=2.22 +GTK_REQUIRED_VERSION=2.12 +GTK3_REQUIRED_VERSION=3.0 AS_IF([test "x$with_gtk" = x3], [PKG_CHECK_MODULES(INDICATOR, indicator3 >= $INDICATOR_REQUIRED_VERSION @@ -110,12 +112,28 @@ AS_IF([test "x$with_gtk" = x3], ], [AC_MSG_FAILURE([Value for --with-gtk was neither 2 nor 3])] ) + +AS_IF([test "x$with_gtk" = x3], + [PKG_CHECK_MODULES(PREF, gio-2.0 >= $GIO_REQUIRED_VERSION + gtk+-3.0 >= $GTK3_REQUIRED_VERSION + unique-3.0) + ], + [test "x$with_gtk" = x2], + [PKG_CHECK_MODULES(PREF, gio-2.0 >= $GIO_REQUIRED_VERSION + gtk+-2.0 >= $GTK_REQUIRED_VERSION + unique-1.0) + ], + [AC_MSG_FAILURE([Value for --with-gtk was neither 2 nor 3])] +) AC_SUBST(INDICATOR_CFLAGS) AC_SUBST(INDICATOR_LIBS) AC_SUBST(SERVICE_CFLAGS) AC_SUBST(SERVICE_LIBS) +AC_SUBST(PREF_CFLAGS) +AC_SUBST(PREF_LIBS) + ########################### # Grab the GSettings Macros ########################### diff --git a/data/Makefile.am b/data/Makefile.am index de417b2..669db77 100644 --- a/data/Makefile.am +++ b/data/Makefile.am @@ -10,8 +10,11 @@ dbus_services_DATA = indicator-datetime.service %.service: %.service.in sed -e "s|\@libexecdir\@|$(libexecdir)|" $< > $@ +pkgdata_DATA = datetime-dialog.ui + EXTRA_DIST = \ $(gsettings_SCHEMAS) \ + datetime-dialog.ui \ indicator-datetime.service.in CLEANFILES = indicator-datetime.service diff --git a/data/com.canonical.indicator.datetime.gschema.xml b/data/com.canonical.indicator.datetime.gschema.xml index 117f965..b33f34e 100644 --- a/data/com.canonical.indicator.datetime.gschema.xml +++ b/data/com.canonical.indicator.datetime.gschema.xml @@ -6,6 +6,13 @@ + + true + Show the clock in the panel + + Controls whether the clock indicator appears in the panel or not. + + 'locale-default' What the time format should be @@ -18,6 +25,17 @@ string and set the custom-time-format setting. + + "%l:%M %p" + The format string passed to strftime + + The format of the time and/or date that is visible on the panel when using + the indicator. For most users this will be a set of predefined values as + determined by the configuration utility, but advanced users can change it + to anything strftime can accept. Look at the man page on strftime for + more information. + + false Show the number of seconds in the indicator @@ -46,19 +64,36 @@ time-format value is set to custom. - - "%l:%M %p" - The format string passed to strftime + + true + Show the monthly calendar in the indicator - The format of the time and/or date that is visible on the panel when using - the indicator. For most users this will be a set of predefined values as - determined by the configuration utility, but advanced users can change it - to anything strftime can accept. Look at the man page on strftime for - more information. + Puts the monthly calendar in indicator-datetime's menu. + + + + false + Show week numbers in calendar + + Shows the week numbers in the monthly calendar in indicator-datetime's menu. + + + + true + Show events in the indicator + + Shows events from Evolution in indicator-datetime's menu. + + + + false + Show locations in the indicator + + Shows custom defined locations in indicator-datetime's menu. - [] + ['UTC'] A List of locations Adds the list of locations the user has configured to display in the diff --git a/data/datetime-dialog.ui b/data/datetime-dialog.ui new file mode 100644 index 0000000..42f3bb6 --- /dev/null +++ b/data/datetime-dialog.ui @@ -0,0 +1,808 @@ + + + + + + False + Locations + time-admin + + + True + False + + + True + True + locationsStore + + + True + True + 0 + + + + + True + False + + + True + True + True + False + + + True + False + gtk-add + + + + + False + True + 0 + + + + + True + True + True + False + + + True + False + gtk-remove + + + + + False + True + 1 + + + + + False + True + 1 + + + + + + + + + + + + + + + False + 5 + Time & Date + time-admin + dialog + + + True + False + + + False + True + end + + + gtk-close + True + True + True + False + True + + + False + False + 0 + + + + + False + True + end + 0 + + + + + True + True + + + True + False + 12 + 6 + + + + + + + + + True + False + 12 + True + + + True + False + 6 + + + True + False + 0 + _Region: + True + regionCombo + + + False + True + 0 + + + + + True + False + + + True + True + 1 + + + + + True + True + 0 + + + + + True + False + 6 + + + True + False + 0 + Time_zone: + True + timezoneCombo + + + False + True + 0 + + + + + True + False + + + True + True + 1 + + + + + False + True + 1 + + + + + False + True + 2 + + + + + True + False + 2 + 2 + 6 + 6 + + + True + False + 6 + + + _Manually + True + True + False + False + True + 0 + True + True + + + False + True + 0 + + + + + _Automatically from the Internet + True + True + False + False + True + 0 + True + manualTimeRadio + + + False + True + 1 + + + + + 1 + 2 + + + + + True + False + 0 + Set the time: + + + GTK_FILL + GTK_FILL + + + + + True + False + 12 + + + True + False + 6 + + + True + False + 0 + Tim_e: + True + timeSpinner + + + False + True + 0 + + + + + True + True + + True + + + False + True + 1 + + + + + False + True + 0 + + + + + True + False + 6 + + + True + False + 0 + _Date: + True + dateSpinner + + + False + True + 0 + + + + + True + True + + True + + + False + True + 1 + + + + + False + True + 1 + + + + + 1 + 2 + 1 + 2 + + + + + + + + False + True + 3 + + + + + + + True + False + 1 + _Time & Date + True + + + False + + + + + True + False + 12 + 12 + + + _Show a clock in the panel + True + True + False + False + True + 0 + True + + + True + True + 0 + + + + + True + False + True + + + True + False + + + True + False + 0 + In the clock, show: + + + False + True + 0 + + + + + _Weekday + True + True + False + False + True + 0 + True + + + False + True + 1 + + + + + _Date and time + True + True + False + False + True + 0 + True + + + False + True + 2 + + + + + _12-hour time + True + True + False + False + True + 0 + True + True + + + False + True + 3 + + + + + _24-hour time + True + True + False + False + True + 0 + True + True + show12HourRadio + + + False + True + 4 + + + + + Seco_nds + True + True + False + False + True + 0 + True + + + False + True + 5 + + + + + True + True + 0 + + + + + True + False + + + True + False + 0 + In the clock’s menu, show: + + + True + True + 0 + + + + + _Monthly calendar + True + True + False + False + True + 0 + True + + + False + True + 1 + + + + + True + False + 0 + 0 + 0 + 0 + 12 + + + True + False + + + Include week num_bers + True + True + False + False + True + 0 + True + + + True + True + 0 + + + + + False + True + 0 + Week begins on: + + + True + True + 1 + + + + + False + True + True + + + S_unday + True + True + False + False + True + 0 + True + True + + + True + True + 0 + + + + + Monda_y + True + True + False + False + True + 0 + True + True + startOnSundayRadio + + + True + True + 1 + + + + + True + True + 2 + + + + + + + False + True + 2 + + + + + True + True + False + False + True + 0 + True + + + True + False + 0 + Coming _events from Evolution Calendar + True + True + showEventsCheck + + + + + False + True + 3 + + + + + Time in _other locations + True + True + False + False + True + 0 + True + + + False + True + 4 + + + + + True + False + 0 + 0 + 0 + 0 + 12 + + + Choose _Locations… + True + True + True + False + True + 0 + + + + + True + True + 5 + + + + + True + True + 1 + + + + + True + True + 1 + + + + + 1 + False + + + + + True + False + _Clock + True + + + 1 + False + + + + + True + True + 1 + + + + + + + + + closeButton + + + diff --git a/src/Makefile.am b/src/Makefile.am index 7a290c6..150c87d 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,4 +1,5 @@ +bin_PROGRAMS = indicator-datetime-preferences libexec_PROGRAMS = indicator-datetime-service indicator_datetime_service_SOURCES = \ @@ -8,7 +9,8 @@ indicator_datetime_service_SOURCES = \ calendar-menu-item.c \ calendar-menu-item.h \ datetime-service.c \ - dbus-shared.h + dbus-shared.h \ + settings-shared.h indicator_datetime_service_CFLAGS = \ -Wall \ -Werror \ @@ -23,6 +25,9 @@ datetimelib_LTLIBRARIES = libdatetime.la libdatetime_la_SOURCES = \ gen-datetime-service.xml.h \ dbus-shared.h \ + settings-shared.h \ + utils.c \ + utils.h \ indicator-datetime.c libdatetime_la_CFLAGS = \ $(INDICATOR_CFLAGS) \ @@ -34,6 +39,19 @@ libdatetime_la_LDFLAGS = \ -module \ -avoid-version +indicator_datetime_preferences_SOURCES =\ + datetime-prefs.c \ + utils.c \ + utils.h \ + settings-shared.h +indicator_datetime_preferences_CFLAGS = \ + -Wall \ + -Werror \ + $(PREF_CFLAGS) \ + -DPKGDATADIR="\"$(pkgdatadir)\"" +indicator_datetime_preferences_LDADD = \ + $(PREF_LIBS) + gen-%.xml.c: %.xml @echo "Building $@ from $<" @echo "const char * _$(subst -,_,$(subst .,_,$(basename $<))) = " > $@ diff --git a/src/datetime-prefs.c b/src/datetime-prefs.c new file mode 100644 index 0000000..1957b7f --- /dev/null +++ b/src/datetime-prefs.c @@ -0,0 +1,211 @@ +/* -*- Mode: C; coding: utf-8; indent-tabs-mode: nil; tab-width: 2 -*- + +A dialog for setting time and date preferences. + +Copyright 2011 Canonical Ltd. + +Authors: + Ted Gould + Michael Terry + +This program is free software: you can redistribute it and/or modify it +under the terms of the GNU General Public License version 3, as published +by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranties of +MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program. If not, see . +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include + +#include "settings-shared.h" +#include "utils.h" + +#define DATETIME_DIALOG_UI_FILE PKGDATADIR "/datetime-dialog.ui" + +/* Turns the boolean property into a string gsettings */ +static GVariant * +bind_hours_set (const GValue * value, const GVariantType * type, gpointer user_data) +{ + const gchar * output = NULL; + gboolean is_12hour_button = (gboolean)GPOINTER_TO_INT(user_data); + + if (g_value_get_boolean(value)) { + /* Only do anything if we're setting active = true */ + output = is_12hour_button ? "12-hour" : "24-hour"; + } else { + return NULL; + } + + return g_variant_new_string (output); +} + +/* Turns a string gsettings into a boolean property */ +static gboolean +bind_hours_get (GValue * value, GVariant * variant, gpointer user_data) +{ + const gchar * str = g_variant_get_string(variant, NULL); + gboolean output = FALSE; + gboolean is_12hour_button = (gboolean)GPOINTER_TO_INT(user_data); + + if (g_strcmp0(str, "locale-default") == 0) { + output = (is_12hour_button == is_locale_12h ()); + } else if (g_strcmp0(str, "12-hour") == 0) { + output = is_12hour_button; + } else if (g_strcmp0(str, "24-hour") == 0) { + output = !is_12hour_button; + } else { + return FALSE; + } + + g_value_set_boolean (value, output); + return TRUE; +} + +static void +widget_dependency_cb (GtkWidget * parent, GParamSpec *pspec, GtkWidget * dependent) +{ + gboolean active, sensitive; + g_object_get (G_OBJECT (parent), + "active", &active, + "sensitive", &sensitive, NULL); + gtk_widget_set_sensitive (dependent, active && sensitive); +} + +static void +add_widget_dependency (GtkWidget * parent, GtkWidget * dependent) +{ + g_signal_connect (parent, "notify::active", G_CALLBACK(widget_dependency_cb), + dependent); + g_signal_connect (parent, "notify::sensitive", G_CALLBACK(widget_dependency_cb), + dependent); + widget_dependency_cb (parent, NULL, dependent); +} + +static GtkWidget * +create_dialog (void) +{ + GError * error = NULL; + + GtkBuilder * builder = gtk_builder_new (); + gtk_builder_add_from_file (builder, DATETIME_DIALOG_UI_FILE, &error); + if (error != NULL) { + /* We have to abort, we can't continue without the ui file */ + g_error ("Could not load ui file %s: %s", DATETIME_DIALOG_UI_FILE, error->message); + g_error_free (error); + return NULL; + } + + gtk_builder_set_translation_domain (builder, GETTEXT_PACKAGE); + + GSettings * conf = g_settings_new (SETTINGS_INTERFACE); + +#define WIG(name) GTK_WIDGET (gtk_builder_get_object (builder, name)) + + /* Set up settings bindings */ + + g_settings_bind (conf, SETTINGS_SHOW_CLOCK_S, WIG ("showClockCheck"), + "active", G_SETTINGS_BIND_DEFAULT); + g_settings_bind (conf, SETTINGS_SHOW_DAY_S, WIG ("showWeekdayCheck"), + "active", G_SETTINGS_BIND_DEFAULT); + g_settings_bind (conf, SETTINGS_SHOW_DATE_S, WIG ("showDateTimeCheck"), + "active", G_SETTINGS_BIND_DEFAULT); + g_settings_bind (conf, SETTINGS_SHOW_SECONDS_S, WIG ("showSecondsCheck"), + "active", G_SETTINGS_BIND_DEFAULT); + g_settings_bind_with_mapping (conf, SETTINGS_TIME_FORMAT_S, + WIG ("show12HourRadio"), "active", + G_SETTINGS_BIND_DEFAULT, + bind_hours_get, bind_hours_set, + GINT_TO_POINTER(TRUE), NULL); + g_settings_bind_with_mapping (conf, SETTINGS_TIME_FORMAT_S, + WIG ("show24HourRadio"), "active", + G_SETTINGS_BIND_DEFAULT, + bind_hours_get, bind_hours_set, + GINT_TO_POINTER(FALSE), NULL); + g_settings_bind (conf, SETTINGS_SHOW_CALENDAR_S, WIG ("showCalendarCheck"), + "active", G_SETTINGS_BIND_DEFAULT); + g_settings_bind (conf, SETTINGS_SHOW_WEEK_NUMBERS_S, WIG ("includeWeekNumbersCheck"), + "active", G_SETTINGS_BIND_DEFAULT); + /*g_settings_bind_(conf, SETTINGS_WEEK_BEGINS_SUNDAY_S, WIG ("startOnSundayRadio"), + "active", G_SETTINGS_BIND_DEFAULT);*/ + g_settings_bind (conf, SETTINGS_SHOW_EVENTS_S, WIG ("showEventsCheck"), + "active", G_SETTINGS_BIND_DEFAULT); + g_settings_bind (conf, SETTINGS_SHOW_LOCATIONS_S, WIG ("showLocationsCheck"), + "active", G_SETTINGS_BIND_DEFAULT); + + /* Set up sensitivities */ + add_widget_dependency (WIG ("showCalendarCheck"), WIG ("calendarOptions")); + add_widget_dependency (WIG ("showClockCheck"), WIG ("clockOptions")); + add_widget_dependency (WIG ("showLocationsCheck"), WIG ("locationsButton")); + add_widget_dependency (WIG ("manualTimeRadio"), WIG ("manualOptions")); + + /* Hacky proxy test for whether evolution-data-server is installed */ + gchar * evo_path = g_find_program_in_path ("evolution"); + gtk_widget_set_sensitive (WIG ("showEventsCheck"), (evo_path != NULL)); + g_free (evo_path); + + GtkWidget * dlg = WIG ("timeDateDialog"); + +#undef WIG + + g_object_unref (conf); + g_object_unref (builder); + + return dlg; +} + +static UniqueResponse +message_received (UniqueApp * app, gint command, UniqueMessageData *message_data, + guint time, gpointer user_data) +{ + if (command == UNIQUE_ACTIVATE) { + gtk_window_present_with_time (GTK_WINDOW (user_data), time); + return UNIQUE_RESPONSE_OK; + } + return UNIQUE_RESPONSE_PASSTHROUGH; +} + +int +main (int argc, char ** argv) +{ + g_type_init (); + + /* Setting up i18n and gettext. Apparently, we need + all of these. */ + setlocale (LC_ALL, ""); + bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR); + textdomain (GETTEXT_PACKAGE); + + gtk_init (&argc, &argv); + + UniqueApp * app = unique_app_new ("com.canonical.indicator.datetime.preferences", NULL); + + if (unique_app_is_running (app)) { + unique_app_send_message (app, UNIQUE_ACTIVATE, NULL); + } else { + // We're first instance. Yay! + GtkWidget * dlg = create_dialog (); + + g_signal_connect (app, "message-received", G_CALLBACK(message_received), dlg); + unique_app_watch_window (app, GTK_WINDOW (dlg)); + + gtk_widget_show_all (dlg); + g_signal_connect (dlg, "response", G_CALLBACK(gtk_main_quit), NULL); + gtk_main (); + } + + return 0; +} + diff --git a/src/datetime-service.c b/src/datetime-service.c index 0894e83..cc6c9d5 100644 --- a/src/datetime-service.c +++ b/src/datetime-service.c @@ -51,11 +51,9 @@ with this program. If not, see . #include "datetime-interface.h" #include "dbus-shared.h" +#include "settings-shared.h" -#define SETTINGS_INTERFACE "com.canonical.indicator.datetime" -#define SETTINGS_LOCATIONS "locations" - static void geo_create_client (GeoclueMaster * master, GeoclueMasterClient * client, gchar * path, GError * error, gpointer user_data); static gboolean update_appointment_menu_items (gpointer user_data); static gboolean update_timezone_menu_items(gpointer user_data); @@ -363,7 +361,7 @@ check_for_calendar (gpointer user_data) static gboolean update_timezone_menu_items(gpointer user_data) { g_debug("Updating timezone menu items"); - gchar ** locations = g_settings_get_strv(conf, SETTINGS_LOCATIONS); + gchar ** locations = g_settings_get_strv(conf, SETTINGS_LOCATIONS_S); if (locations == NULL) { g_debug("No locations configured (NULL)"); return FALSE; @@ -648,13 +646,13 @@ check_for_timeadmin (gpointer user_data) { g_return_val_if_fail (settings != NULL, FALSE); - gchar * timeadmin = g_find_program_in_path("time-admin"); + gchar * timeadmin = g_find_program_in_path("indicator-datetime-preferences"); if (timeadmin != NULL) { - g_debug("Found the time-admin application: %s", timeadmin); + g_debug("Found the indicator-datetime-preferences application: %s", timeadmin); dbusmenu_menuitem_property_set_bool(settings, DBUSMENU_MENUITEM_PROP_ENABLED, TRUE); g_free(timeadmin); } else { - g_debug("Unable to find time-admin app."); + g_debug("Unable to find indicator-datetime-preferences app."); dbusmenu_menuitem_property_set_bool(settings, DBUSMENU_MENUITEM_PROP_ENABLED, FALSE); } @@ -721,7 +719,7 @@ build_menus (DbusmenuMenuitem * root) dbusmenu_menuitem_property_set (settings, DBUSMENU_MENUITEM_PROP_LABEL, _("Time & Date Settings...")); /* insensitive until we check for available apps */ dbusmenu_menuitem_property_set_bool(settings, DBUSMENU_MENUITEM_PROP_ENABLED, FALSE); - g_signal_connect(G_OBJECT(settings), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(activate_cb), "time-admin"); + g_signal_connect(G_OBJECT(settings), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(activate_cb), "indicator-datetime-preferences"); dbusmenu_menuitem_child_append(root, settings); g_idle_add(check_for_timeadmin, NULL); diff --git a/src/indicator-datetime.c b/src/indicator-datetime.c index 0f60428..e27158c 100644 --- a/src/indicator-datetime.c +++ b/src/indicator-datetime.c @@ -23,10 +23,6 @@ with this program. If not, see . #include "config.h" #endif -#include -#include -#include - /* GStuff */ #include #include @@ -43,7 +39,9 @@ with this program. If not, see . #include #include +#include "utils.h" #include "dbus-shared.h" +#include "settings-shared.h" #define INDICATOR_DATETIME_TYPE (indicator_datetime_get_type ()) @@ -117,13 +115,6 @@ struct _indicator_item_t { #define PROP_SHOW_DATE_S "show-date" #define PROP_CUSTOM_TIME_FORMAT_S "custom-time-format" -#define SETTINGS_INTERFACE "com.canonical.indicator.datetime" -#define SETTINGS_TIME_FORMAT_S "time-format" -#define SETTINGS_SHOW_SECONDS_S "show-seconds" -#define SETTINGS_SHOW_DAY_S "show-day" -#define SETTINGS_SHOW_DATE_S "show-date" -#define SETTINGS_CUSTOM_TIME_FORMAT_S "custom-time-format" - enum { SETTINGS_TIME_LOCALE = 0, SETTINGS_TIME_12_HOUR = 1, @@ -964,24 +955,6 @@ T_(const char *msg) return rv; } -/* Check the system locale setting to see if the format is 24-hour - time or 12-hour time */ -static gboolean -is_locale_12h() -{ - static const char *formats_24h[] = {"%H", "%R", "%T", "%OH", "%k", NULL}; - const char *t_fmt = nl_langinfo(T_FMT); - int i; - - for (i = 0; formats_24h[i]; ++i) { - if (strstr(t_fmt, formats_24h[i])) { - return FALSE; - } - } - - return TRUE; -} - /* Respond to changes in the screen to update the text gravity */ static void update_text_gravity (GtkWidget *widget, GdkScreen *previous_screen, gpointer data) diff --git a/src/settings-shared.h b/src/settings-shared.h new file mode 100644 index 0000000..1a66688 --- /dev/null +++ b/src/settings-shared.h @@ -0,0 +1,39 @@ +/* +An indicator to show date and time information. + +Copyright 2010 Canonical Ltd. + +Authors: + Ted Gould + +This program is free software: you can redistribute it and/or modify it +under the terms of the GNU General Public License version 3, as published +by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranties of +MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program. If not, see . +*/ + +#ifndef __DATETIME_SETTINGS_SHARED_H__ +#define __DATETIME_SETTINGS_SHARED_H__ + +#define SETTINGS_INTERFACE "com.canonical.indicator.datetime" +#define SETTINGS_SHOW_CLOCK_S "show-clock" +#define SETTINGS_TIME_FORMAT_S "time-format" +#define SETTINGS_SHOW_SECONDS_S "show-seconds" +#define SETTINGS_SHOW_DAY_S "show-day" +#define SETTINGS_SHOW_DATE_S "show-date" +#define SETTINGS_CUSTOM_TIME_FORMAT_S "custom-time-format" +#define SETTINGS_SHOW_CALENDAR_S "show-calendar" +#define SETTINGS_SHOW_WEEK_NUMBERS_S "show-week-numbers" +#define SETTINGS_WEEK_BEGINS_SUNDAY_S "week-begins-sunday" +#define SETTINGS_SHOW_EVENTS_S "show-events" +#define SETTINGS_SHOW_LOCATIONS_S "show-locations" +#define SETTINGS_LOCATIONS_S "locations" + +#endif diff --git a/src/utils.c b/src/utils.c new file mode 100644 index 0000000..69143b9 --- /dev/null +++ b/src/utils.c @@ -0,0 +1,45 @@ +/* -*- Mode: C; coding: utf-8; indent-tabs-mode: nil; tab-width: 2 -*- + +A dialog for setting time and date preferences. + +Copyright 2010 Canonical Ltd. + +Authors: + Michael Terry + +This program is free software: you can redistribute it and/or modify it +under the terms of the GNU General Public License version 3, as published +by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranties of +MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program. If not, see . +*/ + +#include +#include +#include +#include "utils.h" + +/* Check the system locale setting to see if the format is 24-hour + time or 12-hour time */ +gboolean +is_locale_12h (void) +{ + static const char *formats_24h[] = {"%H", "%R", "%T", "%OH", "%k", NULL}; + const char *t_fmt = nl_langinfo (T_FMT); + int i; + + for (i = 0; formats_24h[i]; ++i) { + if (strstr (t_fmt, formats_24h[i])) { + return FALSE; + } + } + + return TRUE; +} + diff --git a/src/utils.h b/src/utils.h new file mode 100644 index 0000000..f6305c8 --- /dev/null +++ b/src/utils.h @@ -0,0 +1,34 @@ +/* -*- Mode: C; coding: utf-8; indent-tabs-mode: nil; tab-width: 2 -*- + +A dialog for setting time and date preferences. + +Copyright 2010 Canonical Ltd. + +Authors: + Michael Terry + +This program is free software: you can redistribute it and/or modify it +under the terms of the GNU General Public License version 3, as published +by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranties of +MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program. If not, see . +*/ + +#ifndef __DATETIME_UTILS_H__ +#define __DATETIME_UTILS_H__ + +#include + +G_BEGIN_DECLS + +gboolean is_locale_12h (void); + +G_END_DECLS + +#endif -- cgit v1.2.3 From 354fc2c05e901b65f4a0516473632a4df3878ed6 Mon Sep 17 00:00:00 2001 From: Michael Terry Date: Fri, 18 Feb 2011 10:50:49 -0500 Subject: add polkit support and use new gnome-settings-daemon ntp-setting support --- configure.ac | 7 +- data/datetime-dialog.ui | 354 +++++++++++++++++++++++++----------------------- src/datetime-prefs.c | 223 ++++++++++++++++++++++++++---- 3 files changed, 387 insertions(+), 197 deletions(-) diff --git a/configure.ac b/configure.ac index 3cf45ef..2418f12 100644 --- a/configure.ac +++ b/configure.ac @@ -113,15 +113,18 @@ AS_IF([test "x$with_gtk" = x3], [AC_MSG_FAILURE([Value for --with-gtk was neither 2 nor 3])] ) +# FIXME: polkit-gtk-1 isn't gtk3-compatible AS_IF([test "x$with_gtk" = x3], [PKG_CHECK_MODULES(PREF, gio-2.0 >= $GIO_REQUIRED_VERSION gtk+-3.0 >= $GTK3_REQUIRED_VERSION - unique-3.0) + unique-3.0 + polkit-gtk-1) ], [test "x$with_gtk" = x2], [PKG_CHECK_MODULES(PREF, gio-2.0 >= $GIO_REQUIRED_VERSION gtk+-2.0 >= $GTK_REQUIRED_VERSION - unique-1.0) + unique-1.0 + polkit-gtk-1) ], [AC_MSG_FAILURE([Value for --with-gtk was neither 2 nor 3])] ) diff --git a/data/datetime-dialog.ui b/data/datetime-dialog.ui index 42f3bb6..f2a5938 100644 --- a/data/datetime-dialog.ui +++ b/data/datetime-dialog.ui @@ -133,82 +133,91 @@ 12 6 - - - - - - - + True False - 12 - True + 6 - - True - False - 6 - - - True - False - 0 - _Region: - True - regionCombo - - - False - True - 0 - - - - - True - False - - - True - True - 1 - - - - - True - True - 0 - + - + True False - 6 + 12 + True - + True False - 0 - Time_zone: - True - timezoneCombo + 6 + + + True + False + 0 + _Region: + True + regionCombo + + + False + True + 0 + + + + + True + False + + + True + True + 1 + + - False + True True 0 - + True False + 6 + + + True + False + 0 + Time_zone: + True + timezoneCombo + + + False + True + 0 + + + + + True + False + + + True + True + 1 + + - True + False True 1 @@ -220,98 +229,30 @@ 1 - - - False - True - 2 - - - - - True - False - 2 - 2 - 6 - 6 - + True False - 6 + 2 + 2 + 6 + 6 - - _Manually - True - True - False - False - True - 0 - True - True - - - False - True - 0 - - - - - _Automatically from the Internet - True - True - False - False - True - 0 - True - manualTimeRadio - - - False - True - 1 - - - - - 1 - 2 - - - - - True - False - 0 - Set the time: - - - GTK_FILL - GTK_FILL - - - - - True - False - 12 - - + True False 6 - + + _Manually True - False - 0 - Tim_e: + True + False + False True - timeSpinner + 0 + True + True False @@ -320,11 +261,16 @@ - + + _Automatically from the Internet True True - - True + False + False + True + 0 + True + manualTimeRadio False @@ -334,24 +280,62 @@ - False - True - 0 + 1 + 2 - + True False - 6 + 0 + Set the time: + + + GTK_FILL + GTK_FILL + + + + + True + False + 12 - + True False - 0 - _Date: - True - dateSpinner + 6 + + + True + False + 0 + Tim_e: + True + timeSpinner + + + False + True + 0 + + + + + True + True + + 11 + 1 + True + + + False + True + 1 + + False @@ -360,11 +344,40 @@ - + True - True - - True + False + 6 + + + True + False + 0 + _Date: + True + dateSpinner + + + False + True + 0 + + + + + True + True + + 11 + 1 + True + + + False + True + 1 + + False @@ -374,29 +387,33 @@ - False - True - 1 + 1 + 2 + 1 + 2 + + + - 1 - 2 - 1 - 2 + False + True + 2 - - - - False + True True - 3 + end + 0 + + + @@ -443,6 +460,7 @@ True False + 6 True @@ -555,6 +573,7 @@ True False + 6 True @@ -796,9 +815,6 @@ 1 - - - diff --git a/src/datetime-prefs.c b/src/datetime-prefs.c index 1957b7f..87eec94 100644 --- a/src/datetime-prefs.c +++ b/src/datetime-prefs.c @@ -27,8 +27,10 @@ with this program. If not, see . #include #include +#include #include #include +#include #include "settings-shared.h" #include "utils.h" @@ -42,36 +44,36 @@ bind_hours_set (const GValue * value, const GVariantType * type, gpointer user_d const gchar * output = NULL; gboolean is_12hour_button = (gboolean)GPOINTER_TO_INT(user_data); - if (g_value_get_boolean(value)) { + if (g_value_get_boolean(value)) { /* Only do anything if we're setting active = true */ - output = is_12hour_button ? "12-hour" : "24-hour"; - } else { + output = is_12hour_button ? "12-hour" : "24-hour"; + } else { return NULL; } - return g_variant_new_string (output); + return g_variant_new_string (output); } /* Turns a string gsettings into a boolean property */ static gboolean bind_hours_get (GValue * value, GVariant * variant, gpointer user_data) { - const gchar * str = g_variant_get_string(variant, NULL); - gboolean output = FALSE; + const gchar * str = g_variant_get_string(variant, NULL); + gboolean output = FALSE; gboolean is_12hour_button = (gboolean)GPOINTER_TO_INT(user_data); - if (g_strcmp0(str, "locale-default") == 0) { - output = (is_12hour_button == is_locale_12h ()); - } else if (g_strcmp0(str, "12-hour") == 0) { - output = is_12hour_button; - } else if (g_strcmp0(str, "24-hour") == 0) { - output = !is_12hour_button; - } else { - return FALSE; - } + if (g_strcmp0(str, "locale-default") == 0) { + output = (is_12hour_button == is_locale_12h ()); + } else if (g_strcmp0(str, "12-hour") == 0) { + output = is_12hour_button; + } else if (g_strcmp0(str, "24-hour") == 0) { + output = !is_12hour_button; + } else { + return FALSE; + } - g_value_set_boolean (value, output); - return TRUE; + g_value_set_boolean (value, output); + return TRUE; } static void @@ -94,6 +96,163 @@ add_widget_dependency (GtkWidget * parent, GtkWidget * dependent) widget_dependency_cb (parent, NULL, dependent); } +static void +polkit_dependency_cb (GtkWidget * parent, GParamSpec *pspec, GtkWidget * dependent) +{ + gboolean authorized, sensitive; + g_object_get (G_OBJECT (parent), + "is-authorized", &authorized, + "sensitive", &sensitive, NULL); + gtk_widget_set_sensitive (dependent, authorized && sensitive); +} + +static void +add_polkit_dependency (GtkWidget * parent, GtkWidget * dependent) +{ + g_signal_connect (parent, "notify::is-authorized", G_CALLBACK(polkit_dependency_cb), + dependent); + g_signal_connect (parent, "notify::sensitive", G_CALLBACK(polkit_dependency_cb), + dependent); + polkit_dependency_cb (parent, NULL, dependent); +} + +void ntp_set_answered (GObject *object, GAsyncResult *res, gpointer autoRadio) +{ + GError * error = NULL; + GDBusProxy * proxy = G_DBUS_PROXY (object); + GVariant * answers = g_dbus_proxy_call_finish (proxy, res, &error); + + if (error != NULL) { + g_warning("Could not set 'using_ntp' for SettingsDaemon: %s", error->message); + g_error_free(error); + return; + } + + g_variant_unref (answers); +} + +static void +toggle_ntp (GtkWidget * autoRadio, GParamSpec * pspec, gpointer user_data) +{ + gboolean active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (autoRadio)); + GDBusProxy * proxy = G_DBUS_PROXY (g_object_get_data (G_OBJECT (autoRadio), "proxy")); + + g_dbus_proxy_call (proxy, "SetUsingNtp", g_variant_new ("(b)", active), + G_DBUS_CALL_FLAGS_NONE, -1, NULL, ntp_set_answered, autoRadio); +} + +void ntp_query_answered (GObject *object, GAsyncResult *res, gpointer autoRadio) +{ + GError * error = NULL; + GDBusProxy * proxy = G_DBUS_PROXY (object); + GVariant * answers = g_dbus_proxy_call_finish (proxy, res, &error); + + if (error != NULL) { + g_warning("Could not query DBus proxy for SettingsDaemon: %s", error->message); + g_error_free(error); + return; + } + + gboolean can_use_ntp, is_using_ntp; + g_variant_get (answers, "(bb)", &can_use_ntp, &is_using_ntp); + + gtk_widget_set_sensitive (GTK_WIDGET (autoRadio), can_use_ntp); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (autoRadio), is_using_ntp); + + g_signal_connect (autoRadio, "notify::active", G_CALLBACK(toggle_ntp), NULL); + + g_variant_unref (answers); +} + +void ntp_proxy_ready (GObject *object, GAsyncResult *res, gpointer autoRadio) +{ + GError * error = NULL; + GDBusProxy * proxy = g_dbus_proxy_new_for_bus_finish (res, &error); + + if (error != NULL) { + g_critical("Could not grab DBus proxy for SettingsDaemon: %s", error->message); + g_error_free(error); + return; + } + + /* Now attach proxy to button so we can use it later */ + g_object_set_data_full (G_OBJECT (autoRadio), "proxy", proxy, g_object_unref); + + /* And finally ask it what is up */ + g_dbus_proxy_call (proxy, "GetUsingNtp", NULL, G_DBUS_CALL_FLAGS_NONE, -1, + NULL, ntp_query_answered, autoRadio); +} + +static void +setup_ntp (GtkWidget * autoRadio) +{ + /* Do some quick checks to see if ntp is running or installed */ + + /* Start with assumption ntp is unusable until we prove otherwise */ + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (autoRadio), FALSE); + gtk_widget_set_sensitive (autoRadio, FALSE); + + g_dbus_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, NULL, + "org.gnome.SettingsDaemon.DateTimeMechanism", + "/", + "org.gnome.SettingsDaemon.DateTimeMechanism", + NULL, ntp_proxy_ready, autoRadio); +} + +/*static int +input_time_text (GtkWidget * spinner, gdouble *value, gpointer user_data) +{ + //const gchar * text = gtk_entry_get_text (GTK_ENTRY (spinner)); + + return TRUE; +}*/ + +static gboolean +format_time_text (GtkWidget * spinner, gpointer user_data) +{ + GDateTime * datetime = (GDateTime *)g_object_get_data (G_OBJECT (spinner), "datetime"); + + const gchar * format; + if (is_locale_12h ()) { + format = "%I:%M:%S %p"; + } else { + format = "%H:%M:%S"; + } + + gchar * formatted = g_date_time_format (datetime, format); + gtk_entry_set_text (GTK_ENTRY (spinner), formatted); + + return TRUE; +} + +static gboolean +update_spinner (GtkWidget * spinner) +{ + /* Add datetime object to spinner, which will hold the real time value, rather + then using the value of the spinner itself. */ + GDateTime * datetime = g_date_time_new_now_local (); + g_object_set_data_full (G_OBJECT (spinner), "datetime", datetime, (GDestroyNotify)g_date_time_unref); + + format_time_text (spinner, NULL); + + return TRUE; +} + +static void +setup_time_spinner (GtkWidget * spinner) +{ + /* Set up spinner to have reasonable behavior */ + gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spinner), FALSE); + //g_signal_connect (spinner, "input", G_CALLBACK (input_time_text), NULL); + g_signal_connect (spinner, "output", G_CALLBACK (format_time_text), NULL); + + /* 2 seconds is what the indicator itself uses */ + guint time_id = g_timeout_add_seconds (2, (GSourceFunc)update_spinner, spinner); + g_signal_connect_swapped (spinner, "destroy", G_CALLBACK (g_source_remove), GINT_TO_POINTER(time_id)); + + update_spinner (spinner); +} + static GtkWidget * create_dialog (void) { @@ -110,10 +269,16 @@ create_dialog (void) gtk_builder_set_translation_domain (builder, GETTEXT_PACKAGE); - GSettings * conf = g_settings_new (SETTINGS_INTERFACE); + GSettings * conf = g_settings_new (SETTINGS_INTERFACE); #define WIG(name) GTK_WIDGET (gtk_builder_get_object (builder, name)) + /* Add policykit button */ + GtkWidget * polkit_button = polkit_lock_button_new ("org.gnome.settingsdaemon.datetimemechanism.configure"); + polkit_lock_button_set_unlock_text (POLKIT_LOCK_BUTTON (polkit_button), _("Unlock to change these settings")); + polkit_lock_button_set_lock_text (POLKIT_LOCK_BUTTON (polkit_button), _("Lock to prevent further changes")); + gtk_box_pack_start (GTK_BOX (WIG ("timeDateBox")), polkit_button, FALSE, TRUE, 0); + /* Set up settings bindings */ g_settings_bind (conf, SETTINGS_SHOW_CLOCK_S, WIG ("showClockCheck"), @@ -150,12 +315,18 @@ create_dialog (void) add_widget_dependency (WIG ("showClockCheck"), WIG ("clockOptions")); add_widget_dependency (WIG ("showLocationsCheck"), WIG ("locationsButton")); add_widget_dependency (WIG ("manualTimeRadio"), WIG ("manualOptions")); + add_polkit_dependency (polkit_button, WIG ("timeDateOptions")); /* Hacky proxy test for whether evolution-data-server is installed */ gchar * evo_path = g_find_program_in_path ("evolution"); gtk_widget_set_sensitive (WIG ("showEventsCheck"), (evo_path != NULL)); g_free (evo_path); + /* Check if ntp is usable and enabled */ + setup_ntp (WIG ("automaticTimeRadio")); + + setup_time_spinner (WIG ("timeSpinner")); + GtkWidget * dlg = WIG ("timeDateDialog"); #undef WIG @@ -180,17 +351,17 @@ message_received (UniqueApp * app, gint command, UniqueMessageData *message_data int main (int argc, char ** argv) { - g_type_init (); + g_type_init (); - /* Setting up i18n and gettext. Apparently, we need - all of these. */ - setlocale (LC_ALL, ""); - bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR); - textdomain (GETTEXT_PACKAGE); + /* Setting up i18n and gettext. Apparently, we need + all of these. */ + setlocale (LC_ALL, ""); + bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR); + textdomain (GETTEXT_PACKAGE); - gtk_init (&argc, &argv); + gtk_init (&argc, &argv); - UniqueApp * app = unique_app_new ("com.canonical.indicator.datetime.preferences", NULL); + UniqueApp * app = unique_app_new ("com.canonical.indicator.datetime.preferences", NULL); if (unique_app_is_running (app)) { unique_app_send_message (app, UNIQUE_ACTIVATE, NULL); -- cgit v1.2.3 From da3962a55e4e7fab374d1cbbd2401000ed67fe07 Mon Sep 17 00:00:00 2001 From: Michael Terry Date: Fri, 18 Feb 2011 01:51:56 -0500 Subject: make manual date/time fields work --- data/datetime-dialog.ui | 546 ++++++++++++++++++++++++------------------------ src/datetime-prefs.c | 158 ++++++++++---- 2 files changed, 394 insertions(+), 310 deletions(-) diff --git a/data/datetime-dialog.ui b/data/datetime-dialog.ui index f2a5938..1e0f726 100644 --- a/data/datetime-dialog.ui +++ b/data/datetime-dialog.ui @@ -88,6 +88,7 @@ False 5 Time & Date + False time-admin dialog @@ -264,6 +265,7 @@ _Automatically from the Internet True + False True False False @@ -429,139 +431,27 @@ - + True False - 12 - 12 - - - _Show a clock in the panel - True - True - False - False - True - 0 - True - - - True - True - 0 - - + 0 + 0 - + True False - True + 12 + 12 - + + _Show a clock in the panel True - False - 6 - - - True - False - 0 - In the clock, show: - - - False - True - 0 - - - - - _Weekday - True - True - False - False - True - 0 - True - - - False - True - 1 - - - - - _Date and time - True - True - False - False - True - 0 - True - - - False - True - 2 - - - - - _12-hour time - True - True - False - False - True - 0 - True - True - - - False - True - 3 - - - - - _24-hour time - True - True - False - False - True - 0 - True - True - show12HourRadio - - - False - True - 4 - - - - - Seco_nds - True - True - False - False - True - 0 - True - - - False - True - 5 - - + True + False + False + True + 0 + True True @@ -570,16 +460,115 @@ - + True False - 6 + True - + True False - 0 - In the clock’s menu, show: + 6 + + + True + False + 0 + In the clock, show: + + + False + True + 0 + + + + + _Weekday + True + True + False + False + True + 0 + True + + + False + True + 1 + + + + + _Date and time + True + True + False + False + True + 0 + True + + + False + True + 2 + + + + + _12-hour time + True + True + False + False + True + 0 + True + True + + + False + True + 3 + + + + + _24-hour time + True + True + False + False + True + 0 + True + show12HourRadio + + + False + True + 4 + + + + + Seco_nds + True + True + False + False + True + 0 + True + + + False + True + 5 + + True @@ -588,80 +577,62 @@ - - _Monthly calendar - True - True - False - False - True - 0 - True - - - False - True - 1 - - - - + True False - 0 - 0 - 0 - 0 - 12 + 6 - + True False + 0 + In the clock’s menu, show: + + + True + True + 0 + + + + + _Monthly calendar + True + True + False + False + True + 0 + True + + + False + True + 1 + + + + + True + False + 0 + 0 + 0 + 0 + 12 - - Include week num_bers + True - True - False - False - True - 0 - True - - - True - True - 0 - - - - - False - True - 0 - Week begins on: - - - True - True - 1 - - - - False - True - True - - S_unday + + Include week num_bers True True False False True 0 - True True @@ -671,17 +642,11 @@ - - Monda_y - True - True - False - False - True + + False + True 0 - True - True - startOnSundayRadio + Week begins on: True @@ -689,91 +654,139 @@ 1 + + + False + True + True + + + S_unday + True + True + False + False + True + 0 + True + True + + + True + True + 0 + + + + + Monda_y + True + True + False + False + True + 0 + True + startOnSundayRadio + + + True + True + 1 + + + + + True + True + 2 + + - - True - True - 2 - + + False + True + 2 + - - - False - True - 2 - - - - - True - True - False - False - True - 0 - True - + True - False - 0 - Coming _events from Evolution Calendar + True + False + False True - True - showEventsCheck + 0 + True + + + True + False + 0 + Coming _events from Evolution Calendar + True + True + showEventsCheck + + + + False + True + 3 + - - - False - True - 3 - - - - - Time in _other locations - True - True - False - False - True - 0 - True - - - False - True - 4 - - - - - True - False - 0 - 0 - 0 - 0 - 12 - - Choose _Locations… + + Time in _other locations True True - True + False False True 0 + True + + + False + True + 4 + + + + + True + False + 0 + 0 + 0 + 0 + 12 + + + Choose _Locations… + True + True + True + False + True + 0 + + + + True + True + 5 + True True - 5 + 1 @@ -784,11 +797,6 @@ - - True - True - 1 - diff --git a/src/datetime-prefs.c b/src/datetime-prefs.c index 87eec94..a42c46b 100644 --- a/src/datetime-prefs.c +++ b/src/datetime-prefs.c @@ -27,6 +27,7 @@ with this program. If not, see . #include #include +#include #include #include #include @@ -37,6 +38,8 @@ with this program. If not, see . #define DATETIME_DIALOG_UI_FILE PKGDATADIR "/datetime-dialog.ui" +GDBusProxy * proxy = NULL; + /* Turns the boolean property into a string gsettings */ static GVariant * bind_hours_set (const GValue * value, const GVariantType * type, gpointer user_data) @@ -116,14 +119,13 @@ add_polkit_dependency (GtkWidget * parent, GtkWidget * dependent) polkit_dependency_cb (parent, NULL, dependent); } -void ntp_set_answered (GObject *object, GAsyncResult *res, gpointer autoRadio) +void dbus_set_answered (GObject *object, GAsyncResult *res, gpointer command) { GError * error = NULL; - GDBusProxy * proxy = G_DBUS_PROXY (object); GVariant * answers = g_dbus_proxy_call_finish (proxy, res, &error); if (error != NULL) { - g_warning("Could not set 'using_ntp' for SettingsDaemon: %s", error->message); + g_warning("Could not set '%s' for SettingsDaemon: %s", (gchar *)command, error->message); g_error_free(error); return; } @@ -135,16 +137,14 @@ static void toggle_ntp (GtkWidget * autoRadio, GParamSpec * pspec, gpointer user_data) { gboolean active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (autoRadio)); - GDBusProxy * proxy = G_DBUS_PROXY (g_object_get_data (G_OBJECT (autoRadio), "proxy")); g_dbus_proxy_call (proxy, "SetUsingNtp", g_variant_new ("(b)", active), - G_DBUS_CALL_FLAGS_NONE, -1, NULL, ntp_set_answered, autoRadio); + G_DBUS_CALL_FLAGS_NONE, -1, NULL, dbus_set_answered, "using_ntp"); } void ntp_query_answered (GObject *object, GAsyncResult *res, gpointer autoRadio) { GError * error = NULL; - GDBusProxy * proxy = G_DBUS_PROXY (object); GVariant * answers = g_dbus_proxy_call_finish (proxy, res, &error); if (error != NULL) { @@ -164,10 +164,11 @@ void ntp_query_answered (GObject *object, GAsyncResult *res, gpointer autoRadio) g_variant_unref (answers); } -void ntp_proxy_ready (GObject *object, GAsyncResult *res, gpointer autoRadio) +void proxy_ready (GObject *object, GAsyncResult *res, gpointer autoRadio) { GError * error = NULL; - GDBusProxy * proxy = g_dbus_proxy_new_for_bus_finish (res, &error); + + proxy = g_dbus_proxy_new_for_bus_finish (res, &error); if (error != NULL) { g_critical("Could not grab DBus proxy for SettingsDaemon: %s", error->message); @@ -175,48 +176,117 @@ void ntp_proxy_ready (GObject *object, GAsyncResult *res, gpointer autoRadio) return; } - /* Now attach proxy to button so we can use it later */ - g_object_set_data_full (G_OBJECT (autoRadio), "proxy", proxy, g_object_unref); - - /* And finally ask it what is up */ + /* And now, do initial proxy configuration */ g_dbus_proxy_call (proxy, "GetUsingNtp", NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, ntp_query_answered, autoRadio); } -static void -setup_ntp (GtkWidget * autoRadio) +static int +input_time_text (GtkWidget * spinner, gdouble *value, gpointer user_data) { - /* Do some quick checks to see if ntp is running or installed */ + gboolean is_time = (gboolean)GPOINTER_TO_INT (g_object_get_data (G_OBJECT (spinner), "is-time")); + const gchar * text = gtk_entry_get_text (GTK_ENTRY (spinner)); + + GDateTime * now = g_date_time_new_now_local (); + gint year, month, day, hour, minute, second; + year = g_date_time_get_year (now); + month = g_date_time_get_month (now); + day = g_date_time_get_day_of_month (now); + hour = g_date_time_get_hour (now); + minute = g_date_time_get_minute (now); + second = g_date_time_get_second (now); + g_date_time_unref (now); + + /* Parse this string as if it were in the output format */ + gint scanned = 0; + gboolean passed = TRUE, skip = FALSE; + if (is_time) { + gint hour_in, minute_in, second_in; + + if (is_locale_12h ()) { // TODO: make this look-at/watch gsettings? + char ampm[51]; + + scanned = sscanf (text, "%u:%u:%u %50s", &hour_in, &minute_in, &second_in, ampm); + passed = (scanned == 4); + + if (passed) { + const char *pm_str = nl_langinfo (PM_STR); + if (g_ascii_strcasecmp (pm_str, ampm) == 0) { + hour_in += 12; + } + } + } else { + scanned = sscanf (text, "%u:%u:%u", &hour_in, &minute_in, &second_in); + passed = (scanned == 3); + } + + if (passed && (hour_in > 23 || minute_in > 59 || second_in > 59)) { + passed = FALSE; + } + if (passed && hour == hour_in && minute == minute_in && second == second_in) { + skip = TRUE; // no change + } else { + hour = hour_in; + minute = minute_in; + second = second_in; + } + } + else { + gint year_in, month_in, day_in; + + scanned = sscanf (text, "%u-%u-%u", &year_in, &month_in, &day_in); + + if (scanned != 3 || year_in < 1 || year_in > 9999 || + month_in < 1 || month_in > 12 || day_in < 1 || day_in > 31) { + passed = FALSE; + } + if (passed && year == year_in && month == month_in && day == day_in) { + skip = TRUE; // no change + } else { + year = year_in; + month = month_in; + day = day_in; + } + } - /* Start with assumption ntp is unusable until we prove otherwise */ - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (autoRadio), FALSE); - gtk_widget_set_sensitive (autoRadio, FALSE); + if (!passed) { + g_warning ("Could not understand %s", text); + return TRUE; + } - g_dbus_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, NULL, - "org.gnome.SettingsDaemon.DateTimeMechanism", - "/", - "org.gnome.SettingsDaemon.DateTimeMechanism", - NULL, ntp_proxy_ready, autoRadio); -} + if (skip) { + return TRUE; + } -/*static int -input_time_text (GtkWidget * spinner, gdouble *value, gpointer user_data) -{ - //const gchar * text = gtk_entry_get_text (GTK_ENTRY (spinner)); + GDateTime * datetime = g_date_time_new_local (year, month, day, hour, minute, second); + + g_dbus_proxy_call (proxy, "SetTime", g_variant_new ("(x)", g_date_time_to_unix (datetime)), + G_DBUS_CALL_FLAGS_NONE, -1, NULL, dbus_set_answered, "time"); return TRUE; -}*/ +} static gboolean format_time_text (GtkWidget * spinner, gpointer user_data) { + if (gtk_widget_has_focus (spinner)) { + /* Don't do anything if we have focus, user is likely editing us */ + return TRUE; + } + GDateTime * datetime = (GDateTime *)g_object_get_data (G_OBJECT (spinner), "datetime"); + gboolean is_time = (gboolean)GPOINTER_TO_INT (g_object_get_data (G_OBJECT (spinner), "is-time")); const gchar * format; - if (is_locale_12h ()) { - format = "%I:%M:%S %p"; - } else { - format = "%H:%M:%S"; + if (is_time) { + if (is_locale_12h ()) { // TODO: make this look-at/watch gsettings? + format = "%I:%M:%S %p"; + } else { + format = "%H:%M:%S"; + } + } + else { + format = "%Y-%m-%d"; } gchar * formatted = g_date_time_format (datetime, format); @@ -239,16 +309,17 @@ update_spinner (GtkWidget * spinner) } static void -setup_time_spinner (GtkWidget * spinner) +setup_time_spinner (GtkWidget * spinner, GtkWidget * other, gboolean is_time) { /* Set up spinner to have reasonable behavior */ gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spinner), FALSE); - //g_signal_connect (spinner, "input", G_CALLBACK (input_time_text), NULL); - g_signal_connect (spinner, "output", G_CALLBACK (format_time_text), NULL); + g_signal_connect (spinner, "input", G_CALLBACK (input_time_text), other); + g_signal_connect (spinner, "output", G_CALLBACK (format_time_text), other); + g_object_set_data (G_OBJECT (spinner), "is-time", GINT_TO_POINTER (is_time)); /* 2 seconds is what the indicator itself uses */ guint time_id = g_timeout_add_seconds (2, (GSourceFunc)update_spinner, spinner); - g_signal_connect_swapped (spinner, "destroy", G_CALLBACK (g_source_remove), GINT_TO_POINTER(time_id)); + g_signal_connect_swapped (spinner, "destroy", G_CALLBACK (g_source_remove), GINT_TO_POINTER (time_id)); update_spinner (spinner); } @@ -322,13 +393,18 @@ create_dialog (void) gtk_widget_set_sensitive (WIG ("showEventsCheck"), (evo_path != NULL)); g_free (evo_path); - /* Check if ntp is usable and enabled */ - setup_ntp (WIG ("automaticTimeRadio")); - - setup_time_spinner (WIG ("timeSpinner")); + setup_time_spinner (WIG ("timeSpinner"), WIG ("dateSpinner"), TRUE); + setup_time_spinner (WIG ("dateSpinner"), WIG ("timeSpinner"), FALSE); GtkWidget * dlg = WIG ("timeDateDialog"); + /* Grab proxy for settings daemon */ + g_dbus_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, NULL, + "org.gnome.SettingsDaemon.DateTimeMechanism", + "/", + "org.gnome.SettingsDaemon.DateTimeMechanism", + NULL, proxy_ready, WIG ("automaticTimeRadio")); + #undef WIG g_object_unref (conf); -- cgit v1.2.3 From 6dda4370c9cc94bb25c1cd388adce14f1c0e9f19 Mon Sep 17 00:00:00 2001 From: Michael Terry Date: Fri, 18 Feb 2011 14:47:14 -0500 Subject: mark prefs dialog as translatable --- po/POTFILES.in | 2 ++ 1 file changed, 2 insertions(+) diff --git a/po/POTFILES.in b/po/POTFILES.in index 41324a7..2eb7ec1 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -1,2 +1,4 @@ src/indicator-datetime.c src/datetime-service.c +src/datetime-prefs.c +[type: gettext/glade]data/datetime-dialog.ui -- cgit v1.2.3 From 1e274bb18d9936c39d4c22e00ec895dc79178390 Mon Sep 17 00:00:00 2001 From: Michael Terry Date: Fri, 18 Feb 2011 16:31:17 -0500 Subject: start of locations dialog --- data/datetime-dialog.ui | 22 +++++-- po/POTFILES.in | 1 + src/Makefile.am | 2 + src/datetime-prefs-locations.c | 137 +++++++++++++++++++++++++++++++++++++++++ src/datetime-prefs-locations.h | 34 ++++++++++ src/datetime-prefs.c | 11 +++- 6 files changed, 202 insertions(+), 5 deletions(-) create mode 100644 src/datetime-prefs-locations.c create mode 100644 src/datetime-prefs-locations.h diff --git a/data/datetime-dialog.ui b/data/datetime-dialog.ui index 1e0f726..a849107 100644 --- a/data/datetime-dialog.ui +++ b/data/datetime-dialog.ui @@ -5,16 +5,28 @@ False Locations + True + True time-admin True False - + True True - locationsStore + automatic + automatic + + + True + True + locationsStore + True + 0 + + True @@ -27,10 +39,11 @@ True False - + True True True + Add a Location… False @@ -47,10 +60,11 @@ - + True True True + Remove This Location False diff --git a/po/POTFILES.in b/po/POTFILES.in index 2eb7ec1..0fa22d4 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -1,4 +1,5 @@ src/indicator-datetime.c src/datetime-service.c src/datetime-prefs.c +src/datetime-prefs-locations.c [type: gettext/glade]data/datetime-dialog.ui diff --git a/src/Makefile.am b/src/Makefile.am index 150c87d..94d179d 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -41,6 +41,8 @@ libdatetime_la_LDFLAGS = \ indicator_datetime_preferences_SOURCES =\ datetime-prefs.c \ + datetime-prefs-locations.c \ + datetime-prefs-locations.h \ utils.c \ utils.h \ settings-shared.h diff --git a/src/datetime-prefs-locations.c b/src/datetime-prefs-locations.c new file mode 100644 index 0000000..24efd04 --- /dev/null +++ b/src/datetime-prefs-locations.c @@ -0,0 +1,137 @@ +/* -*- Mode: C; coding: utf-8; indent-tabs-mode: nil; tab-width: 2 -*- + +A dialog for setting time and date preferences. + +Copyright 2011 Canonical Ltd. + +Authors: + Michael Terry + +This program is free software: you can redistribute it and/or modify it +under the terms of the GNU General Public License version 3, as published +by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranties of +MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program. If not, see . +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include + +#include "datetime-prefs-locations.h" +#include "settings-shared.h" + +#define DATETIME_DIALOG_UI_FILE PKGDATADIR "/datetime-dialog.ui" + +static void +handle_add (GtkWidget * button, gpointer user_data) +{ +} + +static void +handle_remove (GtkWidget * button, gpointer user_data) +{ +} + +static void +fill_from_settings (GObject * store, GSettings * conf) +{ + gchar ** locations = g_settings_get_strv (conf, SETTINGS_LOCATIONS_S); + + gtk_list_store_clear (GTK_LIST_STORE (store)); + + gchar ** striter; + GtkTreeIter iter; + for (striter = locations; *striter; ++striter) { + gtk_list_store_append (GTK_LIST_STORE (store), &iter); + gtk_list_store_set (GTK_LIST_STORE (store), &iter, 0, *striter, -1); + } + + g_strfreev (locations); +} + +static void +save_to_settings (GtkWidget * dlg, GObject * store) +{ + GVariantBuilder builder; + g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY); + + GtkTreeIter iter; + if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter)) { + do { + GValue value = {0}; + gtk_tree_model_get_value (GTK_TREE_MODEL (store), &iter, 0, &value); + g_variant_builder_add (&builder, "s", g_value_get_string (&value)); + g_value_unset (&value); + } while (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter)); + } + + GVariant * locations = g_variant_builder_end (&builder); + + GSettings * conf = G_SETTINGS (g_object_get_data (G_OBJECT (dlg), "conf")); + g_settings_set_strv (conf, SETTINGS_LOCATIONS_S, g_variant_get_strv (locations, NULL)); + + g_variant_unref (locations); +} + +GtkWidget * +datetime_setup_locations_dialog (GtkWindow * parent) +{ + GError * error = NULL; + GtkBuilder * builder = gtk_builder_new (); + gtk_builder_add_from_file (builder, DATETIME_DIALOG_UI_FILE, &error); + if (error != NULL) { + /* We have to abort, we can't continue without the ui file */ + g_error ("Could not load ui file %s: %s", DATETIME_DIALOG_UI_FILE, error->message); + g_error_free (error); + return NULL; + } + + gtk_builder_set_translation_domain (builder, GETTEXT_PACKAGE); + + GSettings * conf = g_settings_new (SETTINGS_INTERFACE); + +#define WIG(name) GTK_WIDGET (gtk_builder_get_object (builder, name)) + + GtkWidget * dlg = WIG ("locationsDialog"); + GtkWidget * tree = WIG ("locationsView"); + GObject * store = gtk_builder_get_object (builder, "locationsStore"); + + /* Configure tree */ + GtkCellRenderer * cell = gtk_cell_renderer_text_new (); + g_object_set (cell, "editable", TRUE, NULL); + gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (tree), -1, + _("Location"), cell, + "text", 0, NULL); + cell = gtk_cell_renderer_text_new (); + gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (tree), -1, + _("Time"), cell, + "text", 1, NULL); + gtk_tree_selection_set_mode (gtk_tree_view_get_selection (GTK_TREE_VIEW (tree)), GTK_SELECTION_MULTIPLE); + + g_signal_connect (WIG ("addButton"), "clicked", G_CALLBACK (handle_add), NULL); + g_signal_connect (WIG ("removeButton"), "clicked", G_CALLBACK (handle_remove), NULL); + + fill_from_settings (store, conf); + g_object_set_data_full (G_OBJECT (dlg), "conf", g_object_ref (conf), g_object_unref); + g_signal_connect (dlg, "destroy", G_CALLBACK (save_to_settings), store); + + gtk_window_set_transient_for (GTK_WINDOW (dlg), parent); + +#undef WIG + + g_object_unref (conf); + g_object_unref (builder); + + return dlg; +} + diff --git a/src/datetime-prefs-locations.h b/src/datetime-prefs-locations.h new file mode 100644 index 0000000..d5dd534 --- /dev/null +++ b/src/datetime-prefs-locations.h @@ -0,0 +1,34 @@ +/* -*- Mode: C; coding: utf-8; indent-tabs-mode: nil; tab-width: 2 -*- + +A dialog for setting time and date preferences. + +Copyright 2011 Canonical Ltd. + +Authors: + Michael Terry + +This program is free software: you can redistribute it and/or modify it +under the terms of the GNU General Public License version 3, as published +by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranties of +MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program. If not, see . +*/ + +#ifndef __DATETIME_PREFS_LOCATIONS_H__ +#define __DATETIME_PREFS_LOCATIONS_H__ + +#include + +G_BEGIN_DECLS + +GtkWidget * datetime_setup_locations_dialog (GtkWindow * parent); + +G_END_DECLS + +#endif diff --git a/src/datetime-prefs.c b/src/datetime-prefs.c index a42c46b..97b106d 100644 --- a/src/datetime-prefs.c +++ b/src/datetime-prefs.c @@ -35,6 +35,7 @@ with this program. If not, see . #include "settings-shared.h" #include "utils.h" +#include "datetime-prefs-locations.h" #define DATETIME_DIALOG_UI_FILE PKGDATADIR "/datetime-dialog.ui" @@ -324,6 +325,13 @@ setup_time_spinner (GtkWidget * spinner, GtkWidget * other, gboolean is_time) update_spinner (spinner); } +static void +show_locations (GtkWidget * button, GtkWidget * dlg) +{ + GtkWidget * locationsDlg = datetime_setup_locations_dialog (GTK_WINDOW (dlg)); + gtk_widget_show_all (locationsDlg); +} + static GtkWidget * create_dialog (void) { @@ -351,7 +359,6 @@ create_dialog (void) gtk_box_pack_start (GTK_BOX (WIG ("timeDateBox")), polkit_button, FALSE, TRUE, 0); /* Set up settings bindings */ - g_settings_bind (conf, SETTINGS_SHOW_CLOCK_S, WIG ("showClockCheck"), "active", G_SETTINGS_BIND_DEFAULT); g_settings_bind (conf, SETTINGS_SHOW_DAY_S, WIG ("showWeekdayCheck"), @@ -398,6 +405,8 @@ create_dialog (void) GtkWidget * dlg = WIG ("timeDateDialog"); + g_signal_connect (WIG ("locationsButton"), "clicked", G_CALLBACK (show_locations), dlg); + /* Grab proxy for settings daemon */ g_dbus_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, NULL, "org.gnome.SettingsDaemon.DateTimeMechanism", -- cgit v1.2.3 From 45b1165f77cab0ac8dc40ce7d605e32c697fb22d Mon Sep 17 00:00:00 2001 From: Michael Terry Date: Tue, 22 Feb 2011 11:20:34 -0500 Subject: add initial timezone map implementation, borrowed from gnome-control-center --- Makefile.am | 1 + configure.ac | 16 + data/datetime-dialog.ui | 15 +- libmap/Makefile.am | 76 +++++ libmap/Makefile.in | 732 +++++++++++++++++++++++++++++++++++++++++ libmap/README | 5 + libmap/backward | 118 +++++++ libmap/cc-timezone-map.c | 711 +++++++++++++++++++++++++++++++++++++++ libmap/cc-timezone-map.h | 79 +++++ libmap/data/bg.png | Bin 0 -> 213448 bytes libmap/data/cc.png | Bin 0 -> 53948 bytes libmap/data/pin.png | Bin 0 -> 561 bytes libmap/data/timezone_-1.png | Bin 0 -> 8012 bytes libmap/data/timezone_-10.png | Bin 0 -> 7783 bytes libmap/data/timezone_-11.png | Bin 0 -> 7406 bytes libmap/data/timezone_-2.png | Bin 0 -> 4333 bytes libmap/data/timezone_-3.5.png | Bin 0 -> 740 bytes libmap/data/timezone_-3.png | Bin 0 -> 13615 bytes libmap/data/timezone_-4.5.png | Bin 0 -> 1900 bytes libmap/data/timezone_-4.png | Bin 0 -> 15084 bytes libmap/data/timezone_-5.5.png | Bin 0 -> 437 bytes libmap/data/timezone_-5.png | Bin 0 -> 19166 bytes libmap/data/timezone_-6.png | Bin 0 -> 13764 bytes libmap/data/timezone_-7.png | Bin 0 -> 11977 bytes libmap/data/timezone_-8.png | Bin 0 -> 6801 bytes libmap/data/timezone_-9.5.png | Bin 0 -> 437 bytes libmap/data/timezone_-9.png | Bin 0 -> 7908 bytes libmap/data/timezone_0.png | Bin 0 -> 11074 bytes libmap/data/timezone_1.png | Bin 0 -> 15458 bytes libmap/data/timezone_10.5.png | Bin 0 -> 421 bytes libmap/data/timezone_10.png | Bin 0 -> 12829 bytes libmap/data/timezone_11.5.png | Bin 0 -> 446 bytes libmap/data/timezone_11.png | Bin 0 -> 12113 bytes libmap/data/timezone_12.75.png | Bin 0 -> 409 bytes libmap/data/timezone_12.png | Bin 0 -> 7130 bytes libmap/data/timezone_13.png | Bin 0 -> 621 bytes libmap/data/timezone_2.png | Bin 0 -> 12854 bytes libmap/data/timezone_3.5.png | Bin 0 -> 2142 bytes libmap/data/timezone_3.png | Bin 0 -> 17475 bytes libmap/data/timezone_4.5.png | Bin 0 -> 1773 bytes libmap/data/timezone_4.png | Bin 0 -> 4954 bytes libmap/data/timezone_5.5.png | Bin 0 -> 6099 bytes libmap/data/timezone_5.75.png | Bin 0 -> 2885 bytes libmap/data/timezone_5.png | Bin 0 -> 14539 bytes libmap/data/timezone_6.5.png | Bin 0 -> 1609 bytes libmap/data/timezone_6.png | Bin 0 -> 8441 bytes libmap/data/timezone_7.png | Bin 0 -> 14412 bytes libmap/data/timezone_8.png | Bin 0 -> 16725 bytes libmap/data/timezone_9.5.png | Bin 0 -> 1959 bytes libmap/data/timezone_9.png | Bin 0 -> 12608 bytes libmap/datetime-module.c | 46 +++ libmap/dt-lockbutton.c | 627 +++++++++++++++++++++++++++++++++++ libmap/dt-lockbutton.h | 68 ++++ libmap/set-timezone.c | 481 +++++++++++++++++++++++++++ libmap/set-timezone.h | 57 ++++ libmap/test-timezone.c | 55 ++++ libmap/tz.c | 350 ++++++++++++++++++++ libmap/tz.h | 86 +++++ src/Makefile.am | 2 + src/datetime-prefs.c | 58 +++- 60 files changed, 3575 insertions(+), 8 deletions(-) create mode 100644 libmap/Makefile.am create mode 100644 libmap/Makefile.in create mode 100644 libmap/README create mode 100644 libmap/backward create mode 100644 libmap/cc-timezone-map.c create mode 100644 libmap/cc-timezone-map.h create mode 100644 libmap/data/bg.png create mode 100644 libmap/data/cc.png create mode 100644 libmap/data/pin.png create mode 100644 libmap/data/timezone_-1.png create mode 100644 libmap/data/timezone_-10.png create mode 100644 libmap/data/timezone_-11.png create mode 100644 libmap/data/timezone_-2.png create mode 100644 libmap/data/timezone_-3.5.png create mode 100644 libmap/data/timezone_-3.png create mode 100644 libmap/data/timezone_-4.5.png create mode 100644 libmap/data/timezone_-4.png create mode 100644 libmap/data/timezone_-5.5.png create mode 100644 libmap/data/timezone_-5.png create mode 100644 libmap/data/timezone_-6.png create mode 100644 libmap/data/timezone_-7.png create mode 100644 libmap/data/timezone_-8.png create mode 100644 libmap/data/timezone_-9.5.png create mode 100644 libmap/data/timezone_-9.png create mode 100644 libmap/data/timezone_0.png create mode 100644 libmap/data/timezone_1.png create mode 100644 libmap/data/timezone_10.5.png create mode 100644 libmap/data/timezone_10.png create mode 100644 libmap/data/timezone_11.5.png create mode 100644 libmap/data/timezone_11.png create mode 100644 libmap/data/timezone_12.75.png create mode 100644 libmap/data/timezone_12.png create mode 100644 libmap/data/timezone_13.png create mode 100644 libmap/data/timezone_2.png create mode 100644 libmap/data/timezone_3.5.png create mode 100644 libmap/data/timezone_3.png create mode 100644 libmap/data/timezone_4.5.png create mode 100644 libmap/data/timezone_4.png create mode 100644 libmap/data/timezone_5.5.png create mode 100644 libmap/data/timezone_5.75.png create mode 100644 libmap/data/timezone_5.png create mode 100644 libmap/data/timezone_6.5.png create mode 100644 libmap/data/timezone_6.png create mode 100644 libmap/data/timezone_7.png create mode 100644 libmap/data/timezone_8.png create mode 100644 libmap/data/timezone_9.5.png create mode 100644 libmap/data/timezone_9.png create mode 100644 libmap/datetime-module.c create mode 100644 libmap/dt-lockbutton.c create mode 100644 libmap/dt-lockbutton.h create mode 100644 libmap/set-timezone.c create mode 100644 libmap/set-timezone.h create mode 100644 libmap/test-timezone.c create mode 100644 libmap/tz.c create mode 100644 libmap/tz.h diff --git a/Makefile.am b/Makefile.am index a692889..4de650a 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,5 +1,6 @@ SUBDIRS = \ + libmap \ src \ data \ tests \ diff --git a/configure.ac b/configure.ac index 242033e..bcedddc 100644 --- a/configure.ac +++ b/configure.ac @@ -135,6 +135,17 @@ AS_IF([test "x$with_gtk" = x3], ], [AC_MSG_FAILURE([Value for --with-gtk was neither 2 nor 3])] ) + +AS_IF([test "x$with_gtk" = x3], + [PKG_CHECK_MODULES(LIBMAP, gio-2.0 >= $GIO_REQUIRED_VERSION + gtk+-3.0 >= $GTK3_REQUIRED_VERSION) + ], + [test "x$with_gtk" = x2], + [PKG_CHECK_MODULES(LIBMAP, gio-2.0 >= $GIO_REQUIRED_VERSION + gtk+-2.0 >= $GTK_REQUIRED_VERSION) + ], + [AC_MSG_FAILURE([Value for --with-gtk was neither 2 nor 3])] +) AC_SUBST(INDICATOR_CFLAGS) AC_SUBST(INDICATOR_LIBS) @@ -144,6 +155,10 @@ AC_SUBST(SERVICE_LIBS) AC_SUBST(PREF_CFLAGS) AC_SUBST(PREF_LIBS) +AC_SUBST(LIBMAP_CFLAGS) +AC_SUBST(LIBMAP_LIBS) +AC_SUBST(LIBMAP_LDFLAGS) + ########################### # Grab the GSettings Macros ########################### @@ -223,6 +238,7 @@ AM_GLIB_GNU_GETTEXT AC_OUTPUT([ Makefile +libmap/Makefile src/Makefile data/Makefile tests/Makefile diff --git a/data/datetime-dialog.ui b/data/datetime-dialog.ui index a849107..b5eba54 100644 --- a/data/datetime-dialog.ui +++ b/data/datetime-dialog.ui @@ -153,7 +153,20 @@ False 6 - + + True + False + 0 + none + + + + + + True + True + 0 + diff --git a/libmap/Makefile.am b/libmap/Makefile.am new file mode 100644 index 0000000..0cdeb34 --- /dev/null +++ b/libmap/Makefile.am @@ -0,0 +1,76 @@ +uidir = $(pkgdatadir)/libmap/ui +dist_ui_DATA = \ + data/bg.png \ + data/cc.png \ + data/pin.png \ + data/timezone_0.png \ + data/timezone_-10.png \ + data/timezone_10.png \ + data/timezone_10.5.png \ + data/timezone_-1.png \ + data/timezone_1.png \ + data/timezone_-11.png \ + data/timezone_11.png \ + data/timezone_11.5.png \ + data/timezone_12.png \ + data/timezone_12.75.png \ + data/timezone_13.png \ + data/timezone_-2.png \ + data/timezone_2.png \ + data/timezone_-3.png \ + data/timezone_3.png \ + data/timezone_-3.5.png \ + data/timezone_3.5.png \ + data/timezone_-4.png \ + data/timezone_4.png \ + data/timezone_-4.5.png \ + data/timezone_4.5.png \ + data/timezone_-5.png \ + data/timezone_5.png \ + data/timezone_-5.5.png \ + data/timezone_5.5.png \ + data/timezone_5.75.png \ + data/timezone_-6.png \ + data/timezone_6.png \ + data/timezone_6.5.png \ + data/timezone_-7.png \ + data/timezone_7.png \ + data/timezone_-8.png \ + data/timezone_8.png \ + data/timezone_-9.png \ + data/timezone_9.png \ + data/timezone_-9.5.png \ + data/timezone_9.5.png + +tzdatadir = $(pkgdatadir)/libmap/datetime +dist_tzdata_DATA = backward + +AM_CPPFLAGS = \ + $(LIBMAP_CFLAGS) \ + -DGNOMELOCALEDIR="\"$(datadir)/locale\"" \ + -DGNOMECC_DATA_DIR="\"$(pkgdatadir)/libmap\"" \ + -DDATADIR="\"$(uidir)\"" \ + $(NULL) + +noinst_PROGRAMS = test-timezone + +test_timezone_SOURCES = test-timezone.c tz.c tz.h +test_timezone_LDADD = $(LIBMAP_LIBS) +test_timezone_CFLAGS = $(LIBMAP_CFLAGS) + +all-local: check-local + +# FIXME remove "|| :" when we have all the necessary pixmaps +check-local: test-timezone + $(builddir)/test-timezone $(srcdir)/data || : + +noinst_LTLIBRARIES = libmap.la + +libmap_la_SOURCES = \ + cc-timezone-map.c \ + cc-timezone-map.h \ + tz.c tz.h + +libmap_la_LIBADD = $(LIBMAP_LIBS) +libmap_la_LDFLAGS = $(LIBMAP_LDFLAGS) + diff --git a/libmap/Makefile.in b/libmap/Makefile.in new file mode 100644 index 0000000..b4ae6df --- /dev/null +++ b/libmap/Makefile.in @@ -0,0 +1,732 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + + + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +noinst_PROGRAMS = test-timezone$(EXEEXT) +subdir = libmap +DIST_COMMON = README $(dist_tzdata_DATA) $(dist_ui_DATA) \ + $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/intltool.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +LTLIBRARIES = $(noinst_LTLIBRARIES) +am__DEPENDENCIES_1 = +libmap_la_DEPENDENCIES = $(am__DEPENDENCIES_1) +am_libmap_la_OBJECTS = cc-timezone-map.lo tz.lo +libmap_la_OBJECTS = $(am_libmap_la_OBJECTS) +AM_V_lt = $(am__v_lt_$(V)) +am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY)) +am__v_lt_0 = --silent +libmap_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(libmap_la_LDFLAGS) $(LDFLAGS) -o $@ +PROGRAMS = $(noinst_PROGRAMS) +am_test_timezone_OBJECTS = test_timezone-test-timezone.$(OBJEXT) \ + test_timezone-tz.$(OBJEXT) +test_timezone_OBJECTS = $(am_test_timezone_OBJECTS) +test_timezone_DEPENDENCIES = $(am__DEPENDENCIES_1) +test_timezone_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(test_timezone_CFLAGS) \ + $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_$(V)) +am__v_CC_ = $(am__v_CC_$(AM_DEFAULT_VERBOSITY)) +am__v_CC_0 = @echo " CC " $@; +AM_V_at = $(am__v_at_$(V)) +am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY)) +am__v_at_0 = @ +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_$(V)) +am__v_CCLD_ = $(am__v_CCLD_$(AM_DEFAULT_VERBOSITY)) +am__v_CCLD_0 = @echo " CCLD " $@; +AM_V_GEN = $(am__v_GEN_$(V)) +am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY)) +am__v_GEN_0 = @echo " GEN " $@; +SOURCES = $(libmap_la_SOURCES) $(test_timezone_SOURCES) +DIST_SOURCES = $(libmap_la_SOURCES) $(test_timezone_SOURCES) +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__installdirs = "$(DESTDIR)$(tzdatadir)" "$(DESTDIR)$(uidir)" +DATA = $(dist_tzdata_DATA) $(dist_ui_DATA) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +ALL_LINGUAS = @ALL_LINGUAS@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CATALOGS = @CATALOGS@ +CATOBJEXT = @CATOBJEXT@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DATADIRNAME = @DATADIRNAME@ +DBUSSERVICEDIR = @DBUSSERVICEDIR@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ +GLIB_COMPILE_SCHEMAS = @GLIB_COMPILE_SCHEMAS@ +GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ +GLIB_MKENUMS = @GLIB_MKENUMS@ +GMOFILES = @GMOFILES@ +GMSGFMT = @GMSGFMT@ +GNOMELOCALEDIR = @GNOMELOCALEDIR@ +GREP = @GREP@ +GSETTINGS_DISABLE_SCHEMAS_COMPILE = @GSETTINGS_DISABLE_SCHEMAS_COMPILE@ +INDICATORDIR = @INDICATORDIR@ +INDICATORICONSDIR = @INDICATORICONSDIR@ +INDICATOR_CFLAGS = @INDICATOR_CFLAGS@ +INDICATOR_LIBS = @INDICATOR_LIBS@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INSTOBJEXT = @INSTOBJEXT@ +INTLLIBS = @INTLLIBS@ +INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@ +INTLTOOL_MERGE = @INTLTOOL_MERGE@ +INTLTOOL_PERL = @INTLTOOL_PERL@ +INTLTOOL_UPDATE = @INTLTOOL_UPDATE@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBMAP_CFLAGS = @LIBMAP_CFLAGS@ +LIBMAP_LDFLAGS = @LIBMAP_LDFLAGS@ +LIBMAP_LIBS = @LIBMAP_LIBS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +MKINSTALLDIRS = @MKINSTALLDIRS@ +MSGFMT = @MSGFMT@ +MSGFMT_OPTS = @MSGFMT_OPTS@ +MSGMERGE = @MSGMERGE@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +POFILES = @POFILES@ +POSUB = @POSUB@ +PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@ +PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@ +PREF_CFLAGS = @PREF_CFLAGS@ +PREF_LIBS = @PREF_LIBS@ +RANLIB = @RANLIB@ +SED = @SED@ +SERVICE_CFLAGS = @SERVICE_CFLAGS@ +SERVICE_LIBS = @SERVICE_LIBS@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +USE_NLS = @USE_NLS@ +VERSION = @VERSION@ +XGETTEXT = @XGETTEXT@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +gsettingsschemadir = @gsettingsschemadir@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +lt_ECHO = @lt_ECHO@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +uidir = $(pkgdatadir)/libmap/ui +dist_ui_DATA = \ + data/bg.png \ + data/cc.png \ + data/pin.png \ + data/timezone_0.png \ + data/timezone_-10.png \ + data/timezone_10.png \ + data/timezone_10.5.png \ + data/timezone_-1.png \ + data/timezone_1.png \ + data/timezone_-11.png \ + data/timezone_11.png \ + data/timezone_11.5.png \ + data/timezone_12.png \ + data/timezone_12.75.png \ + data/timezone_13.png \ + data/timezone_-2.png \ + data/timezone_2.png \ + data/timezone_-3.png \ + data/timezone_3.png \ + data/timezone_-3.5.png \ + data/timezone_3.5.png \ + data/timezone_-4.png \ + data/timezone_4.png \ + data/timezone_-4.5.png \ + data/timezone_4.5.png \ + data/timezone_-5.png \ + data/timezone_5.png \ + data/timezone_-5.5.png \ + data/timezone_5.5.png \ + data/timezone_5.75.png \ + data/timezone_-6.png \ + data/timezone_6.png \ + data/timezone_6.5.png \ + data/timezone_-7.png \ + data/timezone_7.png \ + data/timezone_-8.png \ + data/timezone_8.png \ + data/timezone_-9.png \ + data/timezone_9.png \ + data/timezone_-9.5.png \ + data/timezone_9.5.png + +tzdatadir = $(pkgdatadir)/libmap/datetime +dist_tzdata_DATA = backward +AM_CPPFLAGS = \ + $(LIBMAP_CFLAGS) \ + -DGNOMELOCALEDIR="\"$(datadir)/locale\"" \ + -DGNOMECC_DATA_DIR="\"$(pkgdatadir)/libmap\"" \ + -DDATADIR="\"$(uidir)\"" \ + $(NULL) + +test_timezone_SOURCES = test-timezone.c tz.c tz.h +test_timezone_LDADD = $(LIBMAP_LIBS) +test_timezone_CFLAGS = $(LIBMAP_CFLAGS) +noinst_LTLIBRARIES = libmap.la +libmap_la_SOURCES = \ + cc-timezone-map.c \ + cc-timezone-map.h \ + tz.c tz.h + +libmap_la_LIBADD = $(LIBMAP_LIBS) +libmap_la_LDFLAGS = $(LIBMAP_LDFLAGS) +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu libmap/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu libmap/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstLTLIBRARIES: + -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +libmap.la: $(libmap_la_OBJECTS) $(libmap_la_DEPENDENCIES) + $(AM_V_CCLD)$(libmap_la_LINK) $(libmap_la_OBJECTS) $(libmap_la_LIBADD) $(LIBS) + +clean-noinstPROGRAMS: + @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list +test-timezone$(EXEEXT): $(test_timezone_OBJECTS) $(test_timezone_DEPENDENCIES) + @rm -f test-timezone$(EXEEXT) + $(AM_V_CCLD)$(test_timezone_LINK) $(test_timezone_OBJECTS) $(test_timezone_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cc-timezone-map.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_timezone-test-timezone.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_timezone-tz.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tz.Plo@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +test_timezone-test-timezone.o: test-timezone.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_timezone_CFLAGS) $(CFLAGS) -MT test_timezone-test-timezone.o -MD -MP -MF $(DEPDIR)/test_timezone-test-timezone.Tpo -c -o test_timezone-test-timezone.o `test -f 'test-timezone.c' || echo '$(srcdir)/'`test-timezone.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_timezone-test-timezone.Tpo $(DEPDIR)/test_timezone-test-timezone.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test-timezone.c' object='test_timezone-test-timezone.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_timezone_CFLAGS) $(CFLAGS) -c -o test_timezone-test-timezone.o `test -f 'test-timezone.c' || echo '$(srcdir)/'`test-timezone.c + +test_timezone-test-timezone.obj: test-timezone.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_timezone_CFLAGS) $(CFLAGS) -MT test_timezone-test-timezone.obj -MD -MP -MF $(DEPDIR)/test_timezone-test-timezone.Tpo -c -o test_timezone-test-timezone.obj `if test -f 'test-timezone.c'; then $(CYGPATH_W) 'test-timezone.c'; else $(CYGPATH_W) '$(srcdir)/test-timezone.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_timezone-test-timezone.Tpo $(DEPDIR)/test_timezone-test-timezone.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test-timezone.c' object='test_timezone-test-timezone.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_timezone_CFLAGS) $(CFLAGS) -c -o test_timezone-test-timezone.obj `if test -f 'test-timezone.c'; then $(CYGPATH_W) 'test-timezone.c'; else $(CYGPATH_W) '$(srcdir)/test-timezone.c'; fi` + +test_timezone-tz.o: tz.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_timezone_CFLAGS) $(CFLAGS) -MT test_timezone-tz.o -MD -MP -MF $(DEPDIR)/test_timezone-tz.Tpo -c -o test_timezone-tz.o `test -f 'tz.c' || echo '$(srcdir)/'`tz.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_timezone-tz.Tpo $(DEPDIR)/test_timezone-tz.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tz.c' object='test_timezone-tz.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_timezone_CFLAGS) $(CFLAGS) -c -o test_timezone-tz.o `test -f 'tz.c' || echo '$(srcdir)/'`tz.c + +test_timezone-tz.obj: tz.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_timezone_CFLAGS) $(CFLAGS) -MT test_timezone-tz.obj -MD -MP -MF $(DEPDIR)/test_timezone-tz.Tpo -c -o test_timezone-tz.obj `if test -f 'tz.c'; then $(CYGPATH_W) 'tz.c'; else $(CYGPATH_W) '$(srcdir)/tz.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_timezone-tz.Tpo $(DEPDIR)/test_timezone-tz.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tz.c' object='test_timezone-tz.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_timezone_CFLAGS) $(CFLAGS) -c -o test_timezone-tz.obj `if test -f 'tz.c'; then $(CYGPATH_W) 'tz.c'; else $(CYGPATH_W) '$(srcdir)/tz.c'; fi` + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +install-dist_tzdataDATA: $(dist_tzdata_DATA) + @$(NORMAL_INSTALL) + test -z "$(tzdatadir)" || $(MKDIR_P) "$(DESTDIR)$(tzdatadir)" + @list='$(dist_tzdata_DATA)'; test -n "$(tzdatadir)" || list=; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(tzdatadir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(tzdatadir)" || exit $$?; \ + done + +uninstall-dist_tzdataDATA: + @$(NORMAL_UNINSTALL) + @list='$(dist_tzdata_DATA)'; test -n "$(tzdatadir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + test -n "$$files" || exit 0; \ + echo " ( cd '$(DESTDIR)$(tzdatadir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(tzdatadir)" && rm -f $$files +install-dist_uiDATA: $(dist_ui_DATA) + @$(NORMAL_INSTALL) + test -z "$(uidir)" || $(MKDIR_P) "$(DESTDIR)$(uidir)" + @list='$(dist_ui_DATA)'; test -n "$(uidir)" || list=; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(uidir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(uidir)" || exit $$?; \ + done + +uninstall-dist_uiDATA: + @$(NORMAL_UNINSTALL) + @list='$(dist_ui_DATA)'; test -n "$(uidir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + test -n "$$files" || exit 0; \ + echo " ( cd '$(DESTDIR)$(uidir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(uidir)" && rm -f $$files + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) check-local +check: check-am +all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(DATA) all-local +installdirs: + for dir in "$(DESTDIR)$(tzdatadir)" "$(DESTDIR)$(uidir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ + clean-noinstPROGRAMS mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-dist_tzdataDATA install-dist_uiDATA + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-dist_tzdataDATA uninstall-dist_uiDATA + +.MAKE: check-am install-am install-strip + +.PHONY: CTAGS GTAGS all all-am all-local check check-am check-local \ + clean clean-generic clean-libtool clean-noinstLTLIBRARIES \ + clean-noinstPROGRAMS ctags distclean distclean-compile \ + distclean-generic distclean-libtool distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dist_tzdataDATA \ + install-dist_uiDATA install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags uninstall uninstall-am uninstall-dist_tzdataDATA \ + uninstall-dist_uiDATA + + +all-local: check-local + +# FIXME remove "|| :" when we have all the necessary pixmaps +check-local: test-timezone + $(builddir)/test-timezone $(srcdir)/data || : + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/libmap/README b/libmap/README new file mode 100644 index 0000000..70d6f6c --- /dev/null +++ b/libmap/README @@ -0,0 +1,5 @@ +This static library is a copied version of the code in GNOME 3.0's control center panel 'datetime', which itself is a version of Ubiquity's map ported to C. + +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. diff --git a/libmap/backward b/libmap/backward new file mode 100644 index 0000000..f1f95a8 --- /dev/null +++ b/libmap/backward @@ -0,0 +1,118 @@ +#
+# @(#)backward	8.9
+# This file is in the public domain, so clarified as of
+# 2009-05-17 by Arthur David Olson.
+
+# This file provides links between current names for time zones
+# and their old names.  Many names changed in late 1993.
+
+Link	Africa/Asmara		Africa/Asmera
+Link	Africa/Bamako		Africa/Timbuktu
+Link	America/Argentina/Catamarca	America/Argentina/ComodRivadavia
+Link	America/Adak		America/Atka
+Link	America/Argentina/Buenos_Aires	America/Buenos_Aires
+Link	America/Argentina/Catamarca	America/Catamarca
+Link	America/Atikokan	America/Coral_Harbour
+Link	America/Argentina/Cordoba	America/Cordoba
+Link	America/Tijuana		America/Ensenada
+Link	America/Indiana/Indianapolis	America/Fort_Wayne
+Link	America/Indiana/Indianapolis	America/Indianapolis
+Link	America/Argentina/Jujuy	America/Jujuy
+Link	America/Indiana/Knox	America/Knox_IN
+Link	America/Kentucky/Louisville	America/Louisville
+Link	America/Argentina/Mendoza	America/Mendoza
+Link	America/Rio_Branco	America/Porto_Acre
+Link	America/Argentina/Cordoba	America/Rosario
+Link	America/St_Thomas	America/Virgin
+Link	Asia/Ashgabat		Asia/Ashkhabad
+Link	Asia/Chongqing		Asia/Chungking
+Link	Asia/Dhaka		Asia/Dacca
+Link	Asia/Kathmandu		Asia/Katmandu
+Link	Asia/Kolkata		Asia/Calcutta
+Link	Asia/Macau		Asia/Macao
+Link	Asia/Jerusalem		Asia/Tel_Aviv
+Link	Asia/Ho_Chi_Minh	Asia/Saigon
+Link	Asia/Thimphu		Asia/Thimbu
+Link	Asia/Makassar		Asia/Ujung_Pandang
+Link	Asia/Ulaanbaatar	Asia/Ulan_Bator
+Link	Atlantic/Faroe		Atlantic/Faeroe
+Link	Europe/Oslo		Atlantic/Jan_Mayen
+Link	Australia/Sydney	Australia/ACT
+Link	Australia/Sydney	Australia/Canberra
+Link	Australia/Lord_Howe	Australia/LHI
+Link	Australia/Sydney	Australia/NSW
+Link	Australia/Darwin	Australia/North
+Link	Australia/Brisbane	Australia/Queensland
+Link	Australia/Adelaide	Australia/South
+Link	Australia/Hobart	Australia/Tasmania
+Link	Australia/Melbourne	Australia/Victoria
+Link	Australia/Perth		Australia/West
+Link	Australia/Broken_Hill	Australia/Yancowinna
+Link	America/Rio_Branco	Brazil/Acre
+Link	America/Noronha		Brazil/DeNoronha
+Link	America/Sao_Paulo	Brazil/East
+Link	America/Manaus		Brazil/West
+Link	America/Halifax		Canada/Atlantic
+Link	America/Winnipeg	Canada/Central
+Link	America/Regina		Canada/East-Saskatchewan
+Link	America/Toronto		Canada/Eastern
+Link	America/Edmonton	Canada/Mountain
+Link	America/St_Johns	Canada/Newfoundland
+Link	America/Vancouver	Canada/Pacific
+Link	America/Regina		Canada/Saskatchewan
+Link	America/Whitehorse	Canada/Yukon
+Link	America/Santiago	Chile/Continental
+Link	Pacific/Easter		Chile/EasterIsland
+Link	America/Havana		Cuba
+Link	Africa/Cairo		Egypt
+Link	Europe/Dublin		Eire
+Link	Europe/London		Europe/Belfast
+Link	Europe/Chisinau		Europe/Tiraspol
+Link	Europe/London		GB
+Link	Europe/London		GB-Eire
+Link	Etc/GMT			GMT+0
+Link	Etc/GMT			GMT-0
+Link	Etc/GMT			GMT0
+Link	Etc/GMT			Greenwich
+Link	Asia/Hong_Kong		Hongkong
+Link	Atlantic/Reykjavik	Iceland
+Link	Asia/Tehran		Iran
+Link	Asia/Jerusalem		Israel
+Link	America/Jamaica		Jamaica
+Link	Asia/Tokyo		Japan
+Link	Pacific/Kwajalein	Kwajalein
+Link	Africa/Tripoli		Libya
+Link	America/Tijuana		Mexico/BajaNorte
+Link	America/Mazatlan	Mexico/BajaSur
+Link	America/Mexico_City	Mexico/General
+Link	Pacific/Auckland	NZ
+Link	Pacific/Chatham		NZ-CHAT
+Link	America/Denver		Navajo
+Link	Asia/Shanghai		PRC
+Link	Pacific/Pago_Pago	Pacific/Samoa
+Link	Pacific/Chuuk		Pacific/Yap
+Link	Pacific/Chuuk		Pacific/Truk
+Link	Pacific/Pohnpei		Pacific/Ponape
+Link	Europe/Warsaw		Poland
+Link	Europe/Lisbon		Portugal
+Link	Asia/Taipei		ROC
+Link	Asia/Seoul		ROK
+Link	Asia/Singapore		Singapore
+Link	Europe/Istanbul		Turkey
+Link	Etc/UCT			UCT
+Link	America/Anchorage	US/Alaska
+Link	America/Adak		US/Aleutian
+Link	America/Phoenix		US/Arizona
+Link	America/Chicago		US/Central
+Link	America/Indiana/Indianapolis	US/East-Indiana
+Link	America/New_York	US/Eastern
+Link	Pacific/Honolulu	US/Hawaii
+Link	America/Indiana/Knox	US/Indiana-Starke
+Link	America/Detroit		US/Michigan
+Link	America/Denver		US/Mountain
+Link	America/Los_Angeles	US/Pacific
+Link	Pacific/Pago_Pago	US/Samoa
+Link	Etc/UTC			UTC
+Link	Etc/UTC			Universal
+Link	Europe/Moscow		W-SU
+Link	Etc/UTC			Zulu
diff --git a/libmap/cc-timezone-map.c b/libmap/cc-timezone-map.c
new file mode 100644
index 0000000..960a049
--- /dev/null
+++ b/libmap/cc-timezone-map.c
@@ -0,0 +1,711 @@
+/*
+ * Copyright (C) 2010 Intel, Inc
+ *
+ * Portions from Ubiquity, Copyright (C) 2009 Canonical Ltd.
+ * Written by Evan Dandrea 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Author: Thomas Wood 
+ *
+ */
+
+#include "cc-timezone-map.h"
+#include 
+#include "tz.h"
+
+G_DEFINE_TYPE (CcTimezoneMap, cc_timezone_map, GTK_TYPE_WIDGET)
+
+#define TIMEZONE_MAP_PRIVATE(o) \
+  (G_TYPE_INSTANCE_GET_PRIVATE ((o), CC_TYPE_TIMEZONE_MAP, CcTimezoneMapPrivate))
+
+
+typedef struct
+{
+  gdouble offset;
+  guchar red;
+  guchar green;
+  guchar blue;
+  guchar alpha;
+} CcTimezoneMapOffset;
+
+struct _CcTimezoneMapPrivate
+{
+  GdkPixbuf *orig_background;
+  GdkPixbuf *orig_color_map;
+
+  GdkPixbuf *background;
+  GdkPixbuf *color_map;
+
+  guchar *visible_map_pixels;
+  gint visible_map_rowstride;
+
+  gdouble selected_offset;
+
+  TzDB *tzdb;
+  TzLocation *location;
+  GHashTable *alias_db;
+};
+
+enum
+{
+  LOCATION_CHANGED,
+  LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL];
+
+
+static CcTimezoneMapOffset color_codes[] =
+{
+    {-11.0, 43, 0, 0, 255 },
+    {-10.0, 85, 0, 0, 255 },
+    {-9.5, 102, 255, 0, 255 },
+    {-9.0, 128, 0, 0, 255 },
+    {-8.0, 170, 0, 0, 255 },
+    {-7.0, 212, 0, 0, 255 },
+    {-6.0, 255, 0, 1, 255 }, // north
+    {-6.0, 255, 0, 0, 255 }, // south
+    {-5.0, 255, 42, 42, 255 },
+    {-4.5, 192, 255, 0, 255 },
+    {-4.0, 255, 85, 85, 255 },
+    {-3.5, 0, 255, 0, 255 },
+    {-3.0, 255, 128, 128, 255 },
+    {-2.0, 255, 170, 170, 255 },
+    {-1.0, 255, 213, 213, 255 },
+    {0.0, 43, 17, 0, 255 },
+    {1.0, 85, 34, 0, 255 },
+    {2.0, 128, 51, 0, 255 },
+    {3.0, 170, 68, 0, 255 },
+    {3.5, 0, 255, 102, 255 },
+    {4.0, 212, 85, 0, 255 },
+    {4.5, 0, 204, 255, 255 },
+    {5.0, 255, 102, 0, 255 },
+    {5.5, 0, 102, 255, 255 },
+    {5.75, 0, 238, 207, 247 },
+    {6.0, 255, 127, 42, 255 },
+    {6.5, 204, 0, 254, 254 },
+    {7.0, 255, 153, 85, 255 },
+    {8.0, 255, 179, 128, 255 },
+    {9.0, 255, 204, 170, 255 },
+    {9.5, 170, 0, 68, 250 },
+    {10.0, 255, 230, 213, 255 },
+    {10.5, 212, 124, 21, 250 },
+    {11.0, 212, 170, 0, 255 },
+    {11.5, 249, 25, 87, 253 },
+    {12.0, 255, 204, 0, 255 },
+    {12.75, 254, 74, 100, 248 },
+    {13.0, 255, 85, 153, 250 },
+    {-100, 0, 0, 0, 0 }
+};
+
+
+static void
+cc_timezone_map_get_property (GObject    *object,
+                              guint       property_id,
+                              GValue     *value,
+                              GParamSpec *pspec)
+{
+  switch (property_id)
+    {
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+    }
+}
+
+static void
+cc_timezone_map_set_property (GObject      *object,
+                              guint         property_id,
+                              const GValue *value,
+                              GParamSpec   *pspec)
+{
+  switch (property_id)
+    {
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+    }
+}
+
+static void
+cc_timezone_map_dispose (GObject *object)
+{
+  CcTimezoneMapPrivate *priv = CC_TIMEZONE_MAP (object)->priv;
+
+  if (priv->orig_background)
+    {
+      g_object_unref (priv->orig_background);
+      priv->orig_background = NULL;
+    }
+
+  if (priv->orig_color_map)
+    {
+      g_object_unref (priv->orig_color_map);
+      priv->orig_color_map = NULL;
+    }
+
+  if (priv->background)
+    {
+      g_object_unref (priv->background);
+      priv->background = NULL;
+    }
+
+  if (priv->color_map)
+    {
+      g_object_unref (priv->color_map);
+      priv->color_map = NULL;
+
+      priv->visible_map_pixels = NULL;
+      priv->visible_map_rowstride = 0;
+    }
+
+  if (priv->alias_db)
+    {
+      g_hash_table_destroy (priv->alias_db);
+      priv->alias_db = NULL;
+    }
+
+  G_OBJECT_CLASS (cc_timezone_map_parent_class)->dispose (object);
+}
+
+static void
+cc_timezone_map_finalize (GObject *object)
+{
+  CcTimezoneMapPrivate *priv = CC_TIMEZONE_MAP (object)->priv;
+
+  if (priv->tzdb)
+    {
+      tz_db_free (priv->tzdb);
+      priv->tzdb = NULL;
+    }
+
+
+  G_OBJECT_CLASS (cc_timezone_map_parent_class)->finalize (object);
+}
+
+/* GtkWidget functions */
+#ifdef CCGTK3
+static void
+cc_timezone_map_get_preferred_width (GtkWidget *widget,
+                                     gint      *minimum,
+                                     gint      *natural)
+{
+  /* choose a minimum size small enough to prevent the window
+   * from growing horizontally
+   */
+  if (minimum != NULL)
+    *minimum = 300;
+  if (natural != NULL)
+    *natural = 300;
+}
+
+static void
+cc_timezone_map_get_preferred_height (GtkWidget *widget,
+                                      gint      *minimum,
+                                      gint      *natural)
+{
+  CcTimezoneMapPrivate *priv = CC_TIMEZONE_MAP (widget)->priv;
+  gint size;
+
+  /* The + 20 here is a slight tweak to make the map fill the
+   * panel better without causing horizontal growing
+   */
+  size = 300 * gdk_pixbuf_get_height (priv->orig_background) / gdk_pixbuf_get_width (priv->orig_background) + 20;
+  if (minimum != NULL)
+    *minimum = size;
+  if (natural != NULL)
+    *natural = size;
+}
+
+#else
+
+static void
+cc_timezone_map_size_request (GtkWidget *widget,
+                              GtkRequisition *requisition)
+{
+  CcTimezoneMapPrivate *priv = CC_TIMEZONE_MAP (widget)->priv;
+
+  if (!requisition)
+    return;
+
+  /* The + 20 here is a slight tweak to make the map fill the
+   * panel better without causing horizontal growing
+   */
+  requisition->height = 300 * gdk_pixbuf_get_height (priv->orig_background) / gdk_pixbuf_get_width (priv->orig_background) + 20;
+  requisition->width = 300;
+}
+#endif
+
+static void
+cc_timezone_map_size_allocate (GtkWidget     *widget,
+                               GtkAllocation *allocation)
+{
+  CcTimezoneMapPrivate *priv = CC_TIMEZONE_MAP (widget)->priv;
+
+  if (priv->background)
+    g_object_unref (priv->background);
+
+  priv->background = gdk_pixbuf_scale_simple (priv->orig_background,
+                                              allocation->width,
+                                              allocation->height,
+                                              GDK_INTERP_BILINEAR);
+
+  if (priv->color_map)
+    g_object_unref (priv->color_map);
+
+  priv->color_map = gdk_pixbuf_scale_simple (priv->orig_color_map,
+                                             allocation->width,
+                                             allocation->height,
+                                             GDK_INTERP_BILINEAR);
+
+  priv->visible_map_pixels = gdk_pixbuf_get_pixels (priv->color_map);
+  priv->visible_map_rowstride = gdk_pixbuf_get_rowstride (priv->color_map);
+
+  GTK_WIDGET_CLASS (cc_timezone_map_parent_class)->size_allocate (widget,
+                                                                  allocation);
+}
+
+static void
+cc_timezone_map_realize (GtkWidget *widget)
+{
+  GdkWindowAttr attr = { 0, };
+  GtkAllocation allocation;
+  GdkCursor *cursor;
+  GdkWindow *window;
+
+  gtk_widget_get_allocation (widget, &allocation);
+
+  gtk_widget_set_realized (widget, TRUE);
+
+  attr.window_type = GDK_WINDOW_CHILD;
+  attr.wclass = GDK_INPUT_OUTPUT;
+  attr.width = allocation.width;
+  attr.height = allocation.height;
+  attr.x = allocation.x;
+  attr.y = allocation.y;
+  attr.event_mask = gtk_widget_get_events (widget)
+                                 | GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK;
+
+  window = gdk_window_new (gtk_widget_get_parent_window (widget), &attr,
+                           GDK_WA_X | GDK_WA_Y);
+
+  gtk_widget_set_style (widget,
+                        gtk_style_attach (gtk_widget_get_style (widget),
+                                          window));
+
+  gdk_window_set_user_data (window, widget);
+
+  cursor = gdk_cursor_new (GDK_HAND2);
+  gdk_window_set_cursor (window, cursor);
+
+  gtk_widget_set_window (widget, window);
+}
+
+
+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;
+}
+
+
+static gboolean
+cc_timezone_map_draw (GtkWidget *widget,
+                      cairo_t   *cr)
+{
+  CcTimezoneMapPrivate *priv = CC_TIMEZONE_MAP (widget)->priv;
+  GdkPixbuf *hilight, *orig_hilight, *pin;
+  GtkAllocation alloc;
+  gchar *file;
+  GError *err = NULL;
+  gdouble pointx, pointy;
+  char buf[16];
+
+  gtk_widget_get_allocation (widget, &alloc);
+
+  /* paint background */
+  gdk_cairo_set_source_pixbuf (cr, priv->background, 0, 0);
+  cairo_paint (cr);
+
+  /* paint hilight */
+  file = g_strdup_printf (DATADIR "/timezone_%s.png",
+                          g_ascii_formatd (buf, sizeof (buf),
+                                           "%g", priv->selected_offset));
+  orig_hilight = gdk_pixbuf_new_from_file (file, &err);
+  g_free (file);
+  file = NULL;
+
+  if (!orig_hilight)
+    {
+      g_warning ("Could not load hilight: %s",
+                 (err) ? err->message : "Unknown Error");
+      if (err)
+        g_clear_error (&err);
+    }
+  else
+    {
+
+      hilight = gdk_pixbuf_scale_simple (orig_hilight, alloc.width,
+                                         alloc.height, GDK_INTERP_BILINEAR);
+      gdk_cairo_set_source_pixbuf (cr, hilight, 0, 0);
+
+      cairo_paint (cr);
+      g_object_unref (hilight);
+      g_object_unref (orig_hilight);
+    }
+
+  /* load pin icon */
+  pin = gdk_pixbuf_new_from_file (DATADIR "/pin.png", &err);
+
+  if (err)
+    {
+      g_warning ("Could not load pin icon: %s", err->message);
+      g_clear_error (&err);
+    }
+
+  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 (cr);
+        }
+    }
+
+  if (pin)
+    {
+      g_object_unref (pin);
+    }
+
+  return TRUE;
+}
+
+#ifndef CCGTK3
+static gboolean
+cc_timezone_map_expose_event (GtkWidget *widget,
+                              GdkEventExpose  *event)
+{
+  gboolean   rv;
+  cairo_t   *cr;
+  cr = gdk_cairo_create (widget->window);
+  rv = cc_timezone_map_draw (widget, cr);
+  cairo_destroy (cr);
+  return rv;
+}
+#endif
+
+
+static void
+cc_timezone_map_class_init (CcTimezoneMapClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+  g_type_class_add_private (klass, sizeof (CcTimezoneMapPrivate));
+
+  object_class->get_property = cc_timezone_map_get_property;
+  object_class->set_property = cc_timezone_map_set_property;
+  object_class->dispose = cc_timezone_map_dispose;
+  object_class->finalize = cc_timezone_map_finalize;
+
+#ifdef CCGTK3
+  widget_class->get_preferred_width = cc_timezone_map_get_preferred_width;
+  widget_class->get_preferred_height = cc_timezone_map_get_preferred_height;
+#else
+  widget_class->size_request = cc_timezone_map_size_request;
+#endif
+  widget_class->size_allocate = cc_timezone_map_size_allocate;
+  widget_class->realize = cc_timezone_map_realize;
+#ifdef CCGTK3
+  widget_class->draw = cc_timezone_map_draw;
+#else
+  widget_class->expose_event = cc_timezone_map_expose_event;
+#endif
+
+  signals[LOCATION_CHANGED] = g_signal_new ("location-changed",
+                                            CC_TYPE_TIMEZONE_MAP,
+                                            G_SIGNAL_RUN_FIRST,
+                                            0,
+                                            NULL,
+                                            NULL,
+                                            g_cclosure_marshal_VOID__POINTER,
+                                            G_TYPE_NONE, 1,
+                                            G_TYPE_POINTER);
+}
+
+
+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 void
+set_location (CcTimezoneMap *map,
+              TzLocation    *location)
+{
+  CcTimezoneMapPrivate *priv = map->priv;
+  TzInfo *info;
+
+  priv->location = location;
+
+  info = tz_info_from_location (priv->location);
+
+  priv->selected_offset = tz_location_get_utc_offset (priv->location)
+    / (60.0*60.0) + ((info->daylight) ? -1.0 : 0.0);
+
+  g_signal_emit (map, signals[LOCATION_CHANGED], 0, priv->location);
+
+  tz_info_free (info);
+}
+
+static gboolean
+button_press_event (GtkWidget      *widget,
+                    GdkEventButton *event)
+{
+  CcTimezoneMapPrivate *priv = CC_TIMEZONE_MAP (widget)->priv;
+  gint x, y;
+  guchar r, g, b, a;
+  guchar *pixels;
+  gint rowstride;
+  gint i;
+
+  const GPtrArray *array;
+  gint width, height;
+  GList *distances = NULL;
+  GtkAllocation alloc;
+
+  x = event->x;
+  y = event->y;
+
+
+  rowstride = priv->visible_map_rowstride;
+  pixels = priv->visible_map_pixels;
+
+  r = pixels[(rowstride * y + x * 4)];
+  g = pixels[(rowstride * y + x * 4) + 1];
+  b = pixels[(rowstride * y + x * 4) + 2];
+  a = pixels[(rowstride * y + x * 4) + 3];
+
+
+  for (i = 0; color_codes[i].offset != -100; i++)
+    {
+       if (color_codes[i].red == r && color_codes[i].green == g
+           && color_codes[i].blue == b && color_codes[i].alpha == a)
+         {
+           priv->selected_offset = color_codes[i].offset;
+         }
+    }
+
+  gtk_widget_queue_draw (widget);
+
+  /* work out the co-ordinates */
+
+  array = tz_get_locations (priv->tzdb);
+
+  gtk_widget_get_allocation (widget, &alloc);
+  width = alloc.width;
+  height = alloc.height;
+
+  for (i = 0; i < array->len; i++)
+    {
+      gdouble pointx, pointy, dx, dy;
+      TzLocation *loc = array->pdata[i];
+
+      pointx = convert_longtitude_to_x (loc->longitude, width);
+      pointy = convert_latitude_to_y (loc->latitude, height);
+
+      dx = pointx - x;
+      dy = pointy - y;
+
+      loc->dist = dx * dx + dy * dy;
+      distances = g_list_prepend (distances, loc);
+
+    }
+  distances = g_list_sort (distances, (GCompareFunc) sort_locations);
+
+
+  set_location (CC_TIMEZONE_MAP (widget), (TzLocation*) distances->data);
+
+  g_list_free (distances);
+
+  return TRUE;
+}
+
+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" 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;
+  GError *err = NULL;
+
+  priv = self->priv = TIMEZONE_MAP_PRIVATE (self);
+
+  priv->orig_background = gdk_pixbuf_new_from_file (DATADIR "/bg.png",
+                                                    &err);
+
+  if (!priv->orig_background)
+    {
+      g_warning ("Could not load background image: %s",
+                 (err) ? err->message : "Unknown error");
+      g_clear_error (&err);
+    }
+
+  priv->orig_color_map = gdk_pixbuf_new_from_file (DATADIR "/cc.png",
+                                                   &err);
+  if (!priv->orig_color_map)
+    {
+      g_warning ("Could not load background image: %s",
+                 (err) ? err->message : "Unknown error");
+      g_clear_error (&err);
+    }
+
+  priv->tzdb = tz_load_db ();
+
+  g_signal_connect (self, "button-press-event", G_CALLBACK (button_press_event),
+                    NULL);
+
+  load_backward_tz (self);
+}
+
+CcTimezoneMap *
+cc_timezone_map_new (void)
+{
+  return g_object_new (CC_TYPE_TIMEZONE_MAP, NULL);
+}
+
+void
+cc_timezone_map_set_timezone (CcTimezoneMap *map,
+                              const gchar   *timezone)
+{
+  GPtrArray *locations;
+  guint i;
+  char *real_tz;
+
+  real_tz = g_hash_table_lookup (map->priv->alias_db, timezone);
+
+  locations = tz_get_locations (map->priv->tzdb);
+
+  for (i = 0; i < locations->len; i++)
+    {
+      TzLocation *loc = locations->pdata[i];
+
+      if (!g_strcmp0 (loc->zone, real_tz ? real_tz : timezone))
+        {
+          set_location (map, loc);
+          break;
+        }
+    }
+
+  gtk_widget_queue_draw (GTK_WIDGET (map));
+}
+
+TzLocation *
+cc_timezone_map_get_location (CcTimezoneMap *map)
+{
+  return map->priv->location;
+}
diff --git a/libmap/cc-timezone-map.h b/libmap/cc-timezone-map.h
new file mode 100644
index 0000000..3c57b27
--- /dev/null
+++ b/libmap/cc-timezone-map.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2010 Intel, Inc
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Author: Thomas Wood 
+ *
+ */
+
+
+#ifndef _CC_TIMEZONE_MAP_H
+#define _CC_TIMEZONE_MAP_H
+
+#include 
+#include "tz.h"
+
+G_BEGIN_DECLS
+
+#define CC_TYPE_TIMEZONE_MAP cc_timezone_map_get_type()
+
+#define CC_TIMEZONE_MAP(obj) \
+  (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
+  CC_TYPE_TIMEZONE_MAP, CcTimezoneMap))
+
+#define CC_TIMEZONE_MAP_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_CAST ((klass), \
+  CC_TYPE_TIMEZONE_MAP, CcTimezoneMapClass))
+
+#define CC_IS_TIMEZONE_MAP(obj) \
+  (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
+  CC_TYPE_TIMEZONE_MAP))
+
+#define CC_IS_TIMEZONE_MAP_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_TYPE ((klass), \
+  CC_TYPE_TIMEZONE_MAP))
+
+#define CC_TIMEZONE_MAP_GET_CLASS(obj) \
+  (G_TYPE_INSTANCE_GET_CLASS ((obj), \
+  CC_TYPE_TIMEZONE_MAP, CcTimezoneMapClass))
+
+typedef struct _CcTimezoneMap CcTimezoneMap;
+typedef struct _CcTimezoneMapClass CcTimezoneMapClass;
+typedef struct _CcTimezoneMapPrivate CcTimezoneMapPrivate;
+
+struct _CcTimezoneMap
+{
+  GtkWidget parent;
+
+  CcTimezoneMapPrivate *priv;
+};
+
+struct _CcTimezoneMapClass
+{
+  GtkWidgetClass parent_class;
+};
+
+GType cc_timezone_map_get_type (void) G_GNUC_CONST;
+
+CcTimezoneMap *cc_timezone_map_new (void);
+
+void cc_timezone_map_set_timezone (CcTimezoneMap *map,
+                                   const gchar   *timezone);
+TzLocation * cc_timezone_map_get_location (CcTimezoneMap *map);
+
+G_END_DECLS
+
+#endif /* _CC_TIMEZONE_MAP_H */
diff --git a/libmap/data/bg.png b/libmap/data/bg.png
new file mode 100644
index 0000000..4180ee8
Binary files /dev/null and b/libmap/data/bg.png differ
diff --git a/libmap/data/cc.png b/libmap/data/cc.png
new file mode 100644
index 0000000..54fb668
Binary files /dev/null and b/libmap/data/cc.png differ
diff --git a/libmap/data/pin.png b/libmap/data/pin.png
new file mode 100644
index 0000000..599a751
Binary files /dev/null and b/libmap/data/pin.png differ
diff --git a/libmap/data/timezone_-1.png b/libmap/data/timezone_-1.png
new file mode 100644
index 0000000..fb00d83
Binary files /dev/null and b/libmap/data/timezone_-1.png differ
diff --git a/libmap/data/timezone_-10.png b/libmap/data/timezone_-10.png
new file mode 100644
index 0000000..472eb88
Binary files /dev/null and b/libmap/data/timezone_-10.png differ
diff --git a/libmap/data/timezone_-11.png b/libmap/data/timezone_-11.png
new file mode 100644
index 0000000..5f8c5d6
Binary files /dev/null and b/libmap/data/timezone_-11.png differ
diff --git a/libmap/data/timezone_-2.png b/libmap/data/timezone_-2.png
new file mode 100644
index 0000000..30a1ec7
Binary files /dev/null and b/libmap/data/timezone_-2.png differ
diff --git a/libmap/data/timezone_-3.5.png b/libmap/data/timezone_-3.5.png
new file mode 100644
index 0000000..c1df00b
Binary files /dev/null and b/libmap/data/timezone_-3.5.png differ
diff --git a/libmap/data/timezone_-3.png b/libmap/data/timezone_-3.png
new file mode 100644
index 0000000..c22dbb6
Binary files /dev/null and b/libmap/data/timezone_-3.png differ
diff --git a/libmap/data/timezone_-4.5.png b/libmap/data/timezone_-4.5.png
new file mode 100644
index 0000000..9e3c134
Binary files /dev/null and b/libmap/data/timezone_-4.5.png differ
diff --git a/libmap/data/timezone_-4.png b/libmap/data/timezone_-4.png
new file mode 100644
index 0000000..4b5a431
Binary files /dev/null and b/libmap/data/timezone_-4.png differ
diff --git a/libmap/data/timezone_-5.5.png b/libmap/data/timezone_-5.5.png
new file mode 100644
index 0000000..b1c788d
Binary files /dev/null and b/libmap/data/timezone_-5.5.png differ
diff --git a/libmap/data/timezone_-5.png b/libmap/data/timezone_-5.png
new file mode 100644
index 0000000..06c15e6
Binary files /dev/null and b/libmap/data/timezone_-5.png differ
diff --git a/libmap/data/timezone_-6.png b/libmap/data/timezone_-6.png
new file mode 100644
index 0000000..8505fb1
Binary files /dev/null and b/libmap/data/timezone_-6.png differ
diff --git a/libmap/data/timezone_-7.png b/libmap/data/timezone_-7.png
new file mode 100644
index 0000000..fec235d
Binary files /dev/null and b/libmap/data/timezone_-7.png differ
diff --git a/libmap/data/timezone_-8.png b/libmap/data/timezone_-8.png
new file mode 100644
index 0000000..bdad7bf
Binary files /dev/null and b/libmap/data/timezone_-8.png differ
diff --git a/libmap/data/timezone_-9.5.png b/libmap/data/timezone_-9.5.png
new file mode 100644
index 0000000..b1c788d
Binary files /dev/null and b/libmap/data/timezone_-9.5.png differ
diff --git a/libmap/data/timezone_-9.png b/libmap/data/timezone_-9.png
new file mode 100644
index 0000000..04cb3cb
Binary files /dev/null and b/libmap/data/timezone_-9.png differ
diff --git a/libmap/data/timezone_0.png b/libmap/data/timezone_0.png
new file mode 100644
index 0000000..e59b773
Binary files /dev/null and b/libmap/data/timezone_0.png differ
diff --git a/libmap/data/timezone_1.png b/libmap/data/timezone_1.png
new file mode 100644
index 0000000..2053b7e
Binary files /dev/null and b/libmap/data/timezone_1.png differ
diff --git a/libmap/data/timezone_10.5.png b/libmap/data/timezone_10.5.png
new file mode 100644
index 0000000..6ec7f9f
Binary files /dev/null and b/libmap/data/timezone_10.5.png differ
diff --git a/libmap/data/timezone_10.png b/libmap/data/timezone_10.png
new file mode 100644
index 0000000..475dcf4
Binary files /dev/null and b/libmap/data/timezone_10.png differ
diff --git a/libmap/data/timezone_11.5.png b/libmap/data/timezone_11.5.png
new file mode 100644
index 0000000..afdedd7
Binary files /dev/null and b/libmap/data/timezone_11.5.png differ
diff --git a/libmap/data/timezone_11.png b/libmap/data/timezone_11.png
new file mode 100644
index 0000000..6168aa2
Binary files /dev/null and b/libmap/data/timezone_11.png differ
diff --git a/libmap/data/timezone_12.75.png b/libmap/data/timezone_12.75.png
new file mode 100644
index 0000000..4f74a85
Binary files /dev/null and b/libmap/data/timezone_12.75.png differ
diff --git a/libmap/data/timezone_12.png b/libmap/data/timezone_12.png
new file mode 100644
index 0000000..d0b3531
Binary files /dev/null and b/libmap/data/timezone_12.png differ
diff --git a/libmap/data/timezone_13.png b/libmap/data/timezone_13.png
new file mode 100644
index 0000000..fe2f134
Binary files /dev/null and b/libmap/data/timezone_13.png differ
diff --git a/libmap/data/timezone_2.png b/libmap/data/timezone_2.png
new file mode 100644
index 0000000..ec1e874
Binary files /dev/null and b/libmap/data/timezone_2.png differ
diff --git a/libmap/data/timezone_3.5.png b/libmap/data/timezone_3.5.png
new file mode 100644
index 0000000..2dc7399
Binary files /dev/null and b/libmap/data/timezone_3.5.png differ
diff --git a/libmap/data/timezone_3.png b/libmap/data/timezone_3.png
new file mode 100644
index 0000000..eda59dc
Binary files /dev/null and b/libmap/data/timezone_3.png differ
diff --git a/libmap/data/timezone_4.5.png b/libmap/data/timezone_4.5.png
new file mode 100644
index 0000000..e09ed90
Binary files /dev/null and b/libmap/data/timezone_4.5.png differ
diff --git a/libmap/data/timezone_4.png b/libmap/data/timezone_4.png
new file mode 100644
index 0000000..483dc53
Binary files /dev/null and b/libmap/data/timezone_4.png differ
diff --git a/libmap/data/timezone_5.5.png b/libmap/data/timezone_5.5.png
new file mode 100644
index 0000000..f904cc2
Binary files /dev/null and b/libmap/data/timezone_5.5.png differ
diff --git a/libmap/data/timezone_5.75.png b/libmap/data/timezone_5.75.png
new file mode 100644
index 0000000..827ce1a
Binary files /dev/null and b/libmap/data/timezone_5.75.png differ
diff --git a/libmap/data/timezone_5.png b/libmap/data/timezone_5.png
new file mode 100644
index 0000000..1bb6d20
Binary files /dev/null and b/libmap/data/timezone_5.png differ
diff --git a/libmap/data/timezone_6.5.png b/libmap/data/timezone_6.5.png
new file mode 100644
index 0000000..d307bf3
Binary files /dev/null and b/libmap/data/timezone_6.5.png differ
diff --git a/libmap/data/timezone_6.png b/libmap/data/timezone_6.png
new file mode 100644
index 0000000..460f9cf
Binary files /dev/null and b/libmap/data/timezone_6.png differ
diff --git a/libmap/data/timezone_7.png b/libmap/data/timezone_7.png
new file mode 100644
index 0000000..239115a
Binary files /dev/null and b/libmap/data/timezone_7.png differ
diff --git a/libmap/data/timezone_8.png b/libmap/data/timezone_8.png
new file mode 100644
index 0000000..3627686
Binary files /dev/null and b/libmap/data/timezone_8.png differ
diff --git a/libmap/data/timezone_9.5.png b/libmap/data/timezone_9.5.png
new file mode 100644
index 0000000..1c3290c
Binary files /dev/null and b/libmap/data/timezone_9.5.png differ
diff --git a/libmap/data/timezone_9.png b/libmap/data/timezone_9.png
new file mode 100644
index 0000000..65d2e46
Binary files /dev/null and b/libmap/data/timezone_9.png differ
diff --git a/libmap/datetime-module.c b/libmap/datetime-module.c
new file mode 100644
index 0000000..8217dc3
--- /dev/null
+++ b/libmap/datetime-module.c
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2010 Intel, Inc
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Author: Thomas Wood 
+ *
+ */
+
+#include 
+
+#include "cc-datetime-panel.h"
+
+#include 
+
+#define GETTEXT_PACKAGE_TIMEZONES GETTEXT_PACKAGE "-timezones"
+
+void
+g_io_module_load (GIOModule *module)
+{
+  bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR);
+  bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
+
+  bindtextdomain (GETTEXT_PACKAGE_TIMEZONES, GNOMELOCALEDIR);
+  bind_textdomain_codeset (GETTEXT_PACKAGE_TIMEZONES, "UTF-8");
+
+  /* register the panel */
+  cc_date_time_panel_register (module);
+}
+
+void
+g_io_module_unload (GIOModule *module)
+{
+}
diff --git a/libmap/dt-lockbutton.c b/libmap/dt-lockbutton.c
new file mode 100644
index 0000000..ecf4c12
--- /dev/null
+++ b/libmap/dt-lockbutton.c
@@ -0,0 +1,627 @@
+/*
+ * Copyright (C) 2010 Red Hat, Inc.
+ * Author: Matthias Clasen
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include "dt-lockbutton.h"
+
+#include 
+#include 
+
+#define P_(s) s
+
+struct _DtLockButtonPrivate
+{
+  GPermission *permission;
+
+  gchar *text_lock;
+  gchar *text_unlock;
+  gchar *text_not_authorized;
+
+  gchar *tooltip_lock;
+  gchar *tooltip_unlock;
+  gchar *tooltip_not_authorized;
+
+  GtkWidget *box;
+  GtkWidget *eventbox;
+  GtkWidget *image;
+  GtkWidget *button;
+  GtkWidget *notebook;
+
+  GtkWidget *label_lock;
+  GtkWidget *label_unlock;
+  GtkWidget *label_not_authorized;
+
+  GCancellable *cancellable;
+
+  gboolean constructed;
+};
+
+enum
+{
+  PROP_0,
+  PROP_PERMISSION,
+  PROP_TEXT_LOCK,
+  PROP_TEXT_UNLOCK,
+  PROP_TEXT_NOT_AUTHORIZED,
+  PROP_TOOLTIP_LOCK,
+  PROP_TOOLTIP_UNLOCK,
+  PROP_TOOLTIP_NOT_AUTHORIZED
+};
+
+static void update_state (DtLockButton *button);
+
+static void on_permission_changed (GPermission *permission,
+                                   GParamSpec  *pspec,
+                                   gpointer     user_data);
+
+static void on_clicked (GtkButton *button,
+                        gpointer   user_data);
+
+static void on_button_press (GtkWidget      *widget,
+                             GdkEventButton *event,
+                             gpointer        user_data);
+
+G_DEFINE_TYPE (DtLockButton, dt_lock_button, GTK_TYPE_BIN);
+
+static void
+dt_lock_button_finalize (GObject *object)
+{
+  DtLockButton *button = DT_LOCK_BUTTON (object);
+  DtLockButtonPrivate *priv = button->priv;
+
+  g_free (priv->text_lock);
+  g_free (priv->text_unlock);
+  g_free (priv->text_not_authorized);
+
+  g_free (priv->tooltip_lock);
+  g_free (priv->tooltip_unlock);
+  g_free (priv->tooltip_not_authorized);
+
+  if (priv->cancellable != NULL)
+    {
+      g_cancellable_cancel (priv->cancellable);
+      g_object_unref (priv->cancellable);
+    }
+
+  g_signal_handlers_disconnect_by_func (priv->permission,
+                                        on_permission_changed,
+                                        button);
+
+  g_object_unref (priv->permission);
+
+  G_OBJECT_CLASS (dt_lock_button_parent_class)->finalize (object);
+}
+
+static void
+dt_lock_button_get_property (GObject    *object,
+                             guint       property_id,
+                             GValue     *value,
+                             GParamSpec *pspec)
+{
+  DtLockButton *button = DT_LOCK_BUTTON (object);
+  DtLockButtonPrivate *priv = button->priv;
+
+  switch (property_id)
+    {
+    case PROP_PERMISSION:
+      g_value_set_object (value, priv->permission);
+      break;
+
+    case PROP_TEXT_LOCK:
+      g_value_set_string (value, priv->text_lock);
+      break;
+
+    case PROP_TEXT_UNLOCK:
+      g_value_set_string (value, priv->text_unlock);
+      break;
+
+    case PROP_TEXT_NOT_AUTHORIZED:
+      g_value_set_string (value, priv->text_not_authorized);
+      break;
+
+    case PROP_TOOLTIP_LOCK:
+      g_value_set_string (value, priv->tooltip_lock);
+      break;
+
+    case PROP_TOOLTIP_UNLOCK:
+      g_value_set_string (value, priv->tooltip_unlock);
+      break;
+
+    case PROP_TOOLTIP_NOT_AUTHORIZED:
+      g_value_set_string (value, priv->tooltip_not_authorized);
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+      break;
+    }
+}
+
+static void
+dt_lock_button_set_property (GObject      *object,
+                             guint         property_id,
+                             const GValue *value,
+                             GParamSpec   *pspec)
+{
+  DtLockButton *button = DT_LOCK_BUTTON (object);
+  DtLockButtonPrivate *priv = button->priv;
+
+  switch (property_id)
+    {
+    case PROP_PERMISSION:
+      priv->permission = g_value_get_object (value);
+      break;
+
+    case PROP_TEXT_LOCK:
+      g_free (priv->text_lock);
+      priv->text_lock = g_value_dup_string (value);
+      break;
+
+    case PROP_TEXT_UNLOCK:
+      g_free (priv->text_unlock);
+      priv->text_unlock = g_value_dup_string (value);
+      break;
+
+    case PROP_TEXT_NOT_AUTHORIZED:
+      g_free (priv->text_not_authorized);
+      priv->text_not_authorized = g_value_dup_string (value);
+      break;
+
+    case PROP_TOOLTIP_LOCK:
+      g_free (priv->tooltip_lock);
+      priv->tooltip_lock = g_value_dup_string (value);
+      break;
+
+    case PROP_TOOLTIP_UNLOCK:
+      g_free (priv->tooltip_unlock);
+      priv->tooltip_unlock = g_value_dup_string (value);
+      break;
+
+    case PROP_TOOLTIP_NOT_AUTHORIZED:
+      g_free (priv->tooltip_not_authorized);
+      priv->tooltip_not_authorized = g_value_dup_string (value);
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+      break;
+    }
+
+  if (priv->constructed)
+    update_state (button);
+}
+
+static void
+dt_lock_button_init (DtLockButton *button)
+{
+  button->priv = G_TYPE_INSTANCE_GET_PRIVATE (button,
+                                              DT_TYPE_LOCK_BUTTON,
+                                              DtLockButtonPrivate);
+}
+
+static void
+dt_lock_button_constructed (GObject *object)
+{
+  DtLockButton *button = DT_LOCK_BUTTON (object);
+  DtLockButtonPrivate *priv = button->priv;
+
+  priv->constructed = TRUE;
+
+  g_signal_connect (priv->permission, "notify",
+                    G_CALLBACK (on_permission_changed), button);
+
+  priv->box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
+  gtk_container_add (GTK_CONTAINER (button), priv->box);
+
+  priv->eventbox = gtk_event_box_new ();
+  gtk_event_box_set_visible_window (GTK_EVENT_BOX (priv->eventbox), FALSE);
+  gtk_container_add (GTK_CONTAINER (priv->box), priv->eventbox);
+  gtk_widget_show (priv->eventbox);
+
+  priv->image = gtk_image_new (); /* image is set in update_state() */
+  gtk_container_add (GTK_CONTAINER (priv->eventbox), priv->image);
+  gtk_widget_show (priv->image);
+
+  priv->notebook = gtk_notebook_new ();
+  gtk_notebook_set_show_tabs (GTK_NOTEBOOK (priv->notebook), FALSE);
+  gtk_notebook_set_show_border (GTK_NOTEBOOK (priv->notebook), FALSE);
+  gtk_widget_show (priv->notebook);
+
+  priv->button = gtk_button_new ();
+  gtk_container_add (GTK_CONTAINER (priv->button), priv->notebook);
+  gtk_widget_show (priv->button);
+
+  priv->label_lock = gtk_label_new (""); /* text is set in update_state */
+  gtk_notebook_append_page (GTK_NOTEBOOK (priv->notebook), priv->label_lock, NULL);
+  gtk_widget_show (priv->label_lock);
+
+  priv->label_unlock = gtk_label_new ("");
+  gtk_notebook_append_page (GTK_NOTEBOOK (priv->notebook), priv->label_unlock, NULL);
+  gtk_widget_show (priv->label_unlock);
+
+  priv->label_not_authorized = gtk_label_new ("");
+  gtk_notebook_append_page (GTK_NOTEBOOK (priv->notebook), priv->label_not_authorized, NULL);
+  gtk_widget_show (priv->label_not_authorized);
+
+  gtk_box_pack_start (GTK_BOX (priv->box), priv->button, FALSE, FALSE, 0);
+  gtk_widget_show (priv->button);
+
+  g_signal_connect (priv->eventbox, "button-press-event",
+                    G_CALLBACK (on_button_press), button);
+  g_signal_connect (priv->button, "clicked",
+                    G_CALLBACK (on_clicked), button);
+
+  gtk_widget_set_no_show_all (priv->box, TRUE);
+
+  update_state (button);
+
+  if (G_OBJECT_CLASS (dt_lock_button_parent_class)->constructed != NULL)
+    G_OBJECT_CLASS (dt_lock_button_parent_class)->constructed (object);
+}
+
+static void
+dt_lock_button_get_preferred_width (GtkWidget *widget,
+                                    gint      *minimum,
+                                    gint      *natural)
+{
+  DtLockButtonPrivate *priv = DT_LOCK_BUTTON (widget)->priv;
+
+  gtk_widget_get_preferred_width (priv->box, minimum, natural);
+}
+
+static void
+dt_lock_button_get_preferred_height (GtkWidget *widget,
+                                     gint      *minimum,
+                                     gint      *natural)
+{
+  DtLockButtonPrivate *priv = DT_LOCK_BUTTON (widget)->priv;
+
+  gtk_widget_get_preferred_height (priv->box, minimum, natural);
+}
+
+static void
+dt_lock_button_size_allocate (GtkWidget     *widget,
+                              GtkAllocation *allocation)
+{
+  DtLockButtonPrivate *priv = DT_LOCK_BUTTON (widget)->priv;
+  GtkRequisition requisition;
+  GtkAllocation child_allocation;
+
+  gtk_widget_set_allocation (widget, allocation);
+  gtk_widget_get_preferred_size (priv->box, &requisition, NULL);
+  child_allocation.x = allocation->x;
+  child_allocation.y = allocation->y;
+  child_allocation.width = requisition.width;
+  child_allocation.height = requisition.height;
+  gtk_widget_size_allocate (priv->box, &child_allocation);
+}
+
+static void
+dt_lock_button_class_init (DtLockButtonClass *klass)
+{
+  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+  gobject_class->finalize     = dt_lock_button_finalize;
+  gobject_class->get_property = dt_lock_button_get_property;
+  gobject_class->set_property = dt_lock_button_set_property;
+  gobject_class->constructed  = dt_lock_button_constructed;
+
+  widget_class->get_preferred_width = dt_lock_button_get_preferred_width;
+  widget_class->get_preferred_height = dt_lock_button_get_preferred_height;
+  widget_class->size_allocate = dt_lock_button_size_allocate;
+
+  g_type_class_add_private (klass, sizeof (DtLockButtonPrivate));
+
+  g_object_class_install_property (gobject_class, PROP_PERMISSION,
+    g_param_spec_object ("permission",
+                         P_("Permission"),
+                         P_("The GPermission object controlling this button"),
+                         G_TYPE_PERMISSION,
+                         G_PARAM_READWRITE |
+                         G_PARAM_CONSTRUCT_ONLY |
+                         G_PARAM_STATIC_STRINGS));
+
+  g_object_class_install_property (gobject_class, PROP_TEXT_LOCK,
+    g_param_spec_string ("text-lock",
+                         P_("Lock Text"),
+                         P_("The text to display when prompting the user to lock"),
+                         _("Lock"),
+                         G_PARAM_READWRITE |
+                         G_PARAM_CONSTRUCT |
+                         G_PARAM_STATIC_STRINGS));
+
+  g_object_class_install_property (gobject_class, PROP_TEXT_UNLOCK,
+    g_param_spec_string ("text-unlock",
+                         P_("Unlock Text"),
+                         P_("The text to display when prompting the user to unlock"),
+                         _("Unlock"),
+                         G_PARAM_READWRITE |
+                         G_PARAM_CONSTRUCT |
+                         G_PARAM_STATIC_STRINGS));
+
+  g_object_class_install_property (gobject_class, PROP_TEXT_NOT_AUTHORIZED,
+    g_param_spec_string ("text-not-authorized",
+                         P_("Not Authorized Text"),
+                         P_("The text to display when prompting the user cannot obtain authorization"),
+                         _("Locked"),
+                         G_PARAM_READWRITE |
+                         G_PARAM_CONSTRUCT |
+                         G_PARAM_STATIC_STRINGS));
+
+  g_object_class_install_property (gobject_class, PROP_TOOLTIP_LOCK,
+    g_param_spec_string ("tooltip-lock",
+                         P_("Lock Tooltip"),
+                         P_("The tooltip to display when prompting the user to lock"),
+                         _("Dialog is unlocked.\nClick to prevent further changes"),
+                         G_PARAM_READWRITE |
+                         G_PARAM_CONSTRUCT |
+                         G_PARAM_STATIC_STRINGS));
+
+  g_object_class_install_property (gobject_class, PROP_TOOLTIP_UNLOCK,
+    g_param_spec_string ("tooltip-unlock",
+                         P_("Unlock Tooltip"),
+                         P_("The tooltip to display when prompting the user to unlock"),
+                         _("Dialog is locked.\nClick to make changes"),
+                         G_PARAM_READWRITE |
+                         G_PARAM_CONSTRUCT |
+                         G_PARAM_STATIC_STRINGS));
+
+  g_object_class_install_property (gobject_class, PROP_TOOLTIP_NOT_AUTHORIZED,
+    g_param_spec_string ("tooltip-not-authorized",
+                         P_("Not Authorized Tooltip"),
+                         P_("The tooltip to display when prompting the user cannot obtain authorization"),
+                         _("System policy prevents changes.\nContact your system administrator"),
+                         G_PARAM_READWRITE |
+                         G_PARAM_CONSTRUCT |
+                         G_PARAM_STATIC_STRINGS));
+}
+
+/**
+ * dt_lock_button_new:
+ * @permission: a #GPermission
+ *
+ * Creates a new lock button which reflects the @permission.
+ *
+ * Returns: a new #DtLockButton
+ *
+ * Since: 3.0
+ */
+GtkWidget *
+dt_lock_button_new (GPermission *permission)
+{
+  g_return_val_if_fail (permission != NULL, NULL);
+
+  return GTK_WIDGET (g_object_new (DT_TYPE_LOCK_BUTTON,
+                                   "permission", permission,
+                                   NULL));
+}
+
+static void
+update_state (DtLockButton *button)
+{
+  DtLockButtonPrivate *priv = button->priv;
+  gint page;
+  const gchar *tooltip;
+  gboolean sensitive;
+  gboolean visible;
+  GIcon *icon;
+
+  visible = TRUE;
+  sensitive = TRUE;
+
+  gtk_label_set_text (GTK_LABEL (priv->label_lock), priv->text_lock);
+  gtk_label_set_text (GTK_LABEL (priv->label_unlock), priv->text_unlock);
+  gtk_label_set_text (GTK_LABEL (priv->label_not_authorized), priv->text_not_authorized);
+
+  if (g_permission_get_allowed (priv->permission))
+    {
+      if (g_permission_get_can_release (priv->permission))
+        {
+          page = 0;
+          tooltip = priv->tooltip_lock;
+          sensitive = TRUE;
+        }
+      else
+        {
+          page = 0;
+          tooltip = "";
+          visible = FALSE;
+        }
+    }
+  else
+    {
+      if (g_permission_get_can_acquire (priv->permission))
+        {
+          page = 1;
+          tooltip = button->priv->tooltip_unlock;
+          sensitive = TRUE;
+        }
+      else
+        {
+          page = 2;
+          tooltip = button->priv->tooltip_not_authorized;
+          sensitive = FALSE;
+        }
+    }
+
+  if (g_permission_get_allowed (priv->permission))
+    {
+      gchar *names[3];
+
+      names[0] = "changes-allow-symbolic";
+      names[1] = "changes-allow";
+      names[2] = NULL;
+      icon = g_themed_icon_new_from_names (names, -1);
+    }
+  else
+    {
+      gchar *names[3];
+
+      names[0] = "changes-prevent-symbolic";
+      names[1] = "changes-prevent";
+      names[2] = NULL;
+      icon = g_themed_icon_new_from_names (names, -1);
+    }
+
+  gtk_image_set_from_gicon (GTK_IMAGE (priv->image), icon, GTK_ICON_SIZE_BUTTON);
+  g_object_unref (icon);
+
+  gtk_notebook_set_current_page (GTK_NOTEBOOK (priv->notebook), page);
+  gtk_widget_set_tooltip_markup (priv->box, tooltip);
+
+  gtk_widget_set_sensitive (priv->box, sensitive);
+
+  if (visible)
+    gtk_widget_show (priv->box);
+  else
+    gtk_widget_hide (priv->box);
+}
+
+static void
+on_permission_changed (GPermission *permission,
+                       GParamSpec  *pspec,
+                       gpointer     user_data)
+{
+  DtLockButton *button = DT_LOCK_BUTTON (user_data);
+
+  update_state (button);
+}
+
+static void
+acquire_cb (GObject      *source,
+            GAsyncResult *result,
+            gpointer      user_data)
+{
+  DtLockButton *button = DT_LOCK_BUTTON (user_data);
+  DtLockButtonPrivate *priv = button->priv;
+  GError *error;
+
+  error = NULL;
+  g_permission_acquire_finish (priv->permission, result, &error);
+
+  if (error)
+    {
+      g_warning ("Error acquiring permission: %s", error->message);
+      g_error_free (error);
+    }
+
+  g_object_unref (priv->cancellable);
+  priv->cancellable = NULL;
+
+  update_state (button);
+}
+
+static void
+release_cb (GObject      *source,
+            GAsyncResult *result,
+            gpointer      user_data)
+{
+  DtLockButton *button = DT_LOCK_BUTTON (user_data);
+  DtLockButtonPrivate *priv = button->priv;
+  GError *error;
+
+  error = NULL;
+  g_permission_release_finish (priv->permission, result, &error);
+
+  if (error)
+    {
+      g_warning ("Error releasing permission: %s", error->message);
+      g_error_free (error);
+    }
+
+  g_object_unref (priv->cancellable);
+  priv->cancellable = NULL;
+
+  update_state (button);
+}
+
+static void
+handle_click (DtLockButton *button)
+{
+  DtLockButtonPrivate *priv = button->priv;
+
+  if (!g_permission_get_allowed (priv->permission) &&
+       g_permission_get_can_acquire (priv->permission))
+    {
+      /* if we already have a pending interactive check, then do nothing */
+      if (priv->cancellable != NULL)
+        goto out;
+
+      priv->cancellable = g_cancellable_new ();
+
+      g_permission_acquire_async (priv->permission,
+                                  priv->cancellable,
+                                  acquire_cb,
+                                  button);
+    }
+  else if (g_permission_get_allowed (priv->permission) &&
+           g_permission_get_can_release (priv->permission))
+    {
+      /* if we already have a pending interactive check, then do nothing */
+      if (priv->cancellable != NULL)
+        goto out;
+
+      priv->cancellable = g_cancellable_new ();
+
+      g_permission_release_async (priv->permission,
+                                  priv->cancellable,
+                                  release_cb,
+                                  button);
+    }
+
+ out: ;
+}
+
+static void
+on_clicked (GtkButton *_button,
+            gpointer   user_data)
+
+{
+  handle_click (DT_LOCK_BUTTON (user_data));
+}
+
+static void
+on_button_press (GtkWidget      *widget,
+                 GdkEventButton *event,
+                 gpointer        user_data)
+{
+  handle_click (DT_LOCK_BUTTON (user_data));
+}
+
+/**
+ * dt_lock_button_get_permission:
+ * @button: a #DtLockButton
+ *
+ * Obtains the #GPermission object that controls @button.
+ *
+ * Returns: the #GPermission of @button
+ *
+ * Since: 3.0
+ */
+GPermission *
+dt_lock_button_get_permission (DtLockButton *button)
+{
+  g_return_val_if_fail (DT_IS_LOCK_BUTTON (button), NULL);
+
+  return button->priv->permission;
+}
+
diff --git a/libmap/dt-lockbutton.h b/libmap/dt-lockbutton.h
new file mode 100644
index 0000000..adab0a7
--- /dev/null
+++ b/libmap/dt-lockbutton.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2010 Red Hat, Inc.
+ * Author: Matthias Clasen
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __DT_LOCK_BUTTON_H__
+#define __DT_LOCK_BUTTON_H__
+
+#include 
+#include 
+
+G_BEGIN_DECLS
+
+#define DT_TYPE_LOCK_BUTTON         (dt_lock_button_get_type ())
+#define DT_LOCK_BUTTON(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), DT_TYPE_LOCK_BUTTON, DtLockButton))
+#define DT_LOCK_BUTTON_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST ((k), DT_LOCK_BUTTON,  DtLockButtonClass))
+#define DT_IS_LOCK_BUTTON(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), DT_TYPE_LOCK_BUTTON))
+#define DT_IS_LOCK_BUTTON_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), DT_TYPE_LOCK_BUTTON))
+#define DT_LOCK_BUTTON_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), DT_TYPE_LOCK_BUTTON, DtLockButtonClass))
+
+typedef struct _DtLockButton        DtLockButton;
+typedef struct _DtLockButtonClass   DtLockButtonClass;
+typedef struct _DtLockButtonPrivate DtLockButtonPrivate;
+
+struct _DtLockButton
+{
+  GtkBin parent;
+
+  DtLockButtonPrivate *priv;
+};
+
+struct _DtLockButtonClass
+{
+  GtkBinClass parent_class;
+
+  void (*reserved0) (void);
+  void (*reserved1) (void);
+  void (*reserved2) (void);
+  void (*reserved3) (void);
+  void (*reserved4) (void);
+  void (*reserved5) (void);
+  void (*reserved6) (void);
+  void (*reserved7) (void);
+};
+
+GType        dt_lock_button_get_type       (void) G_GNUC_CONST;
+GtkWidget   *dt_lock_button_new            (GPermission   *permission);
+GPermission *dt_lock_button_get_permission (DtLockButton *button);
+
+
+G_END_DECLS
+
+#endif  /* __DT_LOCK_BUTTON_H__ */
diff --git a/libmap/set-timezone.c b/libmap/set-timezone.c
new file mode 100644
index 0000000..5aafced
--- /dev/null
+++ b/libmap/set-timezone.c
@@ -0,0 +1,481 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2007 David Zeuthen 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#  include "config.h"
+#endif
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+
+#include "set-timezone.h"
+
+
+static DBusGConnection *
+get_system_bus (GError **err)
+{
+        GError          *error;
+        static DBusGConnection *bus = NULL;
+
+	if (bus == NULL) {
+        	error = NULL;
+        	bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
+        	if (bus == NULL) {
+			g_propagate_error (err, error);
+		}
+        }
+
+        return bus;
+}
+
+#define CACHE_VALIDITY_SEC 2
+
+typedef  void (*CanDoFunc) (gint value);
+
+static void
+notify_can_do (DBusGProxy     *proxy,
+	       DBusGProxyCall *call,
+	       void           *user_data)
+{
+	CanDoFunc callback = user_data;
+	GError *error = NULL;
+	gint value;
+
+	if (dbus_g_proxy_end_call (proxy, call,
+				   &error,
+				   G_TYPE_INT, &value,
+				   G_TYPE_INVALID)) {
+		callback (value);
+	}
+}
+
+static void
+refresh_can_do (const gchar *action, CanDoFunc callback)
+{
+        DBusGConnection *bus;
+        DBusGProxy      *proxy;
+
+        bus = get_system_bus (NULL);
+        if (bus == NULL)
+                return;
+
+	proxy = dbus_g_proxy_new_for_name (bus,
+					   "org.gnome.SettingsDaemon.DateTimeMechanism",
+					   "/",
+					   "org.gnome.SettingsDaemon.DateTimeMechanism");
+
+	dbus_g_proxy_begin_call_with_timeout (proxy,
+					      action,
+					      notify_can_do,
+					      callback, NULL,
+					      INT_MAX,
+					      G_TYPE_INVALID);
+}
+
+static gint   settimezone_cache = 0;
+static time_t settimezone_stamp = 0;
+
+static void
+update_can_settimezone (gint res)
+{
+	settimezone_cache = res;
+	time (&settimezone_stamp);
+}
+
+gint
+can_set_system_timezone (void)
+{
+	time_t          now;
+
+	time (&now);
+	if (ABS (now - settimezone_stamp) > CACHE_VALIDITY_SEC) {
+		refresh_can_do ("CanSetTimezone", update_can_settimezone);
+		settimezone_stamp = now;
+	}
+
+	return settimezone_cache;
+}
+
+static gint   settime_cache = 0;
+static time_t settime_stamp = 0;
+
+static void
+update_can_settime (gint res)
+{
+	settime_cache = res;
+	time (&settime_stamp);
+}
+
+gint
+can_set_system_time (void)
+{
+	time_t now;
+
+	time (&now);
+	if (ABS (now - settime_stamp) > CACHE_VALIDITY_SEC) {
+		refresh_can_do ("CanSetTime", update_can_settime);
+		settime_stamp = now;
+	}
+
+	return settime_cache;
+}
+
+static gint   usingntp_cache = 0;
+static time_t usingntp_stamp = 0;
+
+static void
+update_can_usingntp (gint res)
+{
+	usingntp_cache = res;
+	time (&usingntp_stamp);
+}
+
+gint
+can_set_using_ntp (void)
+{
+	time_t now;
+
+	time (&now);
+	if (ABS (now - usingntp_stamp) > CACHE_VALIDITY_SEC) {
+		refresh_can_do ("CanSetUsingNtp", update_can_usingntp);
+		settime_stamp = now;
+	}
+
+	return usingntp_cache;
+}
+
+typedef struct {
+	gint ref_count;
+        gchar *call;
+	gint64 time;
+	gchar *tz;
+	gboolean using_ntp;
+	GFunc callback;
+	gpointer data;
+	GDestroyNotify notify;
+} SetTimeCallbackData;
+
+static void
+free_data (gpointer d)
+{
+	SetTimeCallbackData *data = d;
+
+	data->ref_count--;
+	if (data->ref_count == 0) {
+		if (data->notify)
+			data->notify (data->data);
+		g_free (data->tz);
+		g_free (data);
+	}
+}
+
+static void
+set_time_notify (DBusGProxy     *proxy,
+		 DBusGProxyCall *call,
+		 void           *user_data)
+{
+	SetTimeCallbackData *data = user_data;
+	GError *error = NULL;
+
+	if (dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INVALID)) {
+		if (data->callback)
+			data->callback (data->data, NULL);
+	}
+	else {
+		if (error->domain == DBUS_GERROR &&
+		    error->code == DBUS_GERROR_NO_REPLY) {
+			/* these errors happen because dbus doesn't
+			 * use monotonic clocks
+			 */	
+			g_warning ("ignoring no-reply error when setting time");
+			g_error_free (error);
+			if (data->callback)
+				data->callback (data->data, NULL);
+		}
+		else {
+			if (data->callback)
+				data->callback (data->data, error);
+			else
+				g_error_free (error);
+		}		
+	}
+}
+
+static void
+set_time_async (SetTimeCallbackData *data)
+{
+        DBusGConnection *bus;
+        DBusGProxy      *proxy;
+	GError          *err = NULL;
+
+        bus = get_system_bus (&err);
+        if (bus == NULL) {
+		if (err) {
+			if (data->callback)
+				data->callback (data->data, err);
+			g_clear_error (&err);
+		}
+		return;
+	}
+
+	proxy = dbus_g_proxy_new_for_name (bus,
+					   "org.gnome.SettingsDaemon.DateTimeMechanism",
+					   "/",
+					   "org.gnome.SettingsDaemon.DateTimeMechanism");
+
+	data->ref_count++;
+	if (strcmp (data->call, "SetTime") == 0)
+		dbus_g_proxy_begin_call_with_timeout (proxy,
+						      "SetTime",
+						      set_time_notify,
+						      data, free_data,
+						      INT_MAX,
+						      /* parameters: */
+						      G_TYPE_INT64, data->time,
+						      G_TYPE_INVALID,
+						      /* return values: */
+						      G_TYPE_INVALID);
+	else if (strcmp (data->call, "SetTimezone") == 0)
+		dbus_g_proxy_begin_call_with_timeout (proxy,
+						      "SetTimezone",
+						      set_time_notify,
+						      data, free_data,
+						      INT_MAX,
+						      /* parameters: */
+						      G_TYPE_STRING, data->tz,
+						      G_TYPE_INVALID,
+						      /* return values: */
+						      G_TYPE_INVALID);
+	else if (strcmp (data->call, "SetUsingNtp") == 0)
+		dbus_g_proxy_begin_call_with_timeout (proxy,
+						      "SetUsingNtp",
+						      set_time_notify,
+						      data, free_data,
+						      INT_MAX,
+						      /* parameters: */
+						      G_TYPE_BOOLEAN, data->using_ntp,
+						      G_TYPE_INVALID,
+						      /* return values: */
+						      G_TYPE_INVALID);
+}
+
+void
+set_system_time_async (gint64         time,
+		       GFunc          callback,
+		       gpointer       d,
+		       GDestroyNotify notify)
+{
+	SetTimeCallbackData *data;
+
+	if (time == -1)
+		return;
+
+	data = g_new0 (SetTimeCallbackData, 1);
+	data->ref_count = 1;
+	data->call = "SetTime";
+	data->time = time;
+	data->tz = NULL;
+	data->callback = callback;
+	data->data = d;
+	data->notify = notify;
+
+	set_time_async (data);
+	free_data (data);
+}
+
+void
+set_system_timezone_async (const gchar    *tz,
+			   GFunc           callback,
+			   gpointer        d,
+			   GDestroyNotify  notify)
+{
+	SetTimeCallbackData *data;
+
+	g_return_if_fail (tz != NULL);
+
+	data = g_new0 (SetTimeCallbackData, 1);
+	data->ref_count = 1;
+	data->call = "SetTimezone";
+	data->time = -1;
+	data->tz = g_strdup (tz);
+	data->callback = callback;
+	data->data = d;
+	data->notify = notify;
+
+	set_time_async (data);
+	free_data (data);
+}
+
+/* get timezone */
+
+typedef struct
+{
+  GetTimezoneFunc callback;
+  GDestroyNotify notify;
+
+  gpointer data;
+
+} GetTimezoneData;
+
+static void
+get_timezone_destroy_notify (GetTimezoneData *data)
+{
+	if (data->notify && data->data)
+		data->notify (data);
+
+	g_free (data);
+}
+
+static void
+get_timezone_notify (DBusGProxy     *proxy,
+		     DBusGProxyCall *call,
+		     void           *user_data)
+{
+	GError *error = NULL;
+	gboolean retval;
+	gchar *string = NULL;
+	GetTimezoneData *data = user_data;
+
+	retval = dbus_g_proxy_end_call (proxy, call, &error,
+					G_TYPE_STRING, &string,
+					G_TYPE_INVALID);
+
+	if (data->callback) {
+		if (!retval) {
+			data->callback (data->data, NULL, error);
+			g_error_free (error);
+		}
+		else {
+			data->callback (data->data, string, NULL);
+			g_free (string);
+		}
+	}
+}
+
+void
+get_system_timezone_async (GetTimezoneFunc callback,
+			   gpointer        user_data,
+			   GDestroyNotify  notify)
+{
+	DBusGConnection *bus;
+	DBusGProxy      *proxy;
+	GetTimezoneData *data;
+	GError          *error = NULL;
+
+	bus = get_system_bus (&error);
+	if (bus == NULL) {
+		if (error) {
+			if (callback)
+				callback (user_data, NULL, error);
+			g_clear_error (&error);
+		}
+		return;
+
+        }
+
+	data = g_new0 (GetTimezoneData, 1);
+	data->data = user_data;
+	data->notify = notify;
+	data->callback = callback;
+
+	proxy = dbus_g_proxy_new_for_name (bus,
+					   "org.gnome.SettingsDaemon.DateTimeMechanism",
+					   "/",
+					   "org.gnome.SettingsDaemon.DateTimeMechanism");
+
+	dbus_g_proxy_begin_call (proxy,
+				 "GetTimezone",
+				 get_timezone_notify,
+				 data,
+				 (GDestroyNotify) get_timezone_destroy_notify,
+				 /* parameters: */
+				 G_TYPE_INVALID,
+				 /* return values: */
+				 G_TYPE_STRING,
+				 G_TYPE_INVALID);
+
+}
+
+gboolean
+get_using_ntp (void)
+{
+	static gboolean can_use_cache = FALSE;
+	static gboolean is_using_cache = FALSE;
+	static time_t   last_refreshed = 0;
+	time_t          now;
+        DBusGConnection *bus;
+        DBusGProxy      *proxy;
+
+	time (&now);
+	if (ABS (now - last_refreshed) > CACHE_VALIDITY_SEC) {
+		gboolean cu, iu;
+		bus = get_system_bus (NULL);
+		if (bus == NULL)
+			return FALSE;
+
+		proxy = dbus_g_proxy_new_for_name (bus,
+						   "org.gnome.SettingsDaemon.DateTimeMechanism",
+						   "/",
+						   "org.gnome.SettingsDaemon.DateTimeMechanism");
+
+
+		if (dbus_g_proxy_call (proxy,
+				       "GetUsingNtp",
+				       NULL,
+				       G_TYPE_INVALID,
+				       G_TYPE_BOOLEAN, &cu,
+				       G_TYPE_BOOLEAN, &iu,
+				       G_TYPE_INVALID)) {
+			can_use_cache = cu;
+			is_using_cache = iu;
+			last_refreshed = now;
+		}
+	}
+
+	return is_using_cache;
+}
+
+void
+set_using_ntp_async (gboolean        using_ntp,
+	             GFunc           callback,
+	             gpointer        d,
+	             GDestroyNotify  notify)
+{
+	SetTimeCallbackData *data;
+
+	data = g_new0 (SetTimeCallbackData, 1);
+	data->ref_count = 1;
+	data->call = "SetUsingNtp";
+	data->time = -1;
+	data->using_ntp = using_ntp;
+	data->callback = callback;
+	data->data = d;
+	data->notify = notify;
+
+	set_time_async (data);
+	free_data (data);
+}
diff --git a/libmap/set-timezone.h b/libmap/set-timezone.h
new file mode 100644
index 0000000..5e657e3
--- /dev/null
+++ b/libmap/set-timezone.h
@@ -0,0 +1,57 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2007 David Zeuthen 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifndef __SET_SYSTEM_TIMEZONE_H__
+
+#include 
+
+#include 
+#include 
+
+typedef void (*GetTimezoneFunc) (gpointer     data,
+                                 const gchar *timezone,
+                                 GError      *error);
+void     get_system_timezone_async   (GetTimezoneFunc callback,
+                                      gpointer        data,
+                                      GDestroyNotify  notify);
+
+gint     can_set_system_timezone (void);
+
+gint     can_set_system_time     (void);
+
+gint     can_set_using_ntp       (void);
+
+void     set_system_time_async   (gint64         time,
+                                  GFunc          callback,
+                                  gpointer       data,
+                                  GDestroyNotify notify);
+
+void     set_system_timezone_async   (const gchar    *tz,
+                                      GFunc           callback,
+                                      gpointer        data,
+                                      GDestroyNotify  notify);
+
+gboolean get_using_ntp               (void);
+
+void     set_using_ntp_async         (gboolean        using_ntp,
+                                      GFunc           callback,
+                                      gpointer        data,
+                                      GDestroyNotify  notify);
+#endif
diff --git a/libmap/test-timezone.c b/libmap/test-timezone.c
new file mode 100644
index 0000000..d667c42
--- /dev/null
+++ b/libmap/test-timezone.c
@@ -0,0 +1,55 @@
+#include 
+#include 
+
+#include "tz.h"
+
+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;
+		}
+
+		g_free (filename);
+		g_free (path);
+	}
+	tz_db_free (db);
+	g_free (pixmap_dir);
+
+	return retval;
+}
diff --git a/libmap/tz.c b/libmap/tz.c
new file mode 100644
index 0000000..3e6c8ae
--- /dev/null
+++ b/libmap/tz.c
@@ -0,0 +1,350 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/* Generic timezone utilities.
+ *
+ * Copyright (C) 2000-2001 Ximian, Inc.
+ *
+ * Authors: Hans Petter Jansson 
+ * 
+ * Largely based on Michael Fulbright's work on Anaconda.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "tz.h"
+
+
+/* Forward declarations for private functions */
+
+static float convert_pos (gchar *pos, int digits);
+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);
+
+
+/* ---------------- *
+ * Public interface *
+ * ---------------- */
+TzDB *
+tz_load_db (void)
+{
+	gchar *tz_data_file;
+	TzDB *tz_db;
+	FILE *tzfile;
+	char buf[4096];
+
+	tz_data_file = tz_data_file_get ();
+	if (!tz_data_file) {
+		g_warning ("Could not get the TimeZone data file name");
+		return NULL;
+	}
+	tzfile = fopen (tz_data_file, "r");
+	if (!tzfile) {
+		g_warning ("Could not open *%s*\n", tz_data_file);
+		g_free (tz_data_file);
+		return NULL;
+	}
+
+	tz_db = g_new0 (TzDB, 1);
+	tz_db->locations = g_ptr_array_new ();
+
+	while (fgets (buf, sizeof(buf), tzfile))
+	{
+		gchar **tmpstrarr;
+		gchar *latstr, *lngstr, *p;
+		TzLocation *loc;
+
+		if (*buf == '#') continue;
+
+		g_strchomp(buf);
+		tmpstrarr = g_strsplit(buf,"\t", 6);
+		
+		latstr = g_strdup (tmpstrarr[1]);
+		p = latstr + 1;
+		while (*p != '-' && *p != '+') p++;
+		lngstr = g_strdup (p);
+		*p = '\0';
+		
+		loc = g_new0 (TzLocation, 1);
+		loc->country = g_strdup (tmpstrarr[0]);
+		loc->zone = g_strdup (tmpstrarr[2]);
+		loc->latitude  = convert_pos (latstr, 2);
+		loc->longitude = convert_pos (lngstr, 3);
+		
+#ifdef __sun
+		if (tmpstrarr[3] && *tmpstrarr[3] == '-' && tmpstrarr[4])
+			loc->comment = g_strdup (tmpstrarr[4]);
+
+		if (tmpstrarr[3] && *tmpstrarr[3] != '-' && !islower(loc->zone)) {
+			TzLocation *locgrp;
+
+			/* duplicate entry */
+			locgrp = g_new0 (TzLocation, 1);
+			locgrp->country = g_strdup (tmpstrarr[0]);
+			locgrp->zone = g_strdup (tmpstrarr[3]);
+			locgrp->latitude  = convert_pos (latstr, 2);
+			locgrp->longitude = convert_pos (lngstr, 3);
+			locgrp->comment = (tmpstrarr[4]) ? g_strdup (tmpstrarr[4]) : NULL;
+
+			g_ptr_array_add (tz_db->locations, (gpointer) locgrp);
+		}
+#else
+		loc->comment = (tmpstrarr[3]) ? g_strdup(tmpstrarr[3]) : NULL;
+#endif
+
+		g_ptr_array_add (tz_db->locations, (gpointer) loc);
+
+		g_free (latstr);
+		g_free (lngstr);
+		g_strfreev (tmpstrarr);
+	}
+	
+	fclose (tzfile);
+	
+	/* now sort by country */
+	sort_locations_by_country (tz_db->locations);
+	
+	g_free (tz_data_file);
+	
+	return tz_db;
+}    
+
+static void
+tz_location_free (TzLocation *loc)
+{
+	g_free (loc->country);
+	g_free (loc->zone);
+	g_free (loc->comment);
+
+	g_free (loc);
+}
+
+void
+tz_db_free (TzDB *db)
+{
+	g_ptr_array_foreach (db->locations, (GFunc) tz_location_free, NULL);
+	g_ptr_array_free (db->locations, TRUE);
+	g_free (db);
+}
+
+GPtrArray *
+tz_get_locations (TzDB *db)
+{
+	return db->locations;
+}
+
+
+gchar *
+tz_location_get_country (TzLocation *loc)
+{
+	return loc->country;
+}
+
+
+gchar *
+tz_location_get_zone (TzLocation *loc)
+{
+	return loc->zone;
+}
+
+
+gchar *
+tz_location_get_comment (TzLocation *loc)
+{
+	return loc->comment;
+}
+
+
+void
+tz_location_get_position (TzLocation *loc, double *longitude, double *latitude)
+{
+	*longitude = loc->longitude;
+	*latitude = loc->latitude;
+}
+
+glong
+tz_location_get_utc_offset (TzLocation *loc)
+{
+	TzInfo *tz_info;
+	glong offset;
+
+	tz_info = tz_info_from_location (loc);
+	offset = tz_info->utc_offset;
+	tz_info_free (tz_info);
+	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;
+	
+	g_return_val_if_fail (loc != NULL, NULL);
+	g_return_val_if_fail (loc->zone != NULL, NULL);
+	
+	setenv ("TZ", loc->zone, 1);
+	
+#if 0
+	tzset ();
+#endif
+	tzinfo = g_new0 (TzInfo, 1);
+
+	curtime = time (NULL);
+	curzone = localtime (&curtime);
+
+#ifndef __sun
+	/* Currently this solution doesnt seem to work - I get that */
+	/* America/Phoenix uses daylight savings, which is wrong    */
+	tzinfo->tzname_normal = g_strdup (curzone->tm_zone);
+	if (curzone->tm_isdst) 
+		tzinfo->tzname_daylight =
+			g_strdup (&curzone->tm_zone[curzone->tm_isdst]);
+	else
+		tzinfo->tzname_daylight = NULL;
+
+	tzinfo->utc_offset = curzone->tm_gmtoff;
+#else
+	tzinfo->tzname_normal = NULL;
+	tzinfo->tzname_daylight = NULL;
+	tzinfo->utc_offset = 0;
+#endif
+
+	tzinfo->daylight = curzone->tm_isdst;
+	
+	return tzinfo;
+}
+
+
+void
+tz_info_free (TzInfo *tzinfo)
+{
+	g_return_if_fail (tzinfo != NULL);
+	
+	if (tzinfo->tzname_normal) g_free (tzinfo->tzname_normal);
+	if (tzinfo->tzname_daylight) g_free (tzinfo->tzname_daylight);
+	g_free (tzinfo);
+}
+
+/* ----------------- *
+ * Private functions *
+ * ----------------- */
+
+static gchar *
+tz_data_file_get (void)
+{
+	gchar *file;
+
+	file = g_strdup (TZ_DATA_FILE);
+
+	return file;
+}
+
+static float
+convert_pos (gchar *pos, int digits)
+{
+	gchar whole[10];
+	gchar *fraction;
+	gint i;
+	float t1, t2;
+	
+	if (!pos || strlen(pos) < 4 || digits > 9) return 0.0;
+	
+	for (i = 0; i < digits + 1; i++) whole[i] = pos[i];
+	whole[i] = '\0';
+	fraction = pos + digits + 1;
+
+	t1 = g_strtod (whole, NULL);
+	t2 = g_strtod (fraction, NULL);
+
+	if (t1 >= 0.0) return t1 + t2/pow (10.0, strlen(fraction));
+	else return t1 - t2/pow (10.0, strlen(fraction));
+}
+
+
+#if 0
+
+/* Currently not working */
+static void
+free_tzdata (TzLocation *tz)
+{
+	
+	if (tz->country)
+	  g_free(tz->country);
+	if (tz->zone)
+	  g_free(tz->zone);
+	if (tz->comment)
+	  g_free(tz->comment);
+	
+	g_free(tz);
+}
+#endif
+
+
+static int
+compare_country_names (const void *a, const void *b)
+{
+	const TzLocation *tza = * (TzLocation **) a;
+	const TzLocation *tzb = * (TzLocation **) b;
+	
+	return strcmp (tza->zone, tzb->zone);
+}
+
+
+static void
+sort_locations_by_country (GPtrArray *locations)
+{
+	qsort (locations->pdata, locations->len, sizeof (gpointer),
+	       compare_country_names);
+}
diff --git a/libmap/tz.h b/libmap/tz.h
new file mode 100644
index 0000000..91281a5
--- /dev/null
+++ b/libmap/tz.h
@@ -0,0 +1,86 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/* Generic timezone utilities.
+ *
+ * Copyright (C) 2000-2001 Ximian, Inc.
+ *
+ * Authors: Hans Petter Jansson 
+ * 
+ * Largely based on Michael Fulbright's work on Anaconda.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#ifndef _E_TZ_H
+#define _E_TZ_H
+
+#include 
+
+#ifndef __sun
+#  define TZ_DATA_FILE "/usr/share/zoneinfo/zone.tab"
+#else
+#  define TZ_DATA_FILE "/usr/share/lib/zoneinfo/tab/zone_sun.tab"
+#endif
+
+typedef struct _TzDB TzDB;
+typedef struct _TzLocation TzLocation;
+typedef struct _TzInfo TzInfo;
+
+
+struct _TzDB
+{
+	GPtrArray *locations;
+};
+
+struct _TzLocation
+{
+	gchar *country;
+	gdouble latitude;
+	gdouble longitude;
+	gchar *zone;
+	gchar *comment;
+
+	gdouble dist; /* distance to clicked point for comparison */
+};
+
+/* see the glibc info page information on time zone information */
+/*  tzname_normal    is the default name for the timezone */
+/*  tzname_daylight  is the name of the zone when in daylight savings */
+/*  utc_offset       is offset in seconds from utc */
+/*  daylight         if non-zero then location obeys daylight savings */
+
+struct _TzInfo
+{
+	gchar *tzname_normal;
+	gchar *tzname_daylight;
+	glong utc_offset;
+	gint daylight;
+};
+
+
+TzDB      *tz_load_db                 (void);
+void       tz_db_free                 (TzDB *db);
+GPtrArray *tz_get_locations           (TzDB *db);
+void       tz_location_get_position   (TzLocation *loc,
+				       double *longitude, double *latitude);
+char      *tz_location_get_country    (TzLocation *loc);
+gchar     *tz_location_get_zone       (TzLocation *loc);
+gchar     *tz_location_get_comment    (TzLocation *loc);
+glong      tz_location_get_utc_offset (TzLocation *loc);
+gint       tz_location_set_locally    (TzLocation *loc);
+TzInfo    *tz_info_from_location      (TzLocation *loc);
+void       tz_info_free               (TzInfo *tz_info);
+
+#endif
diff --git a/src/Makefile.am b/src/Makefile.am
index 94d179d..4c94f7c 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -49,9 +49,11 @@ indicator_datetime_preferences_SOURCES =\
 indicator_datetime_preferences_CFLAGS = \
 	-Wall \
 	-Werror \
+	-I$(top_srcdir)/libmap \
 	$(PREF_CFLAGS) \
 	-DPKGDATADIR="\"$(pkgdatadir)\""
 indicator_datetime_preferences_LDADD = \
+	 $(top_builddir)/libmap/libmap.la \
 	$(PREF_LIBS)
 
 gen-%.xml.c: %.xml
diff --git a/src/datetime-prefs.c b/src/datetime-prefs.c
index 97b106d..ee4b26a 100644
--- a/src/datetime-prefs.c
+++ b/src/datetime-prefs.c
@@ -36,10 +36,13 @@ with this program.  If not, see .
 #include "settings-shared.h"
 #include "utils.h"
 #include "datetime-prefs-locations.h"
+#include "cc-timezone-map.h"
 
 #define DATETIME_DIALOG_UI_FILE PKGDATADIR "/datetime-dialog.ui"
 
 GDBusProxy * proxy = NULL;
+GtkWidget * autoRadio = NULL;
+CcTimezoneMap * tzmap = NULL;
 
 /* Turns the boolean property into a string gsettings */
 static GVariant *
@@ -120,7 +123,8 @@ add_polkit_dependency (GtkWidget * parent, GtkWidget * dependent)
   polkit_dependency_cb (parent, NULL, dependent);
 }
 
-void dbus_set_answered (GObject *object, GAsyncResult *res, gpointer command)
+static void
+dbus_set_answered (GObject *object, GAsyncResult *res, gpointer command)
 {
   GError * error = NULL;
   GVariant * answers = g_dbus_proxy_call_finish (proxy, res, &error);
@@ -135,15 +139,16 @@ void dbus_set_answered (GObject *object, GAsyncResult *res, gpointer command)
 }
 
 static void
-toggle_ntp (GtkWidget * autoRadio, GParamSpec * pspec, gpointer user_data)
+toggle_ntp (GtkWidget * radio, GParamSpec * pspec, gpointer user_data)
 {
-  gboolean active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (autoRadio));
+  gboolean active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (radio));
 
   g_dbus_proxy_call (proxy, "SetUsingNtp", g_variant_new ("(b)", active),
                      G_DBUS_CALL_FLAGS_NONE, -1, NULL, dbus_set_answered, "using_ntp");
 }
 
-void ntp_query_answered (GObject *object, GAsyncResult *res, gpointer autoRadio)
+static void
+ntp_query_answered (GObject *object, GAsyncResult *res, gpointer user_data)
 {
   GError * error = NULL;
   GVariant * answers = g_dbus_proxy_call_finish (proxy, res, &error);
@@ -160,12 +165,44 @@ void ntp_query_answered (GObject *object, GAsyncResult *res, gpointer autoRadio)
   gtk_widget_set_sensitive (GTK_WIDGET (autoRadio), can_use_ntp);
   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (autoRadio), is_using_ntp);
 
-  g_signal_connect (autoRadio, "notify::active", G_CALLBACK(toggle_ntp), NULL);
+  g_signal_connect (autoRadio, "notify::active", G_CALLBACK (toggle_ntp), NULL);
+
+  g_variant_unref (answers);
+}
+
+static void
+tz_changed (CcTimezoneMap * map, TzLocation * location)
+{
+  if (location == NULL)
+    return;
+
+  g_dbus_proxy_call (proxy, "SetTimezone", g_variant_new ("(s)", location->zone),
+                     G_DBUS_CALL_FLAGS_NONE, -1, NULL, dbus_set_answered, "timezone");
+}
+
+static void
+tz_query_answered (GObject *object, GAsyncResult *res, gpointer user_data)
+{
+  GError * error = NULL;
+  GVariant * answers = g_dbus_proxy_call_finish (proxy, res, &error);
+
+  if (error != NULL) {
+    g_warning("Could not query DBus proxy for SettingsDaemon: %s", error->message);
+    g_error_free(error);
+    return;
+  }
+
+  const gchar * timezone;
+  g_variant_get (answers, "(&s)", &timezone);
+
+  cc_timezone_map_set_timezone (tzmap, timezone);
+
+  g_signal_connect (tzmap, "location-changed", G_CALLBACK (tz_changed), NULL);
 
   g_variant_unref (answers);
 }
 
-void proxy_ready (GObject *object, GAsyncResult *res, gpointer autoRadio)
+void proxy_ready (GObject *object, GAsyncResult *res, gpointer user_data)
 {
   GError * error = NULL;
 
@@ -180,6 +217,8 @@ void proxy_ready (GObject *object, GAsyncResult *res, gpointer autoRadio)
   /* And now, do initial proxy configuration */
   g_dbus_proxy_call (proxy, "GetUsingNtp", NULL, G_DBUS_CALL_FLAGS_NONE, -1,
                      NULL, ntp_query_answered, autoRadio);
+  g_dbus_proxy_call (proxy, "GetTimezone", NULL, G_DBUS_CALL_FLAGS_NONE, -1,
+                     NULL, tz_query_answered, NULL);
 }
 
 static int
@@ -358,6 +397,10 @@ create_dialog (void)
   polkit_lock_button_set_lock_text (POLKIT_LOCK_BUTTON (polkit_button), _("Lock to prevent further changes"));
   gtk_box_pack_start (GTK_BOX (WIG ("timeDateBox")), polkit_button, FALSE, TRUE, 0);
 
+  /* Add map */
+  tzmap = cc_timezone_map_new ();
+  gtk_container_add (GTK_CONTAINER (WIG ("mapBox")), GTK_WIDGET (tzmap));
+
   /* Set up settings bindings */
   g_settings_bind (conf, SETTINGS_SHOW_CLOCK_S, WIG ("showClockCheck"),
                    "active", G_SETTINGS_BIND_DEFAULT);
@@ -404,6 +447,7 @@ create_dialog (void)
   setup_time_spinner (WIG ("dateSpinner"), WIG ("timeSpinner"), FALSE);
 
   GtkWidget * dlg = WIG ("timeDateDialog");
+  autoRadio = WIG ("automaticTimeRadio");
 
   g_signal_connect (WIG ("locationsButton"), "clicked", G_CALLBACK (show_locations), dlg);
 
@@ -412,7 +456,7 @@ create_dialog (void)
                             "org.gnome.SettingsDaemon.DateTimeMechanism",
                             "/",                            
                             "org.gnome.SettingsDaemon.DateTimeMechanism",
-                            NULL, proxy_ready, WIG ("automaticTimeRadio"));
+                            NULL, proxy_ready, NULL);
 
 #undef WIG
 
-- 
cgit v1.2.3


From 9265799709d7c1090ffef4082f4485c0d9a5c363 Mon Sep 17 00:00:00 2001
From: Michael Terry 
Date: Tue, 22 Feb 2011 11:22:17 -0500
Subject: drop some unused code from libmap

---
 libmap/datetime-module.c |  46 ----
 libmap/dt-lockbutton.c   | 627 -----------------------------------------------
 libmap/dt-lockbutton.h   |  68 -----
 libmap/set-timezone.c    | 481 ------------------------------------
 libmap/set-timezone.h    |  57 -----
 5 files changed, 1279 deletions(-)
 delete mode 100644 libmap/datetime-module.c
 delete mode 100644 libmap/dt-lockbutton.c
 delete mode 100644 libmap/dt-lockbutton.h
 delete mode 100644 libmap/set-timezone.c
 delete mode 100644 libmap/set-timezone.h

diff --git a/libmap/datetime-module.c b/libmap/datetime-module.c
deleted file mode 100644
index 8217dc3..0000000
--- a/libmap/datetime-module.c
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2010 Intel, Inc
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * Author: Thomas Wood 
- *
- */
-
-#include 
-
-#include "cc-datetime-panel.h"
-
-#include 
-
-#define GETTEXT_PACKAGE_TIMEZONES GETTEXT_PACKAGE "-timezones"
-
-void
-g_io_module_load (GIOModule *module)
-{
-  bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR);
-  bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
-
-  bindtextdomain (GETTEXT_PACKAGE_TIMEZONES, GNOMELOCALEDIR);
-  bind_textdomain_codeset (GETTEXT_PACKAGE_TIMEZONES, "UTF-8");
-
-  /* register the panel */
-  cc_date_time_panel_register (module);
-}
-
-void
-g_io_module_unload (GIOModule *module)
-{
-}
diff --git a/libmap/dt-lockbutton.c b/libmap/dt-lockbutton.c
deleted file mode 100644
index ecf4c12..0000000
--- a/libmap/dt-lockbutton.c
+++ /dev/null
@@ -1,627 +0,0 @@
-/*
- * Copyright (C) 2010 Red Hat, Inc.
- * Author: Matthias Clasen
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include "config.h"
-
-#include "dt-lockbutton.h"
-
-#include 
-#include 
-
-#define P_(s) s
-
-struct _DtLockButtonPrivate
-{
-  GPermission *permission;
-
-  gchar *text_lock;
-  gchar *text_unlock;
-  gchar *text_not_authorized;
-
-  gchar *tooltip_lock;
-  gchar *tooltip_unlock;
-  gchar *tooltip_not_authorized;
-
-  GtkWidget *box;
-  GtkWidget *eventbox;
-  GtkWidget *image;
-  GtkWidget *button;
-  GtkWidget *notebook;
-
-  GtkWidget *label_lock;
-  GtkWidget *label_unlock;
-  GtkWidget *label_not_authorized;
-
-  GCancellable *cancellable;
-
-  gboolean constructed;
-};
-
-enum
-{
-  PROP_0,
-  PROP_PERMISSION,
-  PROP_TEXT_LOCK,
-  PROP_TEXT_UNLOCK,
-  PROP_TEXT_NOT_AUTHORIZED,
-  PROP_TOOLTIP_LOCK,
-  PROP_TOOLTIP_UNLOCK,
-  PROP_TOOLTIP_NOT_AUTHORIZED
-};
-
-static void update_state (DtLockButton *button);
-
-static void on_permission_changed (GPermission *permission,
-                                   GParamSpec  *pspec,
-                                   gpointer     user_data);
-
-static void on_clicked (GtkButton *button,
-                        gpointer   user_data);
-
-static void on_button_press (GtkWidget      *widget,
-                             GdkEventButton *event,
-                             gpointer        user_data);
-
-G_DEFINE_TYPE (DtLockButton, dt_lock_button, GTK_TYPE_BIN);
-
-static void
-dt_lock_button_finalize (GObject *object)
-{
-  DtLockButton *button = DT_LOCK_BUTTON (object);
-  DtLockButtonPrivate *priv = button->priv;
-
-  g_free (priv->text_lock);
-  g_free (priv->text_unlock);
-  g_free (priv->text_not_authorized);
-
-  g_free (priv->tooltip_lock);
-  g_free (priv->tooltip_unlock);
-  g_free (priv->tooltip_not_authorized);
-
-  if (priv->cancellable != NULL)
-    {
-      g_cancellable_cancel (priv->cancellable);
-      g_object_unref (priv->cancellable);
-    }
-
-  g_signal_handlers_disconnect_by_func (priv->permission,
-                                        on_permission_changed,
-                                        button);
-
-  g_object_unref (priv->permission);
-
-  G_OBJECT_CLASS (dt_lock_button_parent_class)->finalize (object);
-}
-
-static void
-dt_lock_button_get_property (GObject    *object,
-                             guint       property_id,
-                             GValue     *value,
-                             GParamSpec *pspec)
-{
-  DtLockButton *button = DT_LOCK_BUTTON (object);
-  DtLockButtonPrivate *priv = button->priv;
-
-  switch (property_id)
-    {
-    case PROP_PERMISSION:
-      g_value_set_object (value, priv->permission);
-      break;
-
-    case PROP_TEXT_LOCK:
-      g_value_set_string (value, priv->text_lock);
-      break;
-
-    case PROP_TEXT_UNLOCK:
-      g_value_set_string (value, priv->text_unlock);
-      break;
-
-    case PROP_TEXT_NOT_AUTHORIZED:
-      g_value_set_string (value, priv->text_not_authorized);
-      break;
-
-    case PROP_TOOLTIP_LOCK:
-      g_value_set_string (value, priv->tooltip_lock);
-      break;
-
-    case PROP_TOOLTIP_UNLOCK:
-      g_value_set_string (value, priv->tooltip_unlock);
-      break;
-
-    case PROP_TOOLTIP_NOT_AUTHORIZED:
-      g_value_set_string (value, priv->tooltip_not_authorized);
-      break;
-
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
-      break;
-    }
-}
-
-static void
-dt_lock_button_set_property (GObject      *object,
-                             guint         property_id,
-                             const GValue *value,
-                             GParamSpec   *pspec)
-{
-  DtLockButton *button = DT_LOCK_BUTTON (object);
-  DtLockButtonPrivate *priv = button->priv;
-
-  switch (property_id)
-    {
-    case PROP_PERMISSION:
-      priv->permission = g_value_get_object (value);
-      break;
-
-    case PROP_TEXT_LOCK:
-      g_free (priv->text_lock);
-      priv->text_lock = g_value_dup_string (value);
-      break;
-
-    case PROP_TEXT_UNLOCK:
-      g_free (priv->text_unlock);
-      priv->text_unlock = g_value_dup_string (value);
-      break;
-
-    case PROP_TEXT_NOT_AUTHORIZED:
-      g_free (priv->text_not_authorized);
-      priv->text_not_authorized = g_value_dup_string (value);
-      break;
-
-    case PROP_TOOLTIP_LOCK:
-      g_free (priv->tooltip_lock);
-      priv->tooltip_lock = g_value_dup_string (value);
-      break;
-
-    case PROP_TOOLTIP_UNLOCK:
-      g_free (priv->tooltip_unlock);
-      priv->tooltip_unlock = g_value_dup_string (value);
-      break;
-
-    case PROP_TOOLTIP_NOT_AUTHORIZED:
-      g_free (priv->tooltip_not_authorized);
-      priv->tooltip_not_authorized = g_value_dup_string (value);
-      break;
-
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
-      break;
-    }
-
-  if (priv->constructed)
-    update_state (button);
-}
-
-static void
-dt_lock_button_init (DtLockButton *button)
-{
-  button->priv = G_TYPE_INSTANCE_GET_PRIVATE (button,
-                                              DT_TYPE_LOCK_BUTTON,
-                                              DtLockButtonPrivate);
-}
-
-static void
-dt_lock_button_constructed (GObject *object)
-{
-  DtLockButton *button = DT_LOCK_BUTTON (object);
-  DtLockButtonPrivate *priv = button->priv;
-
-  priv->constructed = TRUE;
-
-  g_signal_connect (priv->permission, "notify",
-                    G_CALLBACK (on_permission_changed), button);
-
-  priv->box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
-  gtk_container_add (GTK_CONTAINER (button), priv->box);
-
-  priv->eventbox = gtk_event_box_new ();
-  gtk_event_box_set_visible_window (GTK_EVENT_BOX (priv->eventbox), FALSE);
-  gtk_container_add (GTK_CONTAINER (priv->box), priv->eventbox);
-  gtk_widget_show (priv->eventbox);
-
-  priv->image = gtk_image_new (); /* image is set in update_state() */
-  gtk_container_add (GTK_CONTAINER (priv->eventbox), priv->image);
-  gtk_widget_show (priv->image);
-
-  priv->notebook = gtk_notebook_new ();
-  gtk_notebook_set_show_tabs (GTK_NOTEBOOK (priv->notebook), FALSE);
-  gtk_notebook_set_show_border (GTK_NOTEBOOK (priv->notebook), FALSE);
-  gtk_widget_show (priv->notebook);
-
-  priv->button = gtk_button_new ();
-  gtk_container_add (GTK_CONTAINER (priv->button), priv->notebook);
-  gtk_widget_show (priv->button);
-
-  priv->label_lock = gtk_label_new (""); /* text is set in update_state */
-  gtk_notebook_append_page (GTK_NOTEBOOK (priv->notebook), priv->label_lock, NULL);
-  gtk_widget_show (priv->label_lock);
-
-  priv->label_unlock = gtk_label_new ("");
-  gtk_notebook_append_page (GTK_NOTEBOOK (priv->notebook), priv->label_unlock, NULL);
-  gtk_widget_show (priv->label_unlock);
-
-  priv->label_not_authorized = gtk_label_new ("");
-  gtk_notebook_append_page (GTK_NOTEBOOK (priv->notebook), priv->label_not_authorized, NULL);
-  gtk_widget_show (priv->label_not_authorized);
-
-  gtk_box_pack_start (GTK_BOX (priv->box), priv->button, FALSE, FALSE, 0);
-  gtk_widget_show (priv->button);
-
-  g_signal_connect (priv->eventbox, "button-press-event",
-                    G_CALLBACK (on_button_press), button);
-  g_signal_connect (priv->button, "clicked",
-                    G_CALLBACK (on_clicked), button);
-
-  gtk_widget_set_no_show_all (priv->box, TRUE);
-
-  update_state (button);
-
-  if (G_OBJECT_CLASS (dt_lock_button_parent_class)->constructed != NULL)
-    G_OBJECT_CLASS (dt_lock_button_parent_class)->constructed (object);
-}
-
-static void
-dt_lock_button_get_preferred_width (GtkWidget *widget,
-                                    gint      *minimum,
-                                    gint      *natural)
-{
-  DtLockButtonPrivate *priv = DT_LOCK_BUTTON (widget)->priv;
-
-  gtk_widget_get_preferred_width (priv->box, minimum, natural);
-}
-
-static void
-dt_lock_button_get_preferred_height (GtkWidget *widget,
-                                     gint      *minimum,
-                                     gint      *natural)
-{
-  DtLockButtonPrivate *priv = DT_LOCK_BUTTON (widget)->priv;
-
-  gtk_widget_get_preferred_height (priv->box, minimum, natural);
-}
-
-static void
-dt_lock_button_size_allocate (GtkWidget     *widget,
-                              GtkAllocation *allocation)
-{
-  DtLockButtonPrivate *priv = DT_LOCK_BUTTON (widget)->priv;
-  GtkRequisition requisition;
-  GtkAllocation child_allocation;
-
-  gtk_widget_set_allocation (widget, allocation);
-  gtk_widget_get_preferred_size (priv->box, &requisition, NULL);
-  child_allocation.x = allocation->x;
-  child_allocation.y = allocation->y;
-  child_allocation.width = requisition.width;
-  child_allocation.height = requisition.height;
-  gtk_widget_size_allocate (priv->box, &child_allocation);
-}
-
-static void
-dt_lock_button_class_init (DtLockButtonClass *klass)
-{
-  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
-  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
-
-  gobject_class->finalize     = dt_lock_button_finalize;
-  gobject_class->get_property = dt_lock_button_get_property;
-  gobject_class->set_property = dt_lock_button_set_property;
-  gobject_class->constructed  = dt_lock_button_constructed;
-
-  widget_class->get_preferred_width = dt_lock_button_get_preferred_width;
-  widget_class->get_preferred_height = dt_lock_button_get_preferred_height;
-  widget_class->size_allocate = dt_lock_button_size_allocate;
-
-  g_type_class_add_private (klass, sizeof (DtLockButtonPrivate));
-
-  g_object_class_install_property (gobject_class, PROP_PERMISSION,
-    g_param_spec_object ("permission",
-                         P_("Permission"),
-                         P_("The GPermission object controlling this button"),
-                         G_TYPE_PERMISSION,
-                         G_PARAM_READWRITE |
-                         G_PARAM_CONSTRUCT_ONLY |
-                         G_PARAM_STATIC_STRINGS));
-
-  g_object_class_install_property (gobject_class, PROP_TEXT_LOCK,
-    g_param_spec_string ("text-lock",
-                         P_("Lock Text"),
-                         P_("The text to display when prompting the user to lock"),
-                         _("Lock"),
-                         G_PARAM_READWRITE |
-                         G_PARAM_CONSTRUCT |
-                         G_PARAM_STATIC_STRINGS));
-
-  g_object_class_install_property (gobject_class, PROP_TEXT_UNLOCK,
-    g_param_spec_string ("text-unlock",
-                         P_("Unlock Text"),
-                         P_("The text to display when prompting the user to unlock"),
-                         _("Unlock"),
-                         G_PARAM_READWRITE |
-                         G_PARAM_CONSTRUCT |
-                         G_PARAM_STATIC_STRINGS));
-
-  g_object_class_install_property (gobject_class, PROP_TEXT_NOT_AUTHORIZED,
-    g_param_spec_string ("text-not-authorized",
-                         P_("Not Authorized Text"),
-                         P_("The text to display when prompting the user cannot obtain authorization"),
-                         _("Locked"),
-                         G_PARAM_READWRITE |
-                         G_PARAM_CONSTRUCT |
-                         G_PARAM_STATIC_STRINGS));
-
-  g_object_class_install_property (gobject_class, PROP_TOOLTIP_LOCK,
-    g_param_spec_string ("tooltip-lock",
-                         P_("Lock Tooltip"),
-                         P_("The tooltip to display when prompting the user to lock"),
-                         _("Dialog is unlocked.\nClick to prevent further changes"),
-                         G_PARAM_READWRITE |
-                         G_PARAM_CONSTRUCT |
-                         G_PARAM_STATIC_STRINGS));
-
-  g_object_class_install_property (gobject_class, PROP_TOOLTIP_UNLOCK,
-    g_param_spec_string ("tooltip-unlock",
-                         P_("Unlock Tooltip"),
-                         P_("The tooltip to display when prompting the user to unlock"),
-                         _("Dialog is locked.\nClick to make changes"),
-                         G_PARAM_READWRITE |
-                         G_PARAM_CONSTRUCT |
-                         G_PARAM_STATIC_STRINGS));
-
-  g_object_class_install_property (gobject_class, PROP_TOOLTIP_NOT_AUTHORIZED,
-    g_param_spec_string ("tooltip-not-authorized",
-                         P_("Not Authorized Tooltip"),
-                         P_("The tooltip to display when prompting the user cannot obtain authorization"),
-                         _("System policy prevents changes.\nContact your system administrator"),
-                         G_PARAM_READWRITE |
-                         G_PARAM_CONSTRUCT |
-                         G_PARAM_STATIC_STRINGS));
-}
-
-/**
- * dt_lock_button_new:
- * @permission: a #GPermission
- *
- * Creates a new lock button which reflects the @permission.
- *
- * Returns: a new #DtLockButton
- *
- * Since: 3.0
- */
-GtkWidget *
-dt_lock_button_new (GPermission *permission)
-{
-  g_return_val_if_fail (permission != NULL, NULL);
-
-  return GTK_WIDGET (g_object_new (DT_TYPE_LOCK_BUTTON,
-                                   "permission", permission,
-                                   NULL));
-}
-
-static void
-update_state (DtLockButton *button)
-{
-  DtLockButtonPrivate *priv = button->priv;
-  gint page;
-  const gchar *tooltip;
-  gboolean sensitive;
-  gboolean visible;
-  GIcon *icon;
-
-  visible = TRUE;
-  sensitive = TRUE;
-
-  gtk_label_set_text (GTK_LABEL (priv->label_lock), priv->text_lock);
-  gtk_label_set_text (GTK_LABEL (priv->label_unlock), priv->text_unlock);
-  gtk_label_set_text (GTK_LABEL (priv->label_not_authorized), priv->text_not_authorized);
-
-  if (g_permission_get_allowed (priv->permission))
-    {
-      if (g_permission_get_can_release (priv->permission))
-        {
-          page = 0;
-          tooltip = priv->tooltip_lock;
-          sensitive = TRUE;
-        }
-      else
-        {
-          page = 0;
-          tooltip = "";
-          visible = FALSE;
-        }
-    }
-  else
-    {
-      if (g_permission_get_can_acquire (priv->permission))
-        {
-          page = 1;
-          tooltip = button->priv->tooltip_unlock;
-          sensitive = TRUE;
-        }
-      else
-        {
-          page = 2;
-          tooltip = button->priv->tooltip_not_authorized;
-          sensitive = FALSE;
-        }
-    }
-
-  if (g_permission_get_allowed (priv->permission))
-    {
-      gchar *names[3];
-
-      names[0] = "changes-allow-symbolic";
-      names[1] = "changes-allow";
-      names[2] = NULL;
-      icon = g_themed_icon_new_from_names (names, -1);
-    }
-  else
-    {
-      gchar *names[3];
-
-      names[0] = "changes-prevent-symbolic";
-      names[1] = "changes-prevent";
-      names[2] = NULL;
-      icon = g_themed_icon_new_from_names (names, -1);
-    }
-
-  gtk_image_set_from_gicon (GTK_IMAGE (priv->image), icon, GTK_ICON_SIZE_BUTTON);
-  g_object_unref (icon);
-
-  gtk_notebook_set_current_page (GTK_NOTEBOOK (priv->notebook), page);
-  gtk_widget_set_tooltip_markup (priv->box, tooltip);
-
-  gtk_widget_set_sensitive (priv->box, sensitive);
-
-  if (visible)
-    gtk_widget_show (priv->box);
-  else
-    gtk_widget_hide (priv->box);
-}
-
-static void
-on_permission_changed (GPermission *permission,
-                       GParamSpec  *pspec,
-                       gpointer     user_data)
-{
-  DtLockButton *button = DT_LOCK_BUTTON (user_data);
-
-  update_state (button);
-}
-
-static void
-acquire_cb (GObject      *source,
-            GAsyncResult *result,
-            gpointer      user_data)
-{
-  DtLockButton *button = DT_LOCK_BUTTON (user_data);
-  DtLockButtonPrivate *priv = button->priv;
-  GError *error;
-
-  error = NULL;
-  g_permission_acquire_finish (priv->permission, result, &error);
-
-  if (error)
-    {
-      g_warning ("Error acquiring permission: %s", error->message);
-      g_error_free (error);
-    }
-
-  g_object_unref (priv->cancellable);
-  priv->cancellable = NULL;
-
-  update_state (button);
-}
-
-static void
-release_cb (GObject      *source,
-            GAsyncResult *result,
-            gpointer      user_data)
-{
-  DtLockButton *button = DT_LOCK_BUTTON (user_data);
-  DtLockButtonPrivate *priv = button->priv;
-  GError *error;
-
-  error = NULL;
-  g_permission_release_finish (priv->permission, result, &error);
-
-  if (error)
-    {
-      g_warning ("Error releasing permission: %s", error->message);
-      g_error_free (error);
-    }
-
-  g_object_unref (priv->cancellable);
-  priv->cancellable = NULL;
-
-  update_state (button);
-}
-
-static void
-handle_click (DtLockButton *button)
-{
-  DtLockButtonPrivate *priv = button->priv;
-
-  if (!g_permission_get_allowed (priv->permission) &&
-       g_permission_get_can_acquire (priv->permission))
-    {
-      /* if we already have a pending interactive check, then do nothing */
-      if (priv->cancellable != NULL)
-        goto out;
-
-      priv->cancellable = g_cancellable_new ();
-
-      g_permission_acquire_async (priv->permission,
-                                  priv->cancellable,
-                                  acquire_cb,
-                                  button);
-    }
-  else if (g_permission_get_allowed (priv->permission) &&
-           g_permission_get_can_release (priv->permission))
-    {
-      /* if we already have a pending interactive check, then do nothing */
-      if (priv->cancellable != NULL)
-        goto out;
-
-      priv->cancellable = g_cancellable_new ();
-
-      g_permission_release_async (priv->permission,
-                                  priv->cancellable,
-                                  release_cb,
-                                  button);
-    }
-
- out: ;
-}
-
-static void
-on_clicked (GtkButton *_button,
-            gpointer   user_data)
-
-{
-  handle_click (DT_LOCK_BUTTON (user_data));
-}
-
-static void
-on_button_press (GtkWidget      *widget,
-                 GdkEventButton *event,
-                 gpointer        user_data)
-{
-  handle_click (DT_LOCK_BUTTON (user_data));
-}
-
-/**
- * dt_lock_button_get_permission:
- * @button: a #DtLockButton
- *
- * Obtains the #GPermission object that controls @button.
- *
- * Returns: the #GPermission of @button
- *
- * Since: 3.0
- */
-GPermission *
-dt_lock_button_get_permission (DtLockButton *button)
-{
-  g_return_val_if_fail (DT_IS_LOCK_BUTTON (button), NULL);
-
-  return button->priv->permission;
-}
-
diff --git a/libmap/dt-lockbutton.h b/libmap/dt-lockbutton.h
deleted file mode 100644
index adab0a7..0000000
--- a/libmap/dt-lockbutton.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2010 Red Hat, Inc.
- * Author: Matthias Clasen
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __DT_LOCK_BUTTON_H__
-#define __DT_LOCK_BUTTON_H__
-
-#include 
-#include 
-
-G_BEGIN_DECLS
-
-#define DT_TYPE_LOCK_BUTTON         (dt_lock_button_get_type ())
-#define DT_LOCK_BUTTON(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), DT_TYPE_LOCK_BUTTON, DtLockButton))
-#define DT_LOCK_BUTTON_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST ((k), DT_LOCK_BUTTON,  DtLockButtonClass))
-#define DT_IS_LOCK_BUTTON(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), DT_TYPE_LOCK_BUTTON))
-#define DT_IS_LOCK_BUTTON_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), DT_TYPE_LOCK_BUTTON))
-#define DT_LOCK_BUTTON_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), DT_TYPE_LOCK_BUTTON, DtLockButtonClass))
-
-typedef struct _DtLockButton        DtLockButton;
-typedef struct _DtLockButtonClass   DtLockButtonClass;
-typedef struct _DtLockButtonPrivate DtLockButtonPrivate;
-
-struct _DtLockButton
-{
-  GtkBin parent;
-
-  DtLockButtonPrivate *priv;
-};
-
-struct _DtLockButtonClass
-{
-  GtkBinClass parent_class;
-
-  void (*reserved0) (void);
-  void (*reserved1) (void);
-  void (*reserved2) (void);
-  void (*reserved3) (void);
-  void (*reserved4) (void);
-  void (*reserved5) (void);
-  void (*reserved6) (void);
-  void (*reserved7) (void);
-};
-
-GType        dt_lock_button_get_type       (void) G_GNUC_CONST;
-GtkWidget   *dt_lock_button_new            (GPermission   *permission);
-GPermission *dt_lock_button_get_permission (DtLockButton *button);
-
-
-G_END_DECLS
-
-#endif  /* __DT_LOCK_BUTTON_H__ */
diff --git a/libmap/set-timezone.c b/libmap/set-timezone.c
deleted file mode 100644
index 5aafced..0000000
--- a/libmap/set-timezone.c
+++ /dev/null
@@ -1,481 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
- *
- * Copyright (C) 2007 David Zeuthen 
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#  include "config.h"
-#endif
-
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-
-#include 
-#include 
-
-#include "set-timezone.h"
-
-
-static DBusGConnection *
-get_system_bus (GError **err)
-{
-        GError          *error;
-        static DBusGConnection *bus = NULL;
-
-	if (bus == NULL) {
-        	error = NULL;
-        	bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
-        	if (bus == NULL) {
-			g_propagate_error (err, error);
-		}
-        }
-
-        return bus;
-}
-
-#define CACHE_VALIDITY_SEC 2
-
-typedef  void (*CanDoFunc) (gint value);
-
-static void
-notify_can_do (DBusGProxy     *proxy,
-	       DBusGProxyCall *call,
-	       void           *user_data)
-{
-	CanDoFunc callback = user_data;
-	GError *error = NULL;
-	gint value;
-
-	if (dbus_g_proxy_end_call (proxy, call,
-				   &error,
-				   G_TYPE_INT, &value,
-				   G_TYPE_INVALID)) {
-		callback (value);
-	}
-}
-
-static void
-refresh_can_do (const gchar *action, CanDoFunc callback)
-{
-        DBusGConnection *bus;
-        DBusGProxy      *proxy;
-
-        bus = get_system_bus (NULL);
-        if (bus == NULL)
-                return;
-
-	proxy = dbus_g_proxy_new_for_name (bus,
-					   "org.gnome.SettingsDaemon.DateTimeMechanism",
-					   "/",
-					   "org.gnome.SettingsDaemon.DateTimeMechanism");
-
-	dbus_g_proxy_begin_call_with_timeout (proxy,
-					      action,
-					      notify_can_do,
-					      callback, NULL,
-					      INT_MAX,
-					      G_TYPE_INVALID);
-}
-
-static gint   settimezone_cache = 0;
-static time_t settimezone_stamp = 0;
-
-static void
-update_can_settimezone (gint res)
-{
-	settimezone_cache = res;
-	time (&settimezone_stamp);
-}
-
-gint
-can_set_system_timezone (void)
-{
-	time_t          now;
-
-	time (&now);
-	if (ABS (now - settimezone_stamp) > CACHE_VALIDITY_SEC) {
-		refresh_can_do ("CanSetTimezone", update_can_settimezone);
-		settimezone_stamp = now;
-	}
-
-	return settimezone_cache;
-}
-
-static gint   settime_cache = 0;
-static time_t settime_stamp = 0;
-
-static void
-update_can_settime (gint res)
-{
-	settime_cache = res;
-	time (&settime_stamp);
-}
-
-gint
-can_set_system_time (void)
-{
-	time_t now;
-
-	time (&now);
-	if (ABS (now - settime_stamp) > CACHE_VALIDITY_SEC) {
-		refresh_can_do ("CanSetTime", update_can_settime);
-		settime_stamp = now;
-	}
-
-	return settime_cache;
-}
-
-static gint   usingntp_cache = 0;
-static time_t usingntp_stamp = 0;
-
-static void
-update_can_usingntp (gint res)
-{
-	usingntp_cache = res;
-	time (&usingntp_stamp);
-}
-
-gint
-can_set_using_ntp (void)
-{
-	time_t now;
-
-	time (&now);
-	if (ABS (now - usingntp_stamp) > CACHE_VALIDITY_SEC) {
-		refresh_can_do ("CanSetUsingNtp", update_can_usingntp);
-		settime_stamp = now;
-	}
-
-	return usingntp_cache;
-}
-
-typedef struct {
-	gint ref_count;
-        gchar *call;
-	gint64 time;
-	gchar *tz;
-	gboolean using_ntp;
-	GFunc callback;
-	gpointer data;
-	GDestroyNotify notify;
-} SetTimeCallbackData;
-
-static void
-free_data (gpointer d)
-{
-	SetTimeCallbackData *data = d;
-
-	data->ref_count--;
-	if (data->ref_count == 0) {
-		if (data->notify)
-			data->notify (data->data);
-		g_free (data->tz);
-		g_free (data);
-	}
-}
-
-static void
-set_time_notify (DBusGProxy     *proxy,
-		 DBusGProxyCall *call,
-		 void           *user_data)
-{
-	SetTimeCallbackData *data = user_data;
-	GError *error = NULL;
-
-	if (dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INVALID)) {
-		if (data->callback)
-			data->callback (data->data, NULL);
-	}
-	else {
-		if (error->domain == DBUS_GERROR &&
-		    error->code == DBUS_GERROR_NO_REPLY) {
-			/* these errors happen because dbus doesn't
-			 * use monotonic clocks
-			 */	
-			g_warning ("ignoring no-reply error when setting time");
-			g_error_free (error);
-			if (data->callback)
-				data->callback (data->data, NULL);
-		}
-		else {
-			if (data->callback)
-				data->callback (data->data, error);
-			else
-				g_error_free (error);
-		}		
-	}
-}
-
-static void
-set_time_async (SetTimeCallbackData *data)
-{
-        DBusGConnection *bus;
-        DBusGProxy      *proxy;
-	GError          *err = NULL;
-
-        bus = get_system_bus (&err);
-        if (bus == NULL) {
-		if (err) {
-			if (data->callback)
-				data->callback (data->data, err);
-			g_clear_error (&err);
-		}
-		return;
-	}
-
-	proxy = dbus_g_proxy_new_for_name (bus,
-					   "org.gnome.SettingsDaemon.DateTimeMechanism",
-					   "/",
-					   "org.gnome.SettingsDaemon.DateTimeMechanism");
-
-	data->ref_count++;
-	if (strcmp (data->call, "SetTime") == 0)
-		dbus_g_proxy_begin_call_with_timeout (proxy,
-						      "SetTime",
-						      set_time_notify,
-						      data, free_data,
-						      INT_MAX,
-						      /* parameters: */
-						      G_TYPE_INT64, data->time,
-						      G_TYPE_INVALID,
-						      /* return values: */
-						      G_TYPE_INVALID);
-	else if (strcmp (data->call, "SetTimezone") == 0)
-		dbus_g_proxy_begin_call_with_timeout (proxy,
-						      "SetTimezone",
-						      set_time_notify,
-						      data, free_data,
-						      INT_MAX,
-						      /* parameters: */
-						      G_TYPE_STRING, data->tz,
-						      G_TYPE_INVALID,
-						      /* return values: */
-						      G_TYPE_INVALID);
-	else if (strcmp (data->call, "SetUsingNtp") == 0)
-		dbus_g_proxy_begin_call_with_timeout (proxy,
-						      "SetUsingNtp",
-						      set_time_notify,
-						      data, free_data,
-						      INT_MAX,
-						      /* parameters: */
-						      G_TYPE_BOOLEAN, data->using_ntp,
-						      G_TYPE_INVALID,
-						      /* return values: */
-						      G_TYPE_INVALID);
-}
-
-void
-set_system_time_async (gint64         time,
-		       GFunc          callback,
-		       gpointer       d,
-		       GDestroyNotify notify)
-{
-	SetTimeCallbackData *data;
-
-	if (time == -1)
-		return;
-
-	data = g_new0 (SetTimeCallbackData, 1);
-	data->ref_count = 1;
-	data->call = "SetTime";
-	data->time = time;
-	data->tz = NULL;
-	data->callback = callback;
-	data->data = d;
-	data->notify = notify;
-
-	set_time_async (data);
-	free_data (data);
-}
-
-void
-set_system_timezone_async (const gchar    *tz,
-			   GFunc           callback,
-			   gpointer        d,
-			   GDestroyNotify  notify)
-{
-	SetTimeCallbackData *data;
-
-	g_return_if_fail (tz != NULL);
-
-	data = g_new0 (SetTimeCallbackData, 1);
-	data->ref_count = 1;
-	data->call = "SetTimezone";
-	data->time = -1;
-	data->tz = g_strdup (tz);
-	data->callback = callback;
-	data->data = d;
-	data->notify = notify;
-
-	set_time_async (data);
-	free_data (data);
-}
-
-/* get timezone */
-
-typedef struct
-{
-  GetTimezoneFunc callback;
-  GDestroyNotify notify;
-
-  gpointer data;
-
-} GetTimezoneData;
-
-static void
-get_timezone_destroy_notify (GetTimezoneData *data)
-{
-	if (data->notify && data->data)
-		data->notify (data);
-
-	g_free (data);
-}
-
-static void
-get_timezone_notify (DBusGProxy     *proxy,
-		     DBusGProxyCall *call,
-		     void           *user_data)
-{
-	GError *error = NULL;
-	gboolean retval;
-	gchar *string = NULL;
-	GetTimezoneData *data = user_data;
-
-	retval = dbus_g_proxy_end_call (proxy, call, &error,
-					G_TYPE_STRING, &string,
-					G_TYPE_INVALID);
-
-	if (data->callback) {
-		if (!retval) {
-			data->callback (data->data, NULL, error);
-			g_error_free (error);
-		}
-		else {
-			data->callback (data->data, string, NULL);
-			g_free (string);
-		}
-	}
-}
-
-void
-get_system_timezone_async (GetTimezoneFunc callback,
-			   gpointer        user_data,
-			   GDestroyNotify  notify)
-{
-	DBusGConnection *bus;
-	DBusGProxy      *proxy;
-	GetTimezoneData *data;
-	GError          *error = NULL;
-
-	bus = get_system_bus (&error);
-	if (bus == NULL) {
-		if (error) {
-			if (callback)
-				callback (user_data, NULL, error);
-			g_clear_error (&error);
-		}
-		return;
-
-        }
-
-	data = g_new0 (GetTimezoneData, 1);
-	data->data = user_data;
-	data->notify = notify;
-	data->callback = callback;
-
-	proxy = dbus_g_proxy_new_for_name (bus,
-					   "org.gnome.SettingsDaemon.DateTimeMechanism",
-					   "/",
-					   "org.gnome.SettingsDaemon.DateTimeMechanism");
-
-	dbus_g_proxy_begin_call (proxy,
-				 "GetTimezone",
-				 get_timezone_notify,
-				 data,
-				 (GDestroyNotify) get_timezone_destroy_notify,
-				 /* parameters: */
-				 G_TYPE_INVALID,
-				 /* return values: */
-				 G_TYPE_STRING,
-				 G_TYPE_INVALID);
-
-}
-
-gboolean
-get_using_ntp (void)
-{
-	static gboolean can_use_cache = FALSE;
-	static gboolean is_using_cache = FALSE;
-	static time_t   last_refreshed = 0;
-	time_t          now;
-        DBusGConnection *bus;
-        DBusGProxy      *proxy;
-
-	time (&now);
-	if (ABS (now - last_refreshed) > CACHE_VALIDITY_SEC) {
-		gboolean cu, iu;
-		bus = get_system_bus (NULL);
-		if (bus == NULL)
-			return FALSE;
-
-		proxy = dbus_g_proxy_new_for_name (bus,
-						   "org.gnome.SettingsDaemon.DateTimeMechanism",
-						   "/",
-						   "org.gnome.SettingsDaemon.DateTimeMechanism");
-
-
-		if (dbus_g_proxy_call (proxy,
-				       "GetUsingNtp",
-				       NULL,
-				       G_TYPE_INVALID,
-				       G_TYPE_BOOLEAN, &cu,
-				       G_TYPE_BOOLEAN, &iu,
-				       G_TYPE_INVALID)) {
-			can_use_cache = cu;
-			is_using_cache = iu;
-			last_refreshed = now;
-		}
-	}
-
-	return is_using_cache;
-}
-
-void
-set_using_ntp_async (gboolean        using_ntp,
-	             GFunc           callback,
-	             gpointer        d,
-	             GDestroyNotify  notify)
-{
-	SetTimeCallbackData *data;
-
-	data = g_new0 (SetTimeCallbackData, 1);
-	data->ref_count = 1;
-	data->call = "SetUsingNtp";
-	data->time = -1;
-	data->using_ntp = using_ntp;
-	data->callback = callback;
-	data->data = d;
-	data->notify = notify;
-
-	set_time_async (data);
-	free_data (data);
-}
diff --git a/libmap/set-timezone.h b/libmap/set-timezone.h
deleted file mode 100644
index 5e657e3..0000000
--- a/libmap/set-timezone.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
- *
- * Copyright (C) 2007 David Zeuthen 
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- */
-
-#ifndef __SET_SYSTEM_TIMEZONE_H__
-
-#include 
-
-#include 
-#include 
-
-typedef void (*GetTimezoneFunc) (gpointer     data,
-                                 const gchar *timezone,
-                                 GError      *error);
-void     get_system_timezone_async   (GetTimezoneFunc callback,
-                                      gpointer        data,
-                                      GDestroyNotify  notify);
-
-gint     can_set_system_timezone (void);
-
-gint     can_set_system_time     (void);
-
-gint     can_set_using_ntp       (void);
-
-void     set_system_time_async   (gint64         time,
-                                  GFunc          callback,
-                                  gpointer       data,
-                                  GDestroyNotify notify);
-
-void     set_system_timezone_async   (const gchar    *tz,
-                                      GFunc           callback,
-                                      gpointer        data,
-                                      GDestroyNotify  notify);
-
-gboolean get_using_ntp               (void);
-
-void     set_using_ntp_async         (gboolean        using_ntp,
-                                      GFunc           callback,
-                                      gpointer        data,
-                                      GDestroyNotify  notify);
-#endif
-- 
cgit v1.2.3


From 74cf8fa3465f955fc01fd3ac9b826079b0f5cdb6 Mon Sep 17 00:00:00 2001
From: Michael Terry 
Date: Tue, 22 Feb 2011 13:49:07 -0500
Subject: make locations dialog editable

---
 src/datetime-prefs-locations.c | 58 ++++++++++++++++++++++++++++++++++++++----
 1 file changed, 53 insertions(+), 5 deletions(-)

diff --git a/src/datetime-prefs-locations.c b/src/datetime-prefs-locations.c
index 24efd04..90b6f97 100644
--- a/src/datetime-prefs-locations.c
+++ b/src/datetime-prefs-locations.c
@@ -33,13 +33,56 @@ with this program.  If not, see .
 #define DATETIME_DIALOG_UI_FILE PKGDATADIR "/datetime-dialog.ui"
 
 static void
-handle_add (GtkWidget * button, gpointer user_data)
+handle_add (GtkWidget * button, GtkTreeView * tree)
 {
+  GtkListStore * store = GTK_LIST_STORE (gtk_tree_view_get_model (tree));
+
+  GtkTreeIter iter;
+  gtk_list_store_append (store, &iter);
+
+  GtkTreePath * path = gtk_tree_model_get_path (GTK_TREE_MODEL (store), &iter);
+  gtk_tree_view_set_cursor (tree, path, gtk_tree_view_get_column (tree, 0), TRUE);
+  gtk_tree_path_free (path);
 }
 
 static void
-handle_remove (GtkWidget * button, gpointer user_data)
+handle_remove (GtkWidget * button, GtkTreeView * tree)
 {
+  GtkListStore * store = GTK_LIST_STORE (gtk_tree_view_get_model (tree));
+  GtkTreeSelection * selection = gtk_tree_view_get_selection (tree);
+
+  GList * paths = gtk_tree_selection_get_selected_rows (selection, NULL);
+
+  /* Convert all paths to iters so we can safely delete multiple paths.  For a
+     GtkListStore, iters persist past model changes. */
+  GList * tree_iters = NULL;
+  GList * iter;
+  for (iter = paths; iter; iter = iter->next) {
+    GtkTreeIter * tree_iter = g_new(GtkTreeIter, 1);
+    if (gtk_tree_model_get_iter (GTK_TREE_MODEL (store), tree_iter, (GtkTreePath *)iter->data)) {
+      tree_iters = g_list_prepend (tree_iters, tree_iter);
+    }
+    gtk_tree_path_free (iter->data);
+  }
+  g_list_free (paths);
+
+  /* Now delete each iterator */
+  for (iter = tree_iters; iter; iter = iter->next) {
+    gtk_list_store_remove (store, (GtkTreeIter *)iter->data);
+    g_free (iter->data);
+  }
+  g_list_free (tree_iters);
+}
+
+static void
+handle_edit (GtkCellRendererText * renderer, gchar * path, gchar * new_text,
+             GtkListStore * store)
+{
+  GtkTreeIter iter;
+
+  if (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (store), &iter, path)) {
+    gtk_list_store_set (store, &iter, 0, new_text, -1);
+  }
 }
 
 static void
@@ -69,8 +112,12 @@ save_to_settings (GtkWidget * dlg, GObject * store)
   if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter)) {
     do {
       GValue value = {0};
+      const gchar * strval;
       gtk_tree_model_get_value (GTK_TREE_MODEL (store), &iter, 0, &value);
-      g_variant_builder_add (&builder, "s", g_value_get_string (&value));
+      strval = g_value_get_string (&value);
+      if (strval != NULL && strval[0] != 0) {
+        g_variant_builder_add (&builder, "s", strval);
+      }
       g_value_unset (&value);
     } while (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter));
   }
@@ -109,6 +156,7 @@ datetime_setup_locations_dialog (GtkWindow * parent)
   /* Configure tree */
   GtkCellRenderer * cell = gtk_cell_renderer_text_new ();
   g_object_set (cell, "editable", TRUE, NULL);
+  g_signal_connect (cell, "edited", G_CALLBACK (handle_edit), store);
   gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (tree), -1,
                                                _("Location"), cell,
                                                "text", 0, NULL);
@@ -118,8 +166,8 @@ datetime_setup_locations_dialog (GtkWindow * parent)
                                                "text", 1, NULL);
   gtk_tree_selection_set_mode (gtk_tree_view_get_selection (GTK_TREE_VIEW (tree)), GTK_SELECTION_MULTIPLE);
 
-  g_signal_connect (WIG ("addButton"), "clicked", G_CALLBACK (handle_add), NULL);
-  g_signal_connect (WIG ("removeButton"), "clicked", G_CALLBACK (handle_remove), NULL);
+  g_signal_connect (WIG ("addButton"), "clicked", G_CALLBACK (handle_add), tree);
+  g_signal_connect (WIG ("removeButton"), "clicked", G_CALLBACK (handle_remove), tree);
 
   fill_from_settings (store, conf);
   g_object_set_data_full (G_OBJECT (dlg), "conf", g_object_ref (conf), g_object_unref);
-- 
cgit v1.2.3


From 07c5056f4604b4294f42492e27ea3fcf85019dc3 Mon Sep 17 00:00:00 2001
From: Michael Terry 
Date: Tue, 22 Feb 2011 13:58:50 -0500
Subject: make remove button insensitive if nothing selected

---
 src/datetime-prefs-locations.c | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/src/datetime-prefs-locations.c b/src/datetime-prefs-locations.c
index 90b6f97..7df41e7 100644
--- a/src/datetime-prefs-locations.c
+++ b/src/datetime-prefs-locations.c
@@ -130,6 +130,13 @@ save_to_settings (GtkWidget * dlg, GObject * store)
   g_variant_unref (locations);
 }
 
+static void
+selection_changed (GtkTreeSelection * selection, GtkWidget * remove_button)
+{
+  gint count = gtk_tree_selection_count_selected_rows (selection);
+  gtk_widget_set_sensitive (remove_button, count > 0);
+}
+
 GtkWidget *
 datetime_setup_locations_dialog (GtkWindow * parent)
 {
@@ -164,7 +171,11 @@ datetime_setup_locations_dialog (GtkWindow * parent)
   gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (tree), -1,
                                                _("Time"), cell,
                                                "text", 1, NULL);
-  gtk_tree_selection_set_mode (gtk_tree_view_get_selection (GTK_TREE_VIEW (tree)), GTK_SELECTION_MULTIPLE);
+
+  GtkTreeSelection * selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree));
+  gtk_tree_selection_set_mode (selection, GTK_SELECTION_MULTIPLE);
+  g_signal_connect (selection, "changed", G_CALLBACK (selection_changed), WIG ("removeButton"));
+  selection_changed (selection, WIG ("removeButton"));
 
   g_signal_connect (WIG ("addButton"), "clicked", G_CALLBACK (handle_add), tree);
   g_signal_connect (WIG ("removeButton"), "clicked", G_CALLBACK (handle_remove), tree);
-- 
cgit v1.2.3


From deafbc1da6b3c29e04455e46414342bcb9841c2a Mon Sep 17 00:00:00 2001
From: Michael Terry 
Date: Tue, 22 Feb 2011 15:17:48 -0600
Subject: beginnings of completion support

---
 data/datetime-dialog.ui        |  85 ++------------------------
 src/Makefile.am                |   2 +
 src/datetime-prefs-locations.c |  15 +++++
 src/datetime-prefs.c           |  30 +++++++++-
 src/timezone-completion.c      | 131 +++++++++++++++++++++++++++++++++++++++++
 src/timezone-completion.h      |  59 +++++++++++++++++++
 6 files changed, 241 insertions(+), 81 deletions(-)
 create mode 100644 src/timezone-completion.c
 create mode 100644 src/timezone-completion.h

diff --git a/data/datetime-dialog.ui b/data/datetime-dialog.ui
index b5eba54..26c368b 100644
--- a/data/datetime-dialog.ui
+++ b/data/datetime-dialog.ui
@@ -6,6 +6,8 @@
     False
     Locations
     True
+    300
+    200
     True
     time-admin
     
@@ -169,87 +171,10 @@
                       
                     
                     
-                      
+                      
                         True
-                        False
-                        12
-                        True
-                        
-                          
-                            True
-                            False
-                            6
-                            
-                              
-                                True
-                                False
-                                0
-                                _Region:
-                                True
-                                regionCombo
-                              
-                              
-                                False
-                                True
-                                0
-                              
-                            
-                            
-                              
-                                True
-                                False
-                              
-                              
-                                True
-                                True
-                                1
-                              
-                            
-                          
-                          
-                            True
-                            True
-                            0
-                          
-                        
-                        
-                          
-                            True
-                            False
-                            6
-                            
-                              
-                                True
-                                False
-                                0
-                                Time_zone:
-                                True
-                                timezoneCombo
-                              
-                              
-                                False
-                                True
-                                0
-                              
-                            
-                            
-                              
-                                True
-                                False
-                              
-                              
-                                True
-                                True
-                                1
-                              
-                            
-                          
-                          
-                            False
-                            True
-                            1
-                          
-                        
+                        True
+                        
                       
                       
                         False
diff --git a/src/Makefile.am b/src/Makefile.am
index 4c94f7c..7e8ac4b 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -43,6 +43,8 @@ indicator_datetime_preferences_SOURCES =\
 	datetime-prefs.c \
 	datetime-prefs-locations.c \
 	datetime-prefs-locations.h \
+	timezone-completion.c \
+	timezone-completion.h \
 	utils.c \
 	utils.h \
 	settings-shared.h
diff --git a/src/datetime-prefs-locations.c b/src/datetime-prefs-locations.c
index 7df41e7..b13d082 100644
--- a/src/datetime-prefs-locations.c
+++ b/src/datetime-prefs-locations.c
@@ -29,6 +29,7 @@ with this program.  If not, see .
 
 #include "datetime-prefs-locations.h"
 #include "settings-shared.h"
+#include "timezone-completion.h"
 
 #define DATETIME_DIALOG_UI_FILE PKGDATADIR "/datetime-dialog.ui"
 
@@ -85,6 +86,16 @@ handle_edit (GtkCellRendererText * renderer, gchar * path, gchar * new_text,
   }
 }
 
+static void
+handle_edit_started (GtkCellRendererText * renderer, GtkCellEditable * editable,
+                     gchar * path, TimezoneCompletion * completion)
+{
+  if (GTK_IS_ENTRY (editable)) {
+    GtkEntry *entry = GTK_ENTRY (editable);
+    gtk_entry_set_completion (entry, GTK_ENTRY_COMPLETION (timezone_completion_new ()));
+  }
+}
+
 static void
 fill_from_settings (GObject * store, GSettings * conf)
 {
@@ -161,8 +172,10 @@ datetime_setup_locations_dialog (GtkWindow * parent)
   GObject * store = gtk_builder_get_object (builder, "locationsStore");
 
   /* Configure tree */
+  TimezoneCompletion * completion = timezone_completion_new ();
   GtkCellRenderer * cell = gtk_cell_renderer_text_new ();
   g_object_set (cell, "editable", TRUE, NULL);
+  g_signal_connect (cell, "editing-started", G_CALLBACK (handle_edit_started), completion);
   g_signal_connect (cell, "edited", G_CALLBACK (handle_edit), store);
   gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (tree), -1,
                                                _("Location"), cell,
@@ -181,7 +194,9 @@ datetime_setup_locations_dialog (GtkWindow * parent)
   g_signal_connect (WIG ("removeButton"), "clicked", G_CALLBACK (handle_remove), tree);
 
   fill_from_settings (store, conf);
+
   g_object_set_data_full (G_OBJECT (dlg), "conf", g_object_ref (conf), g_object_unref);
+  g_object_set_data_full (G_OBJECT (dlg), "completion", completion, g_object_unref);
   g_signal_connect (dlg, "destroy", G_CALLBACK (save_to_settings), store);
 
   gtk_window_set_transient_for (GTK_WINDOW (dlg), parent);
diff --git a/src/datetime-prefs.c b/src/datetime-prefs.c
index ee4b26a..dbacee1 100644
--- a/src/datetime-prefs.c
+++ b/src/datetime-prefs.c
@@ -36,6 +36,7 @@ with this program.  If not, see .
 #include "settings-shared.h"
 #include "utils.h"
 #include "datetime-prefs-locations.h"
+#include "timezone-completion.h"
 #include "cc-timezone-map.h"
 
 #define DATETIME_DIALOG_UI_FILE PKGDATADIR "/datetime-dialog.ui"
@@ -176,8 +177,10 @@ tz_changed (CcTimezoneMap * map, TzLocation * location)
   if (location == NULL)
     return;
 
-  g_dbus_proxy_call (proxy, "SetTimezone", g_variant_new ("(s)", location->zone),
+  gchar * file = g_build_filename ("/usr/share/zoneinfo", location->zone, NULL);
+  g_dbus_proxy_call (proxy, "SetTimezone", g_variant_new ("(s)", file),
                      G_DBUS_CALL_FLAGS_NONE, -1, NULL, dbus_set_answered, "timezone");
+  g_free (file);
 }
 
 static void
@@ -371,6 +374,25 @@ show_locations (GtkWidget * button, GtkWidget * dlg)
   gtk_widget_show_all (locationsDlg);
 }
 
+static gboolean
+timezone_selected (GtkEntryCompletion * widget, GtkTreeModel * model,
+                   GtkTreeIter * iter, gpointer user_data)
+{
+  GValue value = {0};
+  const gchar * strval;
+
+  gtk_tree_model_get_value (model, iter, TIMEZONE_COMPLETION_ZONE, &value);
+  strval = g_value_get_string (&value);
+
+  if (strval != NULL && strval[0] != 0) {
+    cc_timezone_map_set_timezone (tzmap, strval);
+  }
+
+  g_value_unset (&value);
+
+  return FALSE; // Do normal action too
+}
+
 static GtkWidget *
 create_dialog (void)
 {
@@ -401,6 +423,12 @@ create_dialog (void)
   tzmap = cc_timezone_map_new ();
   gtk_container_add (GTK_CONTAINER (WIG ("mapBox")), GTK_WIDGET (tzmap));
 
+  /* And completion entry */
+  TimezoneCompletion * completion = timezone_completion_new ();
+  gtk_entry_set_completion (GTK_ENTRY (WIG ("timezoneEntry")),
+                            GTK_ENTRY_COMPLETION (completion));
+  g_signal_connect (completion, "match-selected", G_CALLBACK (timezone_selected), NULL);
+
   /* Set up settings bindings */
   g_settings_bind (conf, SETTINGS_SHOW_CLOCK_S, WIG ("showClockCheck"),
                    "active", G_SETTINGS_BIND_DEFAULT);
diff --git a/src/timezone-completion.c b/src/timezone-completion.c
new file mode 100644
index 0000000..d98654a
--- /dev/null
+++ b/src/timezone-completion.c
@@ -0,0 +1,131 @@
+/* -*- Mode: C; coding: utf-8; indent-tabs-mode: nil; tab-width: 2 -*-
+
+Copyright 2011 Canonical Ltd.
+
+Authors:
+    Michael Terry 
+
+This program is free software: you can redistribute it and/or modify it 
+under the terms of the GNU General Public License version 3, as published 
+by the Free Software Foundation.
+
+This program is distributed in the hope that it will be useful, but 
+WITHOUT ANY WARRANTY; without even the implied warranties of 
+MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR 
+PURPOSE.  See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along 
+with this program.  If not, see .
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include 
+#include 
+#include "timezone-completion.h"
+#include "tz.h"
+
+enum {
+  LAST_SIGNAL
+};
+
+/* static guint signals[LAST_SIGNAL] = { }; */
+
+typedef struct _TimezoneCompletionPrivate TimezoneCompletionPrivate;
+struct _TimezoneCompletionPrivate
+{
+  void * placeholder;
+};
+
+#define TIMEZONE_COMPLETION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), TIMEZONE_COMPLETION_TYPE, TimezoneCompletionPrivate))
+
+/* Prototypes */
+static void timezone_completion_class_init (TimezoneCompletionClass *klass);
+static void timezone_completion_init       (TimezoneCompletion *self);
+static void timezone_completion_dispose    (GObject *object);
+static void timezone_completion_finalize   (GObject *object);
+
+G_DEFINE_TYPE (TimezoneCompletion, timezone_completion, GTK_TYPE_ENTRY_COMPLETION);
+
+static GtkListStore *
+get_initial_model (void)
+{
+  TzDB * db = tz_load_db ();
+  GPtrArray * locations = tz_get_locations (db);
+
+  GtkListStore * store = gtk_list_store_new (TIMEZONE_COMPLETION_LAST, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
+
+  gint i;
+  for (i = 0; i < locations->len; ++i) {
+    TzLocation * loc = g_ptr_array_index (locations, i);
+    GtkTreeIter iter;
+    gtk_list_store_append (store, &iter);
+
+    /* FIXME: need something better than below for non-English locales */
+    const gchar * last_bit = ((const gchar *)strrchr (loc->zone, '/')) + 1;
+    if (last_bit == NULL)
+      last_bit = loc->zone;
+    gchar * name = g_strdup (last_bit);
+    gchar * underscore;
+    while ((underscore = strchr (name, '_'))) {
+       *underscore = ' ';
+    }
+
+    gtk_list_store_set (store, &iter,
+                        TIMEZONE_COMPLETION_ZONE, loc->zone,
+                        TIMEZONE_COMPLETION_NAME, name,
+                        TIMEZONE_COMPLETION_COUNTRY, loc->country,
+                        -1);
+
+    g_free (name);
+  }
+
+  tz_db_free (db);
+  return store;
+}
+
+static void
+timezone_completion_class_init (TimezoneCompletionClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  g_type_class_add_private (klass, sizeof (TimezoneCompletionPrivate));
+
+  object_class->dispose = timezone_completion_dispose;
+  object_class->finalize = timezone_completion_finalize;
+
+  return;
+}
+
+static void
+timezone_completion_init (TimezoneCompletion *self)
+{
+  GtkListStore * model = get_initial_model ();
+  gtk_entry_completion_set_model (GTK_ENTRY_COMPLETION (self), GTK_TREE_MODEL (model));
+  gtk_entry_completion_set_text_column (GTK_ENTRY_COMPLETION (self), TIMEZONE_COMPLETION_NAME);
+  return;
+}
+
+static void
+timezone_completion_dispose (GObject *object)
+{
+  G_OBJECT_CLASS (timezone_completion_parent_class)->dispose (object);
+  return;
+}
+
+static void
+timezone_completion_finalize (GObject *object)
+{
+  G_OBJECT_CLASS (timezone_completion_parent_class)->finalize (object);
+  return;
+}
+
+TimezoneCompletion *
+timezone_completion_new ()
+{
+  TimezoneCompletion * self = g_object_new (TIMEZONE_COMPLETION_TYPE, NULL);
+  return self;
+}
+
diff --git a/src/timezone-completion.h b/src/timezone-completion.h
new file mode 100644
index 0000000..6b3ac2b
--- /dev/null
+++ b/src/timezone-completion.h
@@ -0,0 +1,59 @@
+/* -*- Mode: C; coding: utf-8; indent-tabs-mode: nil; tab-width: 2 -*-
+
+Copyright 2011 Canonical Ltd.
+
+Authors:
+    Michael Terry 
+
+This program is free software: you can redistribute it and/or modify it 
+under the terms of the GNU General Public License version 3, as published 
+by the Free Software Foundation.
+
+This program is distributed in the hope that it will be useful, but 
+WITHOUT ANY WARRANTY; without even the implied warranties of 
+MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR 
+PURPOSE.  See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along 
+with this program.  If not, see .
+*/
+
+#ifndef __TIMEZONE_COMPLETION_H__
+#define __TIMEZONE_COMPLETION_H__
+
+#include 
+#include 
+#include 
+
+G_BEGIN_DECLS
+
+#define TIMEZONE_COMPLETION_TYPE            (timezone_completion_get_type ())
+#define TIMEZONE_COMPLETION(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), TIMEZONE_COMPLETION_TYPE, TimezoneCompletion))
+#define TIMEZONE_COMPLETION_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), TIMEZONE_COMPLETION_TYPE, TimezoneCompletionClass))
+#define IS_TIMEZONE_COMPLETION(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TIMEZONE_COMPLETION_TYPE))
+#define IS_TIMEZONE_COMPLETION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TIMEZONE_COMPLETION_TYPE))
+#define TIMEZONE_COMPLETION_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), TIMEZONE_COMPLETION_TYPE, TimezoneCompletionClass))
+
+typedef struct _TimezoneCompletion      TimezoneCompletion;
+typedef struct _TimezoneCompletionClass TimezoneCompletionClass;
+
+struct _TimezoneCompletionClass {
+  GtkEntryCompletionClass parent_class;
+};
+
+struct _TimezoneCompletion {
+  GtkEntryCompletion parent;
+};
+
+#define TIMEZONE_COMPLETION_ZONE    0
+#define TIMEZONE_COMPLETION_NAME    1
+#define TIMEZONE_COMPLETION_COUNTRY 2
+#define TIMEZONE_COMPLETION_LAST    3
+
+GType timezone_completion_get_type (void);
+TimezoneCompletion * timezone_completion_new ();
+
+G_END_DECLS
+
+#endif /* __TIMEZONE_COMPLETION_H__ */
+
-- 
cgit v1.2.3


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

---
 configure.ac                   |   2 +
 data/datetime-dialog.ui        |   2 +
 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 +++++
 po/POTFILES.in                 |   2 +
 src/datetime-prefs-locations.c | 147 +++++++++++--
 src/datetime-prefs-locations.h |   3 +-
 src/datetime-prefs.c           |  29 ++-
 src/indicator-datetime.c       | 173 +--------------
 src/settings-shared.h          |  19 ++
 src/timezone-completion.c      | 227 +++++++++++++++++++-
 src/timezone-completion.h      |  12 +-
 src/utils.c                    | 188 +++++++++++++++++
 src/utils.h                    |   3 +
 18 files changed, 1120 insertions(+), 210 deletions(-)

diff --git a/configure.ac b/configure.ac
index bcedddc..08707bc 100644
--- a/configure.ac
+++ b/configure.ac
@@ -125,12 +125,14 @@ AS_IF([test "x$with_gtk" = x3],
 	[PKG_CHECK_MODULES(PREF, gio-2.0 >= $GIO_REQUIRED_VERSION
 	                         gtk+-3.0 >= $GTK3_REQUIRED_VERSION
                                  unique-3.0
+                                 json-glib-1.0
                                  polkit-gtk-1)
 		],
       [test "x$with_gtk" = x2],
 	[PKG_CHECK_MODULES(PREF, gio-2.0 >= $GIO_REQUIRED_VERSION
 	                         gtk+-2.0 >= $GTK_REQUIRED_VERSION
                                  unique-1.0
+                                 json-glib-1.0
                                  polkit-gtk-1)
         ],
     [AC_MSG_FAILURE([Value for --with-gtk was neither 2 nor 3])]
diff --git a/data/datetime-dialog.ui b/data/datetime-dialog.ui
index 26c368b..8b48702 100644
--- a/data/datetime-dialog.ui
+++ b/data/datetime-dialog.ui
@@ -98,6 +98,8 @@
       
       
       
+      
+      
     
   
   
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)
 {
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 0fa22d4..84ce021 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -2,4 +2,6 @@ src/indicator-datetime.c
 src/datetime-service.c
 src/datetime-prefs.c
 src/datetime-prefs-locations.c
+src/utils.c
+src/settings-shared.h
 [type: gettext/glade]data/datetime-dialog.ui
diff --git a/src/datetime-prefs-locations.c b/src/datetime-prefs-locations.c
index b13d082..e29580f 100644
--- a/src/datetime-prefs-locations.c
+++ b/src/datetime-prefs-locations.c
@@ -24,11 +24,13 @@ with this program.  If not, see .
 #include "config.h"
 #endif
 
-#include 
+#include 
+#include 
 #include 
 
 #include "datetime-prefs-locations.h"
 #include "settings-shared.h"
+#include "utils.h"
 #include "timezone-completion.h"
 
 #define DATETIME_DIALOG_UI_FILE PKGDATADIR "/datetime-dialog.ui"
@@ -86,14 +88,105 @@ handle_edit (GtkCellRendererText * renderer, gchar * path, gchar * new_text,
   }
 }
 
+static gboolean
+timezone_selected (GtkEntryCompletion * widget, GtkTreeModel * model,
+                   GtkTreeIter * iter, gpointer user_data)
+{
+  GValue zone_value = {0}, name_value = {0};
+  const gchar * zone, * name;
+
+  gtk_tree_model_get_value (model, iter, TIMEZONE_COMPLETION_ZONE, &zone_value);
+  zone = g_value_get_string (&zone_value);
+
+  gtk_tree_model_get_value (model, iter, TIMEZONE_COMPLETION_NAME, &name_value);
+  name = g_value_get_string (&name_value);
+
+  if (zone == NULL || zone[0] == 0) {
+    GValue lon_value = {0}, lat_value = {0};
+    const gchar * strlon, * strlat;
+    gdouble lon = 0.0, lat = 0.0;
+
+    gtk_tree_model_get_value (model, iter, TIMEZONE_COMPLETION_LONGITUDE, &lon_value);
+    strlon = g_value_get_string (&lon_value);
+    if (strlon != NULL && strlon[0] != 0) {
+      lon = strtod(strlon, NULL);
+    }
+
+    gtk_tree_model_get_value (model, iter, TIMEZONE_COMPLETION_LATITUDE, &lat_value);
+    strlat = g_value_get_string (&lat_value);
+    if (strlat != NULL && strlat[0] != 0) {
+      lat = strtod(strlat, NULL);
+    }
+
+    CcTimezoneMap * tzmap = CC_TIMEZONE_MAP (g_object_get_data (G_OBJECT (widget), "tzmap"));
+    zone = cc_timezone_map_get_timezone_at_coords (tzmap, lon, lat);
+  }
+
+  GtkListStore * store = GTK_LIST_STORE (g_object_get_data (G_OBJECT (widget), "store"));
+  GtkTreeIter * store_iter = (GtkTreeIter *)g_object_get_data (G_OBJECT (widget), "store_iter");
+  if (store != NULL && store_iter != NULL) {
+    gtk_list_store_set (store, store_iter, 0, name, 2, zone, -1);
+  }
+
+  g_value_unset (&name_value);
+  g_value_unset (&zone_value);
+
+  return FALSE; // Do normal action too
+}
+
 static void
 handle_edit_started (GtkCellRendererText * renderer, GtkCellEditable * editable,
                      gchar * path, TimezoneCompletion * completion)
 {
   if (GTK_IS_ENTRY (editable)) {
     GtkEntry *entry = GTK_ENTRY (editable);
-    gtk_entry_set_completion (entry, GTK_ENTRY_COMPLETION (timezone_completion_new ()));
+    gtk_entry_set_completion (entry, GTK_ENTRY_COMPLETION (completion));
+    timezone_completion_watch_entry (completion, entry);
+
+    GtkListStore * store = GTK_LIST_STORE (g_object_get_data (G_OBJECT (completion), "store"));
+    GtkTreeIter * store_iter = g_new(GtkTreeIter, 1);
+    if (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (store), store_iter, path)) {
+      g_object_set_data_full (G_OBJECT (completion), "store_iter", store_iter, g_free);
+    }
+  }
+}
+
+static gboolean
+update_times (GtkListStore * store)
+{
+  /* For each entry, check zone in column 2 and set column 1 to it's time */
+
+  GDateTime * now = g_date_time_new_now_local ();
+
+  GtkTreeIter iter;
+  if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter)) {
+    do {
+      GValue zone_value = {0};
+      const gchar * strzone;
+
+      gtk_tree_model_get_value (GTK_TREE_MODEL (store), &iter, 2, &zone_value);
+      strzone = g_value_get_string (&zone_value);
+
+      if (strzone != NULL && strzone[0] != 0) {
+        GTimeZone * tz = g_time_zone_new (strzone);
+        GDateTime * now_tz = g_date_time_to_timezone (now, tz);
+        gchar * format = generate_format_string_at_time (now_tz);
+        gchar * time_str = g_date_time_format (now_tz, format);
+
+        gtk_list_store_set (store, &iter, 1, time_str, -1);
+
+        g_free (time_str);
+        g_free (format);
+        g_date_time_unref (now_tz);
+        g_time_zone_unref (tz);
+      }
+
+      g_value_unset (&zone_value);
+    } while (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter));
   }
+
+  g_date_time_unref (now);
+  return TRUE;
 }
 
 static void
@@ -106,30 +199,50 @@ fill_from_settings (GObject * store, GSettings * conf)
   gchar ** striter;
   GtkTreeIter iter;
   for (striter = locations; *striter; ++striter) {
+    gchar * zone, * name;
+    split_settings_location (*striter, &zone, &name);
+
     gtk_list_store_append (GTK_LIST_STORE (store), &iter);
-    gtk_list_store_set (GTK_LIST_STORE (store), &iter, 0, *striter, -1);
+    gtk_list_store_set (GTK_LIST_STORE (store), &iter, 0, name, 2, zone, -1);
+
+    g_free (zone);
+    g_free (name);
   }
 
   g_strfreev (locations);
 }
 
 static void
-save_to_settings (GtkWidget * dlg, GObject * store)
+dialog_closed (GtkWidget * dlg, GObject * store)
 {
+  /* Cleanup a tad */
+  guint time_id = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (dlg), "time-id"));
+  g_source_remove (time_id);
+
+  /* Now save to settings */
   GVariantBuilder builder;
   g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY);
 
   GtkTreeIter iter;
   if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter)) {
     do {
-      GValue value = {0};
-      const gchar * strval;
-      gtk_tree_model_get_value (GTK_TREE_MODEL (store), &iter, 0, &value);
-      strval = g_value_get_string (&value);
-      if (strval != NULL && strval[0] != 0) {
-        g_variant_builder_add (&builder, "s", strval);
+      GValue zone_value = {0}, name_value = {0};
+      const gchar * strzone, * strname;
+
+      gtk_tree_model_get_value (GTK_TREE_MODEL (store), &iter, 0, &name_value);
+      gtk_tree_model_get_value (GTK_TREE_MODEL (store), &iter, 2, &zone_value);
+
+      strzone = g_value_get_string (&zone_value);
+      strname = g_value_get_string (&name_value);
+
+      if (strzone != NULL && strzone[0] != 0 && strname != NULL && strname[0] != 0) {
+        gchar * settings_string = g_strdup_printf("%s %s", strzone, strname);
+        g_variant_builder_add (&builder, "s", settings_string);
+        g_free (settings_string);
       }
-      g_value_unset (&value);
+
+      g_value_unset (&zone_value);
+      g_value_unset (&name_value);
     } while (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter));
   }
 
@@ -149,7 +262,7 @@ selection_changed (GtkTreeSelection * selection, GtkWidget * remove_button)
 }
 
 GtkWidget *
-datetime_setup_locations_dialog (GtkWindow * parent)
+datetime_setup_locations_dialog (GtkWindow * parent, CcTimezoneMap * map)
 {
   GError * error = NULL;
   GtkBuilder * builder = gtk_builder_new ();
@@ -173,6 +286,10 @@ datetime_setup_locations_dialog (GtkWindow * parent)
 
   /* Configure tree */
   TimezoneCompletion * completion = timezone_completion_new ();
+  g_object_set_data (G_OBJECT (completion), "tzmap", map);
+  g_object_set_data (G_OBJECT (completion), "store", store);
+  g_signal_connect (completion, "match-selected", G_CALLBACK (timezone_selected), NULL);
+
   GtkCellRenderer * cell = gtk_cell_renderer_text_new ();
   g_object_set (cell, "editable", TRUE, NULL);
   g_signal_connect (cell, "editing-started", G_CALLBACK (handle_edit_started), completion);
@@ -195,9 +312,13 @@ datetime_setup_locations_dialog (GtkWindow * parent)
 
   fill_from_settings (store, conf);
 
+  guint time_id = g_timeout_add_seconds (2, (GSourceFunc)update_times, store);
+  update_times (GTK_LIST_STORE (store));
+
   g_object_set_data_full (G_OBJECT (dlg), "conf", g_object_ref (conf), g_object_unref);
   g_object_set_data_full (G_OBJECT (dlg), "completion", completion, g_object_unref);
-  g_signal_connect (dlg, "destroy", G_CALLBACK (save_to_settings), store);
+  g_object_set_data (G_OBJECT (dlg), "time-id", GINT_TO_POINTER(time_id));
+  g_signal_connect (dlg, "destroy", G_CALLBACK (dialog_closed), store);
 
   gtk_window_set_transient_for (GTK_WINDOW (dlg), parent);
 
diff --git a/src/datetime-prefs-locations.h b/src/datetime-prefs-locations.h
index d5dd534..1760567 100644
--- a/src/datetime-prefs-locations.h
+++ b/src/datetime-prefs-locations.h
@@ -24,10 +24,11 @@ with this program.  If not, see .
 #define __DATETIME_PREFS_LOCATIONS_H__
 
 #include 
+#include "cc-timezone-map.h"
 
 G_BEGIN_DECLS
 
-GtkWidget * datetime_setup_locations_dialog (GtkWindow * parent);
+GtkWidget * datetime_setup_locations_dialog (GtkWindow * parent, CcTimezoneMap * map);
 
 G_END_DECLS
 
diff --git a/src/datetime-prefs.c b/src/datetime-prefs.c
index dbacee1..622a999 100644
--- a/src/datetime-prefs.c
+++ b/src/datetime-prefs.c
@@ -25,6 +25,7 @@ with this program.  If not, see .
 #include "config.h"
 #endif
 
+#include 
 #include 
 #include 
 #include 
@@ -104,7 +105,7 @@ add_widget_dependency (GtkWidget * parent, GtkWidget * dependent)
   widget_dependency_cb (parent, NULL, dependent);
 }
 
-static void
+/*static void
 polkit_dependency_cb (GtkWidget * parent, GParamSpec *pspec, GtkWidget * dependent)
 {
   gboolean authorized, sensitive;
@@ -122,7 +123,7 @@ add_polkit_dependency (GtkWidget * parent, GtkWidget * dependent)
   g_signal_connect (parent, "notify::sensitive", G_CALLBACK(polkit_dependency_cb),
                     dependent);
   polkit_dependency_cb (parent, NULL, dependent);
-}
+}*/
 
 static void
 dbus_set_answered (GObject *object, GAsyncResult *res, gpointer command)
@@ -370,7 +371,7 @@ setup_time_spinner (GtkWidget * spinner, GtkWidget * other, gboolean is_time)
 static void
 show_locations (GtkWidget * button, GtkWidget * dlg)
 {
-  GtkWidget * locationsDlg = datetime_setup_locations_dialog (GTK_WINDOW (dlg));
+  GtkWidget * locationsDlg = datetime_setup_locations_dialog (GTK_WINDOW (dlg), tzmap);
   gtk_widget_show_all (locationsDlg);
 }
 
@@ -387,6 +388,25 @@ timezone_selected (GtkEntryCompletion * widget, GtkTreeModel * model,
   if (strval != NULL && strval[0] != 0) {
     cc_timezone_map_set_timezone (tzmap, strval);
   }
+  else {
+    GValue lon_value = {0}, lat_value = {0};
+    const gchar * strlon, * strlat;
+    gdouble lon = 0.0, lat = 0.0;
+
+    gtk_tree_model_get_value (model, iter, TIMEZONE_COMPLETION_LONGITUDE, &lon_value);
+    strlon = g_value_get_string (&lon_value);
+    if (strlon != NULL && strlon[0] != 0) {
+      lon = strtod(strlon, NULL);
+    }
+
+    gtk_tree_model_get_value (model, iter, TIMEZONE_COMPLETION_LATITUDE, &lat_value);
+    strlat = g_value_get_string (&lat_value);
+    if (strlat != NULL && strlat[0] != 0) {
+      lat = strtod(strlat, NULL);
+    }
+
+    cc_timezone_map_set_coords (tzmap, lon, lat);
+  }
 
   g_value_unset (&value);
 
@@ -427,6 +447,7 @@ create_dialog (void)
   TimezoneCompletion * completion = timezone_completion_new ();
   gtk_entry_set_completion (GTK_ENTRY (WIG ("timezoneEntry")),
                             GTK_ENTRY_COMPLETION (completion));
+  timezone_completion_watch_entry (completion, GTK_ENTRY (WIG ("timezoneEntry")));
   g_signal_connect (completion, "match-selected", G_CALLBACK (timezone_selected), NULL);
 
   /* Set up settings bindings */
@@ -464,7 +485,7 @@ create_dialog (void)
   add_widget_dependency (WIG ("showClockCheck"), WIG ("clockOptions"));
   add_widget_dependency (WIG ("showLocationsCheck"), WIG ("locationsButton"));
   add_widget_dependency (WIG ("manualTimeRadio"), WIG ("manualOptions"));
-  add_polkit_dependency (polkit_button, WIG ("timeDateOptions"));
+  //add_polkit_dependency (polkit_button, WIG ("timeDateOptions"));
 
   /* Hacky proxy test for whether evolution-data-server is installed */
   gchar * evo_path = g_find_program_in_path ("evolution");
diff --git a/src/indicator-datetime.c b/src/indicator-datetime.c
index 5e73612..fb421cb 100644
--- a/src/indicator-datetime.c
+++ b/src/indicator-datetime.c
@@ -119,23 +119,6 @@ struct _indicator_item_t {
 #define PROP_SHOW_DATE_S                "show-date"
 #define PROP_CUSTOM_TIME_FORMAT_S       "custom-time-format"
 
-enum {
-	SETTINGS_TIME_LOCALE = 0,
-	SETTINGS_TIME_12_HOUR = 1,
-	SETTINGS_TIME_24_HOUR = 2,
-	SETTINGS_TIME_CUSTOM = 3
-};
-
-/* TRANSLATORS: A format string for the strftime function for
-   a clock showing 12-hour time without seconds. */
-#define DEFAULT_TIME_12_FORMAT   N_("%l:%M %p")
-
-/* TRANSLATORS: A format string for the strftime function for
-   a clock showing 24-hour time without seconds. */
-#define DEFAULT_TIME_24_FORMAT   N_("%H:%M")
-
-#define DEFAULT_TIME_FORMAT      DEFAULT_TIME_12_FORMAT
-
 #define INDICATOR_DATETIME_GET_PRIVATE(o) \
 (G_TYPE_INSTANCE_GET_PRIVATE ((o), INDICATOR_DATETIME_TYPE, IndicatorDatetimePrivate))
 
@@ -165,7 +148,6 @@ static const gchar * get_accessible_desc  (IndicatorObject * io);
 static GVariant * bind_enum_set           (const GValue * value, const GVariantType * type, gpointer user_data);
 static gboolean bind_enum_get             (GValue * value, GVariant * variant, gpointer user_data);
 static gchar * generate_format_string_now (IndicatorDatetime * self);
-static gchar * generate_format_string_at_time (IndicatorDatetime * self, GDateTime * time);
 static void update_label                  (IndicatorDatetime * io, GDateTime ** datetime);
 static void guess_label_size              (IndicatorDatetime * self);
 static void setup_timer                   (IndicatorDatetime * self, GDateTime * datetime);
@@ -643,7 +625,7 @@ set_label_to_time_in_zone (IndicatorDatetime * self, GtkLabel * label,
 
 	gchar * timestr;
 	if (format == NULL) {
-		gchar * format_for_time = generate_format_string_at_time(self, datetime_now);
+		gchar * format_for_time = generate_format_string_at_time(datetime_now);
 		timestr = g_date_time_format(datetime_now, format_for_time);
 		g_free(format_for_time);
 	}
@@ -987,41 +969,6 @@ style_changed (GtkWidget * widget, GtkStyle * oldstyle, gpointer data)
 	return;
 }
 
-/* Translate msg according to the locale specified by LC_TIME */
-static char *
-T_(const char *msg)
-{
-	/* General strategy here is to make sure LANGUAGE is empty (since that
-	   trumps all LC_* vars) and then to temporarily swap LC_TIME and
-	   LC_MESSAGES.  Then have gettext translate msg.
-
-	   We strdup the strings because the setlocale & *env functions do not
-	   guarantee anything about the storage used for the string, and thus
-	   the string may not be portably safe after multiple calls.
-
-	   Note that while you might think g_dcgettext would do the trick here,
-	   that actually looks in /usr/share/locale/XX/LC_TIME, not the
-	   LC_MESSAGES directory, so we won't find any translation there.
-	*/
-	char *message_locale = g_strdup(setlocale(LC_MESSAGES, NULL));
-	char *time_locale = g_strdup(setlocale(LC_TIME, NULL));
-	char *language = g_strdup(g_getenv("LANGUAGE"));
-	char *rv;
-	g_unsetenv("LANGUAGE");
-	setlocale(LC_MESSAGES, time_locale);
-
-	/* Get the LC_TIME version */
-	rv = _(msg);
-
-	/* Put everything back the way it was */
-	setlocale(LC_MESSAGES, message_locale);
-	g_setenv("LANGUAGE", language, TRUE);
-	g_free(message_locale);
-	g_free(time_locale);
-	g_free(language);
-	return rv;
-}
-
 /* Respond to changes in the screen to update the text gravity */
 static void
 update_text_gravity (GtkWidget *widget, GdkScreen *previous_screen, gpointer data)
@@ -1037,71 +984,6 @@ update_text_gravity (GtkWidget *widget, GdkScreen *previous_screen, gpointer dat
 	pango_context_set_base_gravity(context, PANGO_GRAVITY_AUTO);
 }
 
-/* Tries to figure out what our format string should be.  Lots
-   of translator comments in here. */
-static gchar *
-generate_format_string_full (IndicatorDatetime * self, gboolean show_day, gboolean show_date)
-{
-	gboolean twelvehour = TRUE;
-
-	if (self->priv->time_mode == SETTINGS_TIME_LOCALE) {
-		twelvehour = is_locale_12h();
-	} else if (self->priv->time_mode == SETTINGS_TIME_24_HOUR) {
-		twelvehour = FALSE;
-	}
-
-	const gchar * time_string = NULL;
-	if (twelvehour) {
-		if (self->priv->show_seconds) {
-			/* TRANSLATORS: A format string for the strftime function for
-			   a clock showing 12-hour time with seconds. */
-			time_string = T_("%l:%M:%S %p");
-		} else {
-			time_string = T_(DEFAULT_TIME_12_FORMAT);
-		}
-	} else {
-		if (self->priv->show_seconds) {
-			/* TRANSLATORS: A format string for the strftime function for
-			   a clock showing 24-hour time with seconds. */
-			time_string = T_("%H:%M:%S");
-		} else {
-			time_string = T_(DEFAULT_TIME_24_FORMAT);
-		}
-	}
-	
-	/* Checkpoint, let's not fail */
-	g_return_val_if_fail(time_string != NULL, g_strdup(DEFAULT_TIME_FORMAT));
-
-	/* If there's no date or day let's just leave now and
-	   not worry about the rest of this code */
-	if (!show_date && !show_day) {
-		return g_strdup(time_string);
-	}
-
-	const gchar * date_string = NULL;
-	if (show_date && show_day) {
-		/* TRANSLATORS:  This is a format string passed to strftime to represent
-		   the day of the week, the month and the day of the month. */
-		date_string = T_("%a %b %e");
-	} else if (show_date) {
-		/* TRANSLATORS:  This is a format string passed to strftime to represent
-		   the month and the day of the month. */
-		date_string = T_("%b %e");
-	} else if (show_day) {
-		/* TRANSLATORS:  This is a format string passed to strftime to represent
-		   the day of the week. */
-		date_string = T_("%a");
-	}
-
-	/* Check point, we should have a date string */
-	g_return_val_if_fail(date_string != NULL, g_strdup(time_string));
-
-	/* TRANSLATORS: This is a format string passed to strftime to combine the
-	   date and the time.  The value of "%s, %s" would result in a string like
-	   this in US English 12-hour time: 'Fri Jul 16, 11:50 AM' */
-	return g_strdup_printf(T_("%s, %s"), date_string, time_string);
-}
-
 static gchar *
 generate_format_string_now (IndicatorDatetime * self)
 {
@@ -1109,62 +991,11 @@ generate_format_string_now (IndicatorDatetime * self)
 		return g_strdup(self->priv->custom_string);
 	}
 	else {
-		return generate_format_string_full(self,
-		                                   self->priv->show_day,
+		return generate_format_string_full(self->priv->show_day,
 		                                   self->priv->show_date);
 	}
 }
 
-static gchar *
-generate_format_string_at_time (IndicatorDatetime * self, GDateTime * time)
-{
-	/* This is a bit less free-form than for the main "now" time label. */
-	/* If it is today, just the time should be shown (e.g. “3:55 PM”)
-           If it is a different day this week, the day and time should be shown (e.g. “Wed 3:55 PM”)
-           If it is after this week, the day, date, and time should be shown (e.g. “Wed 21 Apr 3:55 PM”). 
-           In addition, when presenting the times of upcoming events, the time should be followed by the timezone if it is different from the one the computer is currently set to. For example, “Wed 3:55 PM UTC−5”. */
-	gboolean show_day = FALSE;
-	gboolean show_date = FALSE;
-
-	GDateTime * now = g_date_time_new_now_local();
-
-	/* First, are we same day? */
-	gint time_year, time_month, time_day;
-	gint now_year, now_month, now_day;
-	g_date_time_get_ymd(time, &time_year, &time_month, &time_day);
-	g_date_time_get_ymd(now, &now_year, &now_month, &now_day);
-
-	if (time_year != now_year ||
-	    time_month != now_month ||
-	    time_day != now_day) {
-		/* OK, different days so we must at least show the day. */
-		show_day = TRUE;
-
-		/* Is it this week? */
-		/* Here, we define "is this week" as yesterday, today, or the next five days */
-		GDateTime * past = g_date_time_add_days(now, -1);
-		GDateTime * future = g_date_time_add_days(now, 5);
-		GDateTime * past_bound = g_date_time_new_local(g_date_time_get_year(past),
-		                                               g_date_time_get_month(past),
-		                                               g_date_time_get_day_of_month(past),
-		                                               0, 0, 0.0);
-		GDateTime * future_bound = g_date_time_new_local(g_date_time_get_year(future),
-		                                                 g_date_time_get_month(future),
-		                                                 g_date_time_get_day_of_month(future),
-		                                                 23, 59, 59.9);
-		if (g_date_time_compare(time, past_bound) < 0 ||
-		    g_date_time_compare(time, future_bound) > 0) {
-			show_date = TRUE;
-		}
-		g_date_time_unref(past);
-		g_date_time_unref(future);
-		g_date_time_unref(past_bound);
-		g_date_time_unref(future_bound);
-	}
-
-	return generate_format_string_full(self, show_day, show_date);
-}
-
 static void
 timezone_update_labels (indicator_item_t * mi_data)
 {
diff --git a/src/settings-shared.h b/src/settings-shared.h
index 1a66688..d866b81 100644
--- a/src/settings-shared.h
+++ b/src/settings-shared.h
@@ -22,6 +22,8 @@ with this program.  If not, see .
 #ifndef __DATETIME_SETTINGS_SHARED_H__
 #define __DATETIME_SETTINGS_SHARED_H__
 
+#include 
+
 #define SETTINGS_INTERFACE              "com.canonical.indicator.datetime"
 #define SETTINGS_SHOW_CLOCK_S           "show-clock"
 #define SETTINGS_TIME_FORMAT_S          "time-format"
@@ -36,4 +38,21 @@ with this program.  If not, see .
 #define SETTINGS_SHOW_LOCATIONS_S       "show-locations"
 #define SETTINGS_LOCATIONS_S            "locations"
 
+enum {
+	SETTINGS_TIME_LOCALE = 0,
+	SETTINGS_TIME_12_HOUR = 1,
+	SETTINGS_TIME_24_HOUR = 2,
+	SETTINGS_TIME_CUSTOM = 3
+};
+
+/* TRANSLATORS: A format string for the strftime function for
+   a clock showing 12-hour time without seconds. */
+#define DEFAULT_TIME_12_FORMAT   N_("%l:%M %p")
+
+/* TRANSLATORS: A format string for the strftime function for
+   a clock showing 24-hour time without seconds. */
+#define DEFAULT_TIME_24_FORMAT   N_("%H:%M")
+
+#define DEFAULT_TIME_FORMAT      DEFAULT_TIME_12_FORMAT
+
 #endif
diff --git a/src/timezone-completion.c b/src/timezone-completion.c
index d98654a..a1b4d00 100644
--- a/src/timezone-completion.c
+++ b/src/timezone-completion.c
@@ -22,6 +22,7 @@ with this program.  If not, see .
 #include "config.h"
 #endif
 
+#include 
 #include 
 #include 
 #include "timezone-completion.h"
@@ -36,10 +37,17 @@ enum {
 typedef struct _TimezoneCompletionPrivate TimezoneCompletionPrivate;
 struct _TimezoneCompletionPrivate
 {
-  void * placeholder;
+  GtkEntry *     entry;
+  guint          queued_request;
+  guint          changed_id;
+  GCancellable * cancel;
+  gchar *        request_text;
+  GHashTable *   request_table;
 };
 
-#define TIMEZONE_COMPLETION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), TIMEZONE_COMPLETION_TYPE, TimezoneCompletionPrivate))
+#define TIMEZONE_COMPLETION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), TIMEZONE_COMPLETION_TYPE, TimezoneCompletionPrivate))
+
+#define GEONAME_URL "http://geoname-lookup.ubuntu.com/?query=%s&release=%s"
 
 /* Prototypes */
 static void timezone_completion_class_init (TimezoneCompletionClass *klass);
@@ -49,13 +57,186 @@ static void timezone_completion_finalize   (GObject *object);
 
 G_DEFINE_TYPE (TimezoneCompletion, timezone_completion, GTK_TYPE_ENTRY_COMPLETION);
 
+static void
+json_parse_ready (GObject *object, GAsyncResult *res, gpointer user_data)
+{
+  TimezoneCompletion * completion = TIMEZONE_COMPLETION (user_data);
+  TimezoneCompletionPrivate * priv = TIMEZONE_COMPLETION_GET_PRIVATE(completion);
+  GError * error = NULL;
+
+  json_parser_load_from_stream_finish (JSON_PARSER (object), res, &error);
+
+  if (priv->cancel && (error == NULL || error->code != G_IO_ERROR_CANCELLED)) {
+    g_cancellable_reset (priv->cancel);
+  }
+
+  if (error != NULL) {
+    g_warning ("Could not parse geoname JSON data: %s", error->message);
+    g_error_free (error);
+    return;
+  }
+
+g_print("got json\n");
+  GtkListStore * store = GTK_LIST_STORE (gtk_entry_completion_get_model (GTK_ENTRY_COMPLETION (completion)));
+  JsonReader * reader = json_reader_new (json_parser_get_root (JSON_PARSER (object)));
+
+  if (!json_reader_is_array (reader))
+    return;
+
+  gint i, count = json_reader_count_elements (reader);
+  for (i = 0; i < count; ++i) {
+    if (!json_reader_read_element (reader, i))
+      continue;
+
+    if (json_reader_is_object (reader)) {
+      const gchar * name = NULL;
+      const gchar * admin1 = NULL;
+      const gchar * country = NULL;
+      const gchar * longitude = NULL;
+      const gchar * latitude = NULL;
+      if (json_reader_read_member (reader, "name")) {
+        name = json_reader_get_string_value (reader);
+        json_reader_end_member (reader);
+      }
+      if (json_reader_read_member (reader, "admin1")) {
+        admin1 = json_reader_get_string_value (reader);
+        json_reader_end_member (reader);
+      }
+      if (json_reader_read_member (reader, "country")) {
+        country = json_reader_get_string_value (reader);
+        json_reader_end_member (reader);
+      }
+      if (json_reader_read_member (reader, "longitude")) {
+        longitude = json_reader_get_string_value (reader);
+        json_reader_end_member (reader);
+      }
+      if (json_reader_read_member (reader, "latitude")) {
+        latitude = json_reader_get_string_value (reader);
+        json_reader_end_member (reader);
+      }
+
+g_print("adding %s\n", name);
+      GtkTreeIter iter;
+      gtk_list_store_append (store, &iter);
+      gtk_list_store_set (store, &iter,
+                          TIMEZONE_COMPLETION_ZONE, NULL,
+                          TIMEZONE_COMPLETION_NAME, name,
+                          TIMEZONE_COMPLETION_ADMIN1, admin1,
+                          TIMEZONE_COMPLETION_COUNTRY, country,
+                          TIMEZONE_COMPLETION_LONGITUDE, longitude,
+                          TIMEZONE_COMPLETION_LATITUDE, latitude,
+                          -1);
+    }
+
+    json_reader_end_element (reader);
+  }
+
+  g_hash_table_insert (priv->request_table, g_strdup (priv->request_text), NULL);
+}
+
+static void
+geonames_data_ready (GObject *object, GAsyncResult *res, gpointer user_data)
+{
+  TimezoneCompletion * completion = TIMEZONE_COMPLETION (user_data);
+  TimezoneCompletionPrivate * priv = TIMEZONE_COMPLETION_GET_PRIVATE (completion);
+  GError * error = NULL;
+  GFileInputStream * stream;
+
+  stream = g_file_read_finish (G_FILE (object), res, &error);
+
+  if (priv->cancel && (error == NULL || error->code != G_IO_ERROR_CANCELLED)) {
+    g_cancellable_reset (priv->cancel);
+  }
+
+  if (error != NULL) {
+    g_warning ("Could not connect to geoname lookup server: %s", error->message);
+    g_error_free (error);
+    return;
+  }
+
+  JsonParser * parser = json_parser_new ();
+  json_parser_load_from_stream_async (parser, G_INPUT_STREAM (stream), priv->cancel,
+                                      json_parse_ready, user_data);
+}
+
+static gboolean
+request_zones (TimezoneCompletion * completion)
+{
+  TimezoneCompletionPrivate * priv = TIMEZONE_COMPLETION_GET_PRIVATE (completion);
+
+  priv->queued_request = 0;
+
+g_print("requesting json?\n");
+  if (priv->entry == NULL) {
+    return FALSE;
+  }
+
+  const gchar * text = gtk_entry_get_text (priv->entry);
+
+  if (g_hash_table_lookup_extended (priv->request_table, text, NULL, NULL))
+    return FALSE; // already looked this up
+
+  /* Cancel any ongoing request */
+  if (priv->cancel) {
+    g_cancellable_cancel (priv->cancel);
+    g_cancellable_reset (priv->cancel);
+  }
+  g_free (priv->request_text);
+
+  priv->request_text = g_strdup (text);
+
+g_print("requesting json now\n");
+  gchar * escaped = g_uri_escape_string (text, NULL, FALSE);
+  gchar * url = g_strdup_printf (GEONAME_URL, escaped, "11.04");
+
+  GFile * file =  g_file_new_for_uri (url);
+  g_file_read_async (file, G_PRIORITY_DEFAULT, priv->cancel,
+                     geonames_data_ready, completion);
+
+  return FALSE;
+}
+
+static void
+entry_changed (GtkEntry * entry, TimezoneCompletion * completion)
+{
+  TimezoneCompletionPrivate * priv = TIMEZONE_COMPLETION_GET_PRIVATE (completion);
+
+  if (priv->queued_request) {
+    g_source_remove (priv->queued_request);
+  }
+  priv->queued_request = g_timeout_add (300, (GSourceFunc)request_zones, completion);
+}
+
+void
+timezone_completion_watch_entry (TimezoneCompletion * completion, GtkEntry * entry)
+{
+  TimezoneCompletionPrivate * priv = TIMEZONE_COMPLETION_GET_PRIVATE (completion);
+
+  if (priv->entry) {
+    g_source_remove (priv->changed_id);
+    g_object_remove_weak_pointer (G_OBJECT (priv->entry), (gpointer *)&priv->entry);
+  }
+
+  guint id = g_signal_connect (entry, "changed", G_CALLBACK (entry_changed), completion);
+  priv->changed_id = id;
+
+  priv->entry = entry;
+  g_object_add_weak_pointer (G_OBJECT (entry), (gpointer *)&priv->entry);
+}
+
 static GtkListStore *
 get_initial_model (void)
 {
   TzDB * db = tz_load_db ();
   GPtrArray * locations = tz_get_locations (db);
 
-  GtkListStore * store = gtk_list_store_new (TIMEZONE_COMPLETION_LAST, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
+  GtkListStore * store = gtk_list_store_new (TIMEZONE_COMPLETION_LAST,
+                                             G_TYPE_STRING,
+                                             G_TYPE_STRING,
+                                             G_TYPE_STRING,
+                                             G_TYPE_STRING,
+                                             G_TYPE_STRING,
+                                             G_TYPE_STRING);
 
   gint i;
   for (i = 0; i < locations->len; ++i) {
@@ -100,23 +281,57 @@ timezone_completion_class_init (TimezoneCompletionClass *klass)
 }
 
 static void
-timezone_completion_init (TimezoneCompletion *self)
+timezone_completion_init (TimezoneCompletion * self)
 {
+  TimezoneCompletionPrivate * priv = TIMEZONE_COMPLETION_GET_PRIVATE (self);
+
   GtkListStore * model = get_initial_model ();
   gtk_entry_completion_set_model (GTK_ENTRY_COMPLETION (self), GTK_TREE_MODEL (model));
   gtk_entry_completion_set_text_column (GTK_ENTRY_COMPLETION (self), TIMEZONE_COMPLETION_NAME);
+
+  priv->cancel = g_cancellable_new ();
+
+  priv->request_table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
+
   return;
 }
 
 static void
-timezone_completion_dispose (GObject *object)
+timezone_completion_dispose (GObject * object)
 {
   G_OBJECT_CLASS (timezone_completion_parent_class)->dispose (object);
+
+  TimezoneCompletion * completion = TIMEZONE_COMPLETION (object);
+  TimezoneCompletionPrivate * priv = TIMEZONE_COMPLETION_GET_PRIVATE (completion);
+
+  if (priv->changed_id) {
+    g_source_remove (priv->changed_id);
+    priv->changed_id = 0;
+  }
+
+  if (priv->entry != NULL) {
+    g_object_remove_weak_pointer (G_OBJECT (priv->entry), (gpointer *)&priv->entry);
+  }
+
+  if (priv->queued_request) {
+    g_source_remove (priv->queued_request);
+    priv->queued_request = 0;
+  }
+
+  if (priv->cancel != NULL) {
+    g_cancellable_cancel (priv->cancel);
+    g_object_unref (priv->cancel);
+    priv->cancel = NULL;
+  }
+
+  g_free (priv->request_text);
+  g_hash_table_destroy (priv->request_table);
+
   return;
 }
 
 static void
-timezone_completion_finalize (GObject *object)
+timezone_completion_finalize (GObject * object)
 {
   G_OBJECT_CLASS (timezone_completion_parent_class)->finalize (object);
   return;
diff --git a/src/timezone-completion.h b/src/timezone-completion.h
index 6b3ac2b..fdfb234 100644
--- a/src/timezone-completion.h
+++ b/src/timezone-completion.h
@@ -45,13 +45,17 @@ struct _TimezoneCompletion {
   GtkEntryCompletion parent;
 };
 
-#define TIMEZONE_COMPLETION_ZONE    0
-#define TIMEZONE_COMPLETION_NAME    1
-#define TIMEZONE_COMPLETION_COUNTRY 2
-#define TIMEZONE_COMPLETION_LAST    3
+#define TIMEZONE_COMPLETION_ZONE      0
+#define TIMEZONE_COMPLETION_NAME      1
+#define TIMEZONE_COMPLETION_ADMIN1    2
+#define TIMEZONE_COMPLETION_COUNTRY   3
+#define TIMEZONE_COMPLETION_LONGITUDE 4
+#define TIMEZONE_COMPLETION_LATITUDE  5
+#define TIMEZONE_COMPLETION_LAST      6
 
 GType timezone_completion_get_type (void);
 TimezoneCompletion * timezone_completion_new ();
+void timezone_completion_watch_entry (TimezoneCompletion * completion, GtkEntry * entry);
 
 G_END_DECLS
 
diff --git a/src/utils.c b/src/utils.c
index 69143b9..f73ed14 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -20,10 +20,17 @@ You should have received a copy of the GNU General Public License along
 with this program.  If not, see .
 */
 
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include 
+#include 
 #include 
 #include 
 #include 
 #include "utils.h"
+#include "settings-shared.h"
 
 /* Check the system locale setting to see if the format is 24-hour
    time or 12-hour time */
@@ -43,3 +50,184 @@ is_locale_12h (void)
 	return TRUE;
 }
 
+void
+split_settings_location (const gchar * location, gchar ** zone, gchar ** name)
+{
+  gchar * location_dup = g_strdup (location);
+  gchar * first = strchr (location_dup, ' ');
+
+  if (first) {
+    first[0] = 0;
+  }
+
+  if (zone) {
+    *zone = location_dup;
+  }
+
+  if (name) {
+    gchar * after = first ? g_strstrip (first + 1) : NULL;
+    if (after == NULL || after[0] == 0) {
+      /* Make up name from zone */
+      gchar * slash = strrchr (location_dup, '/');
+      after = slash ? slash + 1 : location_dup;
+    }
+
+    *name = g_strdup (after);
+  }
+}
+
+/* Translate msg according to the locale specified by LC_TIME */
+static char *
+T_(const char *msg)
+{
+	/* General strategy here is to make sure LANGUAGE is empty (since that
+	   trumps all LC_* vars) and then to temporarily swap LC_TIME and
+	   LC_MESSAGES.  Then have gettext translate msg.
+
+	   We strdup the strings because the setlocale & *env functions do not
+	   guarantee anything about the storage used for the string, and thus
+	   the string may not be portably safe after multiple calls.
+
+	   Note that while you might think g_dcgettext would do the trick here,
+	   that actually looks in /usr/share/locale/XX/LC_TIME, not the
+	   LC_MESSAGES directory, so we won't find any translation there.
+	*/
+	char *message_locale = g_strdup(setlocale(LC_MESSAGES, NULL));
+	char *time_locale = g_strdup(setlocale(LC_TIME, NULL));
+	char *language = g_strdup(g_getenv("LANGUAGE"));
+	char *rv;
+	g_unsetenv("LANGUAGE");
+	setlocale(LC_MESSAGES, time_locale);
+
+	/* Get the LC_TIME version */
+	rv = _(msg);
+
+	/* Put everything back the way it was */
+	setlocale(LC_MESSAGES, message_locale);
+	g_setenv("LANGUAGE", language, TRUE);
+	g_free(message_locale);
+	g_free(time_locale);
+	g_free(language);
+	return rv;
+}
+
+/* Tries to figure out what our format string should be.  Lots
+   of translator comments in here. */
+gchar *
+generate_format_string_full (gboolean show_day, gboolean show_date)
+{
+	gboolean twelvehour = TRUE;
+
+	GSettings * settings = g_settings_new (SETTINGS_INTERFACE);
+	gint time_mode = g_settings_get_enum (settings, SETTINGS_TIME_FORMAT_S);
+	gboolean show_seconds = g_settings_get_boolean (settings, SETTINGS_SHOW_SECONDS_S);
+	g_object_unref (settings);
+
+	if (time_mode == SETTINGS_TIME_LOCALE) {
+		twelvehour = is_locale_12h();
+	} else if (time_mode == SETTINGS_TIME_24_HOUR) {
+		twelvehour = FALSE;
+	}
+
+	const gchar * time_string = NULL;
+	if (twelvehour) {
+		if (show_seconds) {
+			/* TRANSLATORS: A format string for the strftime function for
+			   a clock showing 12-hour time with seconds. */
+			time_string = T_("%l:%M:%S %p");
+		} else {
+			time_string = T_(DEFAULT_TIME_12_FORMAT);
+		}
+	} else {
+		if (show_seconds) {
+			/* TRANSLATORS: A format string for the strftime function for
+			   a clock showing 24-hour time with seconds. */
+			time_string = T_("%H:%M:%S");
+		} else {
+			time_string = T_(DEFAULT_TIME_24_FORMAT);
+		}
+	}
+	
+	/* Checkpoint, let's not fail */
+	g_return_val_if_fail(time_string != NULL, g_strdup(DEFAULT_TIME_FORMAT));
+
+	/* If there's no date or day let's just leave now and
+	   not worry about the rest of this code */
+	if (!show_date && !show_day) {
+		return g_strdup(time_string);
+	}
+
+	const gchar * date_string = NULL;
+	if (show_date && show_day) {
+		/* TRANSLATORS:  This is a format string passed to strftime to represent
+		   the day of the week, the month and the day of the month. */
+		date_string = T_("%a %b %e");
+	} else if (show_date) {
+		/* TRANSLATORS:  This is a format string passed to strftime to represent
+		   the month and the day of the month. */
+		date_string = T_("%b %e");
+	} else if (show_day) {
+		/* TRANSLATORS:  This is a format string passed to strftime to represent
+		   the day of the week. */
+		date_string = T_("%a");
+	}
+
+	/* Check point, we should have a date string */
+	g_return_val_if_fail(date_string != NULL, g_strdup(time_string));
+
+	/* TRANSLATORS: This is a format string passed to strftime to combine the
+	   date and the time.  The value of "%s, %s" would result in a string like
+	   this in US English 12-hour time: 'Fri Jul 16, 11:50 AM' */
+	return g_strdup_printf(T_("%s, %s"), date_string, time_string);
+}
+
+gchar *
+generate_format_string_at_time (GDateTime * time)
+{
+	/* This is a bit less free-form than for the main "now" time label. */
+	/* If it is today, just the time should be shown (e.g. “3:55 PM”)
+           If it is a different day this week, the day and time should be shown (e.g. “Wed 3:55 PM”)
+           If it is after this week, the day, date, and time should be shown (e.g. “Wed 21 Apr 3:55 PM”). 
+           In addition, when presenting the times of upcoming events, the time should be followed by the timezone if it is different from the one the computer is currently set to. For example, “Wed 3:55 PM UTC−5”. */
+	gboolean show_day = FALSE;
+	gboolean show_date = FALSE;
+
+	GDateTime * now = g_date_time_new_now_local();
+
+	/* First, are we same day? */
+	gint time_year, time_month, time_day;
+	gint now_year, now_month, now_day;
+	g_date_time_get_ymd(time, &time_year, &time_month, &time_day);
+	g_date_time_get_ymd(now, &now_year, &now_month, &now_day);
+
+	if (time_year != now_year ||
+	    time_month != now_month ||
+	    time_day != now_day) {
+		/* OK, different days so we must at least show the day. */
+		show_day = TRUE;
+
+		/* Is it this week? */
+		/* Here, we define "is this week" as yesterday, today, or the next five days */
+		GDateTime * past = g_date_time_add_days(now, -1);
+		GDateTime * future = g_date_time_add_days(now, 5);
+		GDateTime * past_bound = g_date_time_new_local(g_date_time_get_year(past),
+		                                               g_date_time_get_month(past),
+		                                               g_date_time_get_day_of_month(past),
+		                                               0, 0, 0.0);
+		GDateTime * future_bound = g_date_time_new_local(g_date_time_get_year(future),
+		                                                 g_date_time_get_month(future),
+		                                                 g_date_time_get_day_of_month(future),
+		                                                 23, 59, 59.9);
+		if (g_date_time_compare(time, past_bound) < 0 ||
+		    g_date_time_compare(time, future_bound) > 0) {
+			show_date = TRUE;
+		}
+		g_date_time_unref(past);
+		g_date_time_unref(future);
+		g_date_time_unref(past_bound);
+		g_date_time_unref(future_bound);
+	}
+
+	return generate_format_string_full(show_day, show_date);
+}
+
diff --git a/src/utils.h b/src/utils.h
index f6305c8..5f7842c 100644
--- a/src/utils.h
+++ b/src/utils.h
@@ -28,6 +28,9 @@ with this program.  If not, see .
 G_BEGIN_DECLS
 
 gboolean is_locale_12h (void);
+void split_settings_location (const gchar * location, gchar ** zone, gchar ** name);
+gchar * generate_format_string_full (gboolean show_day, gboolean show_date);
+gchar * generate_format_string_at_time (GDateTime * time);
 
 G_END_DECLS
 
-- 
cgit v1.2.3


From b3a34d487c8c3724752b522fd352c96ba0bcf1a4 Mon Sep 17 00:00:00 2001
From: Michael Terry 
Date: Wed, 23 Feb 2011 14:07:19 -0500
Subject: add week-start controls and settings

---
 data/com.canonical.indicator.datetime.gschema.xml | 12 +++++
 data/datetime-dialog.ui                           |  5 ++-
 src/datetime-prefs.c                              | 53 +++++++++++++++++++++--
 src/settings-shared.h                             |  2 +-
 src/utils.c                                       | 11 +++++
 src/utils.h                                       |  1 +
 6 files changed, 78 insertions(+), 6 deletions(-)

diff --git a/data/com.canonical.indicator.datetime.gschema.xml b/data/com.canonical.indicator.datetime.gschema.xml
index b33f34e..5361896 100644
--- a/data/com.canonical.indicator.datetime.gschema.xml
+++ b/data/com.canonical.indicator.datetime.gschema.xml
@@ -5,6 +5,11 @@
 		
 		
 	
+	
+		
+		
+		
+	
 	
 		
 			true
@@ -78,6 +83,13 @@
 			  Shows the week numbers in the monthly calendar in indicator-datetime's menu.
 			
 		
+		
+			'locale-default'
+			When the week starts
+			
+			  Controls whether weeks in the calendar are shown to start on Sunday or Monday.
+			
+		
 		
 			true
 			Show events in the indicator
diff --git a/data/datetime-dialog.ui b/data/datetime-dialog.ui
index 8b48702..c2a39b9 100644
--- a/data/datetime-dialog.ui
+++ b/data/datetime-dialog.ui
@@ -578,6 +578,7 @@
                                   
                                     True
                                     False
+                                    6
                                     
                                       
                                         Include week num_bers
@@ -597,8 +598,8 @@
                                     
                                     
                                       
+                                        True
                                         False
-                                        True
                                         0
                                         Week begins on:
                                       
@@ -610,8 +611,8 @@
                                     
                                     
                                       
+                                        True
                                         False
-                                        True
                                         True
                                         
                                           
diff --git a/src/datetime-prefs.c b/src/datetime-prefs.c
index 622a999..44b9b24 100644
--- a/src/datetime-prefs.c
+++ b/src/datetime-prefs.c
@@ -29,7 +29,7 @@ with this program.  If not, see .
 #include 
 #include 
 #include 
-#include 
+#include 
 #include 
 #include 
 #include 
@@ -85,6 +85,45 @@ bind_hours_get (GValue * value, GVariant * variant, gpointer user_data)
   return TRUE;
 }
 
+/* Turns the boolean property into a string gsettings */
+static GVariant *
+bind_week_start_set (const GValue * value, const GVariantType * type, gpointer user_data)
+{
+  const gchar * output = NULL;
+  gboolean is_sunday_button = (gboolean)GPOINTER_TO_INT(user_data);
+
+  if (g_value_get_boolean(value)) {
+    /* Only do anything if we're setting active = true */
+    output = is_sunday_button ? "sunday" : "monday";
+  } else {
+    return NULL;
+  }
+
+  return g_variant_new_string (output);
+}
+
+/* Turns a string gsettings into a boolean property */
+static gboolean
+bind_week_start_get (GValue * value, GVariant * variant, gpointer user_data)
+{
+  const gchar * str = g_variant_get_string(variant, NULL);
+  gboolean output = FALSE;
+  gboolean is_sunday_button = (gboolean)GPOINTER_TO_INT(user_data);
+
+  if (g_strcmp0(str, "locale-default") == 0) {
+    output = (is_sunday_button == is_locale_week_start_sunday ());
+  } else if (g_strcmp0(str, "sunday") == 0) {
+    output = is_sunday_button;
+  } else if (g_strcmp0(str, "monday") == 0) {
+    output = !is_sunday_button;
+  } else {
+    return FALSE;
+  }
+
+  g_value_set_boolean (value, output);
+  return TRUE;
+}
+
 static void
 widget_dependency_cb (GtkWidget * parent, GParamSpec *pspec, GtkWidget * dependent)
 {
@@ -473,8 +512,16 @@ create_dialog (void)
                    "active", G_SETTINGS_BIND_DEFAULT);
   g_settings_bind (conf, SETTINGS_SHOW_WEEK_NUMBERS_S, WIG ("includeWeekNumbersCheck"),
                    "active", G_SETTINGS_BIND_DEFAULT);
-  /*g_settings_bind_(conf, SETTINGS_WEEK_BEGINS_SUNDAY_S, WIG ("startOnSundayRadio"),
-                   "active", G_SETTINGS_BIND_DEFAULT);*/
+  g_settings_bind_with_mapping (conf, SETTINGS_WEEK_START_S,
+                                WIG ("startOnSundayRadio"), "active",
+                                G_SETTINGS_BIND_DEFAULT,
+                                bind_week_start_get, bind_week_start_set,
+                                GINT_TO_POINTER(TRUE), NULL);
+  g_settings_bind_with_mapping (conf, SETTINGS_WEEK_START_S,
+                                WIG ("startOnMondayRadio"), "active",
+                                G_SETTINGS_BIND_DEFAULT,
+                                bind_week_start_get, bind_week_start_set,
+                                GINT_TO_POINTER(FALSE), NULL);
   g_settings_bind (conf, SETTINGS_SHOW_EVENTS_S, WIG ("showEventsCheck"),
                    "active", G_SETTINGS_BIND_DEFAULT);
   g_settings_bind (conf, SETTINGS_SHOW_LOCATIONS_S, WIG ("showLocationsCheck"),
diff --git a/src/settings-shared.h b/src/settings-shared.h
index d866b81..b8e1789 100644
--- a/src/settings-shared.h
+++ b/src/settings-shared.h
@@ -33,7 +33,7 @@ with this program.  If not, see .
 #define SETTINGS_CUSTOM_TIME_FORMAT_S   "custom-time-format"
 #define SETTINGS_SHOW_CALENDAR_S        "show-calendar"
 #define SETTINGS_SHOW_WEEK_NUMBERS_S    "show-week-numbers"
-#define SETTINGS_WEEK_BEGINS_SUNDAY_S   "week-begins-sunday"
+#define SETTINGS_WEEK_START_S           "week-start"
 #define SETTINGS_SHOW_EVENTS_S          "show-events"
 #define SETTINGS_SHOW_LOCATIONS_S       "show-locations"
 #define SETTINGS_LOCATIONS_S            "locations"
diff --git a/src/utils.c b/src/utils.c
index f73ed14..89c499b 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -50,6 +50,17 @@ is_locale_12h (void)
 	return TRUE;
 }
 
+/* Check the system locale setting to see if the week starts on Sunday or Monday */
+gboolean
+is_locale_week_start_sunday (void)
+{
+	const char * week_1stday = nl_langinfo (_NL_TIME_WEEK_1STDAY);
+
+  /* This appears to be a special value that libc uses for Sunday, it's not
+     really a string */
+  return (GPOINTER_TO_INT (week_1stday) == 19971130);
+}
+
 void
 split_settings_location (const gchar * location, gchar ** zone, gchar ** name)
 {
diff --git a/src/utils.h b/src/utils.h
index 5f7842c..3dc8df1 100644
--- a/src/utils.h
+++ b/src/utils.h
@@ -28,6 +28,7 @@ with this program.  If not, see .
 G_BEGIN_DECLS
 
 gboolean is_locale_12h (void);
+gboolean is_locale_week_start_sunday (void);
 void split_settings_location (const gchar * location, gchar ** zone, gchar ** name);
 gchar * generate_format_string_full (gboolean show_day, gboolean show_date);
 gchar * generate_format_string_at_time (GDateTime * time);
-- 
cgit v1.2.3


From 415577b327454a934d48ad06c86c2aaa75cc0adf Mon Sep 17 00:00:00 2001
From: Michael Terry 
Date: Wed, 23 Feb 2011 14:08:28 -0500
Subject: whoops, uncomment polkit bits

---
 src/datetime-prefs.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/datetime-prefs.c b/src/datetime-prefs.c
index 44b9b24..20f9829 100644
--- a/src/datetime-prefs.c
+++ b/src/datetime-prefs.c
@@ -144,7 +144,7 @@ add_widget_dependency (GtkWidget * parent, GtkWidget * dependent)
   widget_dependency_cb (parent, NULL, dependent);
 }
 
-/*static void
+static void
 polkit_dependency_cb (GtkWidget * parent, GParamSpec *pspec, GtkWidget * dependent)
 {
   gboolean authorized, sensitive;
@@ -162,7 +162,7 @@ add_polkit_dependency (GtkWidget * parent, GtkWidget * dependent)
   g_signal_connect (parent, "notify::sensitive", G_CALLBACK(polkit_dependency_cb),
                     dependent);
   polkit_dependency_cb (parent, NULL, dependent);
-}*/
+}
 
 static void
 dbus_set_answered (GObject *object, GAsyncResult *res, gpointer command)
@@ -532,7 +532,7 @@ create_dialog (void)
   add_widget_dependency (WIG ("showClockCheck"), WIG ("clockOptions"));
   add_widget_dependency (WIG ("showLocationsCheck"), WIG ("locationsButton"));
   add_widget_dependency (WIG ("manualTimeRadio"), WIG ("manualOptions"));
-  //add_polkit_dependency (polkit_button, WIG ("timeDateOptions"));
+  add_polkit_dependency (polkit_button, WIG ("timeDateOptions"));
 
   /* Hacky proxy test for whether evolution-data-server is installed */
   gchar * evo_path = g_find_program_in_path ("evolution");
-- 
cgit v1.2.3


From cf3ae1adfd378d4bfb3a9cf02609ba45d9f764a8 Mon Sep 17 00:00:00 2001
From: Michael Terry 
Date: Wed, 23 Feb 2011 14:42:24 -0500
Subject: hook show-locations up

---
 src/datetime-service.c | 33 ++++++++++++++++++++++-----------
 src/settings-shared.h  |  2 --
 2 files changed, 22 insertions(+), 13 deletions(-)

diff --git a/src/datetime-service.c b/src/datetime-service.c
index 1f3eac6..45efbf6 100644
--- a/src/datetime-service.c
+++ b/src/datetime-service.c
@@ -114,6 +114,8 @@ check_timezone_sync (void) {
 		g_debug("Timezones are different");
 	}
 
+	gboolean show = g_settings_get_boolean (conf, SETTINGS_SHOW_LOCATIONS_S);
+
 	if (geo_location != NULL && current_location != NULL) {
 		g_debug("Got timezone %s", current_timezone);
 		g_debug("Got timezone %s", geo_timezone);
@@ -144,7 +146,7 @@ check_timezone_sync (void) {
 				// TODO work out the current location name in a nice way
 				dbusmenu_menuitem_property_set (current_location, TIMEZONE_MENUITEM_PROP_ZONE, label);
 				// TODO work out the current time at that location 
-				dbusmenu_menuitem_property_set_bool (current_location, DBUSMENU_MENUITEM_PROP_VISIBLE, TRUE);
+				dbusmenu_menuitem_property_set_bool (current_location, DBUSMENU_MENUITEM_PROP_VISIBLE, show);
 				dbusmenu_menuitem_property_set_bool(current_location, TIMEZONE_MENUITEM_PROP_RADIO, TRUE);
 			} else {
 				g_debug("Label for current location is null, this shouldn't happen");
@@ -153,20 +155,20 @@ check_timezone_sync (void) {
 				// TODO work out the geo location name in a nice way
 				dbusmenu_menuitem_property_set (geo_location, TIMEZONE_MENUITEM_PROP_ZONE, geo_timezone);
 				// TODO work out the current time at that location 
-				dbusmenu_menuitem_property_set_bool (geo_location, DBUSMENU_MENUITEM_PROP_VISIBLE, TRUE);
+				dbusmenu_menuitem_property_set_bool (geo_location, DBUSMENU_MENUITEM_PROP_VISIBLE, show);
 			}
 		} else {
 			// TODO work out the geo location name in a nice way
 			dbusmenu_menuitem_property_set (geo_location, TIMEZONE_MENUITEM_PROP_ZONE, geo_timezone);
 			// TODO work out the current time at that location 
-			dbusmenu_menuitem_property_set_bool(geo_location, DBUSMENU_MENUITEM_PROP_VISIBLE, TRUE);
+			dbusmenu_menuitem_property_set_bool(geo_location, DBUSMENU_MENUITEM_PROP_VISIBLE, show);
 			
 			// TODO work out the current location name in a nice way
 			dbusmenu_menuitem_property_set (current_location, TIMEZONE_MENUITEM_PROP_ZONE, current_timezone);
 			// TODO work out the current time at that location 
 			dbusmenu_menuitem_property_set_bool(current_location, TIMEZONE_MENUITEM_PROP_RADIO, TRUE);
-			dbusmenu_menuitem_property_set_bool(current_location, DBUSMENU_MENUITEM_PROP_VISIBLE, TRUE);
-			dbusmenu_menuitem_property_set_bool(locations_separator, DBUSMENU_MENUITEM_PROP_VISIBLE, TRUE);
+			dbusmenu_menuitem_property_set_bool(current_location, DBUSMENU_MENUITEM_PROP_VISIBLE, show);
+			dbusmenu_menuitem_property_set_bool(locations_separator, DBUSMENU_MENUITEM_PROP_VISIBLE, show);
 		}
 	}
 	g_debug("Finished checking timezone sync");
@@ -368,10 +370,8 @@ update_timezone_menu_items(gpointer user_data) {
 	
 	/* Remove all of the previous locations */
 	if (dconflocations != NULL) {
-		g_debug("Freeing old locations");
 		while (dconflocations != NULL) {
 			DbusmenuMenuitem * litem =  DBUSMENU_MENUITEM(dconflocations->data);
-			g_debug("Freeing old location: %p", litem);
 			// Remove all the existing menu items which are in dconflocations.
 			dconflocations = g_list_remove(dconflocations, litem);
 			dbusmenu_menuitem_child_delete(root, DBUSMENU_MENUITEM(litem));
@@ -379,11 +379,13 @@ update_timezone_menu_items(gpointer user_data) {
 		}
 	}
 	
+	gboolean show = g_settings_get_boolean (conf, SETTINGS_SHOW_LOCATIONS_S);
+
 	// TODO: Remove items from the dconflocations at the end of the iteration
 	// Make sure if there are multiple locations, our current location is shown
 	if (len > 0) {
-		dbusmenu_menuitem_property_set_bool (locations_separator, DBUSMENU_MENUITEM_PROP_VISIBLE, TRUE);
-		dbusmenu_menuitem_property_set_bool (current_location, DBUSMENU_MENUITEM_PROP_VISIBLE, TRUE);
+		dbusmenu_menuitem_property_set_bool (locations_separator, DBUSMENU_MENUITEM_PROP_VISIBLE, show);
+		dbusmenu_menuitem_property_set_bool (current_location, DBUSMENU_MENUITEM_PROP_VISIBLE, show);
 		dbusmenu_menuitem_property_set_bool (current_location, DBUSMENU_MENUITEM_PROP_ENABLED, TRUE);
 	} else {
 		g_debug("No locations configured (Empty List)");
@@ -401,7 +403,7 @@ update_timezone_menu_items(gpointer user_data) {
 			dbusmenu_menuitem_property_set		(item, TIMEZONE_MENUITEM_PROP_ZONE, locations[i]);
 			dbusmenu_menuitem_property_set_bool (item, TIMEZONE_MENUITEM_PROP_RADIO, FALSE);
 			dbusmenu_menuitem_property_set_bool (item, DBUSMENU_MENUITEM_PROP_ENABLED, TRUE);
-			dbusmenu_menuitem_property_set_bool (item, DBUSMENU_MENUITEM_PROP_VISIBLE, TRUE);
+			dbusmenu_menuitem_property_set_bool (item, DBUSMENU_MENUITEM_PROP_VISIBLE, show);
 			dbusmenu_menuitem_child_add_position (root, item, offset++);
 			g_signal_connect(G_OBJECT(item), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(quick_set_tz), NULL);
 			dconflocations = g_list_append(dconflocations, item);
@@ -727,6 +729,13 @@ check_for_timeadmin (gpointer user_data)
 	return FALSE;
 }
 
+static void
+show_locations_changed (void)
+{
+	/* Re-calculate */
+	check_timezone_sync();
+}
+
 /* Does the work to build the default menu, really calls out
    to other functions but this is the core to clean up the
    main function. */
@@ -757,7 +766,7 @@ build_menus (DbusmenuMenuitem * root)
 	
 	locations_separator = dbusmenu_menuitem_new();
 	dbusmenu_menuitem_property_set(locations_separator, DBUSMENU_MENUITEM_PROP_TYPE, DBUSMENU_CLIENT_TYPES_SEPARATOR);
-	dbusmenu_menuitem_property_set_bool (locations_separator, DBUSMENU_MENUITEM_PROP_VISIBLE, TRUE);
+	dbusmenu_menuitem_property_set_bool (locations_separator, DBUSMENU_MENUITEM_PROP_VISIBLE, FALSE);
 	dbusmenu_menuitem_child_append(root, locations_separator);
 
 	geo_location = dbusmenu_menuitem_new();
@@ -778,6 +787,8 @@ build_menus (DbusmenuMenuitem * root)
 	
 	check_timezone_sync();
 	
+	g_signal_connect (conf, "changed::" SETTINGS_SHOW_LOCATIONS_S, G_CALLBACK (show_locations_changed), NULL);
+
 	DbusmenuMenuitem * separator = dbusmenu_menuitem_new();
 	dbusmenu_menuitem_property_set(separator, DBUSMENU_MENUITEM_PROP_TYPE, DBUSMENU_CLIENT_TYPES_SEPARATOR);
 	dbusmenu_menuitem_child_append(root, separator);
diff --git a/src/settings-shared.h b/src/settings-shared.h
index b8e1789..a4fac24 100644
--- a/src/settings-shared.h
+++ b/src/settings-shared.h
@@ -22,8 +22,6 @@ with this program.  If not, see .
 #ifndef __DATETIME_SETTINGS_SHARED_H__
 #define __DATETIME_SETTINGS_SHARED_H__
 
-#include 
-
 #define SETTINGS_INTERFACE              "com.canonical.indicator.datetime"
 #define SETTINGS_SHOW_CLOCK_S           "show-clock"
 #define SETTINGS_TIME_FORMAT_S          "time-format"
-- 
cgit v1.2.3


From 3488f85406e03ebdbecfcc25f520689f300f8f9a Mon Sep 17 00:00:00 2001
From: Michael Terry 
Date: Wed, 23 Feb 2011 14:47:10 -0500
Subject: make map larger

---
 data/datetime-dialog.ui | 1 +
 1 file changed, 1 insertion(+)

diff --git a/data/datetime-dialog.ui b/data/datetime-dialog.ui
index c2a39b9..b8d0777 100644
--- a/data/datetime-dialog.ui
+++ b/data/datetime-dialog.ui
@@ -158,6 +158,7 @@
                     6
                     
                       
+                        300
                         True
                         False
                         0
-- 
cgit v1.2.3


From 02a56bbe87dba95388735c9961345b5166940b1c Mon Sep 17 00:00:00 2001
From: Michael Terry 
Date: Wed, 23 Feb 2011 15:13:42 -0500
Subject: disable clicking on locations; use pretty zone names in indicator

---
 src/Makefile.am          |  2 ++
 src/datetime-service.c   | 64 ++++++++++++++----------------------------------
 src/dbus-shared.h        |  3 ++-
 src/indicator-datetime.c | 10 +++++---
 src/utils.c              | 13 +++++++---
 5 files changed, 37 insertions(+), 55 deletions(-)

diff --git a/src/Makefile.am b/src/Makefile.am
index 7e8ac4b..6d388c7 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -9,6 +9,8 @@ indicator_datetime_service_SOURCES = \
 	calendar-menu-item.c \
 	calendar-menu-item.h \
 	datetime-service.c \
+	utils.c \
+	utils.h \
 	dbus-shared.h \
 	settings-shared.h
 indicator_datetime_service_CFLAGS = \
diff --git a/src/datetime-service.c b/src/datetime-service.c
index 45efbf6..ab609c4 100644
--- a/src/datetime-service.c
+++ b/src/datetime-service.c
@@ -53,6 +53,7 @@ with this program.  If not, see .
 #include "datetime-interface.h"
 #include "dbus-shared.h"
 #include "settings-shared.h"
+#include "utils.h"
 
 
 static void geo_create_client (GeoclueMaster * master, GeoclueMasterClient * client, gchar * path, GError * error, gpointer user_data);
@@ -90,6 +91,16 @@ static GeoclueAddress * geo_address = NULL;
 static gchar 			* current_timezone = NULL;
 static gchar 			* geo_timezone = NULL;
 
+static void
+set_timezone_label (DbusmenuMenuitem * mi, const gchar * location)
+{
+	gchar * zone, * name;
+	split_settings_location (location, &zone, &name);
+
+	dbusmenu_menuitem_property_set (mi, TIMEZONE_MENUITEM_PROP_NAME, name);
+	dbusmenu_menuitem_property_set (mi, TIMEZONE_MENUITEM_PROP_ZONE, zone);
+}
+
 /* Check to see if our timezones are the same */
 static void
 check_timezone_sync (void) {
@@ -144,7 +155,7 @@ check_timezone_sync (void) {
 			
 			if (label != NULL) {
 				// TODO work out the current location name in a nice way
-				dbusmenu_menuitem_property_set (current_location, TIMEZONE_MENUITEM_PROP_ZONE, label);
+				set_timezone_label (current_location, label);
 				// TODO work out the current time at that location 
 				dbusmenu_menuitem_property_set_bool (current_location, DBUSMENU_MENUITEM_PROP_VISIBLE, show);
 				dbusmenu_menuitem_property_set_bool(current_location, TIMEZONE_MENUITEM_PROP_RADIO, TRUE);
@@ -153,18 +164,18 @@ check_timezone_sync (void) {
 			}
 			if (geo_timezone != NULL) {	
 				// TODO work out the geo location name in a nice way
-				dbusmenu_menuitem_property_set (geo_location, TIMEZONE_MENUITEM_PROP_ZONE, geo_timezone);
+				set_timezone_label (geo_location, geo_timezone);
 				// TODO work out the current time at that location 
 				dbusmenu_menuitem_property_set_bool (geo_location, DBUSMENU_MENUITEM_PROP_VISIBLE, show);
 			}
 		} else {
 			// TODO work out the geo location name in a nice way
-			dbusmenu_menuitem_property_set (geo_location, TIMEZONE_MENUITEM_PROP_ZONE, geo_timezone);
+			set_timezone_label (geo_location, geo_timezone);
 			// TODO work out the current time at that location 
 			dbusmenu_menuitem_property_set_bool(geo_location, DBUSMENU_MENUITEM_PROP_VISIBLE, show);
 			
 			// TODO work out the current location name in a nice way
-			dbusmenu_menuitem_property_set (current_location, TIMEZONE_MENUITEM_PROP_ZONE, current_timezone);
+			set_timezone_label (current_location, current_timezone);
 			// TODO work out the current time at that location 
 			dbusmenu_menuitem_property_set_bool(current_location, TIMEZONE_MENUITEM_PROP_RADIO, TRUE);
 			dbusmenu_menuitem_property_set_bool(current_location, DBUSMENU_MENUITEM_PROP_VISIBLE, show);
@@ -211,42 +222,6 @@ update_current_timezone (void) {
 	return;
 }
 
-/* See how our timezone setting went */
-static void
-quick_set_tz_cb (OobsObject * obj, OobsResult result, gpointer user_data)
-{
-	if (result == OOBS_RESULT_OK) {
-		g_debug("Timezone set");
-	} else {
-		g_warning("Unable to quick set timezone");
-	}
-	return;
-}
-
-/* Set the timezone to the Geoclue discovered one */
-static void
-quick_set_tz (DbusmenuMenuitem * menuitem, guint timestamp, gpointer user_data)
-{
-	const gchar * tz = dbusmenu_menuitem_property_get(menuitem, TIMEZONE_MENUITEM_PROP_ZONE);
-
-	g_debug("Quick setting timezone to: %s", tz);
-
-	g_return_if_fail(tz != NULL);
-
-	if (g_strcmp0(tz, current_timezone) == 0)
-		return;
-
-	OobsObject * obj = oobs_time_config_get();
-	g_return_if_fail(obj != NULL);
-
-	OobsTimeConfig * timeconfig = OOBS_TIME_CONFIG(obj);
-	oobs_time_config_set_timezone(timeconfig, tz);
-
-	oobs_object_commit_async(obj, quick_set_tz_cb, NULL);
-
-	return;
-}
-
 /* Updates the label in the date menuitem */
 static gboolean
 update_datetime (gpointer user_data)
@@ -400,12 +375,11 @@ update_timezone_menu_items(gpointer user_data) {
 			g_debug("Adding timezone in update_timezones %s", locations[i]);
 			item = dbusmenu_menuitem_new();
 			dbusmenu_menuitem_property_set      (item, DBUSMENU_MENUITEM_PROP_TYPE, TIMEZONE_MENUITEM_TYPE);
-			dbusmenu_menuitem_property_set		(item, TIMEZONE_MENUITEM_PROP_ZONE, locations[i]);
+			set_timezone_label (item, locations[i]);
 			dbusmenu_menuitem_property_set_bool (item, TIMEZONE_MENUITEM_PROP_RADIO, FALSE);
 			dbusmenu_menuitem_property_set_bool (item, DBUSMENU_MENUITEM_PROP_ENABLED, TRUE);
 			dbusmenu_menuitem_property_set_bool (item, DBUSMENU_MENUITEM_PROP_VISIBLE, show);
 			dbusmenu_menuitem_child_add_position (root, item, offset++);
-			g_signal_connect(G_OBJECT(item), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(quick_set_tz), NULL);
 			dconflocations = g_list_append(dconflocations, item);
 		}
 	}
@@ -771,18 +745,16 @@ build_menus (DbusmenuMenuitem * root)
 
 	geo_location = dbusmenu_menuitem_new();
 	dbusmenu_menuitem_property_set      (geo_location, DBUSMENU_MENUITEM_PROP_TYPE, TIMEZONE_MENUITEM_TYPE);
-	dbusmenu_menuitem_property_set		(geo_location, TIMEZONE_MENUITEM_PROP_ZONE, "");
+	set_timezone_label (geo_location, "");
 	dbusmenu_menuitem_property_set_bool (geo_location, DBUSMENU_MENUITEM_PROP_ENABLED, FALSE);
 	dbusmenu_menuitem_property_set_bool (geo_location, DBUSMENU_MENUITEM_PROP_VISIBLE, TRUE);
-	g_signal_connect(G_OBJECT(geo_location), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(quick_set_tz), NULL);
 	dbusmenu_menuitem_child_append(root, geo_location);
 
 	current_location = dbusmenu_menuitem_new();
 	dbusmenu_menuitem_property_set      (current_location, DBUSMENU_MENUITEM_PROP_TYPE, TIMEZONE_MENUITEM_TYPE);
-	dbusmenu_menuitem_property_set		(current_location, TIMEZONE_MENUITEM_PROP_ZONE, "");
+	set_timezone_label (current_location, "");
 	dbusmenu_menuitem_property_set_bool (current_location, DBUSMENU_MENUITEM_PROP_ENABLED, FALSE);
 	dbusmenu_menuitem_property_set_bool (current_location, DBUSMENU_MENUITEM_PROP_VISIBLE, FALSE);
-	g_signal_connect(G_OBJECT(current_location), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(quick_set_tz), NULL);
 	dbusmenu_menuitem_child_append(root, current_location);
 	
 	check_timezone_sync();
diff --git a/src/dbus-shared.h b/src/dbus-shared.h
index bad8354..f0f05a9 100644
--- a/src/dbus-shared.h
+++ b/src/dbus-shared.h
@@ -35,5 +35,6 @@ with this program.  If not, see .
 #define APPOINTMENT_MENUITEM_PROP_RIGHT    "appointment-time"
 
 #define TIMEZONE_MENUITEM_TYPE             "timezone-item"	
-#define TIMEZONE_MENUITEM_PROP_ZONE        "timezone-zone"
+#define TIMEZONE_MENUITEM_PROP_ZONE        "timezone-zone"	
+#define TIMEZONE_MENUITEM_PROP_NAME        "timezone-name"
 #define TIMEZONE_MENUITEM_PROP_RADIO       "timezone-radio"
diff --git a/src/indicator-datetime.c b/src/indicator-datetime.c
index fb421cb..33f78c4 100644
--- a/src/indicator-datetime.c
+++ b/src/indicator-datetime.c
@@ -999,13 +999,13 @@ generate_format_string_now (IndicatorDatetime * self)
 static void
 timezone_update_labels (indicator_item_t * mi_data)
 {
-	const gchar * zone_name = dbusmenu_menuitem_property_get(mi_data->mi, TIMEZONE_MENUITEM_PROP_ZONE);
+	const gchar * zone = dbusmenu_menuitem_property_get(mi_data->mi, TIMEZONE_MENUITEM_PROP_ZONE);
+	const gchar * name = dbusmenu_menuitem_property_get(mi_data->mi, TIMEZONE_MENUITEM_PROP_NAME);
 
-	/* TODO: Make zone name a little more user friendly */
-	gtk_label_set_text(GTK_LABEL(mi_data->label), zone_name);
+	gtk_label_set_text(GTK_LABEL(mi_data->label), name);
 
 	/* Show current time in that zone on the right */
-	GTimeZone * tz = g_time_zone_new(zone_name);
+	GTimeZone * tz = g_time_zone_new(zone);
 	set_label_to_time_in_zone(mi_data->self, GTK_LABEL(mi_data->right), tz, NULL, NULL);
 	g_time_zone_unref(tz);
 }
@@ -1051,6 +1051,8 @@ indicator_prop_change_cb (DbusmenuMenuitem * mi, gchar * prop, GVariant *value,
 		}
 	} else if (!g_strcmp0(prop, TIMEZONE_MENUITEM_PROP_ZONE)) {
 		timezone_update_labels(mi_data);
+	} else if (!g_strcmp0(prop, TIMEZONE_MENUITEM_PROP_NAME)) {
+		timezone_update_labels(mi_data);
 	} else if (!g_strcmp0(prop, TIMEZONE_MENUITEM_PROP_RADIO)) {
 		gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(mi_data->gmi), g_variant_get_boolean(value));
 	} else {
diff --git a/src/utils.c b/src/utils.c
index 89c499b..20ae958 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -79,11 +79,16 @@ split_settings_location (const gchar * location, gchar ** zone, gchar ** name)
     gchar * after = first ? g_strstrip (first + 1) : NULL;
     if (after == NULL || after[0] == 0) {
       /* Make up name from zone */
-      gchar * slash = strrchr (location_dup, '/');
-      after = slash ? slash + 1 : location_dup;
+      gchar * chr = strrchr (location_dup, '/');
+      after = g_strdup (chr ? chr + 1 : location_dup);
+      while ((chr = strchr (after, '_')) != NULL) { /* and turn underscores to spaces */
+        *chr = ' ';
+      }
+      *name = after;
+    }
+    else {
+      *name = g_strdup (after);
     }
-
-    *name = g_strdup (after);
   }
 }
 
-- 
cgit v1.2.3


From 66f988fe7a494e1aa12c161e415660fba247aaf4 Mon Sep 17 00:00:00 2001
From: Michael Terry 
Date: Wed, 23 Feb 2011 15:30:30 -0500
Subject: some cleanup; when map changes, update entry too

---
 src/datetime-prefs.c      | 26 ++++++++++++++++++++------
 src/indicator-datetime.c  |  4 ++--
 src/timezone-completion.c |  4 ----
 3 files changed, 22 insertions(+), 12 deletions(-)

diff --git a/src/datetime-prefs.c b/src/datetime-prefs.c
index 20f9829..3f5e5e6 100644
--- a/src/datetime-prefs.c
+++ b/src/datetime-prefs.c
@@ -43,7 +43,8 @@ with this program.  If not, see .
 #define DATETIME_DIALOG_UI_FILE PKGDATADIR "/datetime-dialog.ui"
 
 GDBusProxy * proxy = NULL;
-GtkWidget * autoRadio = NULL;
+GtkWidget * auto_radio = NULL;
+GtkWidget * tz_entry = NULL;
 CcTimezoneMap * tzmap = NULL;
 
 /* Turns the boolean property into a string gsettings */
@@ -203,14 +204,23 @@ ntp_query_answered (GObject *object, GAsyncResult *res, gpointer user_data)
   gboolean can_use_ntp, is_using_ntp;
   g_variant_get (answers, "(bb)", &can_use_ntp, &is_using_ntp);
 
-  gtk_widget_set_sensitive (GTK_WIDGET (autoRadio), can_use_ntp);
-  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (autoRadio), is_using_ntp);
+  gtk_widget_set_sensitive (GTK_WIDGET (auto_radio), can_use_ntp);
+  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (auto_radio), is_using_ntp);
 
-  g_signal_connect (autoRadio, "notify::active", G_CALLBACK (toggle_ntp), NULL);
+  g_signal_connect (auto_radio, "notify::active", G_CALLBACK (toggle_ntp), NULL);
 
   g_variant_unref (answers);
 }
 
+static void
+sync_entry (const gchar * location)
+{
+  gchar * name;
+  split_settings_location (location, NULL, &name);
+  gtk_entry_set_text (GTK_ENTRY (tz_entry), name);
+  g_free (name);
+}
+
 static void
 tz_changed (CcTimezoneMap * map, TzLocation * location)
 {
@@ -221,6 +231,8 @@ tz_changed (CcTimezoneMap * map, TzLocation * location)
   g_dbus_proxy_call (proxy, "SetTimezone", g_variant_new ("(s)", file),
                      G_DBUS_CALL_FLAGS_NONE, -1, NULL, dbus_set_answered, "timezone");
   g_free (file);
+
+  sync_entry (location->zone);
 }
 
 static void
@@ -240,6 +252,7 @@ tz_query_answered (GObject *object, GAsyncResult *res, gpointer user_data)
 
   cc_timezone_map_set_timezone (tzmap, timezone);
 
+  sync_entry (timezone);
   g_signal_connect (tzmap, "location-changed", G_CALLBACK (tz_changed), NULL);
 
   g_variant_unref (answers);
@@ -259,7 +272,7 @@ void proxy_ready (GObject *object, GAsyncResult *res, gpointer user_data)
 
   /* And now, do initial proxy configuration */
   g_dbus_proxy_call (proxy, "GetUsingNtp", NULL, G_DBUS_CALL_FLAGS_NONE, -1,
-                     NULL, ntp_query_answered, autoRadio);
+                     NULL, ntp_query_answered, auto_radio);
   g_dbus_proxy_call (proxy, "GetTimezone", NULL, G_DBUS_CALL_FLAGS_NONE, -1,
                      NULL, tz_query_answered, NULL);
 }
@@ -543,7 +556,8 @@ create_dialog (void)
   setup_time_spinner (WIG ("dateSpinner"), WIG ("timeSpinner"), FALSE);
 
   GtkWidget * dlg = WIG ("timeDateDialog");
-  autoRadio = WIG ("automaticTimeRadio");
+  auto_radio = WIG ("automaticTimeRadio");
+  tz_entry = WIG ("timezoneEntry");
 
   g_signal_connect (WIG ("locationsButton"), "clicked", G_CALLBACK (show_locations), dlg);
 
diff --git a/src/indicator-datetime.c b/src/indicator-datetime.c
index 33f78c4..2e336c7 100644
--- a/src/indicator-datetime.c
+++ b/src/indicator-datetime.c
@@ -1176,7 +1176,7 @@ timezone_toggled_cb (GtkCheckMenuItem *checkmenuitem, DbusmenuMenuitem * dbusite
 }
 
 static void
-timezone_destroyed_cb (DbusmenuMenuitem * dbusitem, indicator_item_t * mi_data)
+timezone_destroyed_cb (indicator_item_t * mi_data, DbusmenuMenuitem * dbusitem)
 {
 	IndicatorDatetimePrivate *priv = INDICATOR_DATETIME_GET_PRIVATE(mi_data->self);
 	priv->timezone_items = g_list_remove(priv->timezone_items, mi_data);
@@ -1241,7 +1241,7 @@ new_timezone_item(DbusmenuMenuitem * newitem,
 
 	g_signal_connect(G_OBJECT(mi_data->gmi), "toggled", G_CALLBACK(timezone_toggled_cb), newitem);
 	g_signal_connect(G_OBJECT(newitem), DBUSMENU_MENUITEM_SIGNAL_PROPERTY_CHANGED, G_CALLBACK(indicator_prop_change_cb), mi_data);
-	g_signal_connect(G_OBJECT(newitem), "destroyed", G_CALLBACK(timezone_destroyed_cb), mi_data);
+	g_object_weak_ref(G_OBJECT(newitem), (GWeakNotify)timezone_destroyed_cb, mi_data);
 
 	return TRUE;
 }
diff --git a/src/timezone-completion.c b/src/timezone-completion.c
index a1b4d00..840b3e4 100644
--- a/src/timezone-completion.c
+++ b/src/timezone-completion.c
@@ -76,7 +76,6 @@ json_parse_ready (GObject *object, GAsyncResult *res, gpointer user_data)
     return;
   }
 
-g_print("got json\n");
   GtkListStore * store = GTK_LIST_STORE (gtk_entry_completion_get_model (GTK_ENTRY_COMPLETION (completion)));
   JsonReader * reader = json_reader_new (json_parser_get_root (JSON_PARSER (object)));
 
@@ -115,7 +114,6 @@ g_print("got json\n");
         json_reader_end_member (reader);
       }
 
-g_print("adding %s\n", name);
       GtkTreeIter iter;
       gtk_list_store_append (store, &iter);
       gtk_list_store_set (store, &iter,
@@ -166,7 +164,6 @@ request_zones (TimezoneCompletion * completion)
 
   priv->queued_request = 0;
 
-g_print("requesting json?\n");
   if (priv->entry == NULL) {
     return FALSE;
   }
@@ -185,7 +182,6 @@ g_print("requesting json?\n");
 
   priv->request_text = g_strdup (text);
 
-g_print("requesting json now\n");
   gchar * escaped = g_uri_escape_string (text, NULL, FALSE);
   gchar * url = g_strdup_printf (GEONAME_URL, escaped, "11.04");
 
-- 
cgit v1.2.3


From d38ff688556788a5d6c8e3f033b460c8ac849039 Mon Sep 17 00:00:00 2001
From: Michael Terry 
Date: Wed, 23 Feb 2011 14:46:46 -0600
Subject: skip duplicate completions

---
 src/timezone-completion.c | 55 ++++++++++++++++++++++++++++++++++++++---------
 1 file changed, 45 insertions(+), 10 deletions(-)

diff --git a/src/timezone-completion.c b/src/timezone-completion.c
index 840b3e4..7f5ad68 100644
--- a/src/timezone-completion.c
+++ b/src/timezone-completion.c
@@ -114,16 +114,51 @@ json_parse_ready (GObject *object, GAsyncResult *res, gpointer user_data)
         json_reader_end_member (reader);
       }
 
+      /* See if we have this in our store already */
       GtkTreeIter iter;
-      gtk_list_store_append (store, &iter);
-      gtk_list_store_set (store, &iter,
-                          TIMEZONE_COMPLETION_ZONE, NULL,
-                          TIMEZONE_COMPLETION_NAME, name,
-                          TIMEZONE_COMPLETION_ADMIN1, admin1,
-                          TIMEZONE_COMPLETION_COUNTRY, country,
-                          TIMEZONE_COMPLETION_LONGITUDE, longitude,
-                          TIMEZONE_COMPLETION_LATITUDE, latitude,
-                          -1);
+      gboolean skip = FALSE;
+      if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter)) {
+        do {
+          GValue value = {0};
+
+          gtk_tree_model_get_value (GTK_TREE_MODEL (store), &iter, TIMEZONE_COMPLETION_NAME, &value);
+          if (g_strcmp0 (g_value_get_string (&value), name) != 0) {
+            g_value_unset (&value);
+            continue;
+          }
+          g_value_unset (&value);
+
+          gtk_tree_model_get_value (GTK_TREE_MODEL (store), &iter, TIMEZONE_COMPLETION_ADMIN1, &value);
+          if (g_strcmp0 (g_value_get_string (&value), admin1) != 0) {
+            g_value_unset (&value);
+            continue;
+          }
+          g_value_unset (&value);
+
+          gtk_tree_model_get_value (GTK_TREE_MODEL (store), &iter, TIMEZONE_COMPLETION_COUNTRY, &value);
+          if (g_strcmp0 (g_value_get_string (&value), country) != 0) {
+            g_value_unset (&value);
+            continue;
+          }
+          g_value_unset (&value);
+
+          /* Must be the same, skip this one */
+          skip = TRUE;
+          break;
+        } while (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter));
+      }
+
+      if (!skip) {
+        gtk_list_store_append (store, &iter);
+        gtk_list_store_set (store, &iter,
+                            TIMEZONE_COMPLETION_ZONE, NULL,
+                            TIMEZONE_COMPLETION_NAME, name,
+                            TIMEZONE_COMPLETION_ADMIN1, admin1,
+                            TIMEZONE_COMPLETION_COUNTRY, country,
+                            TIMEZONE_COMPLETION_LONGITUDE, longitude,
+                            TIMEZONE_COMPLETION_LATITUDE, latitude,
+                            -1);
+      }
     }
 
     json_reader_end_element (reader);
@@ -183,7 +218,7 @@ request_zones (TimezoneCompletion * completion)
   priv->request_text = g_strdup (text);
 
   gchar * escaped = g_uri_escape_string (text, NULL, FALSE);
-  gchar * url = g_strdup_printf (GEONAME_URL, escaped, "11.04");
+  gchar * url = g_strdup_printf (GEONAME_URL, escaped, "11.04"); // FIXME: don't hardcode
 
   GFile * file =  g_file_new_for_uri (url);
   g_file_read_async (file, G_PRIORITY_DEFAULT, priv->cancel,
-- 
cgit v1.2.3


From e2fa62d9ad271f26f2a8e4d9297190e0250bb967 Mon Sep 17 00:00:00 2001
From: Michael Terry 
Date: Wed, 23 Feb 2011 15:13:11 -0600
Subject: show admin1 and country in completion dropdown

---
 src/timezone-completion.c | 35 ++++++++++++++++++++++++++++++++++-
 1 file changed, 34 insertions(+), 1 deletion(-)

diff --git a/src/timezone-completion.c b/src/timezone-completion.c
index 7f5ad68..ab7ae5e 100644
--- a/src/timezone-completion.c
+++ b/src/timezone-completion.c
@@ -298,6 +298,35 @@ get_initial_model (void)
   return store;
 }
 
+static void
+data_func (GtkCellLayout *cell_layout, GtkCellRenderer *cell,
+           GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer user_data)
+{
+  GValue name_val = {0}, admin1_val = {0}, country_val = {0};
+  const gchar * name, * admin1, * country;
+
+  gtk_tree_model_get_value (GTK_TREE_MODEL (tree_model), iter, TIMEZONE_COMPLETION_NAME, &name_val);
+  gtk_tree_model_get_value (GTK_TREE_MODEL (tree_model), iter, TIMEZONE_COMPLETION_ADMIN1, &admin1_val);
+  gtk_tree_model_get_value (GTK_TREE_MODEL (tree_model), iter, TIMEZONE_COMPLETION_COUNTRY, &country_val);
+
+  name = g_value_get_string (&name_val);
+  admin1 = g_value_get_string (&admin1_val);
+  country = g_value_get_string (&country_val);
+
+  gchar * user_name;
+  if (admin1 == NULL || admin1[0] == 0) {
+    user_name = g_strdup_printf ("%s (%s)", name, country);
+  } else {
+    user_name = g_strdup_printf ("%s (%s, %s)", name, admin1, country);
+  }
+
+  g_object_set (G_OBJECT (cell), "markup", user_name, NULL);
+
+  g_value_unset (&name_val);
+  g_value_unset (&admin1_val);
+  g_value_unset (&country_val);
+}
+
 static void
 timezone_completion_class_init (TimezoneCompletionClass *klass)
 {
@@ -318,12 +347,16 @@ timezone_completion_init (TimezoneCompletion * self)
 
   GtkListStore * model = get_initial_model ();
   gtk_entry_completion_set_model (GTK_ENTRY_COMPLETION (self), GTK_TREE_MODEL (model));
-  gtk_entry_completion_set_text_column (GTK_ENTRY_COMPLETION (self), TIMEZONE_COMPLETION_NAME);
+  g_object_set (G_OBJECT (self), "text-column", TIMEZONE_COMPLETION_NAME, NULL);
 
   priv->cancel = g_cancellable_new ();
 
   priv->request_table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
 
+  GtkCellRenderer * cell = gtk_cell_renderer_text_new ();
+  gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (self), cell, TRUE);
+  gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (self), cell, data_func, NULL, NULL);
+
   return;
 }
 
-- 
cgit v1.2.3


From ad847471eee3e68c27505af6a35245f9e3f7f532 Mon Sep 17 00:00:00 2001
From: Michael Terry 
Date: Wed, 23 Feb 2011 15:26:49 -0600
Subject: add geonames watermark

---
 libmap/README            |  2 +-
 libmap/cc-timezone-map.c | 30 ++++++++++++++++++++++++++++++
 libmap/cc-timezone-map.h |  2 ++
 src/datetime-prefs.c     |  2 ++
 4 files changed, 35 insertions(+), 1 deletion(-)

diff --git a/libmap/README b/libmap/README
index c83c6d8..6766b42 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 and add cc_timezone_map_set_coords and friends.
+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.  And the watermark.
diff --git a/libmap/cc-timezone-map.c b/libmap/cc-timezone-map.c
index 7647925..5ece1c2 100644
--- a/libmap/cc-timezone-map.c
+++ b/libmap/cc-timezone-map.c
@@ -60,6 +60,8 @@ struct _CcTimezoneMapPrivate
 
   gdouble selected_offset;
 
+  gchar *watermark;
+
   TzDB *tzdb;
   TzLocation *location;
   GHashTable *alias_db;
@@ -574,6 +576,12 @@ cc_timezone_map_dispose (GObject *object)
       priv->alias_db = NULL;
     }
 
+  if (priv->watermark)
+    {
+      g_free (priv->watermark);
+      priv->watermark = NULL;
+    }
+
   G_OBJECT_CLASS (cc_timezone_map_parent_class)->dispose (object);
 }
 
@@ -822,6 +830,18 @@ cc_timezone_map_draw (GtkWidget *widget,
       g_object_unref (pin);
     }
 
+  if (priv->watermark) {
+    cairo_text_extents_t extent;
+    cairo_select_font_face(cr, "Sans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
+    cairo_set_font_size(cr, 12.0);
+    cairo_set_source_rgba(cr, 1, 1, 1, 0.5);
+    cairo_text_extents(cr, priv->watermark, &extent);
+    cairo_move_to(cr, alloc.width - extent.x_advance + extent.x_bearing - 5,
+                      alloc.height - extent.height - extent.y_bearing - 5);
+    cairo_show_text(cr, priv->watermark);
+    cairo_stroke(cr);
+  }
+
   return TRUE;
 }
 
@@ -1150,6 +1170,16 @@ cc_timezone_map_get_timezone_at_coords (CcTimezoneMap *map, gdouble lon, gdouble
   }
 }
 
+void
+cc_timezone_map_set_watermark (CcTimezoneMap *map, const gchar * watermark)
+{
+  if (map->priv->watermark)
+    g_free (map->priv->watermark);
+
+  map->priv->watermark = g_strdup (watermark);
+  gtk_widget_queue_draw (GTK_WIDGET (map));
+}
+
 TzLocation *
 cc_timezone_map_get_location (CcTimezoneMap *map)
 {
diff --git a/libmap/cc-timezone-map.h b/libmap/cc-timezone-map.h
index 8de986d..ace1107 100644
--- a/libmap/cc-timezone-map.h
+++ b/libmap/cc-timezone-map.h
@@ -70,6 +70,8 @@ GType cc_timezone_map_get_type (void) G_GNUC_CONST;
 
 CcTimezoneMap *cc_timezone_map_new (void);
 
+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,
diff --git a/src/datetime-prefs.c b/src/datetime-prefs.c
index 3f5e5e6..fbadd27 100644
--- a/src/datetime-prefs.c
+++ b/src/datetime-prefs.c
@@ -494,6 +494,8 @@ create_dialog (void)
   /* Add map */
   tzmap = cc_timezone_map_new ();
   gtk_container_add (GTK_CONTAINER (WIG ("mapBox")), GTK_WIDGET (tzmap));
+  /* Fufill the CC by Attribution license requirements for the Geonames lookup */
+  cc_timezone_map_set_watermark (tzmap, "Geonames.org");
 
   /* And completion entry */
   TimezoneCompletion * completion = timezone_completion_new ();
-- 
cgit v1.2.3


From 7ef186559335f0f82cf2985ada9151f2232d2c90 Mon Sep 17 00:00:00 2001
From: Michael Terry 
Date: Wed, 23 Feb 2011 15:31:18 -0600
Subject: don't have the map draw a highlight if no zone selected

---
 libmap/cc-timezone-map.c | 48 +++++++++++++++++++++++-------------------------
 1 file changed, 23 insertions(+), 25 deletions(-)

diff --git a/libmap/cc-timezone-map.c b/libmap/cc-timezone-map.c
index 5ece1c2..ec12c84 100644
--- a/libmap/cc-timezone-map.c
+++ b/libmap/cc-timezone-map.c
@@ -774,6 +774,23 @@ cc_timezone_map_draw (GtkWidget *widget,
   gdk_cairo_set_source_pixbuf (cr, priv->background, 0, 0);
   cairo_paint (cr);
 
+  /* paint watermark */
+  if (priv->watermark) {
+    cairo_text_extents_t extent;
+    cairo_select_font_face(cr, "Sans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
+    cairo_set_font_size(cr, 12.0);
+    cairo_set_source_rgba(cr, 1, 1, 1, 0.5);
+    cairo_text_extents(cr, priv->watermark, &extent);
+    cairo_move_to(cr, alloc.width - extent.x_advance + extent.x_bearing - 5,
+                      alloc.height - extent.height - extent.y_bearing - 5);
+    cairo_show_text(cr, priv->watermark);
+    cairo_stroke(cr);
+  }
+
+  if (!priv->location) {
+    return TRUE;
+  }
+
   /* paint hilight */
   file = g_strdup_printf (DATADIR "/timezone_%s.png",
                           g_ascii_formatd (buf, sizeof (buf),
@@ -810,38 +827,19 @@ cc_timezone_map_draw (GtkWidget *widget,
       g_clear_error (&err);
     }
 
-  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;
+  pointx = convert_longtitude_to_x (priv->location->longitude, alloc.width);
+  pointy = convert_latitude_to_y (priv->location->latitude, alloc.height);
 
-      if (pin)
-        {
-          gdk_cairo_set_source_pixbuf (cr, pin, pointx - 8, pointy - 14);
-          cairo_paint (cr);
-        }
-    }
+  if (pointy > alloc.height)
+    pointy = alloc.height;
 
   if (pin)
     {
+      gdk_cairo_set_source_pixbuf (cr, pin, pointx - 8, pointy - 14);
+      cairo_paint (cr);
       g_object_unref (pin);
     }
 
-  if (priv->watermark) {
-    cairo_text_extents_t extent;
-    cairo_select_font_face(cr, "Sans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
-    cairo_set_font_size(cr, 12.0);
-    cairo_set_source_rgba(cr, 1, 1, 1, 0.5);
-    cairo_text_extents(cr, priv->watermark, &extent);
-    cairo_move_to(cr, alloc.width - extent.x_advance + extent.x_bearing - 5,
-                      alloc.height - extent.height - extent.y_bearing - 5);
-    cairo_show_text(cr, priv->watermark);
-    cairo_stroke(cr);
-  }
-
   return TRUE;
 }
 
-- 
cgit v1.2.3


From e1ed5129d99c0b7d6f8829a146173b940ce8890d Mon Sep 17 00:00:00 2001
From: Michael Terry 
Date: Thu, 24 Feb 2011 10:31:33 -0500
Subject: have location column expand

---
 src/datetime-prefs-locations.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/src/datetime-prefs-locations.c b/src/datetime-prefs-locations.c
index e29580f..ce3acaa 100644
--- a/src/datetime-prefs-locations.c
+++ b/src/datetime-prefs-locations.c
@@ -297,6 +297,9 @@ datetime_setup_locations_dialog (GtkWindow * parent, CcTimezoneMap * map)
   gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (tree), -1,
                                                _("Location"), cell,
                                                "text", 0, NULL);
+  GtkTreeViewColumn * loc_col = gtk_tree_view_get_column (GTK_TREE_VIEW (tree), 0);
+  gtk_tree_view_column_set_expand (loc_col, TRUE);
+
   cell = gtk_cell_renderer_text_new ();
   gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (tree), -1,
                                                _("Time"), cell,
-- 
cgit v1.2.3


From 671bcdaf530e6723c2208bb98ae9cae1b1dc23c8 Mon Sep 17 00:00:00 2001
From: Michael Terry 
Date: Thu, 24 Feb 2011 11:01:03 -0500
Subject: don't update locations dialog's times when editing

---
 src/datetime-prefs-locations.c | 15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/src/datetime-prefs-locations.c b/src/datetime-prefs-locations.c
index ce3acaa..0c9a93c 100644
--- a/src/datetime-prefs-locations.c
+++ b/src/datetime-prefs-locations.c
@@ -152,9 +152,17 @@ handle_edit_started (GtkCellRendererText * renderer, GtkCellEditable * editable,
 }
 
 static gboolean
-update_times (GtkListStore * store)
+update_times (TimezoneCompletion * completion)
 {
   /* For each entry, check zone in column 2 and set column 1 to it's time */
+  GtkListStore * store = GTK_LIST_STORE (g_object_get_data (G_OBJECT (completion), "store"));
+  GObject * cell = G_OBJECT (g_object_get_data (G_OBJECT (completion), "name-cell"));
+
+  gboolean editing;
+  g_object_get (cell, "editing", &editing, NULL);
+  if (editing) { /* No updates while editing, it cancels the edit */
+    return TRUE;
+  }
 
   GDateTime * now = g_date_time_new_now_local ();
 
@@ -299,6 +307,7 @@ datetime_setup_locations_dialog (GtkWindow * parent, CcTimezoneMap * map)
                                                "text", 0, NULL);
   GtkTreeViewColumn * loc_col = gtk_tree_view_get_column (GTK_TREE_VIEW (tree), 0);
   gtk_tree_view_column_set_expand (loc_col, TRUE);
+  g_object_set_data (G_OBJECT (completion), "name-cell", cell);
 
   cell = gtk_cell_renderer_text_new ();
   gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (tree), -1,
@@ -315,8 +324,8 @@ datetime_setup_locations_dialog (GtkWindow * parent, CcTimezoneMap * map)
 
   fill_from_settings (store, conf);
 
-  guint time_id = g_timeout_add_seconds (2, (GSourceFunc)update_times, store);
-  update_times (GTK_LIST_STORE (store));
+  guint time_id = g_timeout_add_seconds (2, (GSourceFunc)update_times, completion);
+  update_times (completion);
 
   g_object_set_data_full (G_OBJECT (dlg), "conf", g_object_ref (conf), g_object_unref);
   g_object_set_data_full (G_OBJECT (dlg), "completion", completion, g_object_unref);
-- 
cgit v1.2.3


From ef1648eeba51b9c2e29a3890a6057b569c67b543 Mon Sep 17 00:00:00 2001
From: Michael Terry 
Date: Thu, 24 Feb 2011 11:41:37 -0500
Subject: make sure user always sees new model from geonames when we get it

---
 src/timezone-completion.c | 122 ++++++++++++++++++++++++++--------------------
 1 file changed, 68 insertions(+), 54 deletions(-)

diff --git a/src/timezone-completion.c b/src/timezone-completion.c
index ab7ae5e..f570c33 100644
--- a/src/timezone-completion.c
+++ b/src/timezone-completion.c
@@ -37,6 +37,7 @@ enum {
 typedef struct _TimezoneCompletionPrivate TimezoneCompletionPrivate;
 struct _TimezoneCompletionPrivate
 {
+  GtkTreeModel * initial_model;
   GtkEntry *     entry;
   guint          queued_request;
   guint          changed_id;
@@ -57,6 +58,16 @@ static void timezone_completion_finalize   (GObject *object);
 
 G_DEFINE_TYPE (TimezoneCompletion, timezone_completion, GTK_TYPE_ENTRY_COMPLETION);
 
+static void
+save_and_use_model (TimezoneCompletion * completion, GtkTreeModel * model)
+{
+  TimezoneCompletionPrivate * priv = TIMEZONE_COMPLETION_GET_PRIVATE(completion);
+
+  g_hash_table_insert (priv->request_table, g_strdup (priv->request_text), g_object_ref (model));
+  gtk_entry_completion_set_model (GTK_ENTRY_COMPLETION (completion), model);
+  gtk_entry_completion_complete (GTK_ENTRY_COMPLETION (completion));
+}
+
 static void
 json_parse_ready (GObject *object, GAsyncResult *res, gpointer user_data)
 {
@@ -73,10 +84,18 @@ json_parse_ready (GObject *object, GAsyncResult *res, gpointer user_data)
   if (error != NULL) {
     g_warning ("Could not parse geoname JSON data: %s", error->message);
     g_error_free (error);
+    save_and_use_model (completion, priv->initial_model);
     return;
   }
 
-  GtkListStore * store = GTK_LIST_STORE (gtk_entry_completion_get_model (GTK_ENTRY_COMPLETION (completion)));
+  GtkListStore * store = gtk_list_store_new (TIMEZONE_COMPLETION_LAST,
+                                             G_TYPE_STRING,
+                                             G_TYPE_STRING,
+                                             G_TYPE_STRING,
+                                             G_TYPE_STRING,
+                                             G_TYPE_STRING,
+                                             G_TYPE_STRING);
+
   JsonReader * reader = json_reader_new (json_parser_get_root (JSON_PARSER (object)));
 
   if (!json_reader_is_array (reader))
@@ -114,57 +133,23 @@ json_parse_ready (GObject *object, GAsyncResult *res, gpointer user_data)
         json_reader_end_member (reader);
       }
 
-      /* See if we have this in our store already */
       GtkTreeIter iter;
-      gboolean skip = FALSE;
-      if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter)) {
-        do {
-          GValue value = {0};
-
-          gtk_tree_model_get_value (GTK_TREE_MODEL (store), &iter, TIMEZONE_COMPLETION_NAME, &value);
-          if (g_strcmp0 (g_value_get_string (&value), name) != 0) {
-            g_value_unset (&value);
-            continue;
-          }
-          g_value_unset (&value);
-
-          gtk_tree_model_get_value (GTK_TREE_MODEL (store), &iter, TIMEZONE_COMPLETION_ADMIN1, &value);
-          if (g_strcmp0 (g_value_get_string (&value), admin1) != 0) {
-            g_value_unset (&value);
-            continue;
-          }
-          g_value_unset (&value);
-
-          gtk_tree_model_get_value (GTK_TREE_MODEL (store), &iter, TIMEZONE_COMPLETION_COUNTRY, &value);
-          if (g_strcmp0 (g_value_get_string (&value), country) != 0) {
-            g_value_unset (&value);
-            continue;
-          }
-          g_value_unset (&value);
-
-          /* Must be the same, skip this one */
-          skip = TRUE;
-          break;
-        } while (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter));
-      }
-
-      if (!skip) {
-        gtk_list_store_append (store, &iter);
-        gtk_list_store_set (store, &iter,
-                            TIMEZONE_COMPLETION_ZONE, NULL,
-                            TIMEZONE_COMPLETION_NAME, name,
-                            TIMEZONE_COMPLETION_ADMIN1, admin1,
-                            TIMEZONE_COMPLETION_COUNTRY, country,
-                            TIMEZONE_COMPLETION_LONGITUDE, longitude,
-                            TIMEZONE_COMPLETION_LATITUDE, latitude,
-                            -1);
-      }
+      gtk_list_store_append (store, &iter);
+      gtk_list_store_set (store, &iter,
+                          TIMEZONE_COMPLETION_ZONE, NULL,
+                          TIMEZONE_COMPLETION_NAME, name,
+                          TIMEZONE_COMPLETION_ADMIN1, admin1,
+                          TIMEZONE_COMPLETION_COUNTRY, country,
+                          TIMEZONE_COMPLETION_LONGITUDE, longitude,
+                          TIMEZONE_COMPLETION_LATITUDE, latitude,
+                          -1);
     }
 
     json_reader_end_element (reader);
   }
 
-  g_hash_table_insert (priv->request_table, g_strdup (priv->request_text), NULL);
+  save_and_use_model (completion, GTK_TREE_MODEL (store));
+  g_object_unref (G_OBJECT (store));
 }
 
 static void
@@ -184,6 +169,7 @@ geonames_data_ready (GObject *object, GAsyncResult *res, gpointer user_data)
   if (error != NULL) {
     g_warning ("Could not connect to geoname lookup server: %s", error->message);
     g_error_free (error);
+    save_and_use_model (completion, priv->initial_model);
     return;
   }
 
@@ -205,8 +191,12 @@ request_zones (TimezoneCompletion * completion)
 
   const gchar * text = gtk_entry_get_text (priv->entry);
 
-  if (g_hash_table_lookup_extended (priv->request_table, text, NULL, NULL))
-    return FALSE; // already looked this up
+  gpointer data;
+  if (g_hash_table_lookup_extended (priv->request_table, text, NULL, &data)) {
+    gtk_entry_completion_set_model (GTK_ENTRY_COMPLETION (completion), GTK_TREE_MODEL (data));
+    gtk_entry_completion_complete (GTK_ENTRY_COMPLETION (completion));
+    return FALSE;
+  }
 
   /* Cancel any ongoing request */
   if (priv->cancel) {
@@ -327,6 +317,14 @@ data_func (GtkCellLayout *cell_layout, GtkCellRenderer *cell,
   g_value_unset (&country_val);
 }
 
+static gboolean
+match_func (GtkEntryCompletion *completion, const gchar *key,
+            GtkTreeIter *iter, gpointer user_data)
+{
+  // geonames does the work for us
+  return TRUE;
+}
+
 static void
 timezone_completion_class_init (TimezoneCompletionClass *klass)
 {
@@ -345,13 +343,17 @@ timezone_completion_init (TimezoneCompletion * self)
 {
   TimezoneCompletionPrivate * priv = TIMEZONE_COMPLETION_GET_PRIVATE (self);
 
-  GtkListStore * model = get_initial_model ();
-  gtk_entry_completion_set_model (GTK_ENTRY_COMPLETION (self), GTK_TREE_MODEL (model));
-  g_object_set (G_OBJECT (self), "text-column", TIMEZONE_COMPLETION_NAME, NULL);
+  priv->initial_model = GTK_TREE_MODEL (get_initial_model ());
+
+  gtk_entry_completion_set_match_func (GTK_ENTRY_COMPLETION (self), match_func, NULL, NULL);
+  g_object_set (G_OBJECT (self),
+                "text-column", TIMEZONE_COMPLETION_NAME,
+                "popup-set-width", FALSE,
+                NULL);
 
   priv->cancel = g_cancellable_new ();
 
-  priv->request_table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
+  priv->request_table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
 
   GtkCellRenderer * cell = gtk_cell_renderer_text_new ();
   gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (self), cell, TRUE);
@@ -377,6 +379,11 @@ timezone_completion_dispose (GObject * object)
     g_object_remove_weak_pointer (G_OBJECT (priv->entry), (gpointer *)&priv->entry);
   }
 
+  if (priv->initial_model != NULL) {
+    g_object_unref (G_OBJECT (priv->initial_model));
+    priv->initial_model = NULL;
+  }
+
   if (priv->queued_request) {
     g_source_remove (priv->queued_request);
     priv->queued_request = 0;
@@ -388,8 +395,15 @@ timezone_completion_dispose (GObject * object)
     priv->cancel = NULL;
   }
 
-  g_free (priv->request_text);
-  g_hash_table_destroy (priv->request_table);
+  if (priv->request_text != NULL) {
+    g_free (priv->request_text);
+    priv->request_text = NULL;
+  }
+
+  if (priv->request_table != NULL) {
+    g_hash_table_destroy (priv->request_table);
+    priv->request_table = NULL;
+  }
 
   return;
 }
-- 
cgit v1.2.3


From 486ad3625ca52b318f5514f782b90f1eda0b87e7 Mon Sep 17 00:00:00 2001
From: Michael Terry 
Date: Thu, 24 Feb 2011 15:02:00 -0500
Subject: have spinners work in unison -- only save when neither is focused

---
 src/datetime-prefs.c | 124 ++++++++++++++++++++++++++++++++++++++-------------
 1 file changed, 92 insertions(+), 32 deletions(-)

diff --git a/src/datetime-prefs.c b/src/datetime-prefs.c
index fbadd27..d053c7e 100644
--- a/src/datetime-prefs.c
+++ b/src/datetime-prefs.c
@@ -46,6 +46,11 @@ GDBusProxy * proxy = NULL;
 GtkWidget * auto_radio = NULL;
 GtkWidget * tz_entry = NULL;
 CcTimezoneMap * tzmap = NULL;
+GtkWidget * time_spin = NULL;
+GtkWidget * date_spin = NULL;
+GDateTime * manual_time = NULL;
+guint       save_time_id = 0;
+gboolean    user_edited_time = FALSE;
 
 /* Turns the boolean property into a string gsettings */
 static GVariant *
@@ -277,13 +282,56 @@ void proxy_ready (GObject *object, GAsyncResult *res, gpointer user_data)
                      NULL, tz_query_answered, NULL);
 }
 
+static gboolean
+are_spinners_focused (void)
+{
+  // save_time_id means that we were in focus and haven't finished our save
+  // yet, so act like we are still focused.
+  return save_time_id || gtk_widget_has_focus (time_spin) || gtk_widget_has_focus (date_spin);
+}
+
+static gboolean
+save_time (gpointer user_data)
+{
+  if (user_edited_time) {
+    g_dbus_proxy_call (proxy, "SetTime", g_variant_new ("(x)", g_date_time_to_unix (manual_time)),
+                       G_DBUS_CALL_FLAGS_NONE, -1, NULL, dbus_set_answered, "time");
+  }
+  user_edited_time = FALSE;
+  save_time_id = 0;
+  return FALSE;
+}
+
+static gboolean
+spin_focus_in (void)
+{
+  if (save_time_id > 0) {
+    g_source_remove (save_time_id);
+    save_time_id = 0;
+  }
+  return FALSE;
+}
+
+static gboolean
+spin_focus_out (void)
+{
+  /* We want to only save when both spinners are unfocused.  But it's difficult
+     to tell who is about to get focus during a focus-out.  So we set an idle
+     callback to save the time if we don't focus in to another spinner by that
+     time. */
+  if (save_time_id == 0) {
+    save_time_id = g_idle_add ((GSourceFunc)save_time, NULL);
+  }
+  return FALSE;
+}
+
 static int
 input_time_text (GtkWidget * spinner, gdouble *value, gpointer user_data)
 {
   gboolean is_time = (gboolean)GPOINTER_TO_INT (g_object_get_data (G_OBJECT (spinner), "is-time"));
   const gchar * text = gtk_entry_get_text (GTK_ENTRY (spinner));
 
-  GDateTime * now = g_date_time_new_now_local ();
+  GDateTime * now = manual_time;
   gint year, month, day, hour, minute, second;
   year = g_date_time_get_year (now);
   month = g_date_time_get_month (now);
@@ -291,7 +339,6 @@ input_time_text (GtkWidget * spinner, gdouble *value, gpointer user_data)
   hour = g_date_time_get_hour (now);
   minute = g_date_time_get_minute (now);
   second = g_date_time_get_second (now);
-  g_date_time_unref (now);
 
   /* Parse this string as if it were in the output format */
   gint scanned = 0;
@@ -354,10 +401,9 @@ input_time_text (GtkWidget * spinner, gdouble *value, gpointer user_data)
     return TRUE;
   }
 
-  GDateTime * datetime = g_date_time_new_local (year, month, day, hour, minute, second);
-
-  g_dbus_proxy_call (proxy, "SetTime", g_variant_new ("(x)", g_date_time_to_unix (datetime)),
-                     G_DBUS_CALL_FLAGS_NONE, -1, NULL, dbus_set_answered, "time");
+  g_date_time_unref (manual_time);
+  manual_time = g_date_time_new_local (year, month, day, hour, minute, second);
+  user_edited_time = TRUE;
 
   return TRUE;
 }
@@ -365,12 +411,6 @@ input_time_text (GtkWidget * spinner, gdouble *value, gpointer user_data)
 static gboolean
 format_time_text (GtkWidget * spinner, gpointer user_data)
 {
-  if (gtk_widget_has_focus (spinner)) {
-    /* Don't do anything if we have focus, user is likely editing us */
-    return TRUE;
-  }
-
-  GDateTime * datetime = (GDateTime *)g_object_get_data (G_OBJECT (spinner), "datetime");
   gboolean is_time = (gboolean)GPOINTER_TO_INT (g_object_get_data (G_OBJECT (spinner), "is-time"));
 
   const gchar * format;
@@ -385,39 +425,60 @@ format_time_text (GtkWidget * spinner, gpointer user_data)
     format = "%Y-%m-%d";
   }
 
-  gchar * formatted = g_date_time_format (datetime, format);
+  gchar * formatted = g_date_time_format (manual_time, format);
   gtk_entry_set_text (GTK_ENTRY (spinner), formatted);
 
   return TRUE;
 }
 
 static gboolean
-update_spinner (GtkWidget * spinner)
+update_spinners (void)
 {
   /* Add datetime object to spinner, which will hold the real time value, rather
-     then using the value of the spinner itself. */
-  GDateTime * datetime = g_date_time_new_now_local ();
-  g_object_set_data_full (G_OBJECT (spinner), "datetime", datetime, (GDestroyNotify)g_date_time_unref);
-
-  format_time_text (spinner, NULL);
-
+     then using the value of the spinner itself.  And don't update while user is
+     editing. */
+  if (!are_spinners_focused ()) {
+    if (manual_time != NULL) {
+      g_date_time_unref (manual_time);
+    }
+    manual_time = g_date_time_new_now_local ();
+    format_time_text (time_spin, NULL);
+    format_time_text (date_spin, NULL);
+  }
   return TRUE;
 }
 
 static void
-setup_time_spinner (GtkWidget * spinner, GtkWidget * other, gboolean is_time)
+setup_time_spinners (GtkWidget * time, GtkWidget * date)
 {
-  /* Set up spinner to have reasonable behavior */
-  gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spinner), FALSE);
-  g_signal_connect (spinner, "input", G_CALLBACK (input_time_text), other);
-  g_signal_connect (spinner, "output", G_CALLBACK (format_time_text), other);
-  g_object_set_data (G_OBJECT (spinner), "is-time", GINT_TO_POINTER (is_time));
+  gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (time), FALSE);
+  gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (date), FALSE);
 
-  /* 2 seconds is what the indicator itself uses */
-  guint time_id = g_timeout_add_seconds (2, (GSourceFunc)update_spinner, spinner);
-  g_signal_connect_swapped (spinner, "destroy", G_CALLBACK (g_source_remove), GINT_TO_POINTER (time_id));
+  gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (time), TRUE);
+  gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (date), TRUE);
+
+  g_signal_connect (time, "input", G_CALLBACK (input_time_text), date);
+  g_signal_connect (date, "input", G_CALLBACK (input_time_text), time);
+
+  g_signal_connect (time, "output", G_CALLBACK (format_time_text), date);
+  g_signal_connect (date, "output", G_CALLBACK (format_time_text), time);
+
+  g_signal_connect (time, "focus-in-event", G_CALLBACK (spin_focus_in), date);
+  g_signal_connect (date, "focus-in-event", G_CALLBACK (spin_focus_in), time);
 
-  update_spinner (spinner);
+  g_signal_connect (time, "focus-out-event", G_CALLBACK (spin_focus_out), date);
+  g_signal_connect (date, "focus-out-event", G_CALLBACK (spin_focus_out), time);
+
+  g_object_set_data (G_OBJECT (time), "is-time", GINT_TO_POINTER (TRUE));
+  g_object_set_data (G_OBJECT (date), "is-time", GINT_TO_POINTER (FALSE));
+
+  time_spin = time;
+  date_spin = date;
+
+  /* 2 seconds is what the indicator itself uses */
+  guint time_id = g_timeout_add_seconds (2, (GSourceFunc)update_spinners, NULL);
+  g_signal_connect_swapped (time_spin, "destroy", G_CALLBACK (g_source_remove), GINT_TO_POINTER (time_id));
+  update_spinners ();
 }
 
 static void
@@ -554,8 +615,7 @@ create_dialog (void)
   gtk_widget_set_sensitive (WIG ("showEventsCheck"), (evo_path != NULL));
   g_free (evo_path);
 
-  setup_time_spinner (WIG ("timeSpinner"), WIG ("dateSpinner"), TRUE);
-  setup_time_spinner (WIG ("dateSpinner"), WIG ("timeSpinner"), FALSE);
+  setup_time_spinners (WIG ("timeSpinner"), WIG ("dateSpinner"));
 
   GtkWidget * dlg = WIG ("timeDateDialog");
   auto_radio = WIG ("automaticTimeRadio");
-- 
cgit v1.2.3


From 350271ee98b2ae288f9f1dde5eaea635e9dff3b7 Mon Sep 17 00:00:00 2001
From: Michael Terry 
Date: Fri, 25 Feb 2011 08:18:15 -0500
Subject: add missing olsen_map.png

---
 libmap/data/olsen_map.png | Bin 0 -> 54969 bytes
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 libmap/data/olsen_map.png

diff --git a/libmap/data/olsen_map.png b/libmap/data/olsen_map.png
new file mode 100644
index 0000000..f9bb75c
Binary files /dev/null and b/libmap/data/olsen_map.png differ
-- 
cgit v1.2.3


From 398154d354d19a85f629a6d7131b1a7bd6b7b869 Mon Sep 17 00:00:00 2001
From: karl-qdh 
Date: Fri, 25 Feb 2011 14:04:46 +0000
Subject: Fixing up indicator-datetime  * Config options  * Calendar update
 signals from calendar widget - should update appointments/marks not working
 at present

---
 data/com.canonical.indicator.datetime.gschema.xml | 35 ++++++++-
 src/datetime-service.c                            | 87 ++++++++++++-----------
 src/dbus-shared.h                                 |  9 ++-
 src/indicator-datetime.c                          | 61 +++++++++++++++-
 4 files changed, 148 insertions(+), 44 deletions(-)

diff --git a/data/com.canonical.indicator.datetime.gschema.xml b/data/com.canonical.indicator.datetime.gschema.xml
index 117f965..5881d09 100644
--- a/data/com.canonical.indicator.datetime.gschema.xml
+++ b/data/com.canonical.indicator.datetime.gschema.xml
@@ -5,6 +5,11 @@
 		
 		
 	
+	
+		
+		
+		
+	
 	
 		
 			'locale-default'
@@ -57,13 +62,41 @@
 			  more information.
 			
 		
+		
+			false
+			Show week numbers in calendar
+			
+			  Shows the week numbers in the monthly calendar in indicator-datetime's menu.
+			
+		
 		
-			[]
+			['UTC']
 			A List of locations
 			
 			  Adds the list of locations the user has configured to display in the 
 			  indicator-datetime menu.
 			
 		
+		
+			true
+			Show the monthly calendar in the indicator
+			
+			  Puts the monthly calendar in indicator-datetime's menu.
+			
+		
+		
+			true
+			Show events in the indicator
+			
+			  Shows events from Evolution in indicator-datetime's menu.
+			
+		
+		
+			false
+			Show locations in the indicator
+			
+			  Shows custom defined locations in indicator-datetime's menu.
+			
+		
 	
 
diff --git a/src/datetime-service.c b/src/datetime-service.c
index 347fecb..6a9575e 100644
--- a/src/datetime-service.c
+++ b/src/datetime-service.c
@@ -54,8 +54,11 @@ with this program.  If not, see .
 #include "dbus-shared.h"
 
 
-#define SETTINGS_INTERFACE "com.canonical.indicator.datetime"
-#define SETTINGS_LOCATIONS "locations"
+#define SETTINGS_INTERFACE      "com.canonical.indicator.datetime"
+#define SETTINGS_LOCATIONS      "locations"
+#define SETTINGS_SHOW_CALENDAR  "show-calendar"
+#define SETTINGS_SHOW_EVENTS    "show-events"
+#define SETTINGS_SHOW_LOCATIONS "show-locations"
 
 static void geo_create_client (GeoclueMaster * master, GeoclueMasterClient * client, gchar * path, GError * error, gpointer user_data);
 static gboolean update_appointment_menu_items (gpointer user_data);
@@ -115,6 +118,13 @@ check_timezone_sync (void) {
 	} else {
 		g_debug("Timezones are different");
 	}
+	
+	if (!g_settings_get_boolean(conf, SETTINGS_SHOW_LOCATIONS)) {
+		dbusmenu_menuitem_property_set_bool (locations_separator, DBUSMENU_MENUITEM_PROP_VISIBLE, FALSE);
+		dbusmenu_menuitem_property_set_bool (current_location, DBUSMENU_MENUITEM_PROP_VISIBLE, FALSE);
+		dbusmenu_menuitem_property_set_bool (geo_location, DBUSMENU_MENUITEM_PROP_VISIBLE, FALSE);
+		return;
+	}
 
 	if (geo_location != NULL && current_location != NULL) {
 		g_debug("Got timezone %s", current_timezone);
@@ -288,52 +298,35 @@ activate_cb (DbusmenuMenuitem * menuitem, guint timestamp, const gchar *command)
 	}
 }
 
+static gboolean
+month_changed_cb (DbusmenuMenuitem * menuitem, GVariant *variant, guint timestamp)
+{
+	// TODO: * Decode the month/year from the string we received
+	//       * Check what our current month/year are
+	//		 * Set some globals so when we-re-run update appointment menu items it gets the right start date
+	//		 * update appointment menu items
+	g_debug("Received month changed : %s", g_variant_get_string(variant, NULL));
+	return TRUE;
+}
+
 /* Looks for the calendar application and enables the item if
    we have one */
 static gboolean
 check_for_calendar (gpointer user_data)
 {
 	g_return_val_if_fail (calendar != NULL, FALSE);
+	
+	if (!g_settings_get_boolean(conf, SETTINGS_SHOW_CALENDAR)) return FALSE;
 
 	gchar *evo = g_find_program_in_path("evolution");
 	if (evo != NULL) {
 		g_debug("Found the calendar application: %s", evo);
 		dbusmenu_menuitem_property_set_bool(calendar, DBUSMENU_MENUITEM_PROP_ENABLED, TRUE);
 		dbusmenu_menuitem_property_set_bool(calendar, DBUSMENU_MENUITEM_PROP_VISIBLE, TRUE);
-/*
-		GError *gerror = NULL;
-		// TODO: In reality we should iterate sources of calendar, but getting the local one doens't lag for > a minute
-		g_debug("Setting up ecal.");
-		if (!ecal)
-			ecal = e_cal_new_system_calendar();
-	
-		if (!ecal) {
-			g_debug("e_cal_new_system_calendar failed");
-			ecal = NULL;
-		}
-		g_debug("Open calendar.");
-		if (!e_cal_open(ecal, FALSE, &gerror) ) {
-			g_debug("e_cal_open: %s\n", gerror->message);
-			g_free(ecal);
-			ecal = NULL;
-		}
-		g_debug("Get calendar timezone.");
-		if (!e_cal_get_timezone(ecal, "UTC", &tzone, &gerror)) {
-			g_debug("failed to get time zone\n");
-			g_free(ecal);
-			ecal = NULL;
-		}
-	
-		 This timezone represents the timezone of the calendar, this might be different to the current UTC offset.
-		 * this means we'll have some geoclue interaction going on, and possibly the user will be involved in setting
-		 * their location manually, case in point: trains have satellite links which often geoclue to sweden,
-		 * this shouldn't automatically set the location and mess up all the appointments for the user.
-		 
-		if (ecal) ecal_timezone = icaltimezone_get_tzid(tzone);
-		*/
+
 		DbusmenuMenuitem * separator = dbusmenu_menuitem_new();
 		dbusmenu_menuitem_property_set(separator, DBUSMENU_MENUITEM_PROP_TYPE, DBUSMENU_CLIENT_TYPES_SEPARATOR);
-		dbusmenu_menuitem_child_add_position(root, separator, 3);
+		dbusmenu_menuitem_child_add_position(root, separator, 2);
 
 		add_appointment = dbusmenu_menuitem_new();
 		dbusmenu_menuitem_property_set     (add_appointment, DBUSMENU_MENUITEM_PROP_LABEL, _("Add Appointment"));
@@ -342,9 +335,12 @@ check_for_calendar (gpointer user_data)
 		g_signal_connect(G_OBJECT(add_appointment), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(activate_cb), "evolution -c calendar");
 		dbusmenu_menuitem_child_add_position (root, add_appointment, 3);
 
-		update_appointment_menu_items(NULL);
-		g_signal_connect(root, DBUSMENU_MENUITEM_SIGNAL_ABOUT_TO_SHOW, G_CALLBACK(update_appointment_menu_items), NULL);	
-
+		// Update the calendar items every 30 minutes if it updates the first time
+		if (update_appointment_menu_items(NULL))
+			g_timeout_add_seconds(60*30, update_appointment_menu_items, NULL); 
+			
+		// Connect to event::month-changed 
+		g_signal_connect(calendar, "event::month-changed", G_CALLBACK(month_changed_cb), NULL);
 		g_free(evo);
 	} else {
 		g_debug("Unable to find calendar app.");
@@ -358,7 +354,14 @@ check_for_calendar (gpointer user_data)
 
 static gboolean
 update_timezone_menu_items(gpointer user_data) {
+	if (!g_settings_get_boolean(conf, SETTINGS_SHOW_LOCATIONS)) {
+		dbusmenu_menuitem_property_set_bool (locations_separator, DBUSMENU_MENUITEM_PROP_VISIBLE, FALSE);
+		dbusmenu_menuitem_property_set_bool (current_location, DBUSMENU_MENUITEM_PROP_VISIBLE, FALSE);
+		dbusmenu_menuitem_property_set_bool (geo_location, DBUSMENU_MENUITEM_PROP_VISIBLE, FALSE);
+		return FALSE;
+	} 
 	g_debug("Updating timezone menu items");
+
 	gchar ** locations = g_settings_get_strv(conf, SETTINGS_LOCATIONS);
 	if (locations == NULL) { 
 		g_debug("No locations configured (NULL)");
@@ -425,7 +428,8 @@ auth_func (ECal *ecal, const gchar *prompt, const gchar *key, gpointer user_data
 	else component_name = "Calendar";
 	
 	gchar *password = e_passwords_get_password (component_name, key);
-
+	gboolean remember;
+	
 	if (password == NULL) {
 		password = e_passwords_ask_password (
 			_("Enter password"),
@@ -493,6 +497,9 @@ static gboolean
 update_appointment_menu_items (gpointer user_data) {
 	// FFR: we should take into account short term timers, for instance
 	// tea timers, pomodoro timers etc... that people may add, this is hinted to in the spec.
+	if (calendar == NULL) return FALSE;
+	if (!g_settings_get_boolean(conf, SETTINGS_SHOW_EVENTS)) return FALSE;
+	
 	time_t t1, t2;
 	gchar *query, *is, *ie, *ad;
 	GList *objects = NULL, *l;
@@ -545,7 +552,6 @@ update_appointment_menu_items (gpointer user_data) {
 			g_signal_connect (G_OBJECT(source), "changed", G_CALLBACK (update_appointment_menu_items), NULL);
 			ECal *ecal = e_cal_new(source, E_CAL_SOURCE_TYPE_EVENT);
 			e_cal_set_auth_func (ecal, (ECalAuthFunc) auth_func, NULL);
-			//icaltimezone * tzone;
 			
 			if (!e_cal_open(ecal, FALSE, &gerror)) {
 				g_debug("Failed to get ecal sources %s", gerror->message);
@@ -558,7 +564,8 @@ update_appointment_menu_items (gpointer user_data) {
 			if (!e_cal_get_object_list_as_comp(ecal, query, &objects, &gerror)) {
 				g_debug("Failed to get objects\n");
 				g_free(ecal);
-				return FALSE;
+				gerror = NULL;
+				continue;
 			}
 			g_debug("Number of objects returned: %d", g_list_length(objects));
 			
diff --git a/src/dbus-shared.h b/src/dbus-shared.h
index bad8354..93ea5a1 100644
--- a/src/dbus-shared.h
+++ b/src/dbus-shared.h
@@ -27,7 +27,14 @@ with this program.  If not, see .
 
 #define  MENU_OBJ      "/com/canonical/indicator/datetime/menu"
 
-#define  DBUSMENU_CALENDAR_MENUITEM_TYPE "x-canonical-calendar-item"
+#define DBUSMENU_CALENDAR_MENUITEM_TYPE    "x-canonical-calendar-item"
+
+// The following properties are not *really* properties, but are just
+// a way of accessing the calendar from the service
+#define CALENDAR_MENUITEM_PROP_MARK        "calendar-mark"
+#define CALENDAR_MENUITEM_PROP_UNMARK      "calendar-unmark"
+#define CALENDAR_MENUITEM_PROP_CLEAR_MARKS "calendar-clear-marks"
+
 
 #define APPOINTMENT_MENUITEM_TYPE          "appointment-item"	
 #define APPOINTMENT_MENUITEM_PROP_LABEL    "appointment-label"
diff --git a/src/indicator-datetime.c b/src/indicator-datetime.c
index 54b4507..e793d71 100644
--- a/src/indicator-datetime.c
+++ b/src/indicator-datetime.c
@@ -26,9 +26,11 @@ with this program.  If not, see .
 #include 
 #include 
 #include 
+#include 
 
 /* GStuff */
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -79,6 +81,9 @@ struct _IndicatorDatetimePrivate {
 	gchar * custom_string;
 	gboolean custom_show_seconds;
 
+	gboolean show_week_numbers;
+	gint week_start;
+	
 	guint idle_measure;
 	gint  max_width;
 
@@ -102,7 +107,8 @@ enum {
 	PROP_SHOW_SECONDS,
 	PROP_SHOW_DAY,
 	PROP_SHOW_DATE,
-	PROP_CUSTOM_TIME_FORMAT
+	PROP_CUSTOM_TIME_FORMAT,
+	PROP_SHOW_WEEK_NUMBERS
 };
 
 typedef struct _indicator_item_t indicator_item_t;
@@ -120,6 +126,7 @@ struct _indicator_item_t {
 #define PROP_SHOW_DAY_S                 "show-day"
 #define PROP_SHOW_DATE_S                "show-date"
 #define PROP_CUSTOM_TIME_FORMAT_S       "custom-time-format"
+#define PROP_SHOW_WEEK_NUMBERS_S        "show-week-numbers"
 
 #define SETTINGS_INTERFACE              "com.canonical.indicator.datetime"
 #define SETTINGS_TIME_FORMAT_S          "time-format"
@@ -127,6 +134,7 @@ struct _indicator_item_t {
 #define SETTINGS_SHOW_DAY_S             "show-day"
 #define SETTINGS_SHOW_DATE_S            "show-date"
 #define SETTINGS_CUSTOM_TIME_FORMAT_S   "custom-time-format"
+#define SETTINGS_SHOW_WEEK_NUMBERS_S    "show-week-numbers"
 
 enum {
 	SETTINGS_TIME_LOCALE = 0,
@@ -247,6 +255,13 @@ indicator_datetime_class_init (IndicatorDatetimeClass *klass)
 	                                                     DEFAULT_TIME_FORMAT,
 	                                                     G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
+	g_object_class_install_property (object_class,
+	                                 PROP_SHOW_WEEK_NUMBERS,
+	                                 g_param_spec_boolean(PROP_SHOW_WEEK_NUMBERS_S,
+	                                                      "Whether to show the week numbers in the calendar.",
+	                                                      "Shows the week numbers in the monthly calendar in indicator-datetime's menu.",
+	                                                      FALSE, /* default */
+	                                                      G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 	return;
 }
 
@@ -305,6 +320,11 @@ indicator_datetime_init (IndicatorDatetime *self)
 		                self,
 		                PROP_CUSTOM_TIME_FORMAT_S,
 		                G_SETTINGS_BIND_DEFAULT);
+		g_settings_bind(self->priv->settings,
+		                SETTINGS_SHOW_WEEK_NUMBERS_S,
+		                self,
+		                PROP_SHOW_WEEK_NUMBERS_S,
+		                G_SETTINGS_BIND_DEFAULT);
 	} else {
 		g_warning("Unable to get settings for '" SETTINGS_INTERFACE "'");
 	}
@@ -531,6 +551,18 @@ set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec
 		}
 		break;
 	}
+	case PROP_SHOW_WEEK_NUMBERS: {
+		if (g_value_get_boolean(value) != self->priv->show_week_numbers) {
+			GtkCalendarDisplayOptions flags = ido_calendar_menu_item_get_display_options (self->priv->ido_calendar);
+			if (g_value_get_boolean(value) == TRUE)
+				flags |= GTK_CALENDAR_SHOW_WEEK_NUMBERS;
+			else
+				flags &= ~GTK_CALENDAR_SHOW_WEEK_NUMBERS;
+			ido_calendar_menu_item_set_display_options (self->priv->ido_calendar, flags);
+			self->priv->show_week_numbers = g_value_get_boolean(value);
+		}
+		break;
+	}
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
 		return;
@@ -586,6 +618,9 @@ get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspe
 	case PROP_CUSTOM_TIME_FORMAT:
 		g_value_set_string(value, self->priv->custom_string);
 		break;
+	case PROP_SHOW_WEEK_NUMBERS:
+		g_value_set_boolean(value, self->priv->show_week_numbers);
+		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
 		return;
@@ -1224,6 +1259,15 @@ indicator_prop_change_cb (DbusmenuMenuitem * mi, gchar * prop, GVariant *value,
 		timezone_update_labels(mi_data);
 	} else if (!g_strcmp0(prop, TIMEZONE_MENUITEM_PROP_RADIO)) {
 		gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(mi_data->gmi), g_variant_get_boolean(value));
+		
+	// Properties for marking and unmarking the calendar
+	
+	} else if (!g_strcmp0(prop, CALENDAR_MENUITEM_PROP_MARK)) {
+		ido_calendar_menu_item_mark_day (IDO_CALENDAR_MENU_ITEM (mi_data), g_variant_get_int16(value));
+	} else if (!g_strcmp0(prop, CALENDAR_MENUITEM_PROP_UNMARK)) {
+		ido_calendar_menu_item_unmark_day (IDO_CALENDAR_MENU_ITEM (mi_data), g_variant_get_int16(value));
+	} else if (!g_strcmp0(prop, CALENDAR_MENUITEM_PROP_CLEAR_MARKS)) {
+		ido_calendar_menu_item_clear_marks (IDO_CALENDAR_MENU_ITEM (mi_data));
 	} else {
 		g_warning("Indicator Item property '%s' unknown", prop);
 	}
@@ -1307,6 +1351,19 @@ new_appointment_item (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, Dbu
 	return TRUE;
 }
 
+static void
+month_changed_cb (IdoCalendarMenuItem *ido, 
+                  gpointer        user_data) 
+{
+	gchar datestring[20];
+	guint d,m,y;
+	ido_calendar_menu_item_get_date(ido, &y, &m, &d);
+	g_sprintf(datestring, "%d-%d-%d", y, m, d);
+	GVariant *variant = g_variant_new_string(datestring);
+	guint timestamp = (guint)time(NULL);
+	dbusmenu_menuitem_handle_event(DBUSMENU_MENUITEM(ido), "event::month-changed", variant, timestamp);
+	g_debug("Got month changed signal: %s", datestring);
+}
 
 static gboolean
 new_calendar_item (DbusmenuMenuitem * newitem,
@@ -1331,7 +1388,7 @@ new_calendar_item (DbusmenuMenuitem * newitem,
 	self->priv->ido_calendar = ido;
 
 	dbusmenu_gtkclient_newitem_base(DBUSMENU_GTKCLIENT(client), newitem, GTK_MENU_ITEM(ido), parent);
-
+	g_signal_connect(ido, "month-changed", G_CALLBACK(month_changed_cb), NULL);
 	return TRUE;
 }
 
-- 
cgit v1.2.3


From 2a6b56d0f00d2e23ca48687fe1c81d4e88be3b28 Mon Sep 17 00:00:00 2001
From: Michael Terry 
Date: Fri, 25 Feb 2011 09:18:57 -0500
Subject: remove week-start preference

---
 data/com.canonical.indicator.datetime.gschema.xml | 12 -----
 data/datetime-dialog.ui                           | 61 -----------------------
 src/datetime-prefs.c                              | 49 ------------------
 src/settings-shared.h                             |  1 -
 src/utils.c                                       | 11 ----
 src/utils.h                                       |  1 -
 6 files changed, 135 deletions(-)

diff --git a/data/com.canonical.indicator.datetime.gschema.xml b/data/com.canonical.indicator.datetime.gschema.xml
index 5361896..b33f34e 100644
--- a/data/com.canonical.indicator.datetime.gschema.xml
+++ b/data/com.canonical.indicator.datetime.gschema.xml
@@ -5,11 +5,6 @@
 		
 		
 	
-	
-		
-		
-		
-	
 	
 		
 			true
@@ -83,13 +78,6 @@
 			  Shows the week numbers in the monthly calendar in indicator-datetime's menu.
 			
 		
-		
-			'locale-default'
-			When the week starts
-			
-			  Controls whether weeks in the calendar are shown to start on Sunday or Monday.
-			
-		
 		
 			true
 			Show events in the indicator
diff --git a/data/datetime-dialog.ui b/data/datetime-dialog.ui
index b8d0777..35cb172 100644
--- a/data/datetime-dialog.ui
+++ b/data/datetime-dialog.ui
@@ -597,67 +597,6 @@
                                         0
                                       
                                     
-                                    
-                                      
-                                        True
-                                        False
-                                        0
-                                        Week begins on:
-                                      
-                                      
-                                        True
-                                        True
-                                        1
-                                      
-                                    
-                                    
-                                      
-                                        True
-                                        False
-                                        True
-                                        
-                                          
-                                            S_unday
-                                            True
-                                            True
-                                            False
-                                            False
-                                            True
-                                            0
-                                            True
-                                            True
-                                          
-                                          
-                                            True
-                                            True
-                                            0
-                                          
-                                        
-                                        
-                                          
-                                            Monda_y
-                                            True
-                                            True
-                                            False
-                                            False
-                                            True
-                                            0
-                                            True
-                                            startOnSundayRadio
-                                          
-                                          
-                                            True
-                                            True
-                                            1
-                                          
-                                        
-                                      
-                                      
-                                        True
-                                        True
-                                        2
-                                      
-                                    
                                   
                                 
                               
diff --git a/src/datetime-prefs.c b/src/datetime-prefs.c
index fbadd27..e69d58b 100644
--- a/src/datetime-prefs.c
+++ b/src/datetime-prefs.c
@@ -86,45 +86,6 @@ bind_hours_get (GValue * value, GVariant * variant, gpointer user_data)
   return TRUE;
 }
 
-/* Turns the boolean property into a string gsettings */
-static GVariant *
-bind_week_start_set (const GValue * value, const GVariantType * type, gpointer user_data)
-{
-  const gchar * output = NULL;
-  gboolean is_sunday_button = (gboolean)GPOINTER_TO_INT(user_data);
-
-  if (g_value_get_boolean(value)) {
-    /* Only do anything if we're setting active = true */
-    output = is_sunday_button ? "sunday" : "monday";
-  } else {
-    return NULL;
-  }
-
-  return g_variant_new_string (output);
-}
-
-/* Turns a string gsettings into a boolean property */
-static gboolean
-bind_week_start_get (GValue * value, GVariant * variant, gpointer user_data)
-{
-  const gchar * str = g_variant_get_string(variant, NULL);
-  gboolean output = FALSE;
-  gboolean is_sunday_button = (gboolean)GPOINTER_TO_INT(user_data);
-
-  if (g_strcmp0(str, "locale-default") == 0) {
-    output = (is_sunday_button == is_locale_week_start_sunday ());
-  } else if (g_strcmp0(str, "sunday") == 0) {
-    output = is_sunday_button;
-  } else if (g_strcmp0(str, "monday") == 0) {
-    output = !is_sunday_button;
-  } else {
-    return FALSE;
-  }
-
-  g_value_set_boolean (value, output);
-  return TRUE;
-}
-
 static void
 widget_dependency_cb (GtkWidget * parent, GParamSpec *pspec, GtkWidget * dependent)
 {
@@ -527,16 +488,6 @@ create_dialog (void)
                    "active", G_SETTINGS_BIND_DEFAULT);
   g_settings_bind (conf, SETTINGS_SHOW_WEEK_NUMBERS_S, WIG ("includeWeekNumbersCheck"),
                    "active", G_SETTINGS_BIND_DEFAULT);
-  g_settings_bind_with_mapping (conf, SETTINGS_WEEK_START_S,
-                                WIG ("startOnSundayRadio"), "active",
-                                G_SETTINGS_BIND_DEFAULT,
-                                bind_week_start_get, bind_week_start_set,
-                                GINT_TO_POINTER(TRUE), NULL);
-  g_settings_bind_with_mapping (conf, SETTINGS_WEEK_START_S,
-                                WIG ("startOnMondayRadio"), "active",
-                                G_SETTINGS_BIND_DEFAULT,
-                                bind_week_start_get, bind_week_start_set,
-                                GINT_TO_POINTER(FALSE), NULL);
   g_settings_bind (conf, SETTINGS_SHOW_EVENTS_S, WIG ("showEventsCheck"),
                    "active", G_SETTINGS_BIND_DEFAULT);
   g_settings_bind (conf, SETTINGS_SHOW_LOCATIONS_S, WIG ("showLocationsCheck"),
diff --git a/src/settings-shared.h b/src/settings-shared.h
index a4fac24..df2260e 100644
--- a/src/settings-shared.h
+++ b/src/settings-shared.h
@@ -31,7 +31,6 @@ with this program.  If not, see .
 #define SETTINGS_CUSTOM_TIME_FORMAT_S   "custom-time-format"
 #define SETTINGS_SHOW_CALENDAR_S        "show-calendar"
 #define SETTINGS_SHOW_WEEK_NUMBERS_S    "show-week-numbers"
-#define SETTINGS_WEEK_START_S           "week-start"
 #define SETTINGS_SHOW_EVENTS_S          "show-events"
 #define SETTINGS_SHOW_LOCATIONS_S       "show-locations"
 #define SETTINGS_LOCATIONS_S            "locations"
diff --git a/src/utils.c b/src/utils.c
index 20ae958..7471926 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -50,17 +50,6 @@ is_locale_12h (void)
 	return TRUE;
 }
 
-/* Check the system locale setting to see if the week starts on Sunday or Monday */
-gboolean
-is_locale_week_start_sunday (void)
-{
-	const char * week_1stday = nl_langinfo (_NL_TIME_WEEK_1STDAY);
-
-  /* This appears to be a special value that libc uses for Sunday, it's not
-     really a string */
-  return (GPOINTER_TO_INT (week_1stday) == 19971130);
-}
-
 void
 split_settings_location (const gchar * location, gchar ** zone, gchar ** name)
 {
diff --git a/src/utils.h b/src/utils.h
index 3dc8df1..5f7842c 100644
--- a/src/utils.h
+++ b/src/utils.h
@@ -28,7 +28,6 @@ with this program.  If not, see .
 G_BEGIN_DECLS
 
 gboolean is_locale_12h (void);
-gboolean is_locale_week_start_sunday (void);
 void split_settings_location (const gchar * location, gchar ** zone, gchar ** name);
 gchar * generate_format_string_full (gboolean show_day, gboolean show_date);
 gchar * generate_format_string_at_time (GDateTime * time);
-- 
cgit v1.2.3


From 03eafa311a71cacae4ecca3f198ea7131f33dbb7 Mon Sep 17 00:00:00 2001
From: karl-qdh 
Date: Fri, 25 Feb 2011 15:09:27 +0000
Subject: Get ido calendar and dbusmenu the right way around

---
 src/indicator-datetime.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/src/indicator-datetime.c b/src/indicator-datetime.c
index e793d71..ac8db54 100644
--- a/src/indicator-datetime.c
+++ b/src/indicator-datetime.c
@@ -1357,11 +1357,12 @@ month_changed_cb (IdoCalendarMenuItem *ido,
 {
 	gchar datestring[20];
 	guint d,m,y;
+	DbusmenuMenuitem * item = DBUSMENU_MENUITEM (user_data);
 	ido_calendar_menu_item_get_date(ido, &y, &m, &d);
 	g_sprintf(datestring, "%d-%d-%d", y, m, d);
 	GVariant *variant = g_variant_new_string(datestring);
 	guint timestamp = (guint)time(NULL);
-	dbusmenu_menuitem_handle_event(DBUSMENU_MENUITEM(ido), "event::month-changed", variant, timestamp);
+	dbusmenu_menuitem_handle_event(DBUSMENU_MENUITEM(item), "event::month-changed", variant, timestamp);
 	g_debug("Got month changed signal: %s", datestring);
 }
 
@@ -1388,7 +1389,7 @@ new_calendar_item (DbusmenuMenuitem * newitem,
 	self->priv->ido_calendar = ido;
 
 	dbusmenu_gtkclient_newitem_base(DBUSMENU_GTKCLIENT(client), newitem, GTK_MENU_ITEM(ido), parent);
-	g_signal_connect(ido, "month-changed", G_CALLBACK(month_changed_cb), NULL);
+	g_signal_connect_after(ido, "month-changed", G_CALLBACK(month_changed_cb), (gpointer)newitem);
 	return TRUE;
 }
 
-- 
cgit v1.2.3


From d0e5a69a026bc879759cde57f8ba324c67b6b37a Mon Sep 17 00:00:00 2001
From: karl-qdh 
Date: Fri, 25 Feb 2011 15:43:41 +0000
Subject: Updated to free errors just in case(tm) at dbarths request shortened
 the update time to 5 minutes for calendars

---
 src/datetime-service.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/src/datetime-service.c b/src/datetime-service.c
index 6a9575e..a3e45bf 100644
--- a/src/datetime-service.c
+++ b/src/datetime-service.c
@@ -218,6 +218,7 @@ update_current_timezone (void) {
 
 	check_timezone_sync();
 
+    if (error != NULL) g_error_free(error);
 	return;
 }
 
@@ -335,9 +336,9 @@ check_for_calendar (gpointer user_data)
 		g_signal_connect(G_OBJECT(add_appointment), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(activate_cb), "evolution -c calendar");
 		dbusmenu_menuitem_child_add_position (root, add_appointment, 3);
 
-		// Update the calendar items every 30 minutes if it updates the first time
+		// Update the calendar items every 5 minutes if it updates the first time
 		if (update_appointment_menu_items(NULL))
-			g_timeout_add_seconds(60*30, update_appointment_menu_items, NULL); 
+			g_timeout_add_seconds(60*5, update_appointment_menu_items, NULL); 
 			
 		// Connect to event::month-changed 
 		g_signal_connect(calendar, "event::month-changed", G_CALLBACK(month_changed_cb), NULL);
@@ -710,6 +711,8 @@ update_appointment_menu_items (gpointer user_data) {
 		if (i == 4) break; // See above FIXME regarding query result limit
 		i++;
 	}
+	
+    if (gerror != NULL) g_error_free(gerror);
 	g_object_unref(allobjects);
 	g_debug("End of objects");
 	return TRUE;
-- 
cgit v1.2.3


From 42125be0102026e6ecae842413261a8b05a25e96 Mon Sep 17 00:00:00 2001
From: Michael Terry 
Date: Fri, 25 Feb 2011 11:41:56 -0500
Subject: fix a couple memory leaks noted by MacSlow

---
 libmap/test-timezone.c | 1 +
 src/datetime-service.c | 3 +++
 2 files changed, 4 insertions(+)

diff --git a/libmap/test-timezone.c b/libmap/test-timezone.c
index d667c42..c1935fd 100644
--- a/libmap/test-timezone.c
+++ b/libmap/test-timezone.c
@@ -47,6 +47,7 @@ int main (int argc, char **argv)
 
 		g_free (filename);
 		g_free (path);
+		tz_info_free (info);
 	}
 	tz_db_free (db);
 	g_free (pixmap_dir);
diff --git a/src/datetime-service.c b/src/datetime-service.c
index ab609c4..af63a2a 100644
--- a/src/datetime-service.c
+++ b/src/datetime-service.c
@@ -99,6 +99,9 @@ set_timezone_label (DbusmenuMenuitem * mi, const gchar * location)
 
 	dbusmenu_menuitem_property_set (mi, TIMEZONE_MENUITEM_PROP_NAME, name);
 	dbusmenu_menuitem_property_set (mi, TIMEZONE_MENUITEM_PROP_ZONE, zone);
+
+	g_free (zone);
+	g_free (name);
 }
 
 /* Check to see if our timezones are the same */
-- 
cgit v1.2.3


From b79665734363a3644d3eb7b13a110908ac05d3a1 Mon Sep 17 00:00:00 2001
From: David Barth 
Date: Mon, 28 Feb 2011 11:00:49 +0100
Subject: bumping release number

---
 configure.ac | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/configure.ac b/configure.ac
index 08707bc..a762ea8 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,11 +1,11 @@
 
-AC_INIT(indicator-datetime, 0.1.94, ted@canonical.com)
+AC_INIT(indicator-datetime, 0.1.95, ted@canonical.com)
 AC_COPYRIGHT([Copyright 2009,2010 Canonical])
 
 AC_PREREQ(2.53)
 
 AM_CONFIG_HEADER(config.h)
-AM_INIT_AUTOMAKE(indicator-datetime, 0.1.94)
+AM_INIT_AUTOMAKE(indicator-datetime, 0.1.95)
 
 AM_MAINTAINER_MODE
 
-- 
cgit v1.2.3


From bbd56b119d18a83600c1be706078d3e0d759583d Mon Sep 17 00:00:00 2001
From: karl-qdh 
Date: Mon, 28 Feb 2011 16:45:59 +0000
Subject: Minor change for kenvandine to test sorting

---
 src/datetime-service.c | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/src/datetime-service.c b/src/datetime-service.c
index 6303a98..a6e756e 100644
--- a/src/datetime-service.c
+++ b/src/datetime-service.c
@@ -422,8 +422,10 @@ compare_appointment_items (ECalComponent *a,
 
 	ECalComponentVType vtype = e_cal_component_get_vtype (a);
 	
-	if (vtype != E_CAL_COMPONENT_EVENT && vtype != E_CAL_COMPONENT_TODO) return -1;
-	
+	if (vtype != E_CAL_COMPONENT_EVENT && vtype != E_CAL_COMPONENT_TODO) {
+		g_debug("E-Cal Component is neither an event or a todo");
+		return -1;
+	}
 	if (vtype == E_CAL_COMPONENT_EVENT)
 		e_cal_component_get_dtstart (a, &datetime_a);
 	else
@@ -432,8 +434,11 @@ compare_appointment_items (ECalComponent *a,
 	t_a = mktime(&tm_a);
 	
 	vtype = e_cal_component_get_vtype (b);
-	if (vtype != E_CAL_COMPONENT_EVENT && vtype != E_CAL_COMPONENT_TODO) return 1;
-	
+	if (vtype != E_CAL_COMPONENT_EVENT && vtype != E_CAL_COMPONENT_TODO) {
+		e_cal_component_free_datetime (&datetime_a);
+		g_debug("E-Cal Component is neither an event or a todo");
+		return -1;
+	}
 	if (vtype == E_CAL_COMPONENT_EVENT)
 		e_cal_component_get_dtstart (b, &datetime_b);
 	else
-- 
cgit v1.2.3


From 2de6f443b603965a7fc786df9ef58fcc63841daf Mon Sep 17 00:00:00 2001
From: Ken VanDine 
Date: Mon, 28 Feb 2011 23:05:10 -0500
Subject: Simplify calendar query, we don't need to compute times for the
 range.  The query system has a built in way to specify a relative range.

---
 src/datetime-service.c | 12 ++----------
 1 file changed, 2 insertions(+), 10 deletions(-)

diff --git a/src/datetime-service.c b/src/datetime-service.c
index 6303a98..078ede0 100644
--- a/src/datetime-service.c
+++ b/src/datetime-service.c
@@ -462,8 +462,7 @@ update_appointment_menu_items (gpointer user_data) {
 	if (calendar == NULL) return FALSE;
 	if (!g_settings_get_boolean(conf, SETTINGS_SHOW_EVENTS_S)) return FALSE;
 	
-	time_t t1, t2;
-	gchar *query, *is, *ie, *ad;
+	gchar *query, *ad;
 	GList *objects = NULL, *l;
 	GList *allobjects = NULL;
 	GSList *g;
@@ -472,13 +471,6 @@ update_appointment_menu_items (gpointer user_data) {
 	gint width, height;
 	ESourceList * sources = NULL;
 	
-	time(&t1);
-	time(&t2);
-	t2 += (time_t) (7 * 24 * 60 * 60); /* 7 days ahead of now */
-
-	is = isodate_from_time_t(t1);
-	ie = isodate_from_time_t(t2);
-	
 	gtk_icon_size_lookup(GTK_ICON_SIZE_MENU, &width, &height);
 
 	/* Remove all of the previous appointments */
@@ -497,7 +489,7 @@ update_appointment_menu_items (gpointer user_data) {
 	// TODO Remove all highlights from the calendar widget
 
 	// FIXME can we put a limit on the number of results? Or if not complete, or is event/todo? Or sort it by date?
-	query = g_strdup_printf("(occur-in-time-range? (make-time\"%s\") (make-time\"%s\"))", is, ie);
+	query = g_strdup_printf("(occur-in-time-range? (time-now) (time-add-day (time-now) 7))");
 	
 	if (!e_cal_get_sources(&sources, E_CAL_SOURCE_TYPE_EVENT, &gerror)) {
 		g_debug("Failed to get ecal sources\n");
-- 
cgit v1.2.3


From cf5abb9ac1ec68e2e1acd8d252611d40ff244a2b Mon Sep 17 00:00:00 2001
From: karl-qdh 
Date: Tue, 1 Mar 2011 17:05:51 +0000
Subject: These changes should fix the problems with the recurring appointments
 and dconf changes for show/hide events

---
 src/datetime-service.c | 129 +++++++++++++++++++++++++++++++++----------------
 1 file changed, 88 insertions(+), 41 deletions(-)

diff --git a/src/datetime-service.c b/src/datetime-service.c
index a6e756e..fd73024 100644
--- a/src/datetime-service.c
+++ b/src/datetime-service.c
@@ -73,6 +73,7 @@ static DatetimeInterface * dbus = NULL;
 static DbusmenuMenuitem * date = NULL;
 static DbusmenuMenuitem * calendar = NULL;
 static DbusmenuMenuitem * settings = NULL;
+static DbusmenuMenuitem * events_separator = NULL;
 static DbusmenuMenuitem * locations_separator = NULL;
 static DbusmenuMenuitem * geo_location = NULL;
 static DbusmenuMenuitem * current_location = NULL;
@@ -278,8 +279,38 @@ month_changed_cb (DbusmenuMenuitem * menuitem, GVariant *variant, guint timestam
 	return TRUE;
 }
 
+static guint ecaltimer = 0;
+
+static void
+start_ecal_timer(void)
+{
+	if (ecaltimer != 0) g_source_remove(ecaltimer);
+	if (update_appointment_menu_items(NULL))
+		ecaltimer = g_timeout_add_seconds(60*5, update_appointment_menu_items, NULL); 	
+}
+
+static void
+stop_ecal_timer(void)
+{
+	if (ecaltimer != 0) g_source_remove(ecaltimer);
+}
+
+static void
+show_events_changed (void)
+{
+	if (g_settings_get_boolean(conf, SETTINGS_SHOW_EVENTS_S)) {
+		dbusmenu_menuitem_property_set_bool(add_appointment, DBUSMENU_MENUITEM_PROP_VISIBLE, TRUE);
+		dbusmenu_menuitem_property_set_bool(events_separator, DBUSMENU_MENUITEM_PROP_VISIBLE, TRUE);
+		start_ecal_timer();
+	} else {
+		dbusmenu_menuitem_property_set_bool(add_appointment, DBUSMENU_MENUITEM_PROP_VISIBLE, FALSE);
+		dbusmenu_menuitem_property_set_bool(events_separator, DBUSMENU_MENUITEM_PROP_VISIBLE, FALSE);
+		stop_ecal_timer();
+	}
+}
+
 /* Looks for the calendar application and enables the item if
-   we have one */
+   we have one, starts ecal timer if events are turned on */
 static gboolean
 check_for_calendar (gpointer user_data)
 {
@@ -293,21 +324,26 @@ check_for_calendar (gpointer user_data)
 		dbusmenu_menuitem_property_set_bool(calendar, DBUSMENU_MENUITEM_PROP_ENABLED, TRUE);
 		dbusmenu_menuitem_property_set_bool(calendar, DBUSMENU_MENUITEM_PROP_VISIBLE, TRUE);
 
-		DbusmenuMenuitem * separator = dbusmenu_menuitem_new();
-		dbusmenu_menuitem_property_set(separator, DBUSMENU_MENUITEM_PROP_TYPE, DBUSMENU_CLIENT_TYPES_SEPARATOR);
-		dbusmenu_menuitem_child_add_position(root, separator, 2);
-
+		events_separator = dbusmenu_menuitem_new();
+		dbusmenu_menuitem_property_set(events_separator, DBUSMENU_MENUITEM_PROP_TYPE, DBUSMENU_CLIENT_TYPES_SEPARATOR);
+		dbusmenu_menuitem_child_add_position(root, events_separator, 2);
 		add_appointment = dbusmenu_menuitem_new();
-		dbusmenu_menuitem_property_set     (add_appointment, DBUSMENU_MENUITEM_PROP_LABEL, _("Add Appointment"));
+		dbusmenu_menuitem_property_set (add_appointment, DBUSMENU_MENUITEM_PROP_LABEL, _("Add Appointment"));
 		dbusmenu_menuitem_property_set_bool(add_appointment, DBUSMENU_MENUITEM_PROP_ENABLED, TRUE);
-		dbusmenu_menuitem_property_set_bool(add_appointment, DBUSMENU_MENUITEM_PROP_VISIBLE, TRUE);
 		g_signal_connect(G_OBJECT(add_appointment), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(activate_cb), "evolution -c calendar");
 		dbusmenu_menuitem_child_add_position (root, add_appointment, 3);
 
-		// Update the calendar items every 5 minutes if it updates the first time
-		if (update_appointment_menu_items(NULL))
-			g_timeout_add_seconds(60*5, update_appointment_menu_items, NULL); 
-			
+
+		if (g_settings_get_boolean(conf, SETTINGS_SHOW_EVENTS_S)) {
+			dbusmenu_menuitem_property_set_bool(add_appointment, DBUSMENU_MENUITEM_PROP_VISIBLE, TRUE);
+			dbusmenu_menuitem_property_set_bool(events_separator, DBUSMENU_MENUITEM_PROP_VISIBLE, TRUE);
+			start_ecal_timer();
+		} else {
+			dbusmenu_menuitem_property_set_bool(add_appointment, DBUSMENU_MENUITEM_PROP_VISIBLE, FALSE);
+			dbusmenu_menuitem_property_set_bool(events_separator, DBUSMENU_MENUITEM_PROP_VISIBLE, FALSE);
+			stop_ecal_timer();
+		}
+		
 		// Connect to event::month-changed 
 		g_signal_connect(calendar, "event::month-changed", G_CALLBACK(month_changed_cb), NULL);
 		g_free(evo);
@@ -381,7 +417,11 @@ update_timezone_menu_items(gpointer user_data) {
 
 // Authentication function
 static gchar *
-auth_func (ECal *ecal, const gchar *prompt, const gchar *key, gpointer user_data) {
+auth_func (ECal *ecal, 
+           const gchar *prompt, 
+           const gchar *key, 
+           gpointer user_data)
+{
 	gboolean remember; // TODO: Is this useful?  Should we be storing it somewhere?
 	ESource *source = e_cal_get_source (ecal);
 	gchar *auth_domain = e_source_get_duped_property (source, "auth-domain");
@@ -411,8 +451,8 @@ auth_func (ECal *ecal, const gchar *prompt, const gchar *key, gpointer user_data
 // Compare function for g_list_sort of ECalComponent objects
 static gint 
 compare_appointment_items (ECalComponent *a,
-                           ECalComponent *b) {
-                                       
+                           ECalComponent *b) 
+{
 	ECalComponentDateTime datetime_a, datetime_b;
 	struct tm tm_a, tm_b;
 	time_t t_a, t_b;
@@ -422,10 +462,8 @@ compare_appointment_items (ECalComponent *a,
 
 	ECalComponentVType vtype = e_cal_component_get_vtype (a);
 	
-	if (vtype != E_CAL_COMPONENT_EVENT && vtype != E_CAL_COMPONENT_TODO) {
-		g_debug("E-Cal Component is neither an event or a todo");
-		return -1;
-	}
+	if (vtype != E_CAL_COMPONENT_EVENT && vtype != E_CAL_COMPONENT_TODO) return -1;
+	
 	if (vtype == E_CAL_COMPONENT_EVENT)
 		e_cal_component_get_dtstart (a, &datetime_a);
 	else
@@ -434,11 +472,8 @@ compare_appointment_items (ECalComponent *a,
 	t_a = mktime(&tm_a);
 	
 	vtype = e_cal_component_get_vtype (b);
-	if (vtype != E_CAL_COMPONENT_EVENT && vtype != E_CAL_COMPONENT_TODO) {
-		e_cal_component_free_datetime (&datetime_a);
-		g_debug("E-Cal Component is neither an event or a todo");
-		return -1;
-	}
+	if (vtype != E_CAL_COMPONENT_EVENT && vtype != E_CAL_COMPONENT_TODO) return 1;
+	
 	if (vtype == E_CAL_COMPONENT_EVENT)
 		e_cal_component_get_dtstart (b, &datetime_b);
 	else
@@ -447,12 +482,29 @@ compare_appointment_items (ECalComponent *a,
 	t_b = mktime(&tm_b);
 
 	// Compare datetime_a and datetime_b, newest first in this sort.
-	if (t_a > t_b) retval = 1;
-	else if (t_a < t_b) retval = -1;
-	
-	e_cal_component_free_datetime (&datetime_a);
-	e_cal_component_free_datetime (&datetime_b);
-	return retval;
+	if (t_a > t_b) return = 1;
+	else if (t_a < t_b) return = -1;
+}
+
+static gboolean
+populate_appointment_instances (ECalComponent *comp,
+                                time_t instance_start,
+                                time_t instance_end,
+                                gpointer data)
+{
+	// DEBUG what is the address of "objects" from data
+
+	// The aim here is to receive a usable pointer to the objects list
+	// append to it, and change the list that data points at. 
+	// this is a crafty hack so we're able to sort the items afterwards 
+	GList *objects = (GList *)data;
+	data = (GList *)g_list_append(objects, comp);
+
+	// DEBUG objects should have changed in the resultant location too
+
+	// TODO We also may as well use this opportunity to "mark days" in the calendar
+	// as we're iterating everything of interest here anyway.
+	return TRUE;
 }
 
 /* Populate the menu with todays, next 5 appointments. 
@@ -461,7 +513,8 @@ compare_appointment_items (ECalComponent *a,
  * this is a problem mainly on the EDS side of things, not ours. 
  */
 static gboolean
-update_appointment_menu_items (gpointer user_data) {
+update_appointment_menu_items (gpointer user_data)
+{
 	// FFR: we should take into account short term timers, for instance
 	// tea timers, pomodoro timers etc... that people may add, this is hinted to in the spec.
 	if (calendar == NULL) return FALSE;
@@ -481,8 +534,6 @@ update_appointment_menu_items (gpointer user_data) {
 	time(&t2);
 	t2 += (time_t) (7 * 24 * 60 * 60); /* 7 days ahead of now */
 
-	is = isodate_from_time_t(t1);
-	ie = isodate_from_time_t(t2);
 	
 	gtk_icon_size_lookup(GTK_ICON_SIZE_MENU, &width, &height);
 
@@ -502,7 +553,7 @@ update_appointment_menu_items (gpointer user_data) {
 	// TODO Remove all highlights from the calendar widget
 
 	// FIXME can we put a limit on the number of results? Or if not complete, or is event/todo? Or sort it by date?
-	query = g_strdup_printf("(occur-in-time-range? (make-time\"%s\") (make-time\"%s\"))", is, ie);
+	//query = g_strdup_printf("(occur-in-time-range? (make-time\"%s\") (make-time\"%s\"))", is, ie);
 	
 	if (!e_cal_get_sources(&sources, E_CAL_SOURCE_TYPE_EVENT, &gerror)) {
 		g_debug("Failed to get ecal sources\n");
@@ -527,15 +578,10 @@ update_appointment_menu_items (gpointer user_data) {
 				continue;
         	}
 			
-			g_debug("Getting objects with query: %s", query);
-			if (!e_cal_get_object_list_as_comp(ecal, query, &objects, &gerror)) {
-				g_debug("Failed to get objects\n");
-				g_free(ecal);
-				gerror = NULL;
-				continue;
-			}
+			g_debug("Generating instances");
+			e_cal_generate_instances (client, t1, t2, (ECalRecurInstanceFn) populate_appointment_instances, (gpointer) &objects);
 			g_debug("Number of objects returned: %d", g_list_length(objects));
-			
+			                                               
 			if (allobjects == NULL) {
 				allobjects = objects;
 			} else if (objects != NULL) {
@@ -761,6 +807,7 @@ build_menus (DbusmenuMenuitem * root)
 	check_timezone_sync();
 	
 	g_signal_connect (conf, "changed::" SETTINGS_SHOW_LOCATIONS_S, G_CALLBACK (show_locations_changed), NULL);
+	g_signal_connect (conf, "changed::" SETTINGS_SHOW_EVENTS_S, G_CALLBACK (show_events_changed), NULL);
 
 	DbusmenuMenuitem * separator = dbusmenu_menuitem_new();
 	dbusmenu_menuitem_property_set(separator, DBUSMENU_MENUITEM_PROP_TYPE, DBUSMENU_CLIENT_TYPES_SEPARATOR);
-- 
cgit v1.2.3


From 4ebd048f21f54e01029d50d7d9fe0e9899bc25c2 Mon Sep 17 00:00:00 2001
From: karl-qdh 
Date: Tue, 1 Mar 2011 17:22:44 +0000
Subject: Fixes for the recurring tasks and events settings change, the
 pointers are currently a bit chewed up as I try to figure out the right way
 round to get this.

---
 src/datetime-service.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/src/datetime-service.c b/src/datetime-service.c
index fd73024..33b9720 100644
--- a/src/datetime-service.c
+++ b/src/datetime-service.c
@@ -456,9 +456,8 @@ compare_appointment_items (ECalComponent *a,
 	ECalComponentDateTime datetime_a, datetime_b;
 	struct tm tm_a, tm_b;
 	time_t t_a, t_b;
-	gint retval = 0;
 
-	if (a == NULL || b == NULL) return retval;
+	if (a == NULL || b == NULL) return 0;
 
 	ECalComponentVType vtype = e_cal_component_get_vtype (a);
 	
@@ -482,8 +481,9 @@ compare_appointment_items (ECalComponent *a,
 	t_b = mktime(&tm_b);
 
 	// Compare datetime_a and datetime_b, newest first in this sort.
-	if (t_a > t_b) return = 1;
-	else if (t_a < t_b) return = -1;
+	if (t_a > t_b) return 1;
+	else if (t_a < t_b) return -1;
+	return 0;
 }
 
 static gboolean
@@ -521,7 +521,7 @@ update_appointment_menu_items (gpointer user_data)
 	if (!g_settings_get_boolean(conf, SETTINGS_SHOW_EVENTS_S)) return FALSE;
 	
 	time_t t1, t2;
-	gchar *query, *is, *ie, *ad;
+	gchar *ad;
 	GList *objects = NULL, *l;
 	GList *allobjects = NULL;
 	GSList *g;
@@ -579,7 +579,7 @@ update_appointment_menu_items (gpointer user_data)
         	}
 			
 			g_debug("Generating instances");
-			e_cal_generate_instances (client, t1, t2, (ECalRecurInstanceFn) populate_appointment_instances, (gpointer) &objects);
+			e_cal_generate_instances (ecal, t1, t2, (ECalRecurInstanceFn) populate_appointment_instances, (gpointer) objects);
 			g_debug("Number of objects returned: %d", g_list_length(objects));
 			                                               
 			if (allobjects == NULL) {
-- 
cgit v1.2.3


From 6ee562ac5028df8f28e3559656117d7093b0f73c Mon Sep 17 00:00:00 2001
From: Michael Terry 
Date: Tue, 1 Mar 2011 16:31:28 -0500
Subject: let date spin buttons work

---
 data/datetime-dialog.ui | 14 ++++++++++++
 src/datetime-prefs.c    | 57 ++++++++++++++++++++++++++++++++-----------------
 2 files changed, 52 insertions(+), 19 deletions(-)

diff --git a/data/datetime-dialog.ui b/data/datetime-dialog.ui
index 35cb172..4277d72 100644
--- a/data/datetime-dialog.ui
+++ b/data/datetime-dialog.ui
@@ -2,6 +2,11 @@
 
   
   
+  
+    1.8446744073709552e+19
+    86400
+    864000
+  
   
     False
     Locations
@@ -102,6 +107,11 @@
       
     
   
+  
+    1.8446744073709552e+19
+    60
+    3600
+  
   
     False
     5
@@ -286,6 +296,8 @@
                                     11
                                     1
                                     True
+                                    timeAdjustment
+                                    True
                                   
                                   
                                     False
@@ -328,6 +340,8 @@
                                     11
                                     1
                                     True
+                                    dateAdjustment
+                                    True
                                   
                                   
                                     False
diff --git a/src/datetime-prefs.c b/src/datetime-prefs.c
index c71217a..b6fd1c9 100644
--- a/src/datetime-prefs.c
+++ b/src/datetime-prefs.c
@@ -48,9 +48,9 @@ GtkWidget * tz_entry = NULL;
 CcTimezoneMap * tzmap = NULL;
 GtkWidget * time_spin = NULL;
 GtkWidget * date_spin = NULL;
-GDateTime * manual_time = NULL;
 guint       save_time_id = 0;
 gboolean    user_edited_time = FALSE;
+gboolean    changing_time = FALSE;
 
 /* Turns the boolean property into a string gsettings */
 static GVariant *
@@ -255,7 +255,8 @@ static gboolean
 save_time (gpointer user_data)
 {
   if (user_edited_time) {
-    g_dbus_proxy_call (proxy, "SetTime", g_variant_new ("(x)", g_date_time_to_unix (manual_time)),
+    gdouble current_value = gtk_spin_button_get_value (GTK_SPIN_BUTTON (date_spin));
+    g_dbus_proxy_call (proxy, "SetTime", g_variant_new ("(x)", (guint64)current_value),
                        G_DBUS_CALL_FLAGS_NONE, -1, NULL, dbus_set_answered, "time");
   }
   user_edited_time = FALSE;
@@ -287,12 +288,15 @@ spin_focus_out (void)
 }
 
 static int
-input_time_text (GtkWidget * spinner, gdouble *value, gpointer user_data)
+input_time_text (GtkWidget * spinner, gdouble * value, gpointer user_data)
 {
   gboolean is_time = (gboolean)GPOINTER_TO_INT (g_object_get_data (G_OBJECT (spinner), "is-time"));
   const gchar * text = gtk_entry_get_text (GTK_ENTRY (spinner));
 
-  GDateTime * now = manual_time;
+  gdouble current_value = gtk_spin_button_get_value (GTK_SPIN_BUTTON (spinner));
+  *value = current_value;
+
+  GDateTime * now = g_date_time_new_from_unix_utc (current_value);
   gint year, month, day, hour, minute, second;
   year = g_date_time_get_year (now);
   month = g_date_time_get_month (now);
@@ -362,9 +366,13 @@ input_time_text (GtkWidget * spinner, gdouble *value, gpointer user_data)
     return TRUE;
   }
 
-  g_date_time_unref (manual_time);
-  manual_time = g_date_time_new_local (year, month, day, hour, minute, second);
+  gboolean prev_changing = changing_time;
+  changing_time = TRUE;
+  GDateTime * new_time = g_date_time_new_local (year, month, day, hour, minute, second);
+  *value = g_date_time_to_unix (new_time);
   user_edited_time = TRUE;
+  g_date_time_unref (new_time);
+  changing_time = prev_changing;
 
   return TRUE;
 }
@@ -386,12 +394,25 @@ format_time_text (GtkWidget * spinner, gpointer user_data)
     format = "%Y-%m-%d";
   }
 
-  gchar * formatted = g_date_time_format (manual_time, format);
+  GDateTime * datetime = g_date_time_new_from_unix_utc (gtk_spin_button_get_value (GTK_SPIN_BUTTON (spinner)));
+  gchar * formatted = g_date_time_format (datetime, format);
   gtk_entry_set_text (GTK_ENTRY (spinner), formatted);
+  g_date_time_unref (datetime);
 
   return TRUE;
 }
 
+static void
+spin_copy_value (GtkSpinButton * spinner, GtkSpinButton * other)
+{
+  if (gtk_spin_button_get_value (spinner) != gtk_spin_button_get_value (other)) {
+    gtk_spin_button_set_value (other, gtk_spin_button_get_value (spinner));
+  }
+  if (!changing_time) { /* Means user pressed spin buttons */
+    user_edited_time = TRUE;
+  }
+}
+
 static gboolean
 update_spinners (void)
 {
@@ -399,12 +420,13 @@ update_spinners (void)
      then using the value of the spinner itself.  And don't update while user is
      editing. */
   if (!are_spinners_focused ()) {
-    if (manual_time != NULL) {
-      g_date_time_unref (manual_time);
-    }
-    manual_time = g_date_time_new_now_local ();
-    format_time_text (time_spin, NULL);
-    format_time_text (date_spin, NULL);
+    gboolean prev_changing = changing_time;
+    changing_time = TRUE;
+    GDateTime * now = g_date_time_new_now_local ();
+    gtk_spin_button_set_value (GTK_SPIN_BUTTON (time_spin), (gdouble)g_date_time_to_unix (now));
+    /* will be copied to other spin button */
+    g_date_time_unref (now);
+    changing_time = prev_changing;
   }
   return TRUE;
 }
@@ -412,12 +434,6 @@ update_spinners (void)
 static void
 setup_time_spinners (GtkWidget * time, GtkWidget * date)
 {
-  gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (time), FALSE);
-  gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (date), FALSE);
-
-  gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (time), TRUE);
-  gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (date), TRUE);
-
   g_signal_connect (time, "input", G_CALLBACK (input_time_text), date);
   g_signal_connect (date, "input", G_CALLBACK (input_time_text), time);
 
@@ -430,6 +446,9 @@ setup_time_spinners (GtkWidget * time, GtkWidget * date)
   g_signal_connect (time, "focus-out-event", G_CALLBACK (spin_focus_out), date);
   g_signal_connect (date, "focus-out-event", G_CALLBACK (spin_focus_out), time);
 
+  g_signal_connect (time, "value-changed", G_CALLBACK (spin_copy_value), date);
+  g_signal_connect (date, "value-changed", G_CALLBACK (spin_copy_value), time);
+
   g_object_set_data (G_OBJECT (time), "is-time", GINT_TO_POINTER (TRUE));
   g_object_set_data (G_OBJECT (date), "is-time", GINT_TO_POINTER (FALSE));
 
-- 
cgit v1.2.3


From 3abcff1218b921f7ab88ebf73c392a9c998a5df2 Mon Sep 17 00:00:00 2001
From: karl-qdh 
Date: Wed, 2 Mar 2011 12:16:05 +0000
Subject: Better handling of recurring items get_dtstart returns the same date
 for all items unfortunately

---
 src/datetime-service.c | 71 ++++++++++++++++++++++++++------------------------
 1 file changed, 37 insertions(+), 34 deletions(-)

diff --git a/src/datetime-service.c b/src/datetime-service.c
index 33b9720..d553240 100644
--- a/src/datetime-service.c
+++ b/src/datetime-service.c
@@ -81,6 +81,7 @@ static DbusmenuMenuitem * current_location = NULL;
 static DbusmenuMenuitem * add_appointment = NULL;
 static GList			* appointments = NULL;
 static GList			* dconflocations = NULL;
+static GList			* tmpobjects = NULL;
 GSettings *conf;
 
 
@@ -449,19 +450,25 @@ auth_func (ECal *ecal,
 
 
 // Compare function for g_list_sort of ECalComponent objects
-static gint 
+// Generate instances sorts them by time anyway
+/*static gint 
 compare_appointment_items (ECalComponent *a,
                            ECalComponent *b) 
 {
+	g_debug("Comparing two items from list %d %d", (int)a, (int)b);
 	ECalComponentDateTime datetime_a, datetime_b;
 	struct tm tm_a, tm_b;
 	time_t t_a, t_b;
+	gint retval = 0;
 
 	if (a == NULL || b == NULL) return 0;
 
 	ECalComponentVType vtype = e_cal_component_get_vtype (a);
 	
-	if (vtype != E_CAL_COMPONENT_EVENT && vtype != E_CAL_COMPONENT_TODO) return -1;
+	if (vtype != E_CAL_COMPONENT_EVENT && vtype != E_CAL_COMPONENT_TODO) {
+		g_debug("A is Not a todo or event");
+		return 1;
+	}
 	
 	if (vtype == E_CAL_COMPONENT_EVENT)
 		e_cal_component_get_dtstart (a, &datetime_a);
@@ -471,7 +478,10 @@ compare_appointment_items (ECalComponent *a,
 	t_a = mktime(&tm_a);
 	
 	vtype = e_cal_component_get_vtype (b);
-	if (vtype != E_CAL_COMPONENT_EVENT && vtype != E_CAL_COMPONENT_TODO) return 1;
+	if (vtype != E_CAL_COMPONENT_EVENT && vtype != E_CAL_COMPONENT_TODO) {
+		g_debug("B is Not a todo or event");
+		return -1;
+	}
 	
 	if (vtype == E_CAL_COMPONENT_EVENT)
 		e_cal_component_get_dtstart (b, &datetime_b);
@@ -481,10 +491,16 @@ compare_appointment_items (ECalComponent *a,
 	t_b = mktime(&tm_b);
 
 	// Compare datetime_a and datetime_b, newest first in this sort.
-	if (t_a > t_b) return 1;
-	else if (t_a < t_b) return -1;
+	if (t_a > t_b) {
+		g_debug("A > B: %d > %d", (int)t_a, (int)t_b);
+		retval = 1;
+	} else if (t_a < t_b) {
+		g_debug("B > A: %d > %d", (int)t_b, (int)t_a);
+		retval = -1;
+	}
+	g_debug("A == B: %d == %d", (int)t_a, (int)t_b);
 	return 0;
-}
+}*/
 
 static gboolean
 populate_appointment_instances (ECalComponent *comp,
@@ -492,15 +508,11 @@ populate_appointment_instances (ECalComponent *comp,
                                 time_t instance_end,
                                 gpointer data)
 {
-	// DEBUG what is the address of "objects" from data
-
-	// The aim here is to receive a usable pointer to the objects list
-	// append to it, and change the list that data points at. 
-	// this is a crafty hack so we're able to sort the items afterwards 
-	GList *objects = (GList *)data;
-	data = (GList *)g_list_append(objects, comp);
-
-	// DEBUG objects should have changed in the resultant location too
+	g_debug("Appending item %d", (int)comp);
+	ECalComponentVType vtype = e_cal_component_get_vtype (comp);
+	if (vtype != E_CAL_COMPONENT_EVENT && vtype != E_CAL_COMPONENT_TODO) return FALSE;
+	g_object_ref(comp);
+	tmpobjects = g_list_append(tmpobjects, comp);
 
 	// TODO We also may as well use this opportunity to "mark days" in the calendar
 	// as we're iterating everything of interest here anyway.
@@ -522,17 +534,18 @@ update_appointment_menu_items (gpointer user_data)
 	
 	time_t t1, t2;
 	gchar *ad;
-	GList *objects = NULL, *l;
+	GList *l;
 	GList *allobjects = NULL;
 	GSList *g;
 	GError *gerror = NULL;
+	tmpobjects = NULL;
 	gint i;
 	gint width, height;
 	ESourceList * sources = NULL;
 	
 	time(&t1);
 	time(&t2);
-	t2 += (time_t) (7 * 24 * 60 * 60); /* 7 days ahead of now */
+	t2 += (time_t) (7 * 24 * 60 * 60); /* 7 days ahead of now, we actually need number_of_days_in_this_month */
 
 	
 	gtk_icon_size_lookup(GTK_ICON_SIZE_MENU, &width, &height);
@@ -551,9 +564,6 @@ update_appointment_menu_items (gpointer user_data)
 	}
 	
 	// TODO Remove all highlights from the calendar widget
-
-	// FIXME can we put a limit on the number of results? Or if not complete, or is event/todo? Or sort it by date?
-	//query = g_strdup_printf("(occur-in-time-range? (make-time\"%s\") (make-time\"%s\"))", is, ie);
 	
 	if (!e_cal_get_sources(&sources, E_CAL_SOURCE_TYPE_EVENT, &gerror)) {
 		g_debug("Failed to get ecal sources\n");
@@ -579,21 +589,13 @@ update_appointment_menu_items (gpointer user_data)
         	}
 			
 			g_debug("Generating instances");
-			e_cal_generate_instances (ecal, t1, t2, (ECalRecurInstanceFn) populate_appointment_instances, (gpointer) objects);
-			g_debug("Number of objects returned: %d", g_list_length(objects));
-			                                               
-			if (allobjects == NULL) {
-				allobjects = objects;
-			} else if (objects != NULL) {
-				allobjects = g_list_concat(allobjects, objects);
-				g_object_unref(objects);
-			}
+			e_cal_generate_instances (ecal, t1, t2, (ECalRecurInstanceFn) populate_appointment_instances, NULL);
+			g_debug("Number of objects returned: %d", g_list_length(tmpobjects));
 		}
 	}
+	allobjects = tmpobjects;
+	tmpobjects = NULL;
 	
-	// Sort the list see above FIXME regarding queries
-	g_debug("Sorting objects list");
-	allobjects = g_list_sort(allobjects, (GCompareFunc) compare_appointment_items);
 	i = 0;
 	for (l = allobjects; l; l = l->next) {
 		ECalComponent *ecalcomp = l->data;
@@ -719,12 +721,13 @@ update_appointment_menu_items (gpointer user_data)
 		dbusmenu_menuitem_child_add_position (root, item, 3+i);
 		appointments = g_list_append         (appointments, item); // Keep track of the items here to make them east to remove
 		g_debug("Adding appointment: %p", item);
-		
-		if (i == 4) break; // See above FIXME regarding query result limit
+
+		if (i == 4) break;
 		i++;
 	}
 	
     if (gerror != NULL) g_error_free(gerror);
+    for (l = allobjects; l; l = l->next) g_object_unref(l->data);
 	g_object_unref(allobjects);
 	g_debug("End of objects");
 	return TRUE;
-- 
cgit v1.2.3


From 7b2980b759af73f4ae6ac76409d10d908762d24f Mon Sep 17 00:00:00 2001
From: karl-qdh 
Date: Wed, 2 Mar 2011 13:31:45 +0000
Subject: * Fixed adding/removing locations not triggering update * Improved
 update appointment menu items code * Improved populate_appointment_instances
 * Opened up objects generation to include marking days

---
 src/datetime-service.c | 114 +++++++++++--------------------------------------
 1 file changed, 24 insertions(+), 90 deletions(-)

diff --git a/src/datetime-service.c b/src/datetime-service.c
index d553240..b748841 100644
--- a/src/datetime-service.c
+++ b/src/datetime-service.c
@@ -448,60 +448,6 @@ auth_func (ECal *ecal,
 	return password;
 }
 
-
-// Compare function for g_list_sort of ECalComponent objects
-// Generate instances sorts them by time anyway
-/*static gint 
-compare_appointment_items (ECalComponent *a,
-                           ECalComponent *b) 
-{
-	g_debug("Comparing two items from list %d %d", (int)a, (int)b);
-	ECalComponentDateTime datetime_a, datetime_b;
-	struct tm tm_a, tm_b;
-	time_t t_a, t_b;
-	gint retval = 0;
-
-	if (a == NULL || b == NULL) return 0;
-
-	ECalComponentVType vtype = e_cal_component_get_vtype (a);
-	
-	if (vtype != E_CAL_COMPONENT_EVENT && vtype != E_CAL_COMPONENT_TODO) {
-		g_debug("A is Not a todo or event");
-		return 1;
-	}
-	
-	if (vtype == E_CAL_COMPONENT_EVENT)
-		e_cal_component_get_dtstart (a, &datetime_a);
-	else
-	    e_cal_component_get_due (a, &datetime_a);
-	tm_a = icaltimetype_to_tm(datetime_a.value);
-	t_a = mktime(&tm_a);
-	
-	vtype = e_cal_component_get_vtype (b);
-	if (vtype != E_CAL_COMPONENT_EVENT && vtype != E_CAL_COMPONENT_TODO) {
-		g_debug("B is Not a todo or event");
-		return -1;
-	}
-	
-	if (vtype == E_CAL_COMPONENT_EVENT)
-		e_cal_component_get_dtstart (b, &datetime_b);
-	else
-	    e_cal_component_get_due (b, &datetime_b);
-	tm_b = icaltimetype_to_tm(datetime_b.value);
-	t_b = mktime(&tm_b);
-
-	// Compare datetime_a and datetime_b, newest first in this sort.
-	if (t_a > t_b) {
-		g_debug("A > B: %d > %d", (int)t_a, (int)t_b);
-		retval = 1;
-	} else if (t_a < t_b) {
-		g_debug("B > A: %d > %d", (int)t_b, (int)t_a);
-		retval = -1;
-	}
-	g_debug("A == B: %d == %d", (int)t_a, (int)t_b);
-	return 0;
-}*/
-
 static gboolean
 populate_appointment_instances (ECalComponent *comp,
                                 time_t instance_start,
@@ -511,11 +457,13 @@ populate_appointment_instances (ECalComponent *comp,
 	g_debug("Appending item %d", (int)comp);
 	ECalComponentVType vtype = e_cal_component_get_vtype (comp);
 	if (vtype != E_CAL_COMPONENT_EVENT && vtype != E_CAL_COMPONENT_TODO) return FALSE;
+	
+	icalproperty_status status;
+	e_cal_component_get_status (comp, &status);
+	if (status == ICAL_STATUS_COMPLETED || status == ICAL_STATUS_CANCELLED) return FALSE;
+	
 	g_object_ref(comp);
 	tmpobjects = g_list_append(tmpobjects, comp);
-
-	// TODO We also may as well use this opportunity to "mark days" in the calendar
-	// as we're iterating everything of interest here anyway.
 	return TRUE;
 }
 
@@ -577,7 +525,7 @@ update_appointment_menu_items (gpointer user_data)
 		
 		for (s = e_source_group_peek_sources (group); s; s = s->next) {
 			ESource *source = E_SOURCE (s->data);
-			g_signal_connect (G_OBJECT(source), "changed", G_CALLBACK (update_appointment_menu_items), NULL);
+			//g_signal_connect (G_OBJECT(source), "changed", G_CALLBACK (update_appointment_menu_items), NULL);
 			ECal *ecal = e_cal_new(source, E_CAL_SOURCE_TYPE_EVENT);
 			e_cal_set_auth_func (ecal, (ECalAuthFunc) auth_func, NULL);
 			
@@ -603,27 +551,27 @@ update_appointment_menu_items (gpointer user_data)
 		ECalComponentDateTime datetime;
 		icaltimezone *appointment_zone = NULL;
 		icaltimezone *current_zone = NULL;
-		icalproperty_status status;
 		gchar *summary, *cmd;
 		char right[20];
 		//const gchar *uri;
 		struct tm tmp_tm;
 		DbusmenuMenuitem * item;
 
-		g_debug("Start Object");
+		g_debug("Start Object %p", ecalcomp);
 		ECalComponentVType vtype = e_cal_component_get_vtype (ecalcomp);
 
-		// See above FIXME regarding query result
-		// If it's not an event or todo, continue no-increment
-        if (vtype != E_CAL_COMPONENT_EVENT && vtype != E_CAL_COMPONENT_TODO)
-			continue;
-
-		// See above FIXME regarding query result
-		// if the status is completed, continue no-increment
-		e_cal_component_get_status (ecalcomp, &status);
-		if (status == ICAL_STATUS_COMPLETED || status == ICAL_STATUS_CANCELLED)
-			continue;
-
+		if (vtype == E_CAL_COMPONENT_EVENT)
+			e_cal_component_get_dtstart (ecalcomp, &datetime);
+		else
+		    e_cal_component_get_due (ecalcomp, &datetime);
+		    
+		if (!datetime.value) continue;
+		
+		// TODO Mark days with appointments in the current month
+		
+		if (i >= 5) continue;
+		i++;
+		
 		item = dbusmenu_menuitem_new();
 		dbusmenu_menuitem_property_set       (item, DBUSMENU_MENUITEM_PROP_TYPE, APPOINTMENT_MENUITEM_TYPE);
 		dbusmenu_menuitem_property_set_bool  (item, DBUSMENU_MENUITEM_PROP_ENABLED, TRUE);
@@ -638,23 +586,13 @@ update_appointment_menu_items (gpointer user_data)
 		g_free (summary);
 		
 		// Due text
-		if (vtype == E_CAL_COMPONENT_EVENT)
-			e_cal_component_get_dtstart (ecalcomp, &datetime);
-		else
-		    e_cal_component_get_due (ecalcomp, &datetime);
-		
-		// FIXME need to get the timezone of the above datetime, 
-		// and get the icaltimezone of the geoclue timezone/selected timezone (whichever is preferred)
-		if (!datetime.value) {
-			g_free(item);
-			continue;
-		}
-		
 		appointment_zone = icaltimezone_get_builtin_timezone_from_tzid(datetime.tzid);
 		current_zone = icaltimezone_get_builtin_timezone_from_tzid(current_timezone);
 		if (!appointment_zone || datetime.value->is_date) { // If it's today put in the current timezone?
 			appointment_zone = current_zone;
 		}
+		// FIXME need to get the timezone of the above datetime, 
+		// and get the icaltimezone of the geoclue timezone/selected timezone (whichever is preferred)
 		// TODO: Convert the timezone into a 3 letter abbreviation if it's different to current_timezone
 		// TODO: Add the appointment timezone to the list if it's not already there. 
 		
@@ -680,12 +618,11 @@ update_appointment_menu_items (gpointer user_data)
 		
 		e_cal_component_free_datetime (&datetime);
 		
-		ad = isodate_from_time_t(mktime(&tmp_tm));
 		
 		// Now we pull out the URI for the calendar event and try to create a URI that'll work when we execute evolution
 		// FIXME Because the URI stuff is really broken, we're going to open the calendar at todays date instead
-		
 		//e_cal_component_get_uid(ecalcomp, &uri);
+		ad = isodate_from_time_t(mktime(&tmp_tm));
 		cmd = g_strconcat("evolution calendar:///?startdate=", ad, NULL);
 		g_signal_connect (G_OBJECT(item), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED,
 						  G_CALLBACK (activate_cb), cmd);
@@ -718,17 +655,13 @@ update_appointment_menu_items (gpointer user_data)
 			
 			dbusmenu_menuitem_property_set_image (item, APPOINTMENT_MENUITEM_PROP_ICON, pixbuf);
 		}
-		dbusmenu_menuitem_child_add_position (root, item, 3+i);
+		dbusmenu_menuitem_child_add_position (root, item, 2+i);
 		appointments = g_list_append         (appointments, item); // Keep track of the items here to make them east to remove
 		g_debug("Adding appointment: %p", item);
-
-		if (i == 4) break;
-		i++;
 	}
 	
     if (gerror != NULL) g_error_free(gerror);
     for (l = allobjects; l; l = l->next) g_object_unref(l->data);
-	g_object_unref(allobjects);
 	g_debug("End of objects");
 	return TRUE;
 }
@@ -810,6 +743,7 @@ build_menus (DbusmenuMenuitem * root)
 	check_timezone_sync();
 	
 	g_signal_connect (conf, "changed::" SETTINGS_SHOW_LOCATIONS_S, G_CALLBACK (show_locations_changed), NULL);
+	g_signal_connect (conf, "changed::" SETTINGS_LOCATIONS_S, G_CALLBACK (show_locations_changed), NULL);
 	g_signal_connect (conf, "changed::" SETTINGS_SHOW_EVENTS_S, G_CALLBACK (show_events_changed), NULL);
 
 	DbusmenuMenuitem * separator = dbusmenu_menuitem_new();
-- 
cgit v1.2.3


From 44bd4d29adb79c74ffbedc551a5a2414d652e7b1 Mon Sep 17 00:00:00 2001
From: karl-qdh 
Date: Wed, 2 Mar 2011 14:00:41 +0000
Subject: Remove items from menu when the show events key changes

---
 src/datetime-service.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/src/datetime-service.c b/src/datetime-service.c
index b748841..1983275 100644
--- a/src/datetime-service.c
+++ b/src/datetime-service.c
@@ -306,6 +306,18 @@ show_events_changed (void)
 	} else {
 		dbusmenu_menuitem_property_set_bool(add_appointment, DBUSMENU_MENUITEM_PROP_VISIBLE, FALSE);
 		dbusmenu_menuitem_property_set_bool(events_separator, DBUSMENU_MENUITEM_PROP_VISIBLE, FALSE);
+		/* Remove all of the previous appointments */
+		if (appointments != NULL) {
+			g_debug("Freeing old appointments");
+			while (appointments != NULL) {
+				DbusmenuMenuitem * litem =  DBUSMENU_MENUITEM(appointments->data);
+				g_debug("Freeing old appointment: %p", litem);
+				// Remove all the existing menu items which are in appointments.
+				appointments = g_list_remove(appointments, litem);
+				dbusmenu_menuitem_child_delete(root, DBUSMENU_MENUITEM(litem));
+				g_object_unref(G_OBJECT(litem));
+			}
+		}
 		stop_ecal_timer();
 	}
 }
-- 
cgit v1.2.3


From 64fe32bfc19ffbfcf83e9d047cd0ebc1b881a785 Mon Sep 17 00:00:00 2001
From: karl-qdh 
Date: Thu, 3 Mar 2011 12:45:11 +0000
Subject: This actually gets the current recurrance times etc... properly -
 we're close to getting colours too ;)

---
 src/datetime-service.c | 228 +++++++++++++++++++++++++++++++++++--------------
 1 file changed, 162 insertions(+), 66 deletions(-)

diff --git a/src/datetime-service.c b/src/datetime-service.c
index 1983275..2250c59 100644
--- a/src/datetime-service.c
+++ b/src/datetime-service.c
@@ -81,7 +81,7 @@ static DbusmenuMenuitem * current_location = NULL;
 static DbusmenuMenuitem * add_appointment = NULL;
 static GList			* appointments = NULL;
 static GList			* dconflocations = NULL;
-static GList			* tmpobjects = NULL;
+static GList			* comp_instances = NULL;
 GSettings *conf;
 
 
@@ -93,6 +93,13 @@ static GeoclueAddress * geo_address = NULL;
 static gchar 			* current_timezone = NULL;
 static gchar 			* geo_timezone = NULL;
 
+struct comp_instance {
+        ECalComponent *comp;
+        time_t start;
+        time_t end;
+        ESource *source;
+};
+
 static void
 set_timezone_label (DbusmenuMenuitem * mi, const gchar * location)
 {
@@ -460,13 +467,26 @@ auth_func (ECal *ecal,
 	return password;
 }
 
+static gint
+compare_comp_instances (gconstpointer a, 
+                        gconstpointer b)
+{
+        const struct comp_instance *ci_a = a;
+        const struct comp_instance *ci_b = b;
+        time_t d = ci_a->start - ci_b->start;
+		if (d < 0) return -1;
+		else if (d > 0) return 1; 
+		return 0;
+}
+
 static gboolean
 populate_appointment_instances (ECalComponent *comp,
                                 time_t instance_start,
                                 time_t instance_end,
                                 gpointer data)
 {
-	g_debug("Appending item %d", (int)comp);
+	g_debug("Appending item %p", comp);
+	
 	ECalComponentVType vtype = e_cal_component_get_vtype (comp);
 	if (vtype != E_CAL_COMPONENT_EVENT && vtype != E_CAL_COMPONENT_TODO) return FALSE;
 	
@@ -475,7 +495,63 @@ populate_appointment_instances (ECalComponent *comp,
 	if (status == ICAL_STATUS_COMPLETED || status == ICAL_STATUS_CANCELLED) return FALSE;
 	
 	g_object_ref(comp);
-	tmpobjects = g_list_append(tmpobjects, comp);
+	
+	ECalComponentDateTime datetime;
+	icaltimezone *appointment_zone = NULL;
+	icaltimezone *current_zone = NULL;
+	
+	if (vtype == E_CAL_COMPONENT_EVENT)
+		e_cal_component_get_dtstart (comp, &datetime);
+	else
+	    e_cal_component_get_due (comp, &datetime);
+
+	appointment_zone = icaltimezone_get_builtin_timezone_from_tzid(datetime.tzid);
+	current_zone = icaltimezone_get_builtin_timezone_from_tzid(current_timezone);
+	if (!appointment_zone || datetime.value->is_date) { // If it's today put in the current timezone?
+		appointment_zone = current_zone;
+	}
+	
+	// TODO: Convert the timezone into a 3 letter abbreviation if it's different to current_timezone
+	// TODO: Add the appointment timezone to the list if it's not already there. 
+		
+	GSList *period_list = NULL, *l;
+	if (e_cal_component_has_recurrences (comp)) {
+		e_cal_component_get_rdate_list (comp, &period_list);
+		g_debug("ECalComponent has recurrences");
+	} else {
+		g_debug("ECalComponent doesn't have recurrences");
+	}
+	
+	struct comp_instance *ci;
+	ci = g_new (struct comp_instance, 1);
+	
+	// Do we get rdate_list?
+	if (period_list != NULL) {
+		g_debug("Got recurring periods");
+		for (l = period_list; l; l = l->next) {
+			ECalComponentPeriod *period = l->data;
+			struct tm tmp_tm  = icaltimetype_to_tm_with_zone (&period->start, appointment_zone, current_zone);
+			time_t start = mktime(&tmp_tm);
+			g_debug("period time: %d", (int)start);
+		
+			tmp_tm = icaltimetype_to_tm_with_zone (&period->u.end, appointment_zone, current_zone);
+			time_t end = mktime(&tmp_tm);
+		
+			if (start >= instance_start && end < instance_end) {
+				ci->start = start;
+				ci->end = end;
+			}
+		}
+	} else {
+		ci->start = instance_start;
+		ci->end = instance_end;
+		g_debug("Got no recurring periods set time to start %s, end %s", ctime(&instance_start), ctime(&instance_end));
+	}
+	
+	ci->comp = comp;
+	ci->source = E_SOURCE(data);
+	
+	comp_instances = g_list_append(comp_instances, ci);
 	return TRUE;
 }
 
@@ -495,10 +571,9 @@ update_appointment_menu_items (gpointer user_data)
 	time_t t1, t2;
 	gchar *ad;
 	GList *l;
-	GList *allobjects = NULL;
+	//GList *allobjects = NULL;
 	GSList *g;
 	GError *gerror = NULL;
-	tmpobjects = NULL;
 	gint i;
 	gint width, height;
 	ESourceList * sources = NULL;
@@ -507,9 +582,6 @@ update_appointment_menu_items (gpointer user_data)
 	time(&t2);
 	t2 += (time_t) (7 * 24 * 60 * 60); /* 7 days ahead of now, we actually need number_of_days_in_this_month */
 
-	
-	gtk_icon_size_lookup(GTK_ICON_SIZE_MENU, &width, &height);
-
 	/* Remove all of the previous appointments */
 	if (appointments != NULL) {
 		g_debug("Freeing old appointments");
@@ -529,7 +601,18 @@ update_appointment_menu_items (gpointer user_data)
 		g_debug("Failed to get ecal sources\n");
 		return FALSE;
 	}
-
+	
+	// Free comp_instances if not NULL
+	if (comp_instances != NULL) {
+		g_debug("Freeing comp_instances: may be an overlap\n");
+		for (l = comp_instances; l; l = l->next) {
+			const struct comp_instance *ci = l->data;
+			g_object_unref(ci->comp);
+			g_list_free(comp_instances);
+			comp_instances = NULL;
+		}
+	}
+	
 	// iterate the query for all sources
 	for (g = e_source_list_peek_groups (sources); g; g = g->next) {
 		ESourceGroup *group = E_SOURCE_GROUP (g->data);
@@ -549,37 +632,31 @@ update_appointment_menu_items (gpointer user_data)
         	}
 			
 			g_debug("Generating instances");
-			e_cal_generate_instances (ecal, t1, t2, (ECalRecurInstanceFn) populate_appointment_instances, NULL);
-			g_debug("Number of objects returned: %d", g_list_length(tmpobjects));
+			e_cal_generate_instances (ecal, t1, t2, (ECalRecurInstanceFn) populate_appointment_instances, (gpointer) source);
+			g_debug("Number of objects returned: %d", g_list_length(comp_instances));
 		}
 	}
-	allobjects = tmpobjects;
-	tmpobjects = NULL;
-	
+	GList *sorted_comp_instances = g_list_sort(comp_instances, compare_comp_instances);
+	comp_instances = NULL;
 	i = 0;
-	for (l = allobjects; l; l = l->next) {
-		ECalComponent *ecalcomp = l->data;
+	
+	gtk_icon_size_lookup(GTK_ICON_SIZE_MENU, &width, &height);
+	if (width == 0) width = 16;
+	if (height == 0) height = 16;
+	
+	for (l = sorted_comp_instances; l; l = l->next) {
+		struct comp_instance *ci = l->data;
+		ECalComponent *ecalcomp = ci->comp;
 		ECalComponentText valuetext;
-		ECalComponentDateTime datetime;
-		icaltimezone *appointment_zone = NULL;
-		icaltimezone *current_zone = NULL;
+		//ECalComponentDateTime datetime;
 		gchar *summary, *cmd;
 		char right[20];
 		//const gchar *uri;
-		struct tm tmp_tm;
 		DbusmenuMenuitem * item;
 
 		g_debug("Start Object %p", ecalcomp);
-		ECalComponentVType vtype = e_cal_component_get_vtype (ecalcomp);
-
-		if (vtype == E_CAL_COMPONENT_EVENT)
-			e_cal_component_get_dtstart (ecalcomp, &datetime);
-		else
-		    e_cal_component_get_due (ecalcomp, &datetime);
-		    
-		if (!datetime.value) continue;
 		
-		// TODO Mark days with appointments in the current month
+		// TODO Mark days
 		
 		if (i >= 5) continue;
 		i++;
@@ -597,75 +674,89 @@ update_appointment_menu_items (gpointer user_data)
 		g_debug("Summary: %s", summary);
 		g_free (summary);
 		
-		// Due text
-		appointment_zone = icaltimezone_get_builtin_timezone_from_tzid(datetime.tzid);
-		current_zone = icaltimezone_get_builtin_timezone_from_tzid(current_timezone);
-		if (!appointment_zone || datetime.value->is_date) { // If it's today put in the current timezone?
-			appointment_zone = current_zone;
-		}
+		//appointment_zone = icaltimezone_get_builtin_timezone_from_tzid(datetime.tzid);
+		//current_zone = icaltimezone_get_builtin_timezone_from_tzid(current_timezone);
+		//if (!appointment_zone || datetime.value->is_date) { // If it's today put in the current timezone?
+		//	appointment_zone = current_zone;
+		//}
 		// FIXME need to get the timezone of the above datetime, 
 		// and get the icaltimezone of the geoclue timezone/selected timezone (whichever is preferred)
 		// TODO: Convert the timezone into a 3 letter abbreviation if it's different to current_timezone
 		// TODO: Add the appointment timezone to the list if it's not already there. 
 		
-		tmp_tm = icaltimetype_to_tm_with_zone (datetime.value, appointment_zone, current_zone);
+		//tmp_tm = icaltimetype_to_tm_with_zone (datetime.value, appointment_zone, current_zone);
+		
+		// Due text
+		ECalComponentVType vtype = e_cal_component_get_vtype (ecalcomp);
 		
-		g_debug("Generate time string");
 		// Get today
 		time_t curtime = time(NULL);
-  		struct tm* today = localtime(&curtime);
-		if (today->tm_mday == tmp_tm.tm_mday && 
-		    today->tm_mon == tmp_tm.tm_mon && 
-		    today->tm_year == tmp_tm.tm_year)
-			strftime(right, 20, "%l:%M %P", &tmp_tm);
+  		struct tm *today = localtime(&curtime);
+		
+		int mday = today->tm_mday;
+		int mon = today->tm_mon;
+		int year = today->tm_year;
+		
+		struct tm *due;
+		g_debug("Start time %s", ctime(&ci->start));
+		if (vtype == E_CAL_COMPONENT_EVENT) due = localtime(&ci->start);
+		else if (vtype == E_CAL_COMPONENT_TODO) due = localtime(&ci->end);
+		else continue;
+		
+		strftime(right, 20, "%a %l:%M %p", due);
+		g_debug("Start time %s -> %s", asctime(due), right);
+
+		int dmday = due->tm_mday;
+		int dmon = due->tm_mon;
+		int dyear = due->tm_year;
+		
+		if ((mday == dmday) && (mon == dmon) && (year == dyear))
+			strftime(right, 20, "%l:%M %p", due);
 		else
-			strftime(right, 20, "%a %l:%M %P", &tmp_tm);
+			strftime(right, 20, "%a %l:%M %p", due);
 			
 		g_debug("Appointment time: %s", right);
-		g_debug("Appointment timezone: %s", datetime.tzid);
-		g_debug("Appointment timezone: %s", icaltimezone_get_tzid(appointment_zone)); // These two should be the same
+		//g_debug("Appointment timezone: %s", datetime.tzid);
+		//g_debug("Appointment timezone: %s", icaltimezone_get_tzid(appointment_zone)); // These two should be the same
 		//g_debug("Calendar timezone: %s", ecal_timezone);
 		
 		dbusmenu_menuitem_property_set (item, APPOINTMENT_MENUITEM_PROP_RIGHT, right);
 		
-		e_cal_component_free_datetime (&datetime);
+		//e_cal_component_free_datetime (&datetime);
 		
 		
 		// Now we pull out the URI for the calendar event and try to create a URI that'll work when we execute evolution
 		// FIXME Because the URI stuff is really broken, we're going to open the calendar at todays date instead
 		//e_cal_component_get_uid(ecalcomp, &uri);
-		ad = isodate_from_time_t(mktime(&tmp_tm));
+		ad = isodate_from_time_t(mktime(due));
 		cmd = g_strconcat("evolution calendar:///?startdate=", ad, NULL);
 		g_signal_connect (G_OBJECT(item), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED,
 						  G_CALLBACK (activate_cb), cmd);
 		
 		g_debug("Command to Execute: %s", cmd);
-		
-		// FIXME This is now more difficult to get right with more sources, as we need to keep track
-		// of which ecal or source goes with each ECalComponent :/
-		
-		//ESource *source = e_cal_get_source (ecal);
-        //e_source_get_color (source, &source_color); api has been changed
-        const gchar *color_spec = NULL; //e_source_peek_color_spec(source);
+
+        const gchar *color_spec = e_source_peek_color_spec(ci->source);
         g_debug("Colour to use: %s", color_spec);
 			
 		// Draw the correct icon for the appointment type and then tint it using mask fill.
 		// For now we'll create a circle
         if (color_spec != NULL) {
-        	GdkColor color;
+        	// Fixme causes segfault, but we have colours now yay!
+        	/*GdkColor color;
         	gdk_color_parse (color_spec, &color);
-        	
-			cairo_surface_t *cs = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
-			cairo_t *cr = cairo_create(cs);
-			cairo_arc (cr, width/2, height/2, width/2, 0, 2 * M_PI);
-			gdk_cairo_set_source_color(cr, &color);
-			cairo_fill(cr);
+        	GdkPixmap *pixmap = gdk_pixmap_new(NULL, width, height, 32);
+        	if (pixmap != NULL) {
+				cairo_t *cr = gdk_cairo_create(pixmap);
+				cairo_arc (cr, width/2, height/2, width/2, 0, 2 * M_PI);
+				gdk_cairo_set_source_color(cr, &color);
+				cairo_fill(cr);
 		
-			GdkPixbuf * pixbuf = gdk_pixbuf_get_from_drawable(NULL, (GdkDrawable*)cs, 
-				gdk_colormap_new(gdk_drawable_get_visual((GdkDrawable*)cs), TRUE), 0,0,0,0, width, height);
-			cairo_destroy(cr);
+				GdkPixbuf * pixbuf = gdk_pixbuf_get_from_drawable(NULL, (GdkDrawable*)pixmap, 
+					gdk_colormap_new(gdk_drawable_get_visual((GdkDrawable*)pixmap), TRUE), 0,0,0,0, width, height);
+				cairo_destroy(cr);
 			
-			dbusmenu_menuitem_property_set_image (item, APPOINTMENT_MENUITEM_PROP_ICON, pixbuf);
+				dbusmenu_menuitem_property_set_image (item, APPOINTMENT_MENUITEM_PROP_ICON, pixbuf);
+			}*/
 		}
 		dbusmenu_menuitem_child_add_position (root, item, 2+i);
 		appointments = g_list_append         (appointments, item); // Keep track of the items here to make them east to remove
@@ -673,7 +764,12 @@ update_appointment_menu_items (gpointer user_data)
 	}
 	
     if (gerror != NULL) g_error_free(gerror);
-    for (l = allobjects; l; l = l->next) g_object_unref(l->data);
+	for (l = sorted_comp_instances; l; l = l->next) { 
+		const struct comp_instance *ci = l->data;
+		g_object_unref(ci->comp);
+		g_list_free(sorted_comp_instances);
+	}
+	
 	g_debug("End of objects");
 	return TRUE;
 }
-- 
cgit v1.2.3


From 8dbd819cd5143cb6016b775d0e229819cf324604 Mon Sep 17 00:00:00 2001
From: Michael Terry 
Date: Thu, 3 Mar 2011 09:34:57 -0500
Subject: fix some visual issues mpt found; drop libmap/Makefile.in from bzr

---
 data/datetime-dialog.ui | 849 ++++++++++++++++++++++++------------------------
 libmap/Makefile.in      | 733 -----------------------------------------
 src/datetime-prefs.c    |  35 +-
 3 files changed, 465 insertions(+), 1152 deletions(-)
 delete mode 100644 libmap/Makefile.in

diff --git a/data/datetime-dialog.ui b/data/datetime-dialog.ui
index 35cb172..050c374 100644
--- a/data/datetime-dialog.ui
+++ b/data/datetime-dialog.ui
@@ -102,63 +102,36 @@
       
     
   
-  
+  
     False
     5
     Time & Date
     False
     time-admin
     dialog
-    
-      
+    
+      
         True
-        False
-        
-          
-            False
-            True
-            end
-            
-              
-                gtk-close
-                True
-                True
-                True
-                False
-                True
-              
-              
-                False
-                False
-                0
-              
-            
-          
-          
-            False
-            True
-            end
-            0
-          
-        
+        True
         
-          
+          
             True
-            True
+            False
+            12
+            6
             
-              
+              
                 True
                 False
-                12
-                6
+                12
                 
-                  
+                  
                     True
                     False
                     6
                     
                       
-                        300
+                        265
                         True
                         False
                         0
@@ -174,10 +147,38 @@
                       
                     
                     
-                      
+                      
                         True
-                        True
-                        
+                        False
+                        6
+                        
+                          
+                            True
+                            False
+                            1
+                            _Location:
+                            True
+                            timezoneEntry
+                          
+                          
+                            False
+                            True
+                            0
+                          
+                        
+                        
+                          
+                            True
+                            True
+                            
+                            True
+                          
+                          
+                            True
+                            True
+                            1
+                          
+                        
                       
                       
                         False
@@ -185,30 +186,99 @@
                         1
                       
                     
+                  
+                  
+                    True
+                    True
+                    0
+                  
+                
+                
+                  
+                    True
+                    False
+                    2
+                    2
+                    6
+                    6
                     
-                      
+                      
                         True
                         False
-                        2
-                        2
-                        6
-                        6
+                        6
                         
-                          
+                          
+                            _Manually
+                            True
+                            True
+                            False
+                            False
+                            True
+                            0
+                            True
+                            True
+                          
+                          
+                            False
+                            True
+                            0
+                          
+                        
+                        
+                          
+                            _Automatically from the Internet
+                            True
+                            False
+                            True
+                            False
+                            False
+                            True
+                            0
+                            True
+                            manualTimeRadio
+                          
+                          
+                            False
+                            True
+                            1
+                          
+                        
+                      
+                      
+                        1
+                        2
+                      
+                    
+                    
+                      
+                        True
+                        False
+                        1
+                        Set the time:
+                      
+                      
+                        GTK_FILL
+                        GTK_FILL
+                      
+                    
+                    
+                      
+                        True
+                        False
+                        12
+                        
+                          
                             True
                             False
                             6
                             
-                              
-                                _Manually
+                              
                                 True
                                 True
-                                False
-                                False
-                                True
-                                0
-                                True
-                                True
+                                
+                                11
+                                1
+                                True
                               
                               
                                 False
@@ -216,83 +286,26 @@
                                 0
                               
                             
-                            
-                              
-                                _Automatically from the Internet
-                                True
-                                False
-                                True
-                                False
-                                False
-                                True
-                                0
-                                True
-                                manualTimeRadio
-                              
-                              
-                                False
-                                True
-                                1
-                              
-                            
-                          
-                          
-                            1
-                            2
-                          
-                        
-                        
-                          
-                            True
-                            False
-                            0
-                            Set the time:
                           
                           
-                            GTK_FILL
-                            GTK_FILL
+                            False
+                            True
+                            0
                           
                         
                         
-                          
+                          
                             True
                             False
-                            12
+                            6
                             
-                              
+                              
                                 True
                                 False
-                                6
-                                
-                                  
-                                    True
-                                    False
-                                    0
-                                    Tim_e:
-                                    True
-                                    timeSpinner
-                                  
-                                  
-                                    False
-                                    True
-                                    0
-                                  
-                                
-                                
-                                  
-                                    True
-                                    True
-                                    
-                                    11
-                                    1
-                                    True
-                                  
-                                  
-                                    False
-                                    True
-                                    1
-                                  
-                                
+                                0
+                                _Date:
+                                True
+                                dateSpinner
                               
                               
                                 False
@@ -301,40 +314,13 @@
                               
                             
                             
-                              
+                              
                                 True
-                                False
-                                6
-                                
-                                  
-                                    True
-                                    False
-                                    0
-                                    _Date:
-                                    True
-                                    dateSpinner
-                                  
-                                  
-                                    False
-                                    True
-                                    0
-                                  
-                                
-                                
-                                  
-                                    True
-                                    True
-                                    
-                                    11
-                                    1
-                                    True
-                                  
-                                  
-                                    False
-                                    True
-                                    1
-                                  
-                                
+                                True
+                                
+                                11
+                                1
+                                True
                               
                               
                                 False
@@ -344,133 +330,157 @@
                             
                           
                           
-                            1
-                            2
-                            1
-                            2
+                            False
+                            True
+                            1
                           
                         
-                        
-                          
-                        
                       
                       
-                        False
-                        True
-                        2
+                        1
+                        2
+                        1
+                        2
+                      
+                    
+                    
+                      
+                        True
+                        False
+                        1
+                        Tim_e:
+                        True
+                        timeSpinner
+                      
+                      
+                        1
+                        2
+                        GTK_FILL
+                        GTK_FILL
                       
                     
                   
                   
-                    True
+                    False
                     True
-                    end
-                    0
+                    1
                   
                 
-                
-                  
-                
-              
-            
-            
-              
-                True
-                False
-                1
-                _Time & Date
-                True
               
               
-                False
+                True
+                True
+                end
+                0
               
             
             
-              
+              
+            
+          
+        
+        
+          
+            True
+            False
+            1
+            _Time & Date
+            True
+          
+          
+            False
+          
+        
+        
+          
+            True
+            False
+            0
+            0
+            
+              
                 True
                 False
-                0
-                0
+                12
+                12
+                
+                  
+                    _Show a clock in the menu bar
+                    True
+                    True
+                    False
+                    False
+                    True
+                    0
+                    True
+                  
+                  
+                    True
+                    True
+                    0
+                  
+                
                 
-                  
+                  
                     True
                     False
-                    12
-                    12
+                    True
                     
-                      
-                        _Show a clock in the panel
-                        True
-                        True
-                        False
-                        False
-                        True
-                        0
-                        True
-                      
-                      
-                        True
-                        True
-                        0
-                      
-                    
-                    
-                      
+                      
                         True
                         False
-                        True
+                        6
                         
-                          
+                          
+                            True
+                            False
+                            0
+                            In the clock, show:
+                          
+                          
+                            False
+                            True
+                            0
+                          
+                        
+                        
+                          
+                            _Weekday
+                            True
+                            True
+                            False
+                            False
+                            True
+                            0
+                            True
+                          
+                          
+                            False
+                            True
+                            1
+                          
+                        
+                        
+                          
+                            _Date and time
+                            True
+                            True
+                            False
+                            False
+                            True
+                            0
+                            True
+                          
+                          
+                            False
+                            True
+                            2
+                          
+                        
+                        
+                          
                             True
                             False
-                            6
-                            
-                              
-                                True
-                                False
-                                0
-                                In the clock, show:
-                              
-                              
-                                False
-                                True
-                                0
-                              
-                            
-                            
-                              
-                                _Weekday
-                                True
-                                True
-                                False
-                                False
-                                True
-                                0
-                                True
-                              
-                              
-                                False
-                                True
-                                1
-                              
-                            
-                            
-                              
-                                _Date and time
-                                True
-                                True
-                                False
-                                False
-                                True
-                                0
-                                True
-                              
-                              
-                                False
-                                True
-                                2
-                              
-                            
                             
                               
                                 _12-hour time
@@ -486,7 +496,7 @@
                               
                                 False
                                 True
-                                3
+                                0
                               
                             
                             
@@ -504,27 +514,52 @@
                               
                                 False
                                 True
-                                4
-                              
-                            
-                            
-                              
-                                Seco_nds
-                                True
-                                True
-                                False
-                                False
-                                True
-                                0
-                                True
-                              
-                              
-                                False
-                                True
-                                5
+                                1
                               
                             
                           
+                          
+                            False
+                            True
+                            3
+                          
+                        
+                        
+                          
+                            Seco_nds
+                            True
+                            True
+                            False
+                            False
+                            True
+                            0
+                            True
+                          
+                          
+                            False
+                            True
+                            4
+                          
+                        
+                      
+                      
+                        True
+                        True
+                        0
+                      
+                    
+                    
+                      
+                        True
+                        False
+                        6
+                        
+                          
+                            True
+                            False
+                            0
+                            In the clock’s menu, show:
+                          
                           
                             True
                             True
@@ -532,156 +567,130 @@
                           
                         
                         
-                          
+                          
+                            _Monthly calendar
+                            True
+                            True
+                            False
+                            False
+                            True
+                            0
+                            True
+                          
+                          
+                            False
+                            True
+                            1
+                          
+                        
+                        
+                          
                             True
                             False
-                            6
-                            
-                              
-                                True
-                                False
-                                0
-                                In the clock’s menu, show:
-                              
-                              
-                                True
-                                True
-                                0
-                              
-                            
-                            
-                              
-                                _Monthly calendar
-                                True
-                                True
-                                False
-                                False
-                                True
-                                0
-                                True
-                              
-                              
-                                False
-                                True
-                                1
-                              
-                            
+                            0
+                            0
+                            0
+                            24
                             
-                              
+                              
                                 True
                                 False
-                                0
-                                0
-                                0
-                                0
-                                12
+                                6
                                 
-                                  
+                                  
+                                    Include week num_bers
                                     True
-                                    False
-                                    6
-                                    
-                                      
-                                        Include week num_bers
-                                        True
-                                        True
-                                        False
-                                        False
-                                        True
-                                        0
-                                        True
-                                      
-                                      
-                                        True
-                                        True
-                                        0
-                                      
-                                    
+                                    True
+                                    False
+                                    False
+                                    True
+                                    0
+                                    True
                                   
+                                  
+                                    True
+                                    True
+                                    0
+                                  
                                 
                               
-                              
-                                False
-                                True
-                                2
-                              
                             
+                          
+                          
+                            False
+                            True
+                            2
+                          
+                        
+                        
+                          
+                            True
+                            True
+                            False
+                            False
+                            True
+                            0
+                            True
                             
-                              
+                              
                                 True
-                                True
-                                False
-                                False
-                                True
+                                False
                                 0
-                                True
-                                
-                                  
-                                    True
-                                    False
-                                    0
-                                    Coming _events from Evolution Calendar
-                                    True
-                                    True
-                                    showEventsCheck
-                                  
-                                
+                                Coming _events from Evolution Calendar
+                                True
+                                True
+                                showEventsCheck
                               
-                              
-                                False
-                                True
-                                3
-                              
                             
+                          
+                          
+                            False
+                            True
+                            3
+                          
+                        
+                        
+                          
+                            Time in _other locations
+                            True
+                            True
+                            False
+                            False
+                            True
+                            0
+                            True
+                          
+                          
+                            False
+                            True
+                            5
+                          
+                        
+                        
+                          
+                            True
+                            False
+                            0
+                            0
+                            0
+                            0
+                            24
                             
-                              
-                                Time in _other locations
+                              
+                                Choose _Locations…
                                 True
                                 True
-                                False
+                                True
                                 False
                                 True
                                 0
-                                True
-                              
-                              
-                                False
-                                True
-                                4
-                              
-                            
-                            
-                              
-                                True
-                                False
-                                0
-                                0
-                                0
-                                0
-                                12
-                                
-                                  
-                                    Choose _Locations…
-                                    True
-                                    True
-                                    True
-                                    False
-                                    True
-                                    0
-                                  
-                                
                               
-                              
-                                True
-                                True
-                                5
-                              
                             
                           
                           
                             True
                             True
-                            1
+                            5
                           
                         
                       
@@ -692,36 +701,40 @@
                       
                     
                   
+                  
+                    True
+                    True
+                    1
+                  
                 
               
-              
-                1
-                False
-              
-            
-            
-              
-                True
-                False
-                _Clock
-                True
-              
-              
-                1
-                False
-              
             
           
           
-            True
-            True
             1
+            False
+          
+        
+        
+          
+            True
+            False
+            _Clock
+            True
+          
+          
+            1
+            False
           
         
       
     
-    
-      closeButton
-    
+  
+  
+    
+      
+      
+      
+    
   
 
diff --git a/libmap/Makefile.in b/libmap/Makefile.in
deleted file mode 100644
index dd552a4..0000000
--- a/libmap/Makefile.in
+++ /dev/null
@@ -1,733 +0,0 @@
-# Makefile.in generated by automake 1.11.1 from Makefile.am.
-# @configure_input@
-
-# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006, 2007, 2008, 2009  Free Software Foundation,
-# Inc.
-# This Makefile.in is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
-# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-# PARTICULAR PURPOSE.
-
-@SET_MAKE@
-
-
-
-VPATH = @srcdir@
-pkgdatadir = $(datadir)/@PACKAGE@
-pkgincludedir = $(includedir)/@PACKAGE@
-pkglibdir = $(libdir)/@PACKAGE@
-pkglibexecdir = $(libexecdir)/@PACKAGE@
-am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
-install_sh_DATA = $(install_sh) -c -m 644
-install_sh_PROGRAM = $(install_sh) -c
-install_sh_SCRIPT = $(install_sh) -c
-INSTALL_HEADER = $(INSTALL_DATA)
-transform = $(program_transform_name)
-NORMAL_INSTALL = :
-PRE_INSTALL = :
-POST_INSTALL = :
-NORMAL_UNINSTALL = :
-PRE_UNINSTALL = :
-POST_UNINSTALL = :
-build_triplet = @build@
-host_triplet = @host@
-noinst_PROGRAMS = test-timezone$(EXEEXT)
-subdir = libmap
-DIST_COMMON = README $(dist_tzdata_DATA) $(dist_ui_DATA) \
-	$(srcdir)/Makefile.am $(srcdir)/Makefile.in
-ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/m4/intltool.m4 \
-	$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
-	$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
-	$(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac
-am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
-	$(ACLOCAL_M4)
-mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
-CONFIG_HEADER = $(top_builddir)/config.h
-CONFIG_CLEAN_FILES =
-CONFIG_CLEAN_VPATH_FILES =
-LTLIBRARIES = $(noinst_LTLIBRARIES)
-am__DEPENDENCIES_1 =
-libmap_la_DEPENDENCIES = $(am__DEPENDENCIES_1)
-am_libmap_la_OBJECTS = cc-timezone-map.lo tz.lo
-libmap_la_OBJECTS = $(am_libmap_la_OBJECTS)
-AM_V_lt = $(am__v_lt_$(V))
-am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY))
-am__v_lt_0 = --silent
-libmap_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
-	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
-	$(libmap_la_LDFLAGS) $(LDFLAGS) -o $@
-PROGRAMS = $(noinst_PROGRAMS)
-am_test_timezone_OBJECTS = test_timezone-test-timezone.$(OBJEXT) \
-	test_timezone-tz.$(OBJEXT)
-test_timezone_OBJECTS = $(am_test_timezone_OBJECTS)
-test_timezone_DEPENDENCIES = $(am__DEPENDENCIES_1)
-test_timezone_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
-	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(test_timezone_CFLAGS) \
-	$(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
-DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
-depcomp = $(SHELL) $(top_srcdir)/depcomp
-am__depfiles_maybe = depfiles
-am__mv = mv -f
-COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
-	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
-LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
-	$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
-	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
-	$(AM_CFLAGS) $(CFLAGS)
-AM_V_CC = $(am__v_CC_$(V))
-am__v_CC_ = $(am__v_CC_$(AM_DEFAULT_VERBOSITY))
-am__v_CC_0 = @echo "  CC    " $@;
-AM_V_at = $(am__v_at_$(V))
-am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY))
-am__v_at_0 = @
-CCLD = $(CC)
-LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
-	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
-	$(AM_LDFLAGS) $(LDFLAGS) -o $@
-AM_V_CCLD = $(am__v_CCLD_$(V))
-am__v_CCLD_ = $(am__v_CCLD_$(AM_DEFAULT_VERBOSITY))
-am__v_CCLD_0 = @echo "  CCLD  " $@;
-AM_V_GEN = $(am__v_GEN_$(V))
-am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY))
-am__v_GEN_0 = @echo "  GEN   " $@;
-SOURCES = $(libmap_la_SOURCES) $(test_timezone_SOURCES)
-DIST_SOURCES = $(libmap_la_SOURCES) $(test_timezone_SOURCES)
-am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
-am__vpath_adj = case $$p in \
-    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
-    *) f=$$p;; \
-  esac;
-am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
-am__install_max = 40
-am__nobase_strip_setup = \
-  srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
-am__nobase_strip = \
-  for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
-am__nobase_list = $(am__nobase_strip_setup); \
-  for p in $$list; do echo "$$p $$p"; done | \
-  sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
-  $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
-    if (++n[$$2] == $(am__install_max)) \
-      { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
-    END { for (dir in files) print dir, files[dir] }'
-am__base_list = \
-  sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
-  sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
-am__installdirs = "$(DESTDIR)$(tzdatadir)" "$(DESTDIR)$(uidir)"
-DATA = $(dist_tzdata_DATA) $(dist_ui_DATA)
-ETAGS = etags
-CTAGS = ctags
-DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
-ACLOCAL = @ACLOCAL@
-ALL_LINGUAS = @ALL_LINGUAS@
-AMTAR = @AMTAR@
-AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
-AR = @AR@
-AUTOCONF = @AUTOCONF@
-AUTOHEADER = @AUTOHEADER@
-AUTOMAKE = @AUTOMAKE@
-AWK = @AWK@
-CATALOGS = @CATALOGS@
-CATOBJEXT = @CATOBJEXT@
-CC = @CC@
-CCDEPMODE = @CCDEPMODE@
-CFLAGS = @CFLAGS@
-CPP = @CPP@
-CPPFLAGS = @CPPFLAGS@
-CYGPATH_W = @CYGPATH_W@
-DATADIRNAME = @DATADIRNAME@
-DBUSSERVICEDIR = @DBUSSERVICEDIR@
-DEFS = @DEFS@
-DEPDIR = @DEPDIR@
-DSYMUTIL = @DSYMUTIL@
-DUMPBIN = @DUMPBIN@
-ECHO_C = @ECHO_C@
-ECHO_N = @ECHO_N@
-ECHO_T = @ECHO_T@
-EGREP = @EGREP@
-EXEEXT = @EXEEXT@
-FGREP = @FGREP@
-GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
-GLIB_COMPILE_SCHEMAS = @GLIB_COMPILE_SCHEMAS@
-GLIB_GENMARSHAL = @GLIB_GENMARSHAL@
-GLIB_MKENUMS = @GLIB_MKENUMS@
-GMOFILES = @GMOFILES@
-GMSGFMT = @GMSGFMT@
-GNOMELOCALEDIR = @GNOMELOCALEDIR@
-GREP = @GREP@
-GSETTINGS_DISABLE_SCHEMAS_COMPILE = @GSETTINGS_DISABLE_SCHEMAS_COMPILE@
-INDICATORDIR = @INDICATORDIR@
-INDICATORICONSDIR = @INDICATORICONSDIR@
-INDICATOR_CFLAGS = @INDICATOR_CFLAGS@
-INDICATOR_LIBS = @INDICATOR_LIBS@
-INSTALL = @INSTALL@
-INSTALL_DATA = @INSTALL_DATA@
-INSTALL_PROGRAM = @INSTALL_PROGRAM@
-INSTALL_SCRIPT = @INSTALL_SCRIPT@
-INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
-INSTOBJEXT = @INSTOBJEXT@
-INTLLIBS = @INTLLIBS@
-INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@
-INTLTOOL_MERGE = @INTLTOOL_MERGE@
-INTLTOOL_PERL = @INTLTOOL_PERL@
-INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
-LD = @LD@
-LDFLAGS = @LDFLAGS@
-LIBMAP_CFLAGS = @LIBMAP_CFLAGS@
-LIBMAP_LDFLAGS = @LIBMAP_LDFLAGS@
-LIBMAP_LIBS = @LIBMAP_LIBS@
-LIBOBJS = @LIBOBJS@
-LIBS = @LIBS@
-LIBTOOL = @LIBTOOL@
-LIPO = @LIPO@
-LN_S = @LN_S@
-LTLIBOBJS = @LTLIBOBJS@
-MAINT = @MAINT@
-MAKEINFO = @MAKEINFO@
-MKDIR_P = @MKDIR_P@
-MKINSTALLDIRS = @MKINSTALLDIRS@
-MSGFMT = @MSGFMT@
-MSGFMT_OPTS = @MSGFMT_OPTS@
-MSGMERGE = @MSGMERGE@
-NM = @NM@
-NMEDIT = @NMEDIT@
-OBJDUMP = @OBJDUMP@
-OBJEXT = @OBJEXT@
-OTOOL = @OTOOL@
-OTOOL64 = @OTOOL64@
-PACKAGE = @PACKAGE@
-PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
-PACKAGE_NAME = @PACKAGE_NAME@
-PACKAGE_STRING = @PACKAGE_STRING@
-PACKAGE_TARNAME = @PACKAGE_TARNAME@
-PACKAGE_URL = @PACKAGE_URL@
-PACKAGE_VERSION = @PACKAGE_VERSION@
-PATH_SEPARATOR = @PATH_SEPARATOR@
-PKG_CONFIG = @PKG_CONFIG@
-PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
-PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
-POFILES = @POFILES@
-POSUB = @POSUB@
-PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@
-PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@
-PREF_CFLAGS = @PREF_CFLAGS@
-PREF_LIBS = @PREF_LIBS@
-RANLIB = @RANLIB@
-SED = @SED@
-SERVICE_CFLAGS = @SERVICE_CFLAGS@
-SERVICE_LIBS = @SERVICE_LIBS@
-SET_MAKE = @SET_MAKE@
-SHELL = @SHELL@
-STRIP = @STRIP@
-USE_NLS = @USE_NLS@
-VERSION = @VERSION@
-XGETTEXT = @XGETTEXT@
-abs_builddir = @abs_builddir@
-abs_srcdir = @abs_srcdir@
-abs_top_builddir = @abs_top_builddir@
-abs_top_srcdir = @abs_top_srcdir@
-ac_ct_CC = @ac_ct_CC@
-ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
-am__include = @am__include@
-am__leading_dot = @am__leading_dot@
-am__quote = @am__quote@
-am__tar = @am__tar@
-am__untar = @am__untar@
-bindir = @bindir@
-build = @build@
-build_alias = @build_alias@
-build_cpu = @build_cpu@
-build_os = @build_os@
-build_vendor = @build_vendor@
-builddir = @builddir@
-datadir = @datadir@
-datarootdir = @datarootdir@
-docdir = @docdir@
-dvidir = @dvidir@
-exec_prefix = @exec_prefix@
-gsettingsschemadir = @gsettingsschemadir@
-host = @host@
-host_alias = @host_alias@
-host_cpu = @host_cpu@
-host_os = @host_os@
-host_vendor = @host_vendor@
-htmldir = @htmldir@
-includedir = @includedir@
-infodir = @infodir@
-install_sh = @install_sh@
-libdir = @libdir@
-libexecdir = @libexecdir@
-localedir = @localedir@
-localstatedir = @localstatedir@
-lt_ECHO = @lt_ECHO@
-mandir = @mandir@
-mkdir_p = @mkdir_p@
-oldincludedir = @oldincludedir@
-pdfdir = @pdfdir@
-prefix = @prefix@
-program_transform_name = @program_transform_name@
-psdir = @psdir@
-sbindir = @sbindir@
-sharedstatedir = @sharedstatedir@
-srcdir = @srcdir@
-sysconfdir = @sysconfdir@
-target_alias = @target_alias@
-top_build_prefix = @top_build_prefix@
-top_builddir = @top_builddir@
-top_srcdir = @top_srcdir@
-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 \
-	data/timezone_10.png \
-	data/timezone_10.5.png \
-	data/timezone_-1.png \
-	data/timezone_1.png \
-	data/timezone_-11.png \
-	data/timezone_11.png \
-	data/timezone_11.5.png \
-	data/timezone_12.png \
-	data/timezone_12.75.png \
-	data/timezone_13.png \
-	data/timezone_-2.png \
-	data/timezone_2.png \
-	data/timezone_-3.png \
-	data/timezone_3.png \
-	data/timezone_-3.5.png \
-	data/timezone_3.5.png \
-	data/timezone_-4.png \
-	data/timezone_4.png \
-	data/timezone_-4.5.png \
-	data/timezone_4.5.png \
-	data/timezone_-5.png \
-	data/timezone_5.png \
-	data/timezone_-5.5.png \
-	data/timezone_5.5.png \
-	data/timezone_5.75.png \
-	data/timezone_-6.png \
-	data/timezone_6.png \
-	data/timezone_6.5.png \
-	data/timezone_-7.png \
-	data/timezone_7.png \
-	data/timezone_-8.png \
-	data/timezone_8.png \
-	data/timezone_-9.png \
-	data/timezone_9.png \
-	data/timezone_-9.5.png \
-	data/timezone_9.5.png
-
-tzdatadir = $(pkgdatadir)/libmap/datetime
-dist_tzdata_DATA = backward
-AM_CPPFLAGS = \
-	$(LIBMAP_CFLAGS)				\
-	-DGNOMELOCALEDIR="\"$(datadir)/locale\""	\
-	-DGNOMECC_DATA_DIR="\"$(pkgdatadir)/libmap\""		\
-	-DDATADIR="\"$(uidir)\""			\
-	$(NULL)
-
-test_timezone_SOURCES = test-timezone.c tz.c tz.h
-test_timezone_LDADD = $(LIBMAP_LIBS)
-test_timezone_CFLAGS = $(LIBMAP_CFLAGS)
-noinst_LTLIBRARIES = libmap.la
-libmap_la_SOURCES = \
-	cc-timezone-map.c	\
-	cc-timezone-map.h	\
-	tz.c tz.h
-
-libmap_la_LIBADD = $(LIBMAP_LIBS)
-libmap_la_LDFLAGS = $(LIBMAP_LDFLAGS)
-all: all-am
-
-.SUFFIXES:
-.SUFFIXES: .c .lo .o .obj
-$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
-	@for dep in $?; do \
-	  case '$(am__configure_deps)' in \
-	    *$$dep*) \
-	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
-	        && { if test -f $@; then exit 0; else break; fi; }; \
-	      exit 1;; \
-	  esac; \
-	done; \
-	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu libmap/Makefile'; \
-	$(am__cd) $(top_srcdir) && \
-	  $(AUTOMAKE) --gnu libmap/Makefile
-.PRECIOUS: Makefile
-Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
-	@case '$?' in \
-	  *config.status*) \
-	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
-	  *) \
-	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
-	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
-	esac;
-
-$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
-	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-
-$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
-	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
-	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-$(am__aclocal_m4_deps):
-
-clean-noinstLTLIBRARIES:
-	-test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
-	@list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
-	  dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
-	  test "$$dir" != "$$p" || dir=.; \
-	  echo "rm -f \"$${dir}/so_locations\""; \
-	  rm -f "$${dir}/so_locations"; \
-	done
-libmap.la: $(libmap_la_OBJECTS) $(libmap_la_DEPENDENCIES) 
-	$(AM_V_CCLD)$(libmap_la_LINK)  $(libmap_la_OBJECTS) $(libmap_la_LIBADD) $(LIBS)
-
-clean-noinstPROGRAMS:
-	@list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \
-	echo " rm -f" $$list; \
-	rm -f $$list || exit $$?; \
-	test -n "$(EXEEXT)" || exit 0; \
-	list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
-	echo " rm -f" $$list; \
-	rm -f $$list
-test-timezone$(EXEEXT): $(test_timezone_OBJECTS) $(test_timezone_DEPENDENCIES) 
-	@rm -f test-timezone$(EXEEXT)
-	$(AM_V_CCLD)$(test_timezone_LINK) $(test_timezone_OBJECTS) $(test_timezone_LDADD) $(LIBS)
-
-mostlyclean-compile:
-	-rm -f *.$(OBJEXT)
-
-distclean-compile:
-	-rm -f *.tab.c
-
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cc-timezone-map.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_timezone-test-timezone.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_timezone-tz.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tz.Plo@am__quote@
-
-.c.o:
-@am__fastdepCC_TRUE@	$(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
-@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
-@am__fastdepCC_FALSE@	$(AM_V_CC) @AM_BACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@	$(COMPILE) -c $<
-
-.c.obj:
-@am__fastdepCC_TRUE@	$(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
-@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
-@am__fastdepCC_FALSE@	$(AM_V_CC) @AM_BACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@	$(COMPILE) -c `$(CYGPATH_W) '$<'`
-
-.c.lo:
-@am__fastdepCC_TRUE@	$(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
-@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
-@am__fastdepCC_FALSE@	$(AM_V_CC) @AM_BACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@	$(LTCOMPILE) -c -o $@ $<
-
-test_timezone-test-timezone.o: test-timezone.c
-@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_timezone_CFLAGS) $(CFLAGS) -MT test_timezone-test-timezone.o -MD -MP -MF $(DEPDIR)/test_timezone-test-timezone.Tpo -c -o test_timezone-test-timezone.o `test -f 'test-timezone.c' || echo '$(srcdir)/'`test-timezone.c
-@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/test_timezone-test-timezone.Tpo $(DEPDIR)/test_timezone-test-timezone.Po
-@am__fastdepCC_FALSE@	$(AM_V_CC) @AM_BACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='test-timezone.c' object='test_timezone-test-timezone.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_timezone_CFLAGS) $(CFLAGS) -c -o test_timezone-test-timezone.o `test -f 'test-timezone.c' || echo '$(srcdir)/'`test-timezone.c
-
-test_timezone-test-timezone.obj: test-timezone.c
-@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_timezone_CFLAGS) $(CFLAGS) -MT test_timezone-test-timezone.obj -MD -MP -MF $(DEPDIR)/test_timezone-test-timezone.Tpo -c -o test_timezone-test-timezone.obj `if test -f 'test-timezone.c'; then $(CYGPATH_W) 'test-timezone.c'; else $(CYGPATH_W) '$(srcdir)/test-timezone.c'; fi`
-@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/test_timezone-test-timezone.Tpo $(DEPDIR)/test_timezone-test-timezone.Po
-@am__fastdepCC_FALSE@	$(AM_V_CC) @AM_BACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='test-timezone.c' object='test_timezone-test-timezone.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_timezone_CFLAGS) $(CFLAGS) -c -o test_timezone-test-timezone.obj `if test -f 'test-timezone.c'; then $(CYGPATH_W) 'test-timezone.c'; else $(CYGPATH_W) '$(srcdir)/test-timezone.c'; fi`
-
-test_timezone-tz.o: tz.c
-@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_timezone_CFLAGS) $(CFLAGS) -MT test_timezone-tz.o -MD -MP -MF $(DEPDIR)/test_timezone-tz.Tpo -c -o test_timezone-tz.o `test -f 'tz.c' || echo '$(srcdir)/'`tz.c
-@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/test_timezone-tz.Tpo $(DEPDIR)/test_timezone-tz.Po
-@am__fastdepCC_FALSE@	$(AM_V_CC) @AM_BACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='tz.c' object='test_timezone-tz.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_timezone_CFLAGS) $(CFLAGS) -c -o test_timezone-tz.o `test -f 'tz.c' || echo '$(srcdir)/'`tz.c
-
-test_timezone-tz.obj: tz.c
-@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_timezone_CFLAGS) $(CFLAGS) -MT test_timezone-tz.obj -MD -MP -MF $(DEPDIR)/test_timezone-tz.Tpo -c -o test_timezone-tz.obj `if test -f 'tz.c'; then $(CYGPATH_W) 'tz.c'; else $(CYGPATH_W) '$(srcdir)/tz.c'; fi`
-@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/test_timezone-tz.Tpo $(DEPDIR)/test_timezone-tz.Po
-@am__fastdepCC_FALSE@	$(AM_V_CC) @AM_BACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='tz.c' object='test_timezone-tz.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_timezone_CFLAGS) $(CFLAGS) -c -o test_timezone-tz.obj `if test -f 'tz.c'; then $(CYGPATH_W) 'tz.c'; else $(CYGPATH_W) '$(srcdir)/tz.c'; fi`
-
-mostlyclean-libtool:
-	-rm -f *.lo
-
-clean-libtool:
-	-rm -rf .libs _libs
-install-dist_tzdataDATA: $(dist_tzdata_DATA)
-	@$(NORMAL_INSTALL)
-	test -z "$(tzdatadir)" || $(MKDIR_P) "$(DESTDIR)$(tzdatadir)"
-	@list='$(dist_tzdata_DATA)'; test -n "$(tzdatadir)" || list=; \
-	for p in $$list; do \
-	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
-	  echo "$$d$$p"; \
-	done | $(am__base_list) | \
-	while read files; do \
-	  echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(tzdatadir)'"; \
-	  $(INSTALL_DATA) $$files "$(DESTDIR)$(tzdatadir)" || exit $$?; \
-	done
-
-uninstall-dist_tzdataDATA:
-	@$(NORMAL_UNINSTALL)
-	@list='$(dist_tzdata_DATA)'; test -n "$(tzdatadir)" || list=; \
-	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
-	test -n "$$files" || exit 0; \
-	echo " ( cd '$(DESTDIR)$(tzdatadir)' && rm -f" $$files ")"; \
-	cd "$(DESTDIR)$(tzdatadir)" && rm -f $$files
-install-dist_uiDATA: $(dist_ui_DATA)
-	@$(NORMAL_INSTALL)
-	test -z "$(uidir)" || $(MKDIR_P) "$(DESTDIR)$(uidir)"
-	@list='$(dist_ui_DATA)'; test -n "$(uidir)" || list=; \
-	for p in $$list; do \
-	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
-	  echo "$$d$$p"; \
-	done | $(am__base_list) | \
-	while read files; do \
-	  echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(uidir)'"; \
-	  $(INSTALL_DATA) $$files "$(DESTDIR)$(uidir)" || exit $$?; \
-	done
-
-uninstall-dist_uiDATA:
-	@$(NORMAL_UNINSTALL)
-	@list='$(dist_ui_DATA)'; test -n "$(uidir)" || list=; \
-	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
-	test -n "$$files" || exit 0; \
-	echo " ( cd '$(DESTDIR)$(uidir)' && rm -f" $$files ")"; \
-	cd "$(DESTDIR)$(uidir)" && rm -f $$files
-
-ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
-	list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
-	unique=`for i in $$list; do \
-	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
-	  done | \
-	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
-	      END { if (nonempty) { for (i in files) print i; }; }'`; \
-	mkid -fID $$unique
-tags: TAGS
-
-TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
-		$(TAGS_FILES) $(LISP)
-	set x; \
-	here=`pwd`; \
-	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
-	unique=`for i in $$list; do \
-	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
-	  done | \
-	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
-	      END { if (nonempty) { for (i in files) print i; }; }'`; \
-	shift; \
-	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
-	  test -n "$$unique" || unique=$$empty_fix; \
-	  if test $$# -gt 0; then \
-	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
-	      "$$@" $$unique; \
-	  else \
-	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
-	      $$unique; \
-	  fi; \
-	fi
-ctags: CTAGS
-CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
-		$(TAGS_FILES) $(LISP)
-	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
-	unique=`for i in $$list; do \
-	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
-	  done | \
-	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
-	      END { if (nonempty) { for (i in files) print i; }; }'`; \
-	test -z "$(CTAGS_ARGS)$$unique" \
-	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
-	     $$unique
-
-GTAGS:
-	here=`$(am__cd) $(top_builddir) && pwd` \
-	  && $(am__cd) $(top_srcdir) \
-	  && gtags -i $(GTAGS_ARGS) "$$here"
-
-distclean-tags:
-	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
-
-distdir: $(DISTFILES)
-	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
-	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
-	list='$(DISTFILES)'; \
-	  dist_files=`for file in $$list; do echo $$file; done | \
-	  sed -e "s|^$$srcdirstrip/||;t" \
-	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
-	case $$dist_files in \
-	  */*) $(MKDIR_P) `echo "$$dist_files" | \
-			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
-			   sort -u` ;; \
-	esac; \
-	for file in $$dist_files; do \
-	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
-	  if test -d $$d/$$file; then \
-	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
-	    if test -d "$(distdir)/$$file"; then \
-	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
-	    fi; \
-	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
-	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
-	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
-	    fi; \
-	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
-	  else \
-	    test -f "$(distdir)/$$file" \
-	    || cp -p $$d/$$file "$(distdir)/$$file" \
-	    || exit 1; \
-	  fi; \
-	done
-check-am: all-am
-	$(MAKE) $(AM_MAKEFLAGS) check-local
-check: check-am
-all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(DATA) all-local
-installdirs:
-	for dir in "$(DESTDIR)$(tzdatadir)" "$(DESTDIR)$(uidir)"; do \
-	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
-	done
-install: install-am
-install-exec: install-exec-am
-install-data: install-data-am
-uninstall: uninstall-am
-
-install-am: all-am
-	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
-
-installcheck: installcheck-am
-install-strip:
-	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
-	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
-	  `test -z '$(STRIP)' || \
-	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
-mostlyclean-generic:
-
-clean-generic:
-
-distclean-generic:
-	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
-
-maintainer-clean-generic:
-	@echo "This command is intended for maintainers to use"
-	@echo "it deletes files that may require special tools to rebuild."
-clean: clean-am
-
-clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
-	clean-noinstPROGRAMS mostlyclean-am
-
-distclean: distclean-am
-	-rm -rf ./$(DEPDIR)
-	-rm -f Makefile
-distclean-am: clean-am distclean-compile distclean-generic \
-	distclean-tags
-
-dvi: dvi-am
-
-dvi-am:
-
-html: html-am
-
-html-am:
-
-info: info-am
-
-info-am:
-
-install-data-am: install-dist_tzdataDATA install-dist_uiDATA
-
-install-dvi: install-dvi-am
-
-install-dvi-am:
-
-install-exec-am:
-
-install-html: install-html-am
-
-install-html-am:
-
-install-info: install-info-am
-
-install-info-am:
-
-install-man:
-
-install-pdf: install-pdf-am
-
-install-pdf-am:
-
-install-ps: install-ps-am
-
-install-ps-am:
-
-installcheck-am:
-
-maintainer-clean: maintainer-clean-am
-	-rm -rf ./$(DEPDIR)
-	-rm -f Makefile
-maintainer-clean-am: distclean-am maintainer-clean-generic
-
-mostlyclean: mostlyclean-am
-
-mostlyclean-am: mostlyclean-compile mostlyclean-generic \
-	mostlyclean-libtool
-
-pdf: pdf-am
-
-pdf-am:
-
-ps: ps-am
-
-ps-am:
-
-uninstall-am: uninstall-dist_tzdataDATA uninstall-dist_uiDATA
-
-.MAKE: check-am install-am install-strip
-
-.PHONY: CTAGS GTAGS all all-am all-local check check-am check-local \
-	clean clean-generic clean-libtool clean-noinstLTLIBRARIES \
-	clean-noinstPROGRAMS ctags distclean distclean-compile \
-	distclean-generic distclean-libtool distclean-tags distdir dvi \
-	dvi-am html html-am info info-am install install-am \
-	install-data install-data-am install-dist_tzdataDATA \
-	install-dist_uiDATA install-dvi install-dvi-am install-exec \
-	install-exec-am install-html install-html-am install-info \
-	install-info-am install-man install-pdf install-pdf-am \
-	install-ps install-ps-am install-strip installcheck \
-	installcheck-am installdirs maintainer-clean \
-	maintainer-clean-generic mostlyclean mostlyclean-compile \
-	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
-	tags uninstall uninstall-am uninstall-dist_tzdataDATA \
-	uninstall-dist_uiDATA
-
-
-all-local: check-local
-
-# FIXME remove "|| :" when we have all the necessary pixmaps
-check-local: test-timezone
-	$(builddir)/test-timezone $(srcdir)/data || :
-
-# Tell versions [3.59,3.63) of GNU make to not export all variables.
-# Otherwise a system limit (for SysV at least) may be exceeded.
-.NOEXPORT:
diff --git a/src/datetime-prefs.c b/src/datetime-prefs.c
index e69d58b..2435eff 100644
--- a/src/datetime-prefs.c
+++ b/src/datetime-prefs.c
@@ -30,6 +30,7 @@ with this program.  If not, see .
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -426,6 +427,32 @@ timezone_selected (GtkEntryCompletion * widget, GtkTreeModel * model,
   return FALSE; // Do normal action too
 }
 
+static gboolean
+key_pressed (GtkWidget * widget, GdkEventKey * event, gpointer user_data)
+{
+  switch (event->keyval) {
+  case GDK_KEY_Escape:
+    gtk_widget_destroy (widget);
+    return TRUE;
+  }
+  return FALSE;
+}
+
+static GtkWidget *
+get_child_of_type (GtkContainer * parent, GType type)
+{
+  GList * children, * iter;
+
+  children = gtk_container_get_children (parent);
+  for (iter = children; iter; iter = iter->next) {
+    if (G_TYPE_CHECK_INSTANCE_TYPE (iter->data, type)) {
+      return GTK_WIDGET (iter->data);
+    }
+  }
+
+  return NULL;
+}
+
 static GtkWidget *
 create_dialog (void)
 {
@@ -451,6 +478,11 @@ create_dialog (void)
   polkit_lock_button_set_unlock_text (POLKIT_LOCK_BUTTON (polkit_button), _("Unlock to change these settings"));
   polkit_lock_button_set_lock_text (POLKIT_LOCK_BUTTON (polkit_button), _("Lock to prevent further changes"));
   gtk_box_pack_start (GTK_BOX (WIG ("timeDateBox")), polkit_button, FALSE, TRUE, 0);
+  /* Make sure border around button is visible */
+  GtkWidget * polkit_button_button = get_child_of_type (GTK_CONTAINER (polkit_button), GTK_TYPE_BUTTON);
+  if (polkit_button_button != NULL) {
+    gtk_button_set_relief (GTK_BUTTON (polkit_button_button), GTK_RELIEF_NORMAL);
+  }
 
   /* Add map */
   tzmap = cc_timezone_map_new ();
@@ -513,6 +545,7 @@ create_dialog (void)
   tz_entry = WIG ("timezoneEntry");
 
   g_signal_connect (WIG ("locationsButton"), "clicked", G_CALLBACK (show_locations), dlg);
+  g_signal_connect (dlg, "key-press-event", G_CALLBACK (key_pressed), NULL);
 
   /* Grab proxy for settings daemon */
   g_dbus_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, NULL,
@@ -565,7 +598,7 @@ main (int argc, char ** argv)
     unique_app_watch_window (app, GTK_WINDOW (dlg));
 
     gtk_widget_show_all (dlg);
-    g_signal_connect (dlg, "response", G_CALLBACK(gtk_main_quit), NULL);
+    g_signal_connect (dlg, "destroy", G_CALLBACK(gtk_main_quit), NULL);
     gtk_main ();
   }
 
-- 
cgit v1.2.3


From 27e4da12f64cf3fbb3ae581a70503865c64e76b2 Mon Sep 17 00:00:00 2001
From: karl-qdh 
Date: Thu, 3 Mar 2011 13:46:29 +0000
Subject: Added decent conversion from cairo context to pixbuf and updated the
 colour code so it works. Currently we show a rectangle, but we could equally
 use a mask.

---
 src/datetime-service.c | 66 ++++++++++++++++++++++++++++++++++++++------------
 1 file changed, 50 insertions(+), 16 deletions(-)

diff --git a/src/datetime-service.c b/src/datetime-service.c
index 2250c59..45546a0 100644
--- a/src/datetime-service.c
+++ b/src/datetime-service.c
@@ -641,8 +641,8 @@ update_appointment_menu_items (gpointer user_data)
 	i = 0;
 	
 	gtk_icon_size_lookup(GTK_ICON_SIZE_MENU, &width, &height);
-	if (width == 0) width = 16;
-	if (height == 0) height = 16;
+	if (width == 0) width = 12;
+	if (height == 0) height = 12;
 	
 	for (l = sorted_comp_instances; l; l = l->next) {
 		struct comp_instance *ci = l->data;
@@ -742,21 +742,55 @@ update_appointment_menu_items (gpointer user_data)
 		// For now we'll create a circle
         if (color_spec != NULL) {
         	// Fixme causes segfault, but we have colours now yay!
-        	/*GdkColor color;
-        	gdk_color_parse (color_spec, &color);
-        	GdkPixmap *pixmap = gdk_pixmap_new(NULL, width, height, 32);
-        	if (pixmap != NULL) {
-				cairo_t *cr = gdk_cairo_create(pixmap);
-				cairo_arc (cr, width/2, height/2, width/2, 0, 2 * M_PI);
-				gdk_cairo_set_source_color(cr, &color);
-				cairo_fill(cr);
-		
-				GdkPixbuf * pixbuf = gdk_pixbuf_get_from_drawable(NULL, (GdkDrawable*)pixmap, 
-					gdk_colormap_new(gdk_drawable_get_visual((GdkDrawable*)pixmap), TRUE), 0,0,0,0, width, height);
-				cairo_destroy(cr);
+        	GdkColor color;
+        	gdk_color_parse (color_spec, &color);			                                    
+        	cairo_surface_t *surface = cairo_image_surface_create( CAIRO_FORMAT_ARGB32, width, height ); 
+    		 
+    		cairo_t *cr = cairo_create(surface);
+			gdk_cairo_set_source_color(cr, &color);
+			cairo_paint(cr);
+    		cairo_set_source_rgba(cr, 0,0,0,0.5);
+    		cairo_set_line_width(cr, 1);
+    		cairo_rectangle (cr, 0.5, 0.5, width-1, height-1);
+    		cairo_stroke(cr);
+			// Convert to pixbuf, in gtk3 this is done with gdk_pixbuf_get_from_surface
+			cairo_content_t content = cairo_surface_get_content (surface) | CAIRO_CONTENT_COLOR;
+			GdkPixbuf *pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, 
+			                                    !!(content & CAIRO_CONTENT_ALPHA), 
+			                                    8, width, height);
+			                                    
+    		gint sstride = cairo_image_surface_get_stride( surface ); 
+    		gint dstride = gdk_pixbuf_get_rowstride (pixbuf);
+    		guchar *spixels = cairo_image_surface_get_data( surface );
+    		guchar *dpixels = gdk_pixbuf_get_pixels (pixbuf);
+
+
+  			int x, y;
+  			for (y = 0; y < height; y++) {
+    			guint32 *src = (guint32 *) spixels;
+
+				for (x = 0; x < width; x++) {
+					guint alpha = src[x] >> 24;
+
+					if (alpha == 0) {
+          				dpixels[x * 4 + 0] = 0;
+          				dpixels[x * 4 + 1] = 0;
+          				dpixels[x * 4 + 2] = 0;
+        			} else {
+						dpixels[x * 4 + 0] = (((src[x] & 0xff0000) >> 16) * 255 + alpha / 2) / alpha;
+						dpixels[x * 4 + 1] = (((src[x] & 0x00ff00) >>  8) * 255 + alpha / 2) / alpha;
+						dpixels[x * 4 + 2] = (((src[x] & 0x0000ff) >>  0) * 255 + alpha / 2) / alpha;
+					}
+					dpixels[x * 4 + 3] = alpha;
+				}
+    			spixels += sstride;
+    			dpixels += dstride;
+  			}
+
+			cairo_surface_destroy (surface);
+			cairo_destroy(cr);
 			
-				dbusmenu_menuitem_property_set_image (item, APPOINTMENT_MENUITEM_PROP_ICON, pixbuf);
-			}*/
+			dbusmenu_menuitem_property_set_image (item, APPOINTMENT_MENUITEM_PROP_ICON, pixbuf);
 		}
 		dbusmenu_menuitem_child_add_position (root, item, 2+i);
 		appointments = g_list_append         (appointments, item); // Keep track of the items here to make them east to remove
-- 
cgit v1.2.3


From 55736aa91ce77af6127ec115860cb2379158d48b Mon Sep 17 00:00:00 2001
From: Michael Terry 
Date: Thu, 3 Mar 2011 09:44:42 -0500
Subject: add back missing unref

---
 src/datetime-prefs.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/datetime-prefs.c b/src/datetime-prefs.c
index b6fd1c9..901c290 100644
--- a/src/datetime-prefs.c
+++ b/src/datetime-prefs.c
@@ -304,6 +304,7 @@ input_time_text (GtkWidget * spinner, gdouble * value, gpointer user_data)
   hour = g_date_time_get_hour (now);
   minute = g_date_time_get_minute (now);
   second = g_date_time_get_second (now);
+  g_date_time_unref (now);
 
   /* Parse this string as if it were in the output format */
   gint scanned = 0;
-- 
cgit v1.2.3


From 76825a8ee0227c18fd02a30ab74ecc5a95382b6d Mon Sep 17 00:00:00 2001
From: karl-qdh 
Date: Thu, 3 Mar 2011 14:45:37 +0000
Subject: Added some small fixes to make sure the pixbuf redraws everytime.
 There may be some memory leaks corrupting data somewhere.

---
 src/datetime-service.c | 77 +++++++++++++++++++++++++++-----------------------
 1 file changed, 41 insertions(+), 36 deletions(-)

diff --git a/src/datetime-service.c b/src/datetime-service.c
index 45546a0..fd14af9 100644
--- a/src/datetime-service.c
+++ b/src/datetime-service.c
@@ -82,6 +82,7 @@ static DbusmenuMenuitem * add_appointment = NULL;
 static GList			* appointments = NULL;
 static GList			* dconflocations = NULL;
 static GList			* comp_instances = NULL;
+static gboolean           updating_appointments = FALSE;
 GSettings *conf;
 
 
@@ -567,6 +568,8 @@ update_appointment_menu_items (gpointer user_data)
 	// tea timers, pomodoro timers etc... that people may add, this is hinted to in the spec.
 	if (calendar == NULL) return FALSE;
 	if (!g_settings_get_boolean(conf, SETTINGS_SHOW_EVENTS_S)) return FALSE;
+	if (updating_appointments) return TRUE;
+	updating_appointments = TRUE;
 	
 	time_t t1, t2;
 	gchar *ad;
@@ -640,10 +643,6 @@ update_appointment_menu_items (gpointer user_data)
 	comp_instances = NULL;
 	i = 0;
 	
-	gtk_icon_size_lookup(GTK_ICON_SIZE_MENU, &width, &height);
-	if (width == 0) width = 12;
-	if (height == 0) height = 12;
-	
 	for (l = sorted_comp_instances; l; l = l->next) {
 		struct comp_instance *ci = l->data;
 		ECalComponent *ecalcomp = ci->comp;
@@ -743,7 +742,12 @@ update_appointment_menu_items (gpointer user_data)
         if (color_spec != NULL) {
         	// Fixme causes segfault, but we have colours now yay!
         	GdkColor color;
-        	gdk_color_parse (color_spec, &color);			                                    
+        	gdk_color_parse (color_spec, &color);	
+        	
+			gtk_icon_size_lookup(GTK_ICON_SIZE_MENU, &width, &height);
+			if (width == 0) width = 12;
+			if (height == 0) height = 12;
+			                                    
         	cairo_surface_t *surface = cairo_image_surface_create( CAIRO_FORMAT_ARGB32, width, height ); 
     		 
     		cairo_t *cr = cairo_create(surface);
@@ -758,39 +762,39 @@ update_appointment_menu_items (gpointer user_data)
 			GdkPixbuf *pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, 
 			                                    !!(content & CAIRO_CONTENT_ALPHA), 
 			                                    8, width, height);
-			                                    
-    		gint sstride = cairo_image_surface_get_stride( surface ); 
-    		gint dstride = gdk_pixbuf_get_rowstride (pixbuf);
-    		guchar *spixels = cairo_image_surface_get_data( surface );
-    		guchar *dpixels = gdk_pixbuf_get_pixels (pixbuf);
-
-
-  			int x, y;
-  			for (y = 0; y < height; y++) {
-    			guint32 *src = (guint32 *) spixels;
-
-				for (x = 0; x < width; x++) {
-					guint alpha = src[x] >> 24;
-
-					if (alpha == 0) {
-          				dpixels[x * 4 + 0] = 0;
-          				dpixels[x * 4 + 1] = 0;
-          				dpixels[x * 4 + 2] = 0;
-        			} else {
-						dpixels[x * 4 + 0] = (((src[x] & 0xff0000) >> 16) * 255 + alpha / 2) / alpha;
-						dpixels[x * 4 + 1] = (((src[x] & 0x00ff00) >>  8) * 255 + alpha / 2) / alpha;
-						dpixels[x * 4 + 2] = (((src[x] & 0x0000ff) >>  0) * 255 + alpha / 2) / alpha;
+			if (pixbuf != NULL) {               
+				gint sstride = cairo_image_surface_get_stride( surface ); 
+				gint dstride = gdk_pixbuf_get_rowstride (pixbuf);
+				guchar *spixels = cairo_image_surface_get_data( surface );
+				guchar *dpixels = gdk_pixbuf_get_pixels (pixbuf);
+
+	  			int x, y;
+	  			for (y = 0; y < height; y++) {
+					guint32 *src = (guint32 *) spixels;
+
+					for (x = 0; x < width; x++) {
+						guint alpha = src[x] >> 24;
+
+						if (alpha == 0) {
+		      				dpixels[x * 4 + 0] = 0;
+		      				dpixels[x * 4 + 1] = 0;
+		      				dpixels[x * 4 + 2] = 0;
+		    			} else {
+							dpixels[x * 4 + 0] = (((src[x] & 0xff0000) >> 16) * 255 + alpha / 2) / alpha;
+							dpixels[x * 4 + 1] = (((src[x] & 0x00ff00) >>  8) * 255 + alpha / 2) / alpha;
+							dpixels[x * 4 + 2] = (((src[x] & 0x0000ff) >>  0) * 255 + alpha / 2) / alpha;
+						}
+						dpixels[x * 4 + 3] = alpha;
 					}
-					dpixels[x * 4 + 3] = alpha;
-				}
-    			spixels += sstride;
-    			dpixels += dstride;
-  			}
-
-			cairo_surface_destroy (surface);
-			cairo_destroy(cr);
+					spixels += sstride;
+					dpixels += dstride;
+	  			}
+
+				cairo_surface_destroy (surface);
+				cairo_destroy(cr);
 			
-			dbusmenu_menuitem_property_set_image (item, APPOINTMENT_MENUITEM_PROP_ICON, pixbuf);
+				dbusmenu_menuitem_property_set_image (item, APPOINTMENT_MENUITEM_PROP_ICON, pixbuf);
+			}
 		}
 		dbusmenu_menuitem_child_add_position (root, item, 2+i);
 		appointments = g_list_append         (appointments, item); // Keep track of the items here to make them east to remove
@@ -804,6 +808,7 @@ update_appointment_menu_items (gpointer user_data)
 		g_list_free(sorted_comp_instances);
 	}
 	
+	updating_appointments = FALSE;
 	g_debug("End of objects");
 	return TRUE;
 }
-- 
cgit v1.2.3


From 3aa4316f935bead55058441956d8b80e01146199 Mon Sep 17 00:00:00 2001
From: karl-qdh 
Date: Thu, 3 Mar 2011 14:59:17 +0000
Subject: Width appears to be repeatedly overwritten with zero

---
 src/datetime-service.c | 14 +++++++++-----
 1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/src/datetime-service.c b/src/datetime-service.c
index fd14af9..7b135a8 100644
--- a/src/datetime-service.c
+++ b/src/datetime-service.c
@@ -643,6 +643,9 @@ update_appointment_menu_items (gpointer user_data)
 	comp_instances = NULL;
 	i = 0;
 	
+	gtk_icon_size_lookup(GTK_ICON_SIZE_MENU, &width, &height);
+	if (width == 0) width = 12;
+	if (height == 0) height = 12;
 	for (l = sorted_comp_instances; l; l = l->next) {
 		struct comp_instance *ci = l->data;
 		ECalComponent *ecalcomp = ci->comp;
@@ -743,13 +746,11 @@ update_appointment_menu_items (gpointer user_data)
         	// Fixme causes segfault, but we have colours now yay!
         	GdkColor color;
         	gdk_color_parse (color_spec, &color);	
-        	
-			gtk_icon_size_lookup(GTK_ICON_SIZE_MENU, &width, &height);
-			if (width == 0) width = 12;
-			if (height == 0) height = 12;
 			                                    
         	cairo_surface_t *surface = cairo_image_surface_create( CAIRO_FORMAT_ARGB32, width, height ); 
-    		 
+			// Width keeps becoming zero!!
+			if (width == 0) width = 12;
+			if (height == 0) height = 12;
     		cairo_t *cr = cairo_create(surface);
 			gdk_cairo_set_source_color(cr, &color);
 			cairo_paint(cr);
@@ -759,6 +760,9 @@ update_appointment_menu_items (gpointer user_data)
     		cairo_stroke(cr);
 			// Convert to pixbuf, in gtk3 this is done with gdk_pixbuf_get_from_surface
 			cairo_content_t content = cairo_surface_get_content (surface) | CAIRO_CONTENT_COLOR;
+			// Width keeps becoming zero!!
+			if (width == 0) width = 12;
+			if (height == 0) height = 12;
 			GdkPixbuf *pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, 
 			                                    !!(content & CAIRO_CONTENT_ALPHA), 
 			                                    8, width, height);
-- 
cgit v1.2.3


From cd4699a975d0c019d0143d26cfaa0758af1e655f Mon Sep 17 00:00:00 2001
From: Ken VanDine 
Date: Thu, 3 Mar 2011 13:14:14 -0500
Subject: quit when the close putton is clicked

---
 src/datetime-prefs.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/datetime-prefs.c b/src/datetime-prefs.c
index cb38c24..5248911 100644
--- a/src/datetime-prefs.c
+++ b/src/datetime-prefs.c
@@ -678,6 +678,7 @@ main (int argc, char ** argv)
     unique_app_watch_window (app, GTK_WINDOW (dlg));
 
     gtk_widget_show_all (dlg);
+    g_signal_connect (dlg, "response", G_CALLBACK(gtk_main_quit), NULL);
     g_signal_connect (dlg, "destroy", G_CALLBACK(gtk_main_quit), NULL);
     gtk_main ();
   }
-- 
cgit v1.2.3


From 8a5b40e906646c1b3616855ed8b04f3e4283a604 Mon Sep 17 00:00:00 2001
From: Ted Gould 
Date: Thu, 3 Mar 2011 14:33:04 -0600
Subject: 0.1.96

---
 configure.ac | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/configure.ac b/configure.ac
index a762ea8..8764120 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,11 +1,11 @@
 
-AC_INIT(indicator-datetime, 0.1.95, ted@canonical.com)
+AC_INIT(indicator-datetime, 0.1.96, ted@canonical.com)
 AC_COPYRIGHT([Copyright 2009,2010 Canonical])
 
 AC_PREREQ(2.53)
 
 AM_CONFIG_HEADER(config.h)
-AM_INIT_AUTOMAKE(indicator-datetime, 0.1.95)
+AM_INIT_AUTOMAKE(indicator-datetime, 0.1.96)
 
 AM_MAINTAINER_MODE
 
-- 
cgit v1.2.3


From 96ca6cb8abee237021d36989d08b8ba8d49b7a4b Mon Sep 17 00:00:00 2001
From: Ted Gould 
Date: Thu, 3 Mar 2011 14:54:18 -0600
Subject: releasing version 0.1.96-0ubuntu1~ppa1

---
 debian/changelog | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/debian/changelog b/debian/changelog
index 29df0b5..da12f5e 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,11 +1,11 @@
-indicator-datetime (0.1.96-0ubuntu1~ppa1) UNRELEASED; urgency=low
+indicator-datetime (0.1.96-0ubuntu1~ppa1) natty; urgency=low
 
   * New upstream release.
     * Perference UI cleanups
     * Fix color rendering for appointments
     * Fix spin buttons to behave properly
 
- -- Ted Gould   Thu, 03 Mar 2011 14:48:38 -0600
+ -- Ted Gould   Thu, 03 Mar 2011 14:54:15 -0600
 
 indicator-datetime (0.1.95-0ubuntu1) natty; urgency=low
 
-- 
cgit v1.2.3