From 20aee32a693b5fa78f1a3547351a9fb316534935 Mon Sep 17 00:00:00 2001 From: Michael Terry Date: Thu, 7 Apr 2011 16:48:50 +0100 Subject: when user clicks a timezone location, switch to that timezone (and support showing user's preferred name for the current timezone in the menu) --- src/datetime-prefs.c | 40 ++--------------------- src/datetime-service.c | 88 ++++++++++++++++++++++++++++++++++++++++++++++---- src/utils.c | 36 +++++++++++++++++++++ src/utils.h | 1 + 4 files changed, 121 insertions(+), 44 deletions(-) diff --git a/src/datetime-prefs.c b/src/datetime-prefs.c index 4a32fd6..9b00e60 100644 --- a/src/datetime-prefs.c +++ b/src/datetime-prefs.c @@ -181,46 +181,10 @@ ntp_query_answered (GObject *object, GAsyncResult *res, gpointer user_data) g_variant_unref (answers); } -static gchar * -get_zone_name (const gchar * location) -{ - gchar * new_zone, * new_name; - gchar * old_zone, * old_name; - gchar * rv; - - split_settings_location (location, &new_zone, &new_name); - - GSettings * conf = g_settings_new (SETTINGS_INTERFACE); - gchar * tz_name = g_settings_get_string (conf, SETTINGS_TIMEZONE_NAME_S); - split_settings_location (tz_name, &old_zone, &old_name); - g_free (tz_name); - g_object_unref (conf); - - // new_name is always just a sanitized version of a timezone. - // old_name is potentially a saved "pretty" version of a timezone name from - // geonames. So we prefer to use it if available and the zones match. - - if (g_strcmp0 (old_zone, new_zone) == 0) { - rv = old_name; - old_name = NULL; - } - else { - rv = new_name; - new_name = NULL; - } - - g_free (new_zone); - g_free (old_zone); - g_free (new_name); - g_free (old_name); - - return rv; -} - static void sync_entry (const gchar * location) { - gchar * name = get_zone_name (location); + gchar * name = get_current_zone_name (location); gtk_entry_set_text (GTK_ENTRY (tz_entry), name); g_free (name); @@ -606,7 +570,7 @@ entry_focus_out (GtkEntry * entry, GdkEventFocus * event) if (location == NULL) return FALSE; - gchar * name = get_zone_name (location->zone); + gchar * name = get_current_zone_name (location->zone); gboolean correct = (g_strcmp0 (gtk_entry_get_text (entry), name) == 0); g_free (name); diff --git a/src/datetime-service.c b/src/datetime-service.c index 5e8d312..df37b5e 100644 --- a/src/datetime-service.c +++ b/src/datetime-service.c @@ -114,6 +114,17 @@ set_timezone_label (DbusmenuMenuitem * mi, const gchar * location) g_free (name); } +static void +set_current_timezone_label (DbusmenuMenuitem * mi, const gchar * location) +{ + gchar * name = get_current_zone_name (location); + + dbusmenu_menuitem_property_set (mi, TIMEZONE_MENUITEM_PROP_NAME, name); + dbusmenu_menuitem_property_set (mi, TIMEZONE_MENUITEM_PROP_ZONE, location); + + g_free (name); +} + /* Check to see if our timezones are the same */ static void check_timezone_sync (void) { @@ -168,7 +179,7 @@ check_timezone_sync (void) { if (label != NULL) { // TODO work out the current location name in a nice way - set_timezone_label (current_location, label); + set_current_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); @@ -177,18 +188,18 @@ check_timezone_sync (void) { } if (geo_timezone != NULL) { // TODO work out the geo location name in a nice way - set_timezone_label (geo_location, geo_timezone); + set_current_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 - set_timezone_label (geo_location, geo_timezone); + set_current_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 - set_timezone_label (current_location, current_timezone); + set_current_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); @@ -236,6 +247,69 @@ update_current_timezone (void) { return; } +static void +quick_set_tz_cb (GObject *object, GAsyncResult *res, gpointer data) +{ + GError * error = NULL; + GVariant * answers = g_dbus_proxy_call_finish (G_DBUS_PROXY (object), res, &error); + + if (error != NULL) { + g_warning("Could not set timezone for SettingsDaemon: %s", error->message); + g_error_free(error); + return; + } + + g_variant_unref (answers); +} + +static void +quick_set_tz_proxy_cb (GObject *object, GAsyncResult *res, gpointer zone) +{ + GError * error = NULL; + + GDBusProxy * proxy = g_dbus_proxy_new_for_bus_finish (res, &error); + + if (error != NULL) { + g_warning("Could not grab DBus proxy for SettingsDaemon: %s", error->message); + g_error_free(error); + g_free (zone); + return; + } + + gchar * file = g_build_filename ("/usr/share/zoneinfo", (char *)zone, NULL); + g_dbus_proxy_call (proxy, "SetTimezone", g_variant_new ("(s)", file), + G_DBUS_CALL_FLAGS_NONE, -1, NULL, quick_set_tz_cb, NULL); + g_free (file); + g_free (zone); + g_object_unref (proxy); +} + +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); + + const gchar * name = dbusmenu_menuitem_property_get(menuitem, TIMEZONE_MENUITEM_PROP_NAME); + + /* Set it in gsettings so we don't lose user's preferred name */ + GSettings * conf = g_settings_new (SETTINGS_INTERFACE); + gchar * tz_full = g_strdup_printf ("%s %s", tz, name); + g_settings_set_string (conf, SETTINGS_TIMEZONE_NAME_S, tz_full); + g_free (tz_full); + g_object_unref (conf); + + 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, quick_set_tz_proxy_cb, g_strdup (tz)); + + return; +} + /* Updates the label in the date menuitem */ static gboolean update_datetime (gpointer user_data) @@ -543,6 +617,7 @@ update_timezone_menu_items(gpointer user_data) { 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); } } @@ -1048,14 +1123,15 @@ build_menus (DbusmenuMenuitem * root) geo_location = dbusmenu_menuitem_new(); dbusmenu_menuitem_property_set (geo_location, DBUSMENU_MENUITEM_PROP_TYPE, TIMEZONE_MENUITEM_TYPE); - set_timezone_label (geo_location, ""); + set_current_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); - set_timezone_label (current_location, ""); + set_current_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); dbusmenu_menuitem_child_append(root, current_location); diff --git a/src/utils.c b/src/utils.c index d8851aa..ab93ecf 100644 --- a/src/utils.c +++ b/src/utils.c @@ -81,6 +81,42 @@ split_settings_location (const gchar * location, gchar ** zone, gchar ** name) } } +gchar * +get_current_zone_name (const gchar * location) +{ + gchar * new_zone, * new_name; + gchar * old_zone, * old_name; + gchar * rv; + + split_settings_location (location, &new_zone, &new_name); + + GSettings * conf = g_settings_new (SETTINGS_INTERFACE); + gchar * tz_name = g_settings_get_string (conf, SETTINGS_TIMEZONE_NAME_S); + split_settings_location (tz_name, &old_zone, &old_name); + g_free (tz_name); + g_object_unref (conf); + + // new_name is always just a sanitized version of a timezone. + // old_name is potentially a saved "pretty" version of a timezone name from + // geonames. So we prefer to use it if available and the zones match. + + if (g_strcmp0 (old_zone, new_zone) == 0) { + rv = old_name; + old_name = NULL; + } + else { + rv = new_name; + new_name = NULL; + } + + g_free (new_zone); + g_free (old_zone); + g_free (new_name); + g_free (old_name); + + return rv; +} + /* Translate msg according to the locale specified by LC_TIME */ static char * T_(const char *msg) diff --git a/src/utils.h b/src/utils.h index 5f7842c..c2bc0c5 100644 --- a/src/utils.h +++ b/src/utils.h @@ -29,6 +29,7 @@ G_BEGIN_DECLS gboolean is_locale_12h (void); void split_settings_location (const gchar * location, gchar ** zone, gchar ** name); +gchar * get_current_zone_name (const gchar * location); gchar * generate_format_string_full (gboolean show_day, gboolean show_date); gchar * generate_format_string_at_time (GDateTime * time); -- cgit v1.2.3