The Date and Time Indicator

Merge lp:~ted/indicator-datetime/geoclue-timezone-support into lp:indicator-datetime/0.3

Proposed by Ted Gould on 2010-10-22
Status: Merged
Merged at revision: 25
Proposed branch: lp:~ted/indicator-datetime/geoclue-timezone-support
Merge into: lp:indicator-datetime/0.3
Diff against target: 349 lines (+266/-1) 2 files modified
To merge this branch: bzr merge lp:~ted/indicator-datetime/geoclue-timezone-support
Reviewer Review Type Date Requested Status
Cody Russell (community) 2010-10-22 Approve on 2010-10-23
Review via email: mp+39144@code.launchpad.net

Description of the Change

Add support for looking for timezones in GeoClue

To post a comment you must log in.
Cody Russell (bratsche) wrote :

Wicked.

review: Approve

Preview Diff

1=== modified file 'configure.ac'
2--- configure.ac 2010-09-09 17:43:03 +0000
3+++ configure.ac 2010-10-22 13:41:00 +0000
4@@ -38,12 +38,16 @@
5 GIO_REQUIRED_VERSION=2.25.11
6 # Note: the GIO check below also ensures the proper glib with gsettings support is present
7 INDICATOR_DISPLAY_OBJECTS=0.1.10
8+GEOCLUE_REQUIRED_VERSION=0.12.0
9+OOBS_REQUIRED_VERSION=2.31.0
10
11 PKG_CHECK_MODULES(INDICATOR, indicator >= $INDICATOR_REQUIRED_VERSION
12 dbusmenu-glib >= $DBUSMENUGLIB_REQUIRED_VERSION
13 dbusmenu-gtk >= $DBUSMENUGTK_REQUIRED_VERSION
14 libido-0.1 >= $INDICATOR_DISPLAY_OBJECTS
15- gio-2.0 >= $GIO_REQUIRED_VERSION)
16+ gio-2.0 >= $GIO_REQUIRED_VERSION
17+ geoclue >= $GEOCLUE_REQUIRED_VERSION
18+ liboobs-1 >= $OOBS_REQUIRED_VERSION)
19
20 AC_SUBST(INDICATOR_CFLAGS)
21 AC_SUBST(INDICATOR_LIBS)
22
23=== modified file 'src/datetime-service.c'
24--- src/datetime-service.c 2010-10-06 13:28:50 +0000
25+++ src/datetime-service.c 2010-10-22 13:41:00 +0000
26@@ -30,9 +30,15 @@
27 #include <libdbusmenu-glib/client.h>
28 #include <libdbusmenu-glib/menuitem.h>
29
30+#include <geoclue/geoclue-master.h>
31+#include <geoclue/geoclue-master-client.h>
32+
33+#include <oobs/oobs-timeconfig.h>
34+
35 #include "datetime-interface.h"
36 #include "dbus-shared.h"
37
38+static void geo_create_client (GeoclueMaster * master, GeoclueMasterClient * client, gchar * path, GError * error, gpointer user_data);
39 static void setup_timer (void);
40
41 static IndicatorService * service = NULL;
42@@ -40,11 +46,122 @@
43 static DbusmenuServer * server = NULL;
44 static DbusmenuMenuitem * root = NULL;
45 static DatetimeInterface * dbus = NULL;
46+static gchar * current_timezone = NULL;
47
48 /* Global Items */
49 static DbusmenuMenuitem * date = NULL;
50 static DbusmenuMenuitem * calendar = NULL;
51 static DbusmenuMenuitem * settings = NULL;
52+static DbusmenuMenuitem * tzchange = NULL;
53+
54+/* Geoclue trackers */
55+static GeoclueMasterClient * geo_master = NULL;
56+static GeoclueAddress * geo_address = NULL;
57+static gchar * geo_timezone = NULL;
58+
59+/* Check to see if our timezones are the same */
60+static void
61+check_timezone_sync (void) {
62+ gboolean in_sync = FALSE;
63+
64+ if (geo_timezone == NULL) {
65+ in_sync = TRUE;
66+ }
67+
68+ if (current_timezone == NULL) {
69+ in_sync = TRUE;
70+ }
71+
72+ if (!in_sync && g_strcmp0(geo_timezone, current_timezone) == 0) {
73+ in_sync = TRUE;
74+ }
75+
76+ if (in_sync) {
77+ g_debug("Timezones in sync");
78+ } else {
79+ g_debug("Timezones are different");
80+ }
81+
82+ if (tzchange != NULL) {
83+ if (in_sync) {
84+ dbusmenu_menuitem_property_set_bool(tzchange, DBUSMENU_MENUITEM_PROP_VISIBLE, FALSE);
85+ } else {
86+ gchar * label = g_strdup_printf(_("Change timezone to: %s"), geo_timezone);
87+
88+ dbusmenu_menuitem_property_set(tzchange, DBUSMENU_MENUITEM_PROP_LABEL, label);
89+ dbusmenu_menuitem_property_set_bool(tzchange, DBUSMENU_MENUITEM_PROP_VISIBLE, TRUE);
90+
91+ g_free(label);
92+ }
93+ }
94+
95+ return;
96+}
97+
98+/* Update the current timezone */
99+static void
100+update_current_timezone (void) {
101+ /* Clear old data */
102+ if (current_timezone != NULL) {
103+ g_free(current_timezone);
104+ current_timezone = NULL;
105+ }
106+
107+ GError * error = NULL;
108+ gchar * tempzone = NULL;
109+ if (!g_file_get_contents(TIMEZONE_FILE, &tempzone, NULL, &error)) {
110+ g_warning("Unable to read timezone file '" TIMEZONE_FILE "': %s", error->message);
111+ g_error_free(error);
112+ return;
113+ }
114+
115+ /* This shouldn't happen, so let's make it a big boom! */
116+ g_return_if_fail(tempzone != NULL);
117+
118+ /* Note: this really makes sense as strstrip works in place
119+ so we end up with something a little odd without the dup
120+ so we have the dup to make sure everything is as expected
121+ for everyone else. */
122+ current_timezone = g_strdup(g_strstrip(tempzone));
123+ g_free(tempzone);
124+
125+ g_debug("System timezone is: %s", current_timezone);
126+
127+ check_timezone_sync();
128+
129+ return;
130+}
131+
132+/* See how our timezone setting went */
133+static void
134+quick_set_tz_cb (OobsObject * obj, OobsResult result, gpointer user_data)
135+{
136+ if (result == OOBS_RESULT_OK) {
137+ g_debug("Timezone set");
138+ } else {
139+ g_warning("Unable to quick set timezone");
140+ }
141+ return;
142+}
143+
144+/* Set the timezone to the Geoclue discovered one */
145+static void
146+quick_set_tz (DbusmenuMenuitem * menuitem, guint timestamp, const gchar *command)
147+{
148+ g_debug("Quick setting timezone to: %s", geo_timezone);
149+
150+ g_return_if_fail(geo_timezone != NULL);
151+
152+ OobsObject * obj = oobs_time_config_get();
153+ g_return_if_fail(obj != NULL);
154+
155+ OobsTimeConfig * timeconfig = OOBS_TIME_CONFIG(obj);
156+ oobs_time_config_set_timezone(timeconfig, geo_timezone);
157+
158+ oobs_object_commit_async(obj, quick_set_tz_cb, NULL);
159+
160+ return;
161+}
162
163 /* Updates the label in the date menuitem */
164 static gboolean
165@@ -160,6 +277,13 @@
166 dbusmenu_menuitem_property_set(separator, DBUSMENU_MENUITEM_PROP_TYPE, DBUSMENU_CLIENT_TYPES_SEPARATOR);
167 dbusmenu_menuitem_child_append(root, separator);
168
169+ tzchange = dbusmenu_menuitem_new();
170+ dbusmenu_menuitem_property_set(tzchange, DBUSMENU_MENUITEM_PROP_LABEL, "Set specific timezone");
171+ dbusmenu_menuitem_property_set_bool(tzchange, DBUSMENU_MENUITEM_PROP_VISIBLE, FALSE);
172+ g_signal_connect(G_OBJECT(tzchange), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(quick_set_tz), NULL);
173+ dbusmenu_menuitem_child_append(root, tzchange);
174+ check_timezone_sync();
175+
176 settings = dbusmenu_menuitem_new();
177 dbusmenu_menuitem_property_set (settings, DBUSMENU_MENUITEM_PROP_LABEL, _("Time & Date Settings..."));
178 /* insensitive until we check for available apps */
179@@ -175,6 +299,7 @@
180 static void
181 timezone_changed (GFileMonitor * monitor, GFile * file, GFile * otherfile, GFileMonitorEvent event, gpointer user_data)
182 {
183+ update_current_timezone();
184 datetime_interface_update(DATETIME_INTERFACE(user_data));
185 update_datetime(NULL);
186 setup_timer();
187@@ -233,6 +358,134 @@
188 return;
189 }
190
191+/* Callback from getting the address */
192+static void
193+geo_address_cb (GeoclueAddress * address, int timestamp, GHashTable * addy_data, GeoclueAccuracy * accuracy, GError * error, gpointer user_data)
194+{
195+ if (error != NULL) {
196+ g_warning("Unable to get Geoclue address: %s", error->message);
197+ return;
198+ }
199+
200+ g_debug("Geoclue timezone is: %s", (gchar *)g_hash_table_lookup(addy_data, "timezone"));
201+
202+ if (geo_timezone != NULL) {
203+ g_free(geo_timezone);
204+ geo_timezone = NULL;
205+ }
206+
207+ gpointer tz_hash = g_hash_table_lookup(addy_data, "timezone");
208+ if (tz_hash != NULL) {
209+ geo_timezone = g_strdup((gchar *)tz_hash);
210+ }
211+
212+ check_timezone_sync();
213+
214+ return;
215+}
216+
217+/* Callback from creating the address */
218+static void
219+geo_create_address (GeoclueMasterClient * master, GeoclueAddress * address, GError * error, gpointer user_data)
220+{
221+ if (error != NULL) {
222+ g_warning("Unable to create GeoClue address: %s", error->message);
223+ return;
224+ }
225+
226+ g_debug("Created Geoclue Address");
227+ geo_address = address;
228+ g_object_ref(G_OBJECT(geo_address));
229+
230+ geoclue_address_get_address_async(geo_address, geo_address_cb, NULL);
231+
232+ g_signal_connect(G_OBJECT(address), "address-changed", G_CALLBACK(geo_address_cb), NULL);
233+
234+ return;
235+}
236+
237+/* Callback from setting requirements */
238+static void
239+geo_req_set (GeoclueMasterClient * master, GError * error, gpointer user_data)
240+{
241+ if (error != NULL) {
242+ g_warning("Unable to set Geoclue requirements: %s", error->message);
243+ }
244+ return;
245+}
246+
247+/* Client is killing itself rather oddly */
248+static void
249+geo_client_invalid (GeoclueMasterClient * client, gpointer user_data)
250+{
251+ g_warning("Master client invalid, rebuilding.");
252+
253+ if (geo_master != NULL) {
254+ g_object_unref(G_OBJECT(geo_master));
255+ }
256+ geo_master = NULL;
257+
258+ GeoclueMaster * master = geoclue_master_get_default();
259+ geoclue_master_create_client_async(master, geo_create_client, NULL);
260+
261+ if (geo_timezone != NULL) {
262+ g_free(geo_timezone);
263+ geo_timezone = NULL;
264+ }
265+
266+ check_timezone_sync();
267+
268+ return;
269+}
270+
271+/* Address provider changed, we need to get that one */
272+static void
273+geo_address_change (GeoclueMasterClient * client, gchar * a, gchar * b, gchar * c, gchar * d, gpointer user_data)
274+{
275+ g_warning("Address provider changed. Let's change");
276+
277+ if (geo_address != NULL) {
278+ g_object_unref(G_OBJECT(geo_address));
279+ }
280+ geo_address = NULL;
281+
282+ geoclue_master_client_create_address_async(geo_master, geo_create_address, NULL);
283+
284+ if (geo_timezone != NULL) {
285+ g_free(geo_timezone);
286+ geo_timezone = NULL;
287+ }
288+
289+ check_timezone_sync();
290+
291+ return;
292+}
293+
294+/* Callback from creating the client */
295+static void
296+geo_create_client (GeoclueMaster * master, GeoclueMasterClient * client, gchar * path, GError * error, gpointer user_data)
297+{
298+ g_debug("Created Geoclue client at: %s", path);
299+
300+ geo_master = client;
301+ g_object_ref(G_OBJECT(geo_master));
302+
303+ geoclue_master_client_set_requirements_async(geo_master,
304+ GEOCLUE_ACCURACY_LEVEL_REGION,
305+ 0,
306+ FALSE,
307+ GEOCLUE_RESOURCE_ALL,
308+ geo_req_set,
309+ NULL);
310+
311+ geoclue_master_client_create_address_async(geo_master, geo_create_address, NULL);
312+
313+ g_signal_connect(G_OBJECT(client), "invalidated", G_CALLBACK(geo_client_invalid), NULL);
314+ g_signal_connect(G_OBJECT(client), "address-provider-changed", G_CALLBACK(geo_address_change), NULL);
315+
316+ return;
317+}
318+
319 /* Repsonds to the service object saying it's time to shutdown.
320 It stops the mainloop. */
321 static void
322@@ -259,12 +512,19 @@
323 bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR);
324 textdomain (GETTEXT_PACKAGE);
325
326+ /* Cache the timezone */
327+ update_current_timezone();
328+
329 /* Building the base menu */
330 server = dbusmenu_server_new(MENU_OBJ);
331 root = dbusmenu_menuitem_new();
332 dbusmenu_server_set_root(server, root);
333 build_menus(root);
334
335+ /* Setup geoclue */
336+ GeoclueMaster * master = geoclue_master_get_default();
337+ geoclue_master_create_client_async(master, geo_create_client, NULL);
338+
339 /* Setup dbus interface */
340 dbus = g_object_new(DATETIME_INTERFACE_TYPE, NULL);
341
342@@ -277,6 +537,7 @@
343 mainloop = g_main_loop_new(NULL, FALSE);
344 g_main_loop_run(mainloop);
345
346+ g_object_unref(G_OBJECT(master));
347 g_object_unref(G_OBJECT(dbus));
348 g_object_unref(G_OBJECT(service));
349 g_object_unref(G_OBJECT(server));

Subscribers

People subscribed via source and target branches

to all changes: