diff options
Diffstat (limited to 'src/timezone-file.c')
-rw-r--r-- | src/timezone-file.c | 240 |
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); +} |