[gnome-settings-daemon] datetime: Display notifications on timezone changes



commit 37ea00039cf5b8704e90d6c741d6072203eb0709
Author: Kalev Lember <kalevlember gmail com>
Date:   Sat Aug 31 20:02:24 2013 +0200

    datetime: Display notifications on timezone changes
    
    Also, bump glib dependency to 2.37.7 for new %z format modifiers.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=707191

 configure.ac                            |    2 +-
 plugins/datetime/gsd-datetime-manager.c |  109 +++++++++++++++++++++++++++++++
 plugins/datetime/gsd-timezone-monitor.c |   32 ++++++++-
 plugins/datetime/gsd-timezone-monitor.h |    2 +
 4 files changed, 140 insertions(+), 5 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 77d45e0..22ac242 100644
--- a/configure.ac
+++ b/configure.ac
@@ -43,7 +43,7 @@ dnl ---------------------------------------------------------------------------
 dnl - Dependencies
 dnl ---------------------------------------------------------------------------
 
-GLIB_REQUIRED_VERSION=2.35.3
+GLIB_REQUIRED_VERSION=2.37.7
 GIO_REQUIRED_VERSION=${GLIB_REQUIRED_VERSION}
 GTK_REQUIRED_VERSION=3.7.8
 GCONF_REQUIRED_VERSION=2.6.1
diff --git a/plugins/datetime/gsd-datetime-manager.c b/plugins/datetime/gsd-datetime-manager.c
index e08203b..e4ff830 100644
--- a/plugins/datetime/gsd-datetime-manager.c
+++ b/plugins/datetime/gsd-datetime-manager.c
@@ -21,6 +21,8 @@
 #include "config.h"
 
 #include <gio/gio.h>
+#include <glib/gi18n.h>
+#include <libnotify/notify.h>
 
 #include "gsd-datetime-manager.h"
 #include "gsd-timezone-monitor.h"
@@ -35,6 +37,7 @@ struct GsdDatetimeManagerPrivate
 {
         GSettings *settings;
         GsdTimezoneMonitor *timezone_monitor;
+        NotifyNotification *notification;
 };
 
 static void gsd_datetime_manager_class_init (GsdDatetimeManagerClass *klass);
@@ -45,6 +48,102 @@ G_DEFINE_TYPE (GsdDatetimeManager, gsd_datetime_manager, G_TYPE_OBJECT)
 
 static gpointer manager_object = NULL;
 
