~ubuntu-branches/ubuntu/natty/indicator-datetime/natty

« back to all changes in this revision

Viewing changes to src/datetime-service.c

  • Committer: Bazaar Package Importer
  • Author(s): Ken VanDine
  • Date: 2010-12-13 11:30:25 UTC
  • mfrom: (1.1.5 upstream)
  • Revision ID: james.westby@ubuntu.com-20101213113025-gzu3kuukayeo3ets
Tags: 0.1.90.is.0.0.6-0ubuntu1
Uploading 0.0.6 again to superceed 0.1.90 which is still blocked on
MIR

Show diffs side-by-side

added added

removed removed

Lines of Context:
21
21
 
22
22
#include <config.h>
23
23
#include <libindicator/indicator-service.h>
24
 
#include <locale.h>
25
24
 
26
25
#include <glib/gi18n.h>
27
26
#include <gio/gio.h>
30
29
#include <libdbusmenu-glib/client.h>
31
30
#include <libdbusmenu-glib/menuitem.h>
32
31
 
33
 
#include <geoclue/geoclue-master.h>
34
 
#include <geoclue/geoclue-master-client.h>
35
 
 
36
 
#include <oobs/oobs-timeconfig.h>
37
 
 
38
32
#include "datetime-interface.h"
39
33
#include "dbus-shared.h"
40
34
 
41
 
static void geo_create_client (GeoclueMaster * master, GeoclueMasterClient * client, gchar * path, GError * error, gpointer user_data);
42
35
static void setup_timer (void);
43
36
 
44
37
static IndicatorService * service = NULL;
46
39
static DbusmenuServer * server = NULL;
47
40
static DbusmenuMenuitem * root = NULL;
48
41
static DatetimeInterface * dbus = NULL;
49
 
static gchar * current_timezone = NULL;
50
42
 
51
43
/* Global Items */
52
44
static DbusmenuMenuitem * date = NULL;
53
45
static DbusmenuMenuitem * calendar = NULL;
54
46
static DbusmenuMenuitem * settings = NULL;
55
 
static DbusmenuMenuitem * tzchange = NULL;
56
 
 
57
 
/* Geoclue trackers */
58
 
static GeoclueMasterClient * geo_master = NULL;
59
 
static GeoclueAddress * geo_address = NULL;
60
 
static gchar * geo_timezone = NULL;
61
 
 
62
 
/* Check to see if our timezones are the same */
63
 
static void
64
 
check_timezone_sync (void) {
65
 
        gboolean in_sync = FALSE;
66
 
 
67
 
        if (geo_timezone == NULL) {
68
 
                in_sync = TRUE;
69
 
        }
70
 
 
71
 
        if (current_timezone == NULL) {
72
 
                in_sync = TRUE;
73
 
        }
74
 
 
75
 
        if (!in_sync && g_strcmp0(geo_timezone, current_timezone) == 0) {
76
 
                in_sync = TRUE;
77
 
        }
78
 
 
79
 
        if (in_sync) {
80
 
                g_debug("Timezones in sync");
81
 
        } else {
82
 
                g_debug("Timezones are different");
83
 
        }
84
 
 
85
 
        if (tzchange != NULL) {
86
 
                if (in_sync) {
87
 
                        dbusmenu_menuitem_property_set_bool(tzchange, DBUSMENU_MENUITEM_PROP_VISIBLE, FALSE);
88
 
                } else {
89
 
                        gchar * label = g_strdup_printf(_("Change timezone to: %s"), geo_timezone);
90
 
 
91
 
                        dbusmenu_menuitem_property_set(tzchange, DBUSMENU_MENUITEM_PROP_LABEL, label);
92
 
                        dbusmenu_menuitem_property_set_bool(tzchange, DBUSMENU_MENUITEM_PROP_VISIBLE, TRUE);
93
 
 
94
 
                        g_free(label);
95
 
                }
96
 
        }
97
 
 
98
 
        return;
99
 
}
100
 
 
101
 
/* Update the current timezone */
102
 
static void
103
 
update_current_timezone (void) {
104
 
        /* Clear old data */
105
 
        if (current_timezone != NULL) {
106
 
                g_free(current_timezone);
107
 
                current_timezone = NULL;
108
 
        }
109
 
 
110
 
        GError * error = NULL;
111
 
        gchar * tempzone = NULL;
112
 
        if (!g_file_get_contents(TIMEZONE_FILE, &tempzone, NULL, &error)) {
113
 
                g_warning("Unable to read timezone file '" TIMEZONE_FILE "': %s", error->message);
114
 
                g_error_free(error);
115
 
                return;
116
 
        }
117
 
 
118
 
        /* This shouldn't happen, so let's make it a big boom! */
119
 
        g_return_if_fail(tempzone != NULL);
120
 
 
121
 
        /* Note: this really makes sense as strstrip works in place
122
 
           so we end up with something a little odd without the dup
123
 
           so we have the dup to make sure everything is as expected
124
 
           for everyone else. */
125
 
        current_timezone = g_strdup(g_strstrip(tempzone));
126
 
        g_free(tempzone);
127
 
 
128
 
        g_debug("System timezone is: %s", current_timezone);
129
 
 
130
 
        check_timezone_sync();
131
 
 
132
 
        return;
133
 
}
134
 
 
135
 
