diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile.am | 4 | ||||
-rw-r--r-- | src/datetime-service.c | 216 | ||||
-rw-r--r-- | src/indicator-datetime.c | 51 | ||||
-rw-r--r-- | src/location-geoclue.c | 261 | ||||
-rw-r--r-- | src/location-geoclue.h | 61 | ||||
-rw-r--r-- | src/location.c | 108 | ||||
-rw-r--r-- | src/location.h | 68 |
7 files changed, 567 insertions, 202 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index a31cb4b..f9b8562 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -11,6 +11,10 @@ indicator_datetime_service_SOURCES = \ datetime-interface.h \ gen-datetime-service.xml.c \ datetime-service.c \ + location.c \ + location.h \ + location-geoclue.c \ + location-geoclue.h \ utils.c \ utils.h \ dbus-shared.h \ diff --git a/src/datetime-service.c b/src/datetime-service.c index 6f3cf7b..52d9647 100644 --- a/src/datetime-service.c +++ b/src/datetime-service.c @@ -35,9 +35,6 @@ with this program. If not, see <http://www.gnu.org/licenses/>. #include <libdbusmenu-glib/client.h> #include <libdbusmenu-glib/menuitem.h> -#include <geoclue/geoclue-master.h> -#include <geoclue/geoclue-master-client.h> - #include <time.h> #include <libecal/libecal.h> #include <libical/ical.h> @@ -48,6 +45,7 @@ with this program. If not, see <http://www.gnu.org/licenses/>. #include "datetime-interface.h" #include "dbus-shared.h" +#include "location-geoclue.h" #include "settings-shared.h" #include "utils.h" @@ -92,11 +90,11 @@ static time_t start_time_appointments = (time_t) 0; static GSettings * conf = NULL; static ESourceRegistry * source_registry = NULL; static GList * appointment_sources = NULL; +static IndicatorDatetimeLocation * geo_location = NULL; /* Our 2 important timezones */ static gchar * current_timezone = NULL; -static gchar * geo_timezone = NULL; struct comp_instance { ECalComponent *comp; @@ -187,11 +185,14 @@ update_location_menu_items (void) const time_t now = time(NULL); /* maybe add geo_timezone */ - if (geo_timezone != NULL) { - const gboolean visible = g_settings_get_boolean (conf, SETTINGS_SHOW_DETECTED_S); - gchar * name = get_current_zone_name (geo_timezone); - locations = locations_add (locations, geo_timezone, name, visible, now); - g_free (name); + if (geo_location != NULL) { + const char * geo_timezone = indicator_datetime_location_get_timezone (geo_location); + if (geo_timezone && *geo_timezone) { + const gboolean visible = g_settings_get_boolean (conf, SETTINGS_SHOW_DETECTED_S); + gchar * name = get_current_zone_name (geo_timezone); + locations = locations_add (locations, geo_timezone, name, visible, now); + g_free (name); + } } /* maybe add current_timezone */ @@ -1182,174 +1183,6 @@ system_proxy_cb (GObject * object, GAsyncResult * res, gpointer user_data) g_signal_connect(proxy, "g-signal", G_CALLBACK(session_active_change_cb), user_data); } - -/**** -***** GEOCLUE -****/ - -static void geo_start (void); -static void geo_stop (void); -static void geo_create_client (GeoclueMaster * master, GeoclueMasterClient * client, gchar * path, GError * error, gpointer user_data); -static void geo_client_invalid (GeoclueMasterClient * client, gpointer user_data); - -static GeoclueMaster * geo_master = NULL; -static GeoclueMasterClient * geo_client = NULL; -static GeoclueAddress * geo_address = NULL; - -static void -geo_set_timezone (const gchar * timezone) -{ - if (geo_timezone != timezone) { - g_clear_pointer (&geo_timezone, g_free); - geo_timezone = g_strdup (timezone); - g_debug("Geoclue timezone is: %s", timezone ? timezone : "(Null)"); - update_location_menu_items(); - } -} - -/* Callback from getting the address */ -static void -geo_address_cb (GeoclueAddress * address, int timestamp, GHashTable * addy_data, GeoclueAccuracy * accuracy, GError * error, gpointer user_data) -{ - if (error == NULL) { - geo_set_timezone (g_hash_table_lookup (addy_data, "timezone")); - } else { - g_warning("Unable to get Geoclue address: %s", error->message); - g_clear_error (&error); - } -} - -/* Clean up the reference we kept to the address and make sure to - drop the signals incase someone else has one. */ -static void -geo_address_clean (void) -{ - if (geo_address != NULL) { - g_signal_handlers_disconnect_by_func (geo_address, geo_address_cb, NULL); - g_clear_object (&geo_address); - } -} - -/* Clean up and remove all signal handlers from the client as we - unreference it as well. */ -static void -geo_client_clean (void) -{ - if (geo_client != NULL) { - g_signal_handlers_disconnect_by_func (geo_client, geo_client_invalid, NULL); - g_clear_object (&geo_client); - } -} - -/* Callback from creating the address */ -static void -geo_create_address (GeoclueMasterClient * master, GeoclueAddress * address, GError * error, gpointer user_data) -{ - if (error != NULL) { - g_warning("Unable to create GeoClue address: %s", error->message); - g_clear_error (&error); - return; - } - - /* We shouldn't have created a new address if we already had one - so this is a warning. But, it really is only a mem-leak so we - don't need to error out. */ - g_warn_if_fail(geo_address == NULL); - geo_address_clean(); - - g_debug("Created Geoclue Address"); - geo_address = g_object_ref (address); - - geoclue_address_get_address_async (geo_address, geo_address_cb, NULL); - - g_signal_connect (address, "address-changed", G_CALLBACK(geo_address_cb), NULL); -} - -/* Callback from setting requirements */ -static void -geo_req_set (GeoclueMasterClient * master, GError * error, gpointer user_data) -{ - if (error != NULL) { - g_warning("Unable to set Geoclue requirements: %s", error->message); - g_clear_error (&error); - } -} - -/* Client is killing itself rather oddly */ -static void -geo_client_invalid (GeoclueMasterClient * client, gpointer user_data) -{ - g_warning("Master client invalid, rebuilding."); - geo_stop (); - geo_start (); -} - -static void -geo_stop (void) -{ - geo_set_timezone (NULL); - - geo_address_clean (); - geo_client_clean (); - g_clear_object (&geo_master); -} - -static void -geo_start (void) -{ - g_warn_if_fail (geo_master == NULL); - - g_clear_object (&geo_master); - geo_master = geoclue_master_get_default(); - geoclue_master_create_client_async (geo_master, geo_create_client, NULL); -} - -/* Callback from creating the client */ -static void -geo_create_client (GeoclueMaster * master, GeoclueMasterClient * client, gchar * path, GError * error, gpointer user_data) -{ - g_debug("Created Geoclue client at: %s", path); - - geo_client = client; - - if (error != NULL) { - g_warning("Unable to get a GeoClue client! '%s' Geolocation based timezone support will not be available.", error->message); - g_clear_error (&error); - return; - } - - if (client == NULL) { - g_warning(_("Unable to get a GeoClue client! Geolocation based timezone support will not be available.")); - return; - } - - g_object_ref (geo_client); - - /* New client, make sure we don't have an address hanging on */ - geo_address_clean(); - - geoclue_master_client_set_requirements_async(geo_client, - GEOCLUE_ACCURACY_LEVEL_REGION, - 0, - FALSE, - GEOCLUE_RESOURCE_ALL, - geo_req_set, - NULL); - - geoclue_master_client_create_address_async(geo_client, geo_create_address, NULL); - - g_signal_connect(client, "invalidated", G_CALLBACK(geo_client_invalid), NULL); -} - -static void -on_use_geoclue_changed_cb (GSettings * settings, gchar * key, gpointer unused G_GNUC_UNUSED) -{ - geo_stop (); - - if (g_settings_get_boolean (conf, SETTINGS_SHOW_DETECTED_S)) - geo_start (); -} - /**** ***** ****/ @@ -1417,10 +1250,34 @@ source_registry_changed_cb (ESourceRegistry *registry __attribute__ ((unused)), update_appointment_menu_items (user_data); } +static void +on_use_geoclue_changed_cb (GSettings *settings, + gchar *key G_GNUC_UNUSED, + gpointer user_data G_GNUC_UNUSED) +{ + const gboolean using = geo_location != NULL; + const gboolean should_use = g_settings_get_boolean (conf, "show-auto-detected-location"); + + if (using && !should_use) + { + g_signal_handlers_disconnect_by_func (geo_location, update_location_menu_items, 0); + g_clear_object (&geo_location); + update_location_menu_items (); + } + else if (should_use && !using) + { + geo_location = indicator_datetime_location_geoclue_new (); + g_signal_connect (geo_location, "notify::timezone", + G_CALLBACK(update_location_menu_items), NULL); + } +} + /* Function to build everything up. Entry point from asm. */ int main (int argc, char ** argv) { + gtk_init (&argc, &argv); + /* Acknowledging the service init and setting up the interface */ service = indicator_service_new_version(SERVICE_NAME, SERVICE_VERSION); g_signal_connect(service, INDICATOR_SERVICE_SIGNAL_SHUTDOWN, G_CALLBACK(service_shutdown), NULL); @@ -1461,8 +1318,7 @@ main (int argc, char ** argv) update_current_timezone(); /* Setup geoclue */ - if (g_settings_get_boolean (conf, SETTINGS_SHOW_DETECTED_S)) - geo_start (); + on_use_geoclue_changed_cb (conf, NULL, NULL); /* Setup dbus interface */ dbus = g_object_new(DATETIME_INTERFACE_TYPE, NULL); @@ -1501,7 +1357,7 @@ main (int argc, char ** argv) icaltimezone_free_builtin_timezones(); - geo_stop (); + g_clear_object (&geo_location); return 0; } diff --git a/src/indicator-datetime.c b/src/indicator-datetime.c index 9546664..f7d1a78 100644 --- a/src/indicator-datetime.c +++ b/src/indicator-datetime.c @@ -266,28 +266,35 @@ indicator_datetime_class_init (IndicatorDatetimeClass *klass) } static void -menu_visible_notfy_cb(GtkWidget * menu, G_GNUC_UNUSED GParamSpec *pspec, gpointer user_data) +menu_visible_notify_cb(GtkWidget * menu, G_GNUC_UNUSED GParamSpec *pspec, gpointer user_data) { - GtkWidget * w; - GtkCalendar * calendar; - IndicatorDatetime * self = INDICATOR_DATETIME(user_data); - GDateTime *datetime; - gint cur_y, cur_m, cur_d; - guint cal_y, cal_m, cal_d; - - g_debug("notify visible signal received"); - - /* set the calendar to today's date */ - datetime = g_date_time_new_now_local (); - g_date_time_get_ymd (datetime, &cur_y, &cur_m, &cur_d); - g_date_time_unref (datetime); - w = ido_calendar_menu_item_get_calendar (self->priv->ido_calendar); - calendar = GTK_CALENDAR(w); - gtk_calendar_get_date (calendar, &cal_y, &cal_m, &cal_d); - if ((cur_y != cal_y) || (cur_m-1 != cal_m)) - gtk_calendar_select_month (calendar, cur_m-1, cur_y); /* (cur_m is 1-based) */ - if (cur_d != cal_d) - gtk_calendar_select_day (calendar, cur_d); + IndicatorDatetime * self; + g_debug ("notify visible signal received"); + + self = INDICATOR_DATETIME (user_data); + g_assert (self != NULL); + + /* if the calendar widget's been created, set it to today's datë */ + if (self->priv->ido_calendar != NULL) { + GtkWidget * w; + GtkCalendar * calendar; + gint cur_y, cur_m, cur_d; + guint cal_y, cal_m, cal_d; + GDateTime * datetime = g_date_time_new_now_local (); + + g_date_time_get_ymd (datetime, &cur_y, &cur_m, &cur_d); + w = ido_calendar_menu_item_get_calendar (self->priv->ido_calendar); + calendar = GTK_CALENDAR(w); + g_return_if_fail (calendar != NULL); + + gtk_calendar_get_date (calendar, &cal_y, &cal_m, &cal_d); + if ((cur_y != cal_y) || (cur_m-1 != cal_m)) + gtk_calendar_select_month (calendar, cur_m-1, cur_y); /* (cur_m is 1-based) */ + if (cur_d != cal_d) + gtk_calendar_select_day (calendar, cur_d); + + g_date_time_unref (datetime); + } /* Update in case date was changed outside of indicator-datetime */ update_label(self, NULL); @@ -380,7 +387,7 @@ indicator_datetime_init (IndicatorDatetime *self) self->priv->menu = dbusmenu_gtkmenu_new(SERVICE_NAME, MENU_OBJ); - g_signal_connect(self->priv->menu, "notify::visible", G_CALLBACK(menu_visible_notfy_cb), self); + g_signal_connect(self->priv->menu, "notify::visible", G_CALLBACK(menu_visible_notify_cb), self); DbusmenuGtkClient *client = dbusmenu_gtkmenu_get_client(self->priv->menu); dbusmenu_client_add_type_handler_full(DBUSMENU_CLIENT(client), DBUSMENU_CALENDAR_MENUITEM_TYPE, new_calendar_item, self, NULL); diff --git a/src/location-geoclue.c b/src/location-geoclue.c new file mode 100644 index 0000000..2e57f39 --- /dev/null +++ b/src/location-geoclue.c @@ -0,0 +1,261 @@ +/* + * 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 <glib.h> +#include <glib/gi18n-lib.h> + +#include <geoclue/geoclue-master.h> +#include <geoclue/geoclue-master-client.h> + +#include "location-geoclue.h" + +struct _IndicatorDatetimeLocationGeocluePriv +{ + GeoclueMaster * master; + GeoclueMasterClient * client; + GeoclueAddress * address; + gchar * timezone; +}; + +typedef IndicatorDatetimeLocationGeocluePriv priv_t; + +G_DEFINE_TYPE (IndicatorDatetimeLocationGeoclue, + indicator_datetime_location_geoclue, + INDICATOR_TYPE_DATETIME_LOCATION) + +static void geo_restart (IndicatorDatetimeLocationGeoclue * self); + +/*** +**** +***/ + +static void +set_timezone (IndicatorDatetimeLocationGeoclue * self, const gchar * timezone) +{ + priv_t * p = self->priv; + + if (p->timezone != timezone) + { + g_free (p->timezone); + p->timezone = g_strdup (timezone); + indicator_datetime_location_notify_timezone (INDICATOR_DATETIME_LOCATION(self)); + } +} + +static void +on_address_changed (GeoclueAddress * address, + int timestamp, + GHashTable * addy_data, + GeoclueAccuracy * accuracy, + GError * error, + gpointer gself) +{ + if (error != NULL) + { + g_warning ("%s Unable to get timezone from GeoClue: %s", G_STRFUNC, error->message); + g_error_free (error); + } + else + { + IndicatorDatetimeLocationGeoclue * self = INDICATOR_DATETIME_LOCATION_GEOCLUE (gself); + const char * timezone = g_hash_table_lookup (addy_data, "timezone"); + set_timezone (self, timezone); + } +} + +static void +on_address_created (GeoclueMasterClient * master, + GeoclueAddress * address, + GError * error, + gpointer gself) +{ + if (error != NULL) + { + g_warning ("%s Unable to get timezone from GeoClue: %s", G_STRFUNC, error->message); + g_error_free (error); + } + else + { + priv_t * p = INDICATOR_DATETIME_LOCATION_GEOCLUE(gself)->priv; + + g_assert (p->address == NULL); + p->address = g_object_ref (address); + + geoclue_address_get_address_async (address, on_address_changed, gself); + g_signal_connect (address, "address-changed", G_CALLBACK(on_address_changed), gself); + } +} + +static void +on_requirements_set (GeoclueMasterClient * master, GError * error, gpointer user_data) +{ + if (error != NULL) + { + g_warning ("%s Unable to get timezone from GeoClue: %s", G_STRFUNC, error->message); + g_error_free (error); + } +} + +static void +on_client_created (GeoclueMaster * master, + GeoclueMasterClient * client, + gchar * path, + GError * error, + gpointer gself) +{ + g_debug ("Created Geoclue client at: %s", path); + + if (error != NULL) + { + g_warning ("%s Unable to get timezone from GeoClue: %s", G_STRFUNC, error->message); + g_error_free (error); + } + else if (client == NULL) + { + g_warning ("%s Unable to get timezone from GeoClue: %s", G_STRFUNC, error->message); + } + else + { + IndicatorDatetimeLocationGeoclue * self = INDICATOR_DATETIME_LOCATION_GEOCLUE (gself); + priv_t * p = self->priv; + + g_clear_object (&p->client); + p->client = g_object_ref (client); + g_signal_connect_swapped (p->client, "invalidated", G_CALLBACK(geo_restart), gself); + + geoclue_master_client_set_requirements_async (p->client, + GEOCLUE_ACCURACY_LEVEL_REGION, + 0, + FALSE, + GEOCLUE_RESOURCE_ALL, + on_requirements_set, + NULL); + + geoclue_master_client_create_address_async (p->client, on_address_created, gself); + } +} + +static void +geo_start (IndicatorDatetimeLocationGeoclue * self) +{ + priv_t * p = self->priv; + + g_assert (p->master == NULL); + p->master = geoclue_master_get_default (); + geoclue_master_create_client_async (p->master, on_client_created, self); +} + +static void +geo_stop (IndicatorDatetimeLocationGeoclue * self) +{ + priv_t * p = self->priv; + + if (p->address != NULL) + { + g_signal_handlers_disconnect_by_func (p->address, on_address_changed, self); + g_clear_object (&p->address); + } + + if (p->client != NULL) + { + g_signal_handlers_disconnect_by_func (p->client, geo_restart, self); + g_clear_object (&p->client); + } + + g_clear_object (&p->master); +} + +static void +geo_restart (IndicatorDatetimeLocationGeoclue * self) +{ + geo_stop (self); + geo_start (self); +} + +/*** +**** +***/ + +static const char * +my_get_timezone (IndicatorDatetimeLocation * self) +{ + return INDICATOR_DATETIME_LOCATION_GEOCLUE(self)->priv->timezone; +} + +static void +my_dispose (GObject * o) +{ + geo_stop (INDICATOR_DATETIME_LOCATION_GEOCLUE (o)); + + G_OBJECT_CLASS (indicator_datetime_location_geoclue_parent_class)->dispose (o); +} + +static void +my_finalize (GObject * o) +{ + IndicatorDatetimeLocationGeoclue * self = INDICATOR_DATETIME_LOCATION_GEOCLUE (o); + priv_t * p = self->priv; + + g_free (p->timezone); + + G_OBJECT_CLASS (indicator_datetime_location_geoclue_parent_class)->finalize (o); +} + +static void +indicator_datetime_location_geoclue_class_init (IndicatorDatetimeLocationGeoclueClass * klass) +{ + GObjectClass * object_class; + IndicatorDatetimeLocationClass * location_class; + + object_class = G_OBJECT_CLASS (klass); + object_class->dispose = my_dispose; + object_class->finalize = my_finalize; + + location_class = INDICATOR_DATETIME_LOCATION_CLASS (klass); + location_class->get_timezone = my_get_timezone; + + g_type_class_add_private (klass, sizeof (IndicatorDatetimeLocationGeocluePriv)); +} + +static void +indicator_datetime_location_geoclue_init (IndicatorDatetimeLocationGeoclue * self) +{ + priv_t * p; + + p = G_TYPE_INSTANCE_GET_PRIVATE (self, + INDICATOR_TYPE_DATETIME_LOCATION_GEOCLUE, + IndicatorDatetimeLocationGeocluePriv); + self->priv = p; + + geo_start (self); +} + +/*** +**** Public +***/ + +IndicatorDatetimeLocation * +indicator_datetime_location_geoclue_new (void) +{ + gpointer o = g_object_new (INDICATOR_TYPE_DATETIME_LOCATION_GEOCLUE, NULL); + + return INDICATOR_DATETIME_LOCATION (o); +} diff --git a/src/location-geoclue.h b/src/location-geoclue.h new file mode 100644 index 0000000..7b65917 --- /dev/null +++ b/src/location-geoclue.h @@ -0,0 +1,61 @@ +/* + * 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/>. + */ + +#ifndef __INDICATOR_DATETIME_LOCATION_GEOCLUE__H__ +#define __INDICATOR_DATETIME_LOCATION_GEOCLUE__H__ + +#include <glib.h> +#include <glib-object.h> + +#include "location.h" /* parent class */ + +G_BEGIN_DECLS + +#define INDICATOR_TYPE_DATETIME_LOCATION_GEOCLUE (indicator_datetime_location_geoclue_get_type()) +#define INDICATOR_DATETIME_LOCATION_GEOCLUE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), INDICATOR_TYPE_DATETIME_LOCATION_GEOCLUE, IndicatorDatetimeLocationGeoclue)) +#define INDICATOR_DATETIME_LOCATION_GEOCLUE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), INDICATOR_TYPE_DATETIME_LOCATION_GEOCLUE, IndicatorDatetimeLocationGeoclueClass)) +#define INDICATOR_IS_DATETIME_LOCATION_GEOCLUE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), INDICATOR_TYPE_DATETIME_LOCATION_GEOCLUE)) + +typedef struct _IndicatorDatetimeLocationGeoclue IndicatorDatetimeLocationGeoclue; +typedef struct _IndicatorDatetimeLocationGeocluePriv IndicatorDatetimeLocationGeocluePriv; +typedef struct _IndicatorDatetimeLocationGeoclueClass IndicatorDatetimeLocationGeoclueClass; + +GType indicator_datetime_location_geoclue_get_type (void); + +/** + * An implementation of IndicatorDatetimeLocation that gets its user information + * from org.freedesktop.ConsoleKit and org.freedesktop.Accounts over DBus. + */ +struct _IndicatorDatetimeLocationGeoclue +{ + /*< private >*/ + IndicatorDatetimeLocation parent; + IndicatorDatetimeLocationGeocluePriv * priv; +}; + +struct _IndicatorDatetimeLocationGeoclueClass +{ + IndicatorDatetimeLocationClass parent_class; +}; + +IndicatorDatetimeLocation * indicator_datetime_location_geoclue_new (void); + +G_END_DECLS + +#endif /* __INDICATOR_DATETIME_LOCATION_GEOCLUE__H__ */ diff --git a/src/location.c b/src/location.c new file mode 100644 index 0000000..12e25c3 --- /dev/null +++ b/src/location.c @@ -0,0 +1,108 @@ +/* + * 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 "location.h" + +G_DEFINE_TYPE (IndicatorDatetimeLocation, + indicator_datetime_location, + G_TYPE_OBJECT) + +enum +{ + PROP_0, + PROP_TIMEZONE, + PROP_LAST +}; + +static GParamSpec * properties[PROP_LAST] = { 0 }; + +static void +my_get_property (GObject * o, + guint property_id, + GValue * value, + GParamSpec * pspec) +{ + IndicatorDatetimeLocation * self = INDICATOR_DATETIME_LOCATION (o); + + switch (property_id) + { + case PROP_TIMEZONE: + g_value_set_string (value, indicator_datetime_location_get_timezone (self)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (o, property_id, pspec); + } +} + +static void +my_dispose (GObject * object) +{ + G_OBJECT_CLASS (indicator_datetime_location_parent_class)->dispose (object); +} + +static void +/* cppcheck-suppress unusedFunction */ +indicator_datetime_location_class_init (IndicatorDatetimeLocationClass * klass) +{ + GObjectClass * object_class; + const GParamFlags flags = G_PARAM_READABLE | G_PARAM_STATIC_STRINGS; + + object_class = G_OBJECT_CLASS (klass); + object_class->get_property = my_get_property; + object_class->dispose = my_dispose; + + klass->get_timezone = NULL; + + properties[PROP_0] = NULL; + + properties[PROP_TIMEZONE] = g_param_spec_string ("timezone", + "Timezone", + "Timezone", + "", + flags); + + g_object_class_install_properties (object_class, PROP_LAST, properties); +} + +static void +indicator_datetime_location_init (IndicatorDatetimeLocation * self G_GNUC_UNUSED) +{ +} + +/*** +**** +***/ + +const char * +indicator_datetime_location_get_timezone (IndicatorDatetimeLocation * self) +{ + g_return_val_if_fail (INDICATOR_IS_DATETIME_LOCATION (self), NULL); + + return INDICATOR_DATETIME_LOCATION_GET_CLASS (self)->get_timezone (self); +} + +void +indicator_datetime_location_notify_timezone (IndicatorDatetimeLocation * self) +{ + g_return_if_fail (INDICATOR_IS_DATETIME_LOCATION (self)); + + g_object_notify_by_pspec (G_OBJECT(self), properties[PROP_TIMEZONE]); +} + diff --git a/src/location.h b/src/location.h new file mode 100644 index 0000000..f9fd2ce --- /dev/null +++ b/src/location.h @@ -0,0 +1,68 @@ +/* + * 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/>. + */ + +#ifndef __INDICATOR_DATETIME_LOCATION__H__ +#define __INDICATOR_DATETIME_LOCATION__H__ + +#include <glib.h> +#include <glib-object.h> + +G_BEGIN_DECLS + +#define INDICATOR_TYPE_DATETIME_LOCATION (indicator_datetime_location_get_type()) +#define INDICATOR_DATETIME_LOCATION(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), INDICATOR_TYPE_DATETIME_LOCATION, IndicatorDatetimeLocation)) +#define INDICATOR_DATETIME_LOCATION_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), INDICATOR_TYPE_DATETIME_LOCATION, IndicatorDatetimeLocationClass)) +#define INDICATOR_DATETIME_LOCATION_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), INDICATOR_TYPE_DATETIME_LOCATION, IndicatorDatetimeLocationClass)) +#define INDICATOR_IS_DATETIME_LOCATION(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), INDICATOR_TYPE_DATETIME_LOCATION)) + +typedef struct _IndicatorDatetimeLocation IndicatorDatetimeLocation; +typedef struct _IndicatorDatetimeLocationClass IndicatorDatetimeLocationClass; + +GType indicator_datetime_location_get_type (void); + +/** + * Abstract Base Class for the mechanisms that determine timezone by location + */ +struct _IndicatorDatetimeLocation +{ + /*< private >*/ + GObject parent; +}; + +struct _IndicatorDatetimeLocationClass +{ + GObjectClass parent_class; + + /* virtual functions */ + const char * (*get_timezone) (IndicatorDatetimeLocation * self); +}; + +/*** +**** +***/ + +#define INDICATOR_DATETIME_LOCATION_PROPERTY_TIMEZONE "timezone" + +const char * indicator_datetime_location_get_timezone (IndicatorDatetimeLocation *); + +void indicator_datetime_location_notify_timezone (IndicatorDatetimeLocation *); + +G_END_DECLS + +#endif /* __INDICATOR_DATETIME_LOCATION__H__ */ |