[gnome-desktop] Add GnomeWallClock



commit fb9ee91145db8904f1baf7c60fbbfaf36dd05e47
Author: Colin Walters <walters verbum org>
Date:   Thu Sep 1 11:53:23 2011 -0400

    Add GnomeWallClock
    
    Since clocks are a bit tricky, it's useful to centralize this class.
    See https://bugzilla.gnome.org/show_bug.cgi?id=655129
    See https://bugzilla.gnome.org/show_bug.cgi?id=657074
    
    https://bugzilla.gnome.org/show_bug.cgi?id=657955

 libgnome-desktop/Makefile.am            |    4 +-
 libgnome-desktop/gnome-wall-clock.c     |  239 +++++++++++++++++++++++++++++++
 libgnome-desktop/gnome-wall-clock.h     |   66 +++++++++
 libgnome-desktop/tests/test-wallclock.c |   36 +++++
 4 files changed, 344 insertions(+), 1 deletions(-)
---
diff --git a/libgnome-desktop/Makefile.am b/libgnome-desktop/Makefile.am
index 812421f..1e9525f 100644
--- a/libgnome-desktop/Makefile.am
+++ b/libgnome-desktop/Makefile.am
@@ -24,6 +24,7 @@ introspection_sources = 		\
 	gnome-rr-config.c		\
 	gnome-rr-output-info.c		\
 	gnome-rr-labeler.c		\
+	gnome-wall-clock.c		\
 	edid-parse.c
 
 libgnome_desktop_3_la_SOURCES = 	\
@@ -53,7 +54,8 @@ libgnome_desktop_HEADERS = \
         gnome-desktop-thumbnail.h       \
         gnome-rr.h                      \
         gnome-rr-config.h               \
-        gnome-rr-labeler.h
+        gnome-rr-labeler.h		\
+        gnome-wall-clock.h
 
 if USE_INTERNAL_PNP_IDS
 pnpdatadir = $(datadir)/libgnome-desktop-3.0