/* See how our timezone setting went */
136
 
static void
137
 
quick_set_tz_cb (OobsObject * obj, OobsResult result, gpointer user_data)
138
 
{
139
 
        if (result == OOBS_RESULT_OK) {
140
 
                g_debug("Timezone set");
141
 
        } else {
142
 
                g_warning("Unable to quick set timezone");
143
 
        }
144
 
        return;
145
 
}
146
 
 
147
 
/* Set the timezone to the Geoclue discovered one */
148
 
static void
149
 
quick_set_tz (DbusmenuMenuitem * menuitem, guint timestamp, const gchar *command)
150
 
{
151
 
        g_debug("Quick setting timezone to: %s", geo_timezone);
152
 
 
153
 
        g_return_if_fail(geo_timezone != NULL);
154
 
 
155
 
        OobsObject * obj = oobs_time_config_get();
156
 
        g_return_if_fail(obj != NULL);
157
 
 
158
 
        OobsTimeConfig * timeconfig = OOBS_TIME_CONFIG(obj);
159
 
        oobs_time_config_set_timezone(timeconfig, geo_timezone);
160
 
 
161
 
        oobs_object_commit_async(obj, quick_set_tz_cb, NULL);
162
 
 
163
 
        return;
164
 
}
165
47
 
166
48
/* Updates the label in the date menuitem */
167
49
static gboolean
277
159
        dbusmenu_menuitem_property_set(separator, DBUSMENU_MENUITEM_PROP_TYPE, DBUSMENU_CLIENT_TYPES_SEPARATOR);
278
160
        dbusmenu_menuitem_child_append(root, separator);
279
161
 
280
 
        tzchange = dbusmenu_menuitem_new();
281
 
        dbusmenu_menuitem_property_set(tzchange, DBUSMENU_MENUITEM_PROP_LABEL, "Set specific timezone");
282
 
        dbusmenu_menuitem_property_set_bool(tzchange, DBUSMENU_MENUITEM_PROP_VISIBLE, FALSE);
283
 
        g_signal_connect(G_OBJECT(tzchange), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(quick_set_tz), NULL);
284
 
        dbusmenu_menuitem_child_append(root, tzchange);
285
 
        check_timezone_sync();
286
 
 
287
162
        settings = dbusmenu_menuitem_new();
288
163
        dbusmenu_menuitem_property_set     (settings, DBUSMENU_MENUITEM_PROP_LABEL, _("Time & Date Settings..."));
289
164
        /* insensitive until we check for available apps */
299
174
static void
300
175
timezone_changed (GFileMonitor * monitor, GFile * file, GFile * otherfile, GFileMonitorEvent event, gpointer user_data)
301
176
{
302
 
        update_current_timezone();
303
177
        datetime_interface_update(DATETIME_INTERFACE(user_data));
304
178
        update_datetime(NULL);
305
179
        setup_timer();
358
232
        return;
359
233
}
360
234
 
361
 
/* Callback from getting the address */
362
 
static void
363
 
geo_address_cb (GeoclueAddress * address, int timestamp, GHashTable * addy_data, GeoclueAccuracy * accuracy, GError * error, gpointer user_data)
364
 
{
365
 
        if (error != NULL) {
366
 
                g_warning("Unable to get Geoclue address: %s", error->message);
367
 
                return;
368
 
        }
369
 
 
370
 
        g_debug("Geoclue timezone is: %s", (gchar *)g_hash_table_lookup(addy_data, "timezone"));
371
 
 
372
 
        if (geo_timezone != NULL) {
373
 
                g_free(geo_timezone);
374
 
                geo_timezone = NULL;
375
 
        }
376
 
 
377
 
        gpointer tz_hash = g_hash_table_lookup(addy_data, "timezone");
378
 
        if (tz_hash != NULL) {
379
 
                geo_timezone = g_strdup((gchar *)tz_hash);
380
 
        }
381
 
 
382
 
        check_timezone_sync();
383
 
 
384
 
        return;
385
 
}
386
 
 
387
 
/* Callback from creating the address */
388
 
static void
389
 
geo_create_address (GeoclueMasterClient * master, GeoclueAddress * address, GError * error, gpointer user_data)
390
 
{
391
 
        if (error != NULL) {
392
 
                g_warning("Unable to create GeoClue address: %s", error->message);
393
 
                return;
394
 
        }
395
 
 
396
 
        g_debug("Created Geoclue Address");
397
 
        geo_address = address;
398
 
        g_object_ref(G_OBJECT(geo_address));
399
 
 
400
 
        geoclue_address_get_address_async(geo_address, geo_address_cb, NULL);
401
 
 
402
 
        g_signal_connect(G_OBJECT(address), "address-changed", G_CALLBACK(geo_address_cb), NULL);
403
 
 
404
 
        return;
405
 
}
406
 
 
407
 
