aboutsummaryrefslogtreecommitdiff
path: root/src/timezone-file.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/timezone-file.c')
-rw-r--r--src/timezone-file.c240
1 files changed, 240 insertions, 0 deletions
diff --git a/src/timezone-file.c b/src/timezone-file.c
new file mode 100644
index 0000000..2adf2ca
--- /dev/null
+++ b/src/timezone-file.c
@@ -0,0 +1,240 @@
+/*
+ * Copyright 2013 Canonical Ltd.
+ *
+ * Authors:
+ * Charles Kerr <charles.kerr@canonical.com>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include <gio/gio.h> /* GFile, GFileMonitor */
+
+#include "timezone-file.h"
+
+enum
+{
+ PROP_0,
+ PROP_FILENAME,
+ PROP_LAST
+};
+
+static GParamSpec * properties[PROP_LAST] = { 0 };
+
+struct _IndicatorDatetimeTimezoneFilePriv
+{
+ gchar * filename;
+ GFile * file;
+ GFileMonitor * monitor;
+ gchar * timezone;
+};
+
+typedef IndicatorDatetimeTimezoneFilePriv priv_t;
+
+G_DEFINE_TYPE (IndicatorDatetimeTimezoneFile,
+ indicator_datetime_timezone_file,
+ INDICATOR_TYPE_DATETIME_TIMEZONE)
+
+/***
+****
+***/
+
+static void
+reload (IndicatorDatetimeTimezoneFile * self)
+{
+ priv_t * p = self->priv;
+
+ GError * err = NULL;
+ gchar * new_timezone = NULL;
+
+ if (!g_file_get_contents (p->filename, &new_timezone, NULL, &err))
+ {
+ g_warning ("%s Unable to read timezone file '%s': %s", G_STRLOC, p->filename, err->message);
+ g_error_free (err);
+ }
+ else
+ {
+ g_strstrip (new_timezone);
+
+ if (g_strcmp0 (p->timezone, new_timezone))
+ {
+ g_free (p->timezone);
+ p->timezone = g_strdup (new_timezone);
+ g_debug ("%s new timezone set: '%s'", G_STRLOC, p->timezone);
+ indicator_datetime_timezone_notify_timezone (INDICATOR_DATETIME_TIMEZONE(self));
+ }
+
+ g_free (new_timezone);
+ }
+}
+
+static void
+set_filename (IndicatorDatetimeTimezoneFile * self, const char * filename)
+{
+ GError * err;
+ priv_t * p = self->priv;
+
+ g_clear_object (&p->monitor);
+ g_clear_object (&p->file);
+ g_free (p->filename);
+
+ p->filename = g_strdup (filename);
+ p->file = g_file_new_for_path (p->filename);
+
+ err = NULL;
+ p->monitor = g_file_monitor_file (p->file, G_FILE_MONITOR_NONE, NULL, &err);
+ if (err != NULL)
+ {
+ g_warning ("%s Unable to monitor timezone file '%s': %s", G_STRLOC, TIMEZONE_FILE, err->message);
+ g_error_free (err);
+ }
+ else
+ {
+ g_signal_connect_swapped (p->monitor, "changed", G_CALLBACK(reload), self);
+ g_debug ("%s Monitoring timezone file '%s'", G_STRLOC, p->filename);
+ }
+
+ reload (self);
+}
+
+/***
+**** IndicatorDatetimeTimezoneClass funcs
+***/
+
+static const char *
+my_get_timezone (IndicatorDatetimeTimezone * self)
+{
+ return INDICATOR_DATETIME_TIMEZONE_FILE(self)->priv->timezone;
+}
+
+/***
+**** GObjectClass funcs
+***/
+
+static void
+my_get_property (GObject * o,
+ guint property_id,
+ GValue * value,
+ GParamSpec * pspec)
+{
+ IndicatorDatetimeTimezoneFile * self = INDICATOR_DATETIME_TIMEZONE_FILE (o);
+
+ switch (property_id)
+ {
+ case PROP_FILENAME:
+ g_value_set_string (value, self->priv->filename);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (o, property_id, pspec);
+ }
+}
+
+static void
+my_set_property (GObject * o,
+ guint property_id,
+ const GValue * value,
+ GParamSpec * pspec)
+{
+ IndicatorDatetimeTimezoneFile * self = INDICATOR_DATETIME_TIMEZONE_FILE (o);
+
+ switch (property_id)
+ {
+ case PROP_FILENAME:
+ set_filename (self, g_value_get_string (value));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (o, property_id, pspec);
+ }
+}
+
+static void
+my_dispose (GObject * o)
+{
+ IndicatorDatetimeTimezoneFile * self = INDICATOR_DATETIME_TIMEZONE_FILE (o);
+ priv_t * p = self->priv;
+
+ g_clear_object (&p->monitor);
+ g_clear_object (&p->file);
+
+ G_OBJECT_CLASS (indicator_datetime_timezone_file_parent_class)->dispose (o);
+}
+
+static void
+my_finalize (GObject * o)
+{
+ IndicatorDatetimeTimezoneFile * self = INDICATOR_DATETIME_TIMEZONE_FILE (o);
+ priv_t * p = self->priv;
+
+ g_free (p->filename);
+ g_free (p->timezone);
+
+ G_OBJECT_CLASS (indicator_datetime_timezone_file_parent_class)->finalize (o);
+}
+
+/***
+****
+***/
+
+static void
+indicator_datetime_timezone_file_class_init (IndicatorDatetimeTimezoneFileClass * klass)
+{
+ GObjectClass * object_class;
+ IndicatorDatetimeTimezoneClass * location_class;
+ const GParamFlags flags = G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS;
+
+ object_class = G_OBJECT_CLASS (klass);
+ object_class->dispose = my_dispose;
+ object_class->finalize = my_finalize;
+ object_class->set_property = my_set_property;
+ object_class->get_property = my_get_property;
+
+ location_class = INDICATOR_DATETIME_TIMEZONE_CLASS (klass);
+ location_class->get_timezone = my_get_timezone;
+
+ g_type_class_add_private (klass, sizeof (IndicatorDatetimeTimezoneFilePriv));
+
+ /* install properties */
+
+ properties[PROP_0] = NULL;
+
+ properties[PROP_FILENAME] = g_param_spec_string ("filename",
+ "Filename",
+ "Filename to monitor for TZ changes",
+ "",
+ flags);
+
+ g_object_class_install_properties (object_class, PROP_LAST, properties);
+}
+
+static void
+indicator_datetime_timezone_file_init (IndicatorDatetimeTimezoneFile * self)
+{
+ self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
+ INDICATOR_TYPE_DATETIME_TIMEZONE_FILE,
+ IndicatorDatetimeTimezoneFilePriv);
+}
+
+/***
+**** Public
+***/
+
+IndicatorDatetimeTimezone *
+indicator_datetime_timezone_file_new (const char * filename)
+{
+ gpointer o = g_object_new (INDICATOR_TYPE_DATETIME_TIMEZONE_FILE, "filename", filename, NULL);
+
+ return INDICATOR_DATETIME_TIMEZONE (o);
+}