+static gboolean
+notification_server_has_actions (void)
+{
+        GList *caps;
+        gboolean has_actions = FALSE;
+
+        caps = notify_get_server_caps ();
+        if (g_list_find_custom (caps, "actions", (GCompareFunc)g_strcmp0) != NULL)
+                has_actions = TRUE;
+        g_list_free_full (caps, g_free);
+
+        return has_actions;
+}
+
+static void
+notification_closed_cb (NotifyNotification *n,
+                        GsdDatetimeManager *self)
+{
+        g_clear_object (&self->priv->notification);
+}
+
+static void
+open_settings_cb (NotifyNotification *n,
+                  const char         *action,
+                  const char         *path)
+{
+        const gchar *argv[] = { "gnome-control-center", "datetime", NULL };
+
+        g_debug ("Running gnome-control-center datetime");
+        g_spawn_async (NULL, (gchar **) argv, NULL, G_SPAWN_SEARCH_PATH,
+                       NULL, NULL, NULL, NULL);
+
+        notify_notification_close (n, NULL);
+}
+
+static void
+timezone_changed_cb (GsdTimezoneMonitor *timezone_monitor,
+                     const gchar        *timezone_id,
+                     GsdDatetimeManager *self)
+{
+        GDateTime *datetime;
+        GTimeZone *tz;
+        gchar *control_center;
+        gchar *notification_summary;
+        gchar *timezone_name;
+        gchar *utc_offset;
+
+        tz = g_time_zone_new (timezone_id);
+        datetime = g_date_time_new_now (tz);
+        g_time_zone_unref (tz);
+
+        /* Translators: UTC here means the Coordinated Universal Time.
+         * %:::z will be replaced by the offset from UTC e.g. UTC+02 */
+        utc_offset = g_date_time_format (datetime, _("UTC%:::z"));
+        timezone_name = g_strdup (g_date_time_get_timezone_abbreviation (datetime));
+        g_date_time_unref (datetime);
+
+        notification_summary = g_strdup_printf (_("Time Zone Updated to %s (%s)"),
+                                                timezone_name,
+                                                utc_offset);
+        g_free (timezone_name);
+        g_free (utc_offset);
+
+        if (self->priv->notification == NULL) {
+                self->priv->notification = notify_notification_new (notification_summary, NULL,
+                                                                    "preferences-system-time-symbolic");
+                g_signal_connect (self->priv->notification,
+                                  "closed",
+                                  G_CALLBACK (notification_closed_cb),
+                                  self);
+        } else {
+                notify_notification_update (self->priv->notification,
+                                            notification_summary, NULL,
+                                            "preferences-system-time-symbolic");
+        }
+        g_free (notification_summary);
+
+        notify_notification_set_app_name (self->priv->notification, _("Date & Time Settings"));
+        notify_notification_set_urgency (self->priv->notification, NOTIFY_URGENCY_NORMAL);
+        notify_notification_set_timeout (self->priv->notification, NOTIFY_EXPIRES_NEVER);
+
+        control_center = g_find_program_in_path ("gnome-control-center");
+        if (control_center != NULL && notification_server_has_actions ()) {
+                notify_notification_add_action (self->priv->notification,
+                                                "settings",
+                                                _("Settings"),
+                                                (NotifyActionCallback) open_settings_cb,
+                                                NULL, NULL);
+        }
+        g_free (control_center);
+
+        if (!notify_notification_show (self->priv->notification, NULL)) {
+                g_warning ("Failed to send timezone notification");
+        }
+}
+
 static void
 auto_timezone_settings_changed_cb (GSettings          *settings,
                                    const char         *key,
@@ -56,6 +155,9 @@ auto_timezone_settings_changed_cb (GSettings          *settings,
         if (enabled && self->priv->timezone_monitor == NULL) {
                 g_debug ("Automatic timezone enabled");
                 self->priv->timezone_monitor = gsd_timezone_monitor_new ();
+
+                g_signal_connect (self->priv->timezone_monitor, "timezone-changed",
+                                  G_CALLBACK (timezone_changed_cb), self);
         } else {
                 g_debug ("Automatic timezone disabled");
                 g_clear_object (&self->priv->timezone_monitor);
@@ -87,6 +189,13 @@ gsd_datetime_manager_stop (GsdDatetimeManager *self)
 
         g_clear_object (&self->priv->settings);
         g_clear_object (&self->priv->timezone_monitor);
+
+        if (self->priv->notification != NULL) {
+                g_signal_handlers_disconnect_by_func (self->priv->notification,
+                                                      G_CALLBACK (notification_closed_cb),
+                                                      self);
+                g_clear_object (&self->priv->notification);
+        }
 }
 
 static GObject *
diff --git a/plugins/datetime/gsd-timezone-monitor.c b/plugins/datetime/gsd-timezone-monitor.c
index 73a88ae..1a4f7bf 100644
--- a/plugins/datetime/gsd-timezone-monitor.c
+++ b/plugins/datetime/gsd-timezone-monitor.c
@@ -31,6 +31,13 @@
 
 #define SET_TIMEZONE_PERMISSION "org.freedesktop.timedate1.set-timezone"
 
+enum {
+        TIMEZONE_CHANGED,
+        LAST_SIGNAL
+};
+
+static int signals[LAST_SIGNAL] = { 0 };
+
 typedef struct
 {
         GCancellable *cancellable;
@@ -59,17 +66,21 @@ set_timezone_cb (GObject      *source,
                                                  &error)) {
                 g_warning ("Could not set system timezone: %s", error->message);
                 g_error_free (error);
+                return;
         }
+
+        g_signal_emit (G_OBJECT (self),
+                       signals[TIMEZONE_CHANGED],
+                       0, priv->current_timezone);
 }
 
 static void
-queue_set_timezone (GsdTimezoneMonitor *self,
-                    const char *timezone)
+queue_set_timezone (GsdTimezoneMonitor *self)
 {
         GsdTimezoneMonitorPrivate *priv = gsd_timezone_monitor_get_instance_private (self);
 
         timedate1_call_set_timezone (priv->dtm,
-                                     timezone,
+                                     priv->current_timezone,
                                      TRUE,
                                      priv->cancellable,
                                      set_timezone_cb,
@@ -125,6 +136,8 @@ process_location (GsdTimezoneMonitor *self,
         TzLocation *closest_tz_location;
         gint i;
 
+        g_return_if_fail (priv->current_timezone != NULL);
+
         array = tz_get_locations (priv->tzdb);
 
         for (i = 0; i < array->len; i++) {
@@ -140,7 +153,9 @@ process_location (GsdTimezoneMonitor *self,
         closest_tz_location = (TzLocation*) distances->data;
         if (g_strcmp0 (priv->current_timezone, closest_tz_location->zone) != 0) {
                 g_debug ("Changing timezone to %s", closest_tz_location->zone);
-                queue_set_timezone (self, closest_tz_location->zone);
+                g_free (priv->current_timezone);
+                priv->current_timezone = g_strdup (closest_tz_location->zone);
+                queue_set_timezone (self);
         }
 
         g_list_free (distances);
@@ -330,6 +345,15 @@ gsd_timezone_monitor_class_init (GsdTimezoneMonitorClass *klass)
         GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
         object_class->finalize = gsd_timezone_monitor_finalize;
+
+        signals[TIMEZONE_CHANGED] =
+                g_signal_new ("timezone-changed",
+                              G_TYPE_FROM_CLASS (klass),
+                              G_SIGNAL_RUN_LAST,
+                              G_STRUCT_OFFSET (GsdTimezoneMonitorClass, timezone_changed),
+                              NULL, NULL,
+                              NULL,
+                              G_TYPE_NONE, 1, G_TYPE_POINTER);
 }
 
 static void
diff --git a/plugins/datetime/gsd-timezone-monitor.h b/plugins/datetime/gsd-timezone-monitor.h
index d3aa3b3..4b4c580 100644
--- a/plugins/datetime/gsd-timezone-monitor.h
+++ b/plugins/datetime/gsd-timezone-monitor.h
@@ -43,6 +43,8 @@ struct _GsdTimezoneMonitor
 struct _GsdTimezoneMonitorClass
 {
        GObjectClass parent_class;
+
+       void (*timezone_changed) (GsdTimezoneMonitor *monitor, gchar *timezone_id);
 };
 
 GType gsd_timezone_monitor_get_type (void) G_GNUC_CONST;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]