aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Terry <mike@mterry.name>2011-04-07 16:48:50 +0100
committerMichael Terry <mike@mterry.name>2011-04-07 16:48:50 +0100
commit20aee32a693b5fa78f1a3547351a9fb316534935 (patch)
treeca3d8550f19c7b05408ffd2dda2352e3fa3151e4
parentf62a2a6767eb177f261a6a5b0ddf18ce9482f6ba (diff)
downloadayatana-indicator-datetime-20aee32a693b5fa78f1a3547351a9fb316534935.tar.gz
ayatana-indicator-datetime-20aee32a693b5fa78f1a3547351a9fb316534935.tar.bz2
ayatana-indicator-datetime-20aee32a693b5fa78f1a3547351a9fb316534935.zip
when user clicks a timezone location, switch to that timezone (and support showing user's preferred name for the current timezone in the menu)
-rw-r--r--src/datetime-prefs.c40
-rw-r--r--src/datetime-service.c88
-rw-r--r--src/utils.c36
-rw-r--r--src/utils.h1
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);