/* Callback from setting requirements */
408
 
static void
409
 
geo_req_set (GeoclueMasterClient * master, GError * error, gpointer user_data)
410
 
{
411
 
        if (error != NULL) {
412
 
                g_warning("Unable to set Geoclue requirements: %s", error->message);
413
 
        }
414
 
        return;
415
 
}
416
 
 
417
 
/* Client is killing itself rather oddly */
418
 
static void
419
 
geo_client_invalid (GeoclueMasterClient * client, gpointer user_data)
420
 
{
421
 
        g_warning("Master client invalid, rebuilding.");
422
 
 
423
 
        if (geo_master != NULL) {
424
 
                g_object_unref(G_OBJECT(geo_master));
425
 
        }
426
 
        geo_master = NULL;
427
 
 
428
 
        GeoclueMaster * master = geoclue_master_get_default();
429
 
        geoclue_master_create_client_async(master, geo_create_client, NULL);
430
 
 
431
 
        if (geo_timezone != NULL) {
432
 
                g_free(geo_timezone);
433
 
                geo_timezone = NULL;
434
 
        }
435
 
 
436
 
        check_timezone_sync();
437
 
 
438
 
        return;
439
 
}
440
 
 
441
 
/* Address provider changed, we need to get that one */
442
 
static void
443
 
geo_address_change (GeoclueMasterClient * client, gchar * a, gchar * b, gchar * c, gchar * d, gpointer user_data)
444
 
{
445
 
        g_warning("Address provider changed.  Let's change");
446
 
 
447
 
        if (geo_address != NULL) {
448
 
                g_object_unref(G_OBJECT(geo_address));
449
 
        }
450
 
        geo_address = NULL;
451
 
 
452
 
        geoclue_master_client_create_address_async(geo_master, geo_create_address, NULL);
453
 
 
454
 
        if (geo_timezone != NULL) {
455
 
                g_free(geo_timezone);
456
 
                geo_timezone = NULL;
457
 
        }
458
 
 
459
 
        check_timezone_sync();
460
 
 
461
 
        return;
462
 
}
463
 
 
464
 
/* Callback from creating the client */
465
 
static void
466
 
geo_create_client (GeoclueMaster * master, GeoclueMasterClient * client, gchar * path, GError * error, gpointer user_data)
467
 
{
468
 
        g_debug("Created Geoclue client at: %s", path);
469
 
 
470
 
        geo_master = client;
471
 
        g_object_ref(G_OBJECT(geo_master));
472
 
 
473
 
        geoclue_master_client_set_requirements_async(geo_master,
474
 
                                                     GEOCLUE_ACCURACY_LEVEL_REGION,
475
 
                                                     0,
476
 
                                                     FALSE,
477
 
                                                     GEOCLUE_RESOURCE_ALL,
478
 
                                                     geo_req_set,
479
 
                                                     NULL);
480
 
 
481
 
        geoclue_master_client_create_address_async(geo_master, geo_create_address, NULL);
482
 
 
483
 
        g_signal_connect(G_OBJECT(client), "invalidated", G_CALLBACK(geo_client_invalid), NULL);
484
 
        g_signal_connect(G_OBJECT(client), "address-provider-changed", G_CALLBACK(geo_address_change), NULL);
485
 
 
486
 
        return;
487
 
}
488
 
 
489
235
/* Repsonds to the service object saying it's time to shutdown.
490
236
   It stops the mainloop. */
491
237
static void 
512
258
        bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR);
513
259
        textdomain (GETTEXT_PACKAGE);
514
260
 
515
 
        /* Cache the timezone */
516
 
        update_current_timezone();
517
 
 
518
261
        /* Building the base menu */
519
262
        server = dbusmenu_server_new(MENU_OBJ);
520
263
        root = dbusmenu_menuitem_new();
521
264
        dbusmenu_server_set_root(server, root);
522
265
        build_menus(root);
523
266
 
524
 
        /* Setup geoclue */
525
 
        GeoclueMaster * master = geoclue_master_get_default();
526
 
        geoclue_master_create_client_async(master, geo_create_client, NULL);
527
 
 
528
267
        /* Setup dbus interface */
529
268
        dbus = g_object_new(DATETIME_INTERFACE_TYPE, NULL);
530
269
 
537
276
        mainloop = g_main_loop_new(NULL, FALSE);
538
277
        g_main_loop_run(mainloop);
539
278
 
540
 
        g_object_unref(G_OBJECT(master));
541
279
        g_object_unref(G_OBJECT(dbus));
542
280
        g_object_unref(G_OBJECT(service));
543
281
        g_object_unref(G_OBJECT(server));