diff --git a/libgnome-desktop/gnome-wall-clock.c b/libgnome-desktop/gnome-wall-clock.c
new file mode 100644
index 0000000..2989b8c
--- /dev/null
+++ b/libgnome-desktop/gnome-wall-clock.c
@@ -0,0 +1,239 @@
+/* -*- mode: C; c-file-style: "linux"; indent-tabs-mode: t -*-
+ * gnome-wall-clock.h - monitors TZ setting files and signals changes
+ *
+ * Copyright (C) 2010 Red Hat, Inc.
+ * Copyright (C) 2011 Red Hat, Inc.
+ *
+ * This program 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 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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: Colin Walters <walters verbum org>
+ */
+
+#include "config.h"
+
+#include <glib/gi18n-lib.h>
+
+#define GNOME_DESKTOP_USE_UNSTABLE_API
+#include "gnome-wall-clock.h"
+#include <gdesktop-enums.h>
+
+struct _GnomeWallClockPrivate {
+	guint clock_update_id;
+	
+	char *clock_string;
+	
+	GFileMonitor *tz_monitor;
+	GSettings    *desktop_settings;
+};
+
+enum {
+	PROP_0,
+	PROP_CLOCK
+};
+
+G_DEFINE_TYPE (GnomeWallClock, gnome_wall_clock, G_TYPE_OBJECT);
+
+static gboolean update_clock (gpointer data);
+static void on_schema_change (GSettings *schema,
+                              const char *key,
+                              gpointer user_data);
+static void on_tz_changed (GFileMonitor *monitor,
+                           GFile        *file,
+                           GFile        *other_file,
+                           GFileMonitorEvent *event,
+                           gpointer      user_data);
+
+
+static void
+gnome_wall_clock_init (GnomeWallClock *self)
+{
+	GFile *tz;
+
+	self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GNOME_TYPE_WALL_CLOCK, GnomeWallClockPrivate);
+	
+	self->priv->clock_string = NULL;
+	
+	tz = g_file_new_for_path ("/etc/localtime");
+	self->priv->tz_monitor = g_file_monitor_file (tz, 0, NULL, NULL);
+	g_object_unref (tz);
+	
+	g_signal_connect (self->priv->tz_monitor, "changed", G_CALLBACK(on_tz_changed), self);
+	
+	self->priv->desktop_settings = g_settings_new ("org.gnome.desktop.interface");
+	g_signal_connect (self->priv->desktop_settings, "changed", G_CALLBACK(on_schema_change), self);
+
+	update_clock (self);
+}
+
+static void
+gnome_wall_clock_dispose (GObject *object)
+{
+	GnomeWallClock *self = GNOME_WALL_CLOCK (object);
+
+	if (self->priv->tz_monitor != NULL) {
+		g_object_unref (self->priv->tz_monitor);
+		self->priv->tz_monitor = NULL;
+	}
+
+	if (self->priv->desktop_settings != NULL) {
+		g_object_unref (self->priv->desktop_settings);
+		self->priv->desktop_settings = NULL;
+	}
+
+	G_OBJECT_CLASS(gnome_wall_clock_parent_class)->dispose (object);
+}
+
+static void
+gnome_wall_clock_finalize (GObject *object)
+{
+	GnomeWallClock *self = GNOME_WALL_CLOCK (object);
+
+	g_free (self->priv->clock_string);
+
+	G_OBJECT_CLASS(gnome_wall_clock_parent_class)->finalize (object);
+}
+
+static void
+gnome_wall_clock_get_property (GObject    *gobject,
+			       guint       prop_id,
+			       GValue     *value,
+			       GParamSpec *pspec)
+{
+	GnomeWallClock *self = GNOME_WALL_CLOCK (gobject);
+
+	switch (prop_id)
+	{
+	case PROP_CLOCK:
+		g_value_set_string (value, self->priv->clock_string);
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
+		break;
+	}
+}
+
+static void
+gnome_wall_clock_class_init (GnomeWallClockClass *klass)
+{
+	GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+	gobject_class->get_property = gnome_wall_clock_get_property;
+	gobject_class->dispose = gnome_wall_clock_dispose;
+	gobject_class->finalize = gnome_wall_clock_finalize;
+
+	/**
+	 * GnomeWallClock:clock:
+	 *
+	 * A formatted string representing the current clock display.
+	 */
+	g_object_class_install_property (gobject_class,
+					 PROP_CLOCK,
+					 g_param_spec_string ("clock",
+							      "",
+							      "",
+							      NULL,
+							      G_PARAM_READABLE));
+
+
+	g_type_class_add_private (gobject_class, sizeof (GnomeWallClockPrivate));
+}
+
+static gboolean
+update_clock (gpointer data)
+{
+	GnomeWallClock   *self = data;
+	GDesktopClockFormat clock_format;
+	const char *format_string;
+	gboolean show_date;
+	gboolean show_seconds;
+	GSource *source;
+	GDateTime *now;
+	GDateTime *expiry;
+  
+	now = g_date_time_new_now_local ();
+	expiry = g_date_time_add_seconds (now, 60 - g_date_time_get_second (now));
+  
+	if (self->priv->clock_update_id)
+		g_source_remove (self->priv->clock_update_id);
+  
+	source = g_timeout_source_new_seconds (1);
+	g_source_set_priority (source, G_PRIORITY_HIGH);
+	g_source_set_callback (source, update_clock, self, NULL);
+	self->priv->clock_update_id = g_source_attach (source, NULL);
+	g_source_unref (source);
+
+	clock_format = g_settings_get_enum (self->priv->desktop_settings, "clock-format");
+	show_date = g_settings_get_boolean (self->priv->desktop_settings, "clock-show-date");
+	show_seconds = g_settings_get_boolean (self->priv->desktop_settings, "clock-show-seconds");
+
+	if (clock_format == G_DESKTOP_CLOCK_FORMAT_24H) {
+		if (show_date)
+			/* Translators: This is the time format with date used
+			   in 24-hour mode. */
+			format_string = show_seconds ? _("%a %b %e, %R:%S")
+				: _("%a %b %e, %R");
+		else
+			/* Translators: This is the time format without date used
+			   in 24-hour mode. */
+			format_string = show_seconds ? _("%a %R:%S")
+				: _("%a %R");
+	} else {
+		if (show_date)
+			/* Translators: This is a time format with date used
+			   for AM/PM. */
+			format_string = show_seconds ? _("%a %b %e, %l:%M:%S %p")
+				: _("%a %b %e, %l:%M %p");
+		else
+			/* Translators: This is a time format without date used
+			   for AM/PM. */
+			format_string = show_seconds ? _("%a %l:%M:%S %p")
+				: _("%a %l:%M %p");
+	}
+
+	g_free (self->priv->clock_string);
+	self->priv->clock_string = g_date_time_format (now, format_string);
+
+	g_date_time_unref (now);
+	g_date_time_unref (expiry);
+      
+	g_object_notify ((GObject*)self, "clock");
+
+	return FALSE;
+}
+
+static void
+on_schema_change (GSettings *schema,
+                  const char *key,
+                  gpointer user_data)
+{
+	update_clock (user_data);
+}
+
+static void
+on_tz_changed (GFileMonitor      *monitor,
+               GFile             *file,
+               GFile             *other_file,
+               GFileMonitorEvent *event,
+               gpointer           user_data)
+{
+	update_clock (user_data);
+}
+
+const char *
+gnome_wall_clock_get_clock (GnomeWallClock *clock)
+{
+	return clock->priv->clock_string;
+}
diff --git a/libgnome-desktop/gnome-wall-clock.h b/libgnome-desktop/gnome-wall-clock.h
new file mode 100644
index 0000000..3d54a45
--- /dev/null
+++ b/libgnome-desktop/gnome-wall-clock.h
@@ -0,0 +1,66 @@
+/* gnome-tz-monitor.h - fade window background between two surfaces
+
+   Copyright 2008, Red Hat, Inc.
+   Copyright 2011, Red Hat, Inc.
+
+   This file is part of the Gnome Library.
+
+   The Gnome 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.
+
+   The Gnome 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 the Gnome Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.
+
+   Author: Colin Walters <walters verbum org>
+*/
+
+#ifndef __GNOME_WALL_CLOCK_H__
+#define __GNOME_WALL_CLOCK_H__
+
+#ifndef GNOME_DESKTOP_USE_UNSTABLE_API
+#error    This is unstable API. You must define GNOME_DESKTOP_USE_UNSTABLE_API before including gnome-wall-clock.h
+#endif
+
+#include <gio/gio.h>
+
+G_BEGIN_DECLS
+
+#define GNOME_TYPE_WALL_CLOCK            (gnome_wall_clock_get_type ())
+#define GNOME_WALL_CLOCK(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GNOME_TYPE_WALL_CLOCK, GnomeWallClock))
+#define GNOME_WALL_CLOCK_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass),  GNOME_TYPE_WALL_CLOCK, GnomeWallClockClass))
+#define GNOME_IS_WALL_CLOCK(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GNOME_TYPE_WALL_CLOCK))
+#define GNOME_IS_WALL_CLOCK_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),  GNOME_TYPE_WALL_CLOCK))
+#define GNOME_WALL_CLOCK_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj),  GNOME_TYPE_WALL_CLOCK, GnomeWallClockClass))
+
+typedef struct _GnomeWallClockPrivate GnomeWallClockPrivate;
+typedef struct _GnomeWallClock GnomeWallClock;
+typedef struct _GnomeWallClockClass GnomeWallClockClass;
+
+struct _GnomeWallClock
+{
+	GObject parent_object;
+
+	GnomeWallClockPrivate *priv;
+};
+
+struct _GnomeWallClockClass
+{
+	GObjectClass parent_class;
+};
+
+GType             gnome_wall_clock_get_type      (void);
+
+const char *      gnome_wall_clock_get_clock     (GnomeWallClock *clock);
+
+G_END_DECLS
+
+#endif
diff --git a/libgnome-desktop/tests/test-wallclock.c b/libgnome-desktop/tests/test-wallclock.c
new file mode 100644
index 0000000..2e0c089
--- /dev/null
+++ b/libgnome-desktop/tests/test-wallclock.c
@@ -0,0 +1,36 @@
+#define GNOME_DESKTOP_USE_UNSTABLE_API
+#include <libgnome-desktop/gnome-wall-clock.h>
+
+static void
+update_clock (GnomeWallClock *clock)
+{
+  g_print ("%s\n", gnome_wall_clock_get_clock (clock));
+}
+
+static void
+on_clock_changed (GnomeWallClock *clock,
+		  GParamSpec     *pspec,
+		  gpointer        user_data)
+{
+  update_clock (clock);
+}
+
+int
+main (int    argc,
+      char **argv)
+{
+  GnomeWallClock *clock;
+  GMainLoop *loop;
+
+  g_type_init ();
+  
+  loop = g_main_loop_new (NULL, TRUE);
+  
+  clock = g_object_new (GNOME_TYPE_WALL_CLOCK, NULL);
+  g_signal_connect (clock, "notify::clock", G_CALLBACK (on_clock_changed), NULL);
+  update_clock (clock);
+
+  g_main_loop_run (loop);
+
+  return 0;
+}



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