aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--data/com.canonical.indicator.datetime.gschema.xml8
-rw-r--r--src/datetime-service.c322
-rw-r--r--src/indicator-datetime.c66
3 files changed, 299 insertions, 97 deletions
diff --git a/data/com.canonical.indicator.datetime.gschema.xml b/data/com.canonical.indicator.datetime.gschema.xml
index fe493f7..117f965 100644
--- a/data/com.canonical.indicator.datetime.gschema.xml
+++ b/data/com.canonical.indicator.datetime.gschema.xml
@@ -57,5 +57,13 @@
more information.
</description>
</key>
+ <key name="locations" type="as">
+ <default>[]</default>
+ <summary>A List of locations</summary>
+ <description>
+ Adds the list of locations the user has configured to display in the
+ indicator-datetime menu.
+ </description>
+ </key>
</schema>
</schemalist>
diff --git a/src/datetime-service.c b/src/datetime-service.c
index e373ae8..976e7e6 100644
--- a/src/datetime-service.c
+++ b/src/datetime-service.c
@@ -52,8 +52,13 @@ with this program. If not, see <http://www.gnu.org/licenses/>.
#include "datetime-interface.h"
#include "dbus-shared.h"
+
+#define SETTINGS_INTERFACE "com.canonical.indicator.datetime"
+#define SETTINGS_LOCATIONS "locations"
+
static void geo_create_client (GeoclueMaster * master, GeoclueMasterClient * client, gchar * path, GError * error, gpointer user_data);
static gboolean update_appointment_menu_items (gpointer user_data);
+static gboolean update_timezone_menu_items(gpointer user_data);
static void setup_timer (void);
static void geo_client_invalid (GeoclueMasterClient * client, gpointer user_data);
static void geo_address_change (GeoclueMasterClient * client, gchar * a, gchar * b, gchar * c, gchar * d, gpointer user_data);
@@ -63,30 +68,40 @@ static GMainLoop * mainloop = NULL;
static DbusmenuServer * server = NULL;
static DbusmenuMenuitem * root = NULL;
static DatetimeInterface * dbus = NULL;
-static gchar * current_timezone = NULL;
/* Global Items */
static DbusmenuMenuitem * date = NULL;
static DbusmenuMenuitem * calendar = NULL;
static DbusmenuMenuitem * settings = NULL;
-static DbusmenuMenuitem * tzchange = NULL;
+static DbusmenuMenuitem * locations_separator = NULL;
+static DbusmenuMenuitem * geo_location = NULL;
+static DbusmenuMenuitem * current_location = NULL;
+//static DbusmenuMenuitem * ecal_location = NULL;
static DbusmenuMenuitem * add_appointment = NULL;
+<<<<<<< TREE
+=======
// static DbusmenuMenuitem * add_location = NULL;
+>>>>>>> MERGE-SOURCE
static GList * appointments = NULL;
-static ECal * ecal = NULL;
-static const gchar * ecal_timezone = NULL;
-static icaltimezone *tzone;
+static GList * dconflocations = NULL;
+GSettings *conf;
+
/* Geoclue trackers */
static GeoclueMasterClient * geo_master = NULL;
static GeoclueAddress * geo_address = NULL;
-static gchar * geo_timezone = NULL;
+
+/* Our 3 important timezones */
+static const gchar * ecal_timezone = NULL;
+static gchar * current_timezone = NULL;
+static gchar * geo_timezone = NULL;
/* Check to see if our timezones are the same */
static void
check_timezone_sync (void) {
+ gchar * label;
gboolean in_sync = FALSE;
-
+
if (geo_timezone == NULL) {
in_sync = TRUE;
}
@@ -105,18 +120,67 @@ check_timezone_sync (void) {
g_debug("Timezones are different");
}
- if (tzchange != NULL) {
+ if (geo_location != NULL && current_location != NULL) {
+ g_debug("Got timezone %s", current_timezone);
+ g_debug("Got timezone %s", geo_timezone);
+ // Show neither current location nor geo location if both are the same
+ // however, we want to set their time and label accordingly
if (in_sync) {
- dbusmenu_menuitem_property_set_bool(tzchange, DBUSMENU_MENUITEM_PROP_VISIBLE, FALSE);
+ if (current_timezone == NULL && geo_timezone == NULL) {
+ dbusmenu_menuitem_property_set_bool(locations_separator, DBUSMENU_MENUITEM_PROP_VISIBLE, FALSE);
+ dbusmenu_menuitem_property_set_bool (current_location, DBUSMENU_MENUITEM_PROP_VISIBLE, FALSE);
+ dbusmenu_menuitem_property_set_bool (geo_location, DBUSMENU_MENUITEM_PROP_VISIBLE, FALSE);
+ update_timezone_menu_items(NULL); // Update the timezone menu items
+ return;
+ }
+
+ dbusmenu_menuitem_property_set_bool (locations_separator, DBUSMENU_MENUITEM_PROP_VISIBLE, FALSE);
+ dbusmenu_menuitem_property_set_bool (current_location, DBUSMENU_MENUITEM_PROP_VISIBLE, FALSE);
+ dbusmenu_menuitem_property_set_bool (current_location, DBUSMENU_MENUITEM_PROP_ENABLED, TRUE);
+ dbusmenu_menuitem_property_set_bool (geo_location, DBUSMENU_MENUITEM_PROP_VISIBLE, FALSE);
+ dbusmenu_menuitem_property_set_bool (geo_location, DBUSMENU_MENUITEM_PROP_ENABLED, TRUE);
+
+ if (current_timezone != NULL) {
+ label = current_timezone;
+ } else {
+ label = geo_timezone;
+ }
+
+ if (label != NULL) {
+ // TODO work out the current location name in a nice way
+ dbusmenu_menuitem_property_set (current_location, TIMEZONE_MENUITEM_PROP_LABEL, label);
+ // TODO work out the current time at that location
+ dbusmenu_menuitem_property_set (current_location, TIMEZONE_MENUITEM_PROP_RIGHT, "+tzone");
+ dbusmenu_menuitem_property_set_bool (current_location, DBUSMENU_MENUITEM_PROP_VISIBLE, TRUE);
+ dbusmenu_menuitem_property_set_bool(current_location, TIMEZONE_MENUITEM_PROP_RADIO, TRUE);
+ } else {
+ g_debug("Label for current location is null, this shouldn't happen");
+ }
+ if (geo_timezone != NULL) {
+ // TODO work out the geo location name in a nice way
+ dbusmenu_menuitem_property_set (geo_location, TIMEZONE_MENUITEM_PROP_LABEL, geo_timezone);
+ // TODO work out the current time at that location
+ dbusmenu_menuitem_property_set (geo_location, TIMEZONE_MENUITEM_PROP_RIGHT, "+tzone");
+ dbusmenu_menuitem_property_set_bool (geo_location, DBUSMENU_MENUITEM_PROP_VISIBLE, TRUE);
+ }
} else {
- gchar * label = g_strdup_printf(_("Change timezone to: %s"), geo_timezone);
-
- dbusmenu_menuitem_property_set(tzchange, DBUSMENU_MENUITEM_PROP_LABEL, label);
- dbusmenu_menuitem_property_set_bool(tzchange, DBUSMENU_MENUITEM_PROP_VISIBLE, TRUE);
-
- g_free(label);
+ // TODO work out the geo location name in a nice way
+ dbusmenu_menuitem_property_set (geo_location, TIMEZONE_MENUITEM_PROP_LABEL, geo_timezone);
+ // TODO work out the current time at that location
+ dbusmenu_menuitem_property_set (geo_location, TIMEZONE_MENUITEM_PROP_RIGHT, "+tzone");
+ dbusmenu_menuitem_property_set_bool(geo_location, DBUSMENU_MENUITEM_PROP_VISIBLE, TRUE);
+
+ // TODO work out the current location name in a nice way
+ dbusmenu_menuitem_property_set (current_location, TIMEZONE_MENUITEM_PROP_LABEL, current_timezone);
+ // TODO work out the current time at that location
+ dbusmenu_menuitem_property_set (current_location, TIMEZONE_MENUITEM_PROP_RIGHT, "+tzone");
+ dbusmenu_menuitem_property_set_bool(current_location, TIMEZONE_MENUITEM_PROP_RADIO, TRUE);
+ dbusmenu_menuitem_property_set_bool(current_location, DBUSMENU_MENUITEM_PROP_VISIBLE, TRUE);
+ dbusmenu_menuitem_property_set_bool(locations_separator, DBUSMENU_MENUITEM_PROP_VISIBLE, TRUE);
}
}
+ g_debug("Finished checking timezone sync");
+ update_timezone_menu_items(NULL); // Update the timezone menu items
return;
}
@@ -169,17 +233,22 @@ quick_set_tz_cb (OobsObject * obj, OobsResult result, gpointer user_data)
/* Set the timezone to the Geoclue discovered one */
static void
-quick_set_tz (DbusmenuMenuitem * menuitem, guint timestamp, const gchar *command)
+quick_set_tz (DbusmenuMenuitem * menuitem, guint timestamp, gpointer user_data)
{
- g_debug("Quick setting timezone to: %s", geo_timezone);
+ const gchar * tz = dbusmenu_menuitem_property_get(menuitem, TIMEZONE_MENUITEM_PROP_LABEL);
+
+ g_debug("Quick setting timezone to: %s", tz);
- g_return_if_fail(geo_timezone != NULL);
+ g_return_if_fail(tz != NULL);
+
+ if (g_strcmp0(tz, current_timezone) == 0)
+ return;
OobsObject * obj = oobs_time_config_get();
g_return_if_fail(obj != NULL);
OobsTimeConfig * timeconfig = OOBS_TIME_CONFIG(obj);
- oobs_time_config_set_timezone(timeconfig, geo_timezone);
+ oobs_time_config_set_timezone(timeconfig, tz);
oobs_object_commit_async(obj, quick_set_tz_cb, NULL);
@@ -239,9 +308,7 @@ check_for_calendar (gpointer user_data)
g_debug("Found the calendar application: %s", evo);
dbusmenu_menuitem_property_set_bool(calendar, DBUSMENU_MENUITEM_PROP_ENABLED, TRUE);
dbusmenu_menuitem_property_set_bool(calendar, DBUSMENU_MENUITEM_PROP_VISIBLE, TRUE);
- dbusmenu_menuitem_property_set_bool(add_appointment, DBUSMENU_MENUITEM_PROP_ENABLED, TRUE);
- dbusmenu_menuitem_property_set_bool(add_appointment, DBUSMENU_MENUITEM_PROP_VISIBLE, TRUE);
-
+/*
GError *gerror = NULL;
// TODO: In reality we should iterate sources of calendar, but getting the local one doens't lag for > a minute
g_debug("Setting up ecal.");
@@ -265,15 +332,26 @@ check_for_calendar (gpointer user_data)
ecal = NULL;
}
- /* This timezone represents the timezone of the calendar, this might be different to the current UTC offset.
+ This timezone represents the timezone of the calendar, this might be different to the current UTC offset.
* this means we'll have some geoclue interaction going on, and possibly the user will be involved in setting
* their location manually, case in point: trains have satellite links which often geoclue to sweden,
* this shouldn't automatically set the location and mess up all the appointments for the user.
- */
+
if (ecal) ecal_timezone = icaltimezone_get_tzid(tzone);
-
+ */
+ DbusmenuMenuitem * separator = dbusmenu_menuitem_new();
+ dbusmenu_menuitem_property_set(separator, DBUSMENU_MENUITEM_PROP_TYPE, DBUSMENU_CLIENT_TYPES_SEPARATOR);
+ dbusmenu_menuitem_child_add_position(root, separator, 3);
+
+ add_appointment = dbusmenu_menuitem_new();
+ dbusmenu_menuitem_property_set (add_appointment, DBUSMENU_MENUITEM_PROP_LABEL, _("Add Appointment"));
+ dbusmenu_menuitem_property_set_bool(add_appointment, DBUSMENU_MENUITEM_PROP_ENABLED, TRUE);
+ dbusmenu_menuitem_property_set_bool(add_appointment, DBUSMENU_MENUITEM_PROP_VISIBLE, TRUE);
+ g_signal_connect(G_OBJECT(add_appointment), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(activate_cb), "evolution -c calendar");
+ dbusmenu_menuitem_child_add_position (root, add_appointment, 3);
+
update_appointment_menu_items(NULL);
- g_signal_connect(root, DBUSMENU_MENUITEM_SIGNAL_ABOUT_TO_SHOW, G_CALLBACK(update_appointment_menu_items), NULL);
+ g_signal_connect(root, DBUSMENU_MENUITEM_SIGNAL_ABOUT_TO_SHOW, G_CALLBACK(update_appointment_menu_items), NULL);
g_free(evo);
} else {
@@ -288,12 +366,60 @@ check_for_calendar (gpointer user_data)
/*
static gboolean
update_timezone_menu_items(gpointer user_data) {
- // Get the current location as specified by the user as a place name and time and add it,
- // Get the location from geoclue as a place and time and add it,
- // Get the evolution calendar timezone as a place and time and add it,
- // Get the current timezone that the clock uses and select that
- // Iterate over configured places and add any which aren't already listed
- // Hook up each of these to setting the time/current timezone
+ g_debug("Updating timezone menu items");
+ gchar ** locations = g_settings_get_strv(conf, SETTINGS_LOCATIONS);
+ if (locations == NULL) {
+ g_debug("No locations configured (NULL)");
+ return FALSE;
+ }
+ guint len = g_strv_length(locations);
+ DbusmenuMenuitem *item;
+ gint i, offset;
+
+ /* Remove all of the previous locations */
+ if (dconflocations != NULL) {
+ g_debug("Freeing old locations");
+ while (dconflocations != NULL) {
+ DbusmenuMenuitem * litem = DBUSMENU_MENUITEM(dconflocations->data);
+ g_debug("Freeing old location: %p", litem);
+ // Remove all the existing menu items which are in dconflocations.
+ dconflocations = g_list_remove(dconflocations, litem);
+ dbusmenu_menuitem_child_delete(root, DBUSMENU_MENUITEM(litem));
+ g_object_unref(G_OBJECT(litem));
+ }
+ }
+
+ // TODO: Remove items from the dconflocations at the end of the iteration
+ // Make sure if there are multiple locations, our current location is shown
+ if (len > 0) {
+ dbusmenu_menuitem_property_set_bool (locations_separator, DBUSMENU_MENUITEM_PROP_VISIBLE, TRUE);
+ dbusmenu_menuitem_property_set_bool (current_location, DBUSMENU_MENUITEM_PROP_VISIBLE, TRUE);
+ dbusmenu_menuitem_property_set_bool (current_location, DBUSMENU_MENUITEM_PROP_ENABLED, TRUE);
+ } else {
+ g_debug("No locations configured (Empty List)");
+ return FALSE;
+ }
+
+ offset = dbusmenu_menuitem_get_position (current_location, root)+1;
+ for (i = 0; i < len; i++) {
+ // Iterate over configured places and add any which aren't already listed
+ if (g_strcmp0(locations[i], current_timezone) != 0 &&
+ g_strcmp0(locations[i], geo_timezone) != 0) {
+ g_debug("Adding timezone in update_timezones %s", locations[i]);
+ item = dbusmenu_menuitem_new();
+ dbusmenu_menuitem_property_set (item, DBUSMENU_MENUITEM_PROP_TYPE, TIMEZONE_MENUITEM_TYPE);
+ dbusmenu_menuitem_property_set (item, TIMEZONE_MENUITEM_PROP_LABEL, locations[i]);
+ dbusmenu_menuitem_property_set (item, TIMEZONE_MENUITEM_PROP_RIGHT, "+tzone");
+ dbusmenu_menuitem_property_set_bool (item, TIMEZONE_MENUITEM_PROP_RADIO, FALSE);
+ dbusmenu_menuitem_property_set_bool (item, DBUSMENU_MENUITEM_PROP_ENABLED, TRUE);
+ dbusmenu_menuitem_property_set_bool (item, DBUSMENU_MENUITEM_PROP_VISIBLE, TRUE);
+ dbusmenu_menuitem_child_add_position (root, item, offset++);
+ g_signal_connect(G_OBJECT(item), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(quick_set_tz), NULL);
+ dconflocations = g_list_append(dconflocations, item);
+ }
+ }
+ g_strfreev (locations);
+ // Get the evolution calendar timezone as a place and time and add it
return FALSE;
}
*/
@@ -346,6 +472,7 @@ update_appointment_menu_items (gpointer user_data) {
time_t t1, t2;
gchar *query, *is, *ie, *ad;
GList *objects = NULL, *l;
+ GList *allobjects = NULL;
GError *gerror = NULL;
gint i;
gint width, height;
@@ -357,17 +484,15 @@ update_appointment_menu_items (gpointer user_data) {
is = isodate_from_time_t(t1);
ie = isodate_from_time_t(t2);
+ gtk_icon_size_lookup(GTK_ICON_SIZE_MENU, &width, &height);
+
// FIXME can we put a limit on the number of results? Or if not complete, or is event/todo? Or sort it by date?
query = g_strdup_printf("(occur-in-time-range? (make-time\"%s\") (make-time\"%s\"))", is, ie);
- g_debug("Getting objects with query: %s", query);
- if (!e_cal_get_object_list_as_comp(ecal, query, &objects, &gerror)) {
- g_debug("Failed to get objects\n");
- g_free(ecal);
- ecal = NULL;
+
+ if (!e_cal_get_sources(&sources, E_CAL_SOURCE_TYPE_EVENT, &gerror)) {
+ g_debug("Failed to get ecal sources\n");
return FALSE;
}
- g_debug("Number of objects returned: %d", g_list_length(objects));
- gtk_icon_size_lookup(GTK_ICON_SIZE_MENU, &width, &height);
/* Remove all of the previous appointments */
if (appointments != NULL) {
@@ -382,14 +507,50 @@ update_appointment_menu_items (gpointer user_data) {
}
}
+ // TODO Remove all highlights from the calendar widget
+
+ // iterate the query for all sources
+ for (g = e_source_list_peek_groups (sources); g; g = g->next) {
+ ESourceGroup *group = E_SOURCE_GROUP (g->data);
+ GSList *s;
+
+ for (s = e_source_group_peek_sources (group); s; s = s->next) {
+ ESource *source = E_SOURCE (s->data);
+ ECal *ecal = e_cal_new(source, E_CAL_SOURCE_TYPE_EVENT);
+
+ icaltimezone * tzone;
+
+ if (!e_cal_open(ecal, FALSE, &gerror)) {
+ g_debug("Failed to get ecal sources %s", gerror->message);
+ return FALSE;
+ }
+
+ g_debug("Getting objects with query: %s", query);
+ if (!e_cal_get_object_list_as_comp(ecal, query, &objects, &gerror)) {
+ g_debug("Failed to get objects\n");
+ g_free(ecal);
+ return FALSE;
+ }
+ g_debug("Number of objects returned: %d", g_list_length(objects));
+
+ if (allobjects == NULL) {
+ allobjects = objects;
+ } else if (objects != NULL) {
+ allobjects = g_list_concat(allobjects, objects);
+ g_list_free(objects);
+ }
+ }
+ }
+
// Sort the list see above FIXME regarding queries
- objects = g_list_sort(objects, (GCompareFunc) compare_appointment_items);
+ allobjects = g_list_sort(allobjects, (GCompareFunc) compare_appointment_items);
i = 0;
- for (l = objects; l; l = l->next) {
+ for (l = allobjects; l; l = l->next) {
ECalComponent *ecalcomp = l->data;
ECalComponentText valuetext;
ECalComponentDateTime datetime;
icaltimezone *appointment_zone = NULL;
+ icaltimezone *current_zone = NULL;
icalproperty_status status;
gchar *summary, *cmd;
char right[20];
@@ -437,10 +598,15 @@ update_appointment_menu_items (gpointer user_data) {
continue;
}
+ appointment_zone = icaltimezone_get_builtin_timezone_from_tzid(datetime.tzid);
+ current_zone = icaltimezone_get_builtin_timezone_from_tzid(current_timezone);
if (!appointment_zone || datetime.value->is_date) { // If it's today put in the current timezone?
- appointment_zone = tzone;
+ appointment_zone = current_zone;
}
- tmp_tm = icaltimetype_to_tm_with_zone (datetime.value, appointment_zone, tzone);
+ // TODO: Convert the timezone into a 3 letter abbreviation if it's different to current_timezone
+ // TODO: Add the appointment timezone to the list if it's not already there.
+
+ tmp_tm = icaltimetype_to_tm_with_zone (datetime.value, appointment_zone, current_zone);
g_debug("Generate time string");
// Get today
@@ -454,11 +620,15 @@ update_appointment_menu_items (gpointer user_data) {
strftime(right, 20, "%a %l:%M %P", &tmp_tm);
g_debug("Appointment time: %s", right);
+ g_debug("Appointment timezone: %s", datetime.tzid);
+ g_debug("Appointment timezone: %s", icaltimezone_get_tzid(appointment_zone)); // These two should be the same
+ g_debug("Calendar timezone: %s", ecal_timezone);
+
dbusmenu_menuitem_property_set (item, APPOINTMENT_MENUITEM_PROP_RIGHT, right);
e_cal_component_free_datetime (&datetime);
- ad = is = isodate_from_time_t(mktime(&tmp_tm));
+ ad = isodate_from_time_t(mktime(&tmp_tm));
// Now we pull out the URI for the calendar event and try to create a URI that'll work when we execute evolution
// FIXME Because the URI stuff is really broken, we're going to open the calendar at todays date instead
@@ -493,14 +663,14 @@ update_appointment_menu_items (gpointer user_data) {
dbusmenu_menuitem_property_set_image (item, APPOINTMENT_MENUITEM_PROP_ICON, pixbuf);
}
- dbusmenu_menuitem_child_add_position (root, item, 4+i);
+ dbusmenu_menuitem_child_add_position (root, item, 3+i);
appointments = g_list_append (appointments, item); // Keep track of the items here to make them east to remove
g_debug("Adding appointment: %p", item);
if (i == 4) break; // See above FIXME regarding query result limit
i++;
}
- g_list_free(objects);
+ g_list_free(allobjects);
g_debug("End of objects");
return TRUE;
}
@@ -552,31 +722,32 @@ build_menus (DbusmenuMenuitem * root)
g_idle_add(check_for_calendar, NULL);
}
- DbusmenuMenuitem * separator;
- separator = dbusmenu_menuitem_new();
- dbusmenu_menuitem_property_set(separator, DBUSMENU_MENUITEM_PROP_TYPE, DBUSMENU_CLIENT_TYPES_SEPARATOR);
- dbusmenu_menuitem_child_append(root, separator);
-
- add_appointment = dbusmenu_menuitem_new();
- dbusmenu_menuitem_property_set (add_appointment, DBUSMENU_MENUITEM_PROP_LABEL, _("Add Appointment"));
- dbusmenu_menuitem_property_set_bool(add_appointment, DBUSMENU_MENUITEM_PROP_ENABLED, FALSE);
- dbusmenu_menuitem_property_set_bool(add_appointment, DBUSMENU_MENUITEM_PROP_VISIBLE, TRUE);
- g_signal_connect(G_OBJECT(add_appointment), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(activate_cb), "evolution -c calendar");
- dbusmenu_menuitem_child_add_position (root, add_appointment, 4);
+ locations_separator = dbusmenu_menuitem_new();
+ dbusmenu_menuitem_property_set(locations_separator, DBUSMENU_MENUITEM_PROP_TYPE, DBUSMENU_CLIENT_TYPES_SEPARATOR);
+ dbusmenu_menuitem_property_set_bool (locations_separator, DBUSMENU_MENUITEM_PROP_VISIBLE, TRUE);
+ dbusmenu_menuitem_child_append(root, locations_separator);
+
+ geo_location = dbusmenu_menuitem_new();
+ dbusmenu_menuitem_property_set (geo_location, DBUSMENU_MENUITEM_PROP_TYPE, TIMEZONE_MENUITEM_TYPE);
+ dbusmenu_menuitem_property_set (geo_location, TIMEZONE_MENUITEM_PROP_LABEL, "Updating location information...");
+ dbusmenu_menuitem_property_set_bool (geo_location, DBUSMENU_MENUITEM_PROP_ENABLED, FALSE);
+ dbusmenu_menuitem_property_set_bool (geo_location, DBUSMENU_MENUITEM_PROP_VISIBLE, TRUE);
+ g_signal_connect(G_OBJECT(geo_location), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(quick_set_tz), NULL);
+ dbusmenu_menuitem_child_append(root, geo_location);
+
+ current_location = dbusmenu_menuitem_new();
+ dbusmenu_menuitem_property_set (current_location, DBUSMENU_MENUITEM_PROP_TYPE, TIMEZONE_MENUITEM_TYPE);
+ dbusmenu_menuitem_property_set (current_location, TIMEZONE_MENUITEM_PROP_LABEL, "Current Timezone");
+ dbusmenu_menuitem_property_set_bool (current_location, DBUSMENU_MENUITEM_PROP_ENABLED, FALSE);
+ dbusmenu_menuitem_property_set_bool (current_location, DBUSMENU_MENUITEM_PROP_VISIBLE, FALSE);
+ g_signal_connect(G_OBJECT(current_location), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(quick_set_tz), NULL);
+ dbusmenu_menuitem_child_append(root, current_location);
- separator = dbusmenu_menuitem_new();
- dbusmenu_menuitem_property_set(separator, DBUSMENU_MENUITEM_PROP_TYPE, DBUSMENU_CLIENT_TYPES_SEPARATOR);
- dbusmenu_menuitem_child_append(root, separator);
-
- tzchange = dbusmenu_menuitem_new();
- dbusmenu_menuitem_property_set(tzchange, DBUSMENU_MENUITEM_PROP_LABEL, "Set specific timezone");
- dbusmenu_menuitem_property_set_bool(tzchange, DBUSMENU_MENUITEM_PROP_VISIBLE, FALSE);
- g_signal_connect(G_OBJECT(tzchange), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(quick_set_tz), NULL);
- dbusmenu_menuitem_child_append(root, tzchange);
check_timezone_sync();
-
- separator = dbusmenu_menuitem_new();
+ //g_signal_connect(root, DBUSMENU_MENUITEM_SIGNAL_ABOUT_TO_SHOW, G_CALLBACK(update_timezone_menu_items), NULL);
+
+ DbusmenuMenuitem * separator = dbusmenu_menuitem_new();
dbusmenu_menuitem_property_set(separator, DBUSMENU_MENUITEM_PROP_TYPE, DBUSMENU_CLIENT_TYPES_SEPARATOR);
dbusmenu_menuitem_child_append(root, separator);
@@ -859,8 +1030,9 @@ main (int argc, char ** argv)
bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR);
textdomain (GETTEXT_PACKAGE);
- /* Cache the timezone */
- update_current_timezone();
+ /* Set up GSettings */
+ conf = g_settings_new(SETTINGS_INTERFACE);
+ // TODO Add a signal handler to catch gsettings changes and respond to them
/* Building the base menu */
server = dbusmenu_server_new(MENU_OBJ);
@@ -868,6 +1040,9 @@ main (int argc, char ** argv)
dbusmenu_server_set_root(server, root);
build_menus(root);
+
+ /* Cache the timezone */
+ update_current_timezone();
/* Setup geoclue */
GeoclueMaster * master = geoclue_master_get_default();
@@ -885,14 +1060,15 @@ main (int argc, char ** argv)
mainloop = g_main_loop_new(NULL, FALSE);
g_main_loop_run(mainloop);
- geo_address_clean();
- geo_client_clean();
-
+ g_object_unref(G_OBJECT(conf));
g_object_unref(G_OBJECT(master));
g_object_unref(G_OBJECT(dbus));
g_object_unref(G_OBJECT(service));
g_object_unref(G_OBJECT(server));
g_object_unref(G_OBJECT(root));
+ geo_address_clean();
+ geo_client_clean();
+
return 0;
}
diff --git a/src/indicator-datetime.c b/src/indicator-datetime.c
index 1f61864..0f60428 100644
--- a/src/indicator-datetime.c
+++ b/src/indicator-datetime.c
@@ -105,7 +105,7 @@ enum {
typedef struct _indicator_item_t indicator_item_t;
struct _indicator_item_t {
- GtkWidget * radio;
+ GtkWidget * gmi;
GtkWidget * icon;
GtkWidget * label;
GtkWidget * right;
@@ -176,7 +176,6 @@ static void update_time (IndicatorDatetime * self);
static void receive_signal (GDBusProxy * proxy, gchar * sender_name, gchar * signal_name, GVariant * parameters, gpointer user_data);
static void service_proxy_cb (GObject * object, GAsyncResult * res, gpointer user_data);
static gint generate_strftime_bitmask (const char *time_str);
-static GSList *location_group = NULL;
/* Indicator Module Config */
INDICATOR_SET_VERSION
@@ -1070,14 +1069,14 @@ generate_format_string (IndicatorDatetime * self)
/* Whenever we have a property change on a DbusmenuMenuitem
we need to be responsive to that. */
static void
-indicator_prop_change_cb (DbusmenuMenuitem * mi, gchar * prop, gchar * value, indicator_item_t * mi_data)
+indicator_prop_change_cb (DbusmenuMenuitem * mi, gchar * prop, GVariant *value, indicator_item_t * mi_data)
{
if (!g_strcmp0(prop, APPOINTMENT_MENUITEM_PROP_LABEL)) {
/* Set the main label */
- gtk_label_set_text(GTK_LABEL(mi_data->label), value);
+ gtk_label_set_text(GTK_LABEL(mi_data->label), g_variant_get_string(value, NULL));
} else if (!g_strcmp0(prop, APPOINTMENT_MENUITEM_PROP_RIGHT)) {
/* Set the right label */
- gtk_label_set_text(GTK_LABEL(mi_data->right), value);
+ gtk_label_set_text(GTK_LABEL(mi_data->right), g_variant_get_string(value, NULL));
} else if (!g_strcmp0(prop, APPOINTMENT_MENUITEM_PROP_ICON)) {
/* We don't use the value here, which is probably less efficient,
but it's easier to use the easy function. And since th value
@@ -1106,6 +1105,14 @@ indicator_prop_change_cb (DbusmenuMenuitem * mi, gchar * prop, gchar * value, in
g_object_unref(resized_pixbuf);
}
}
+ } else if (!g_strcmp0(prop, TIMEZONE_MENUITEM_PROP_LABEL)) {
+ /* Set the main label */
+ gtk_label_set_text(GTK_LABEL(mi_data->label), g_variant_get_string(value, NULL));
+ } else if (!g_strcmp0(prop, TIMEZONE_MENUITEM_PROP_RIGHT)) {
+ /* Set the right label */
+ gtk_label_set_text(GTK_LABEL(mi_data->right), g_variant_get_string(value, NULL));
+ } else if (!g_strcmp0(prop, TIMEZONE_MENUITEM_PROP_RADIO)) {
+ gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(mi_data->gmi), g_variant_get_boolean(value));
} else {
g_warning("Indicator Item property '%s' unknown", prop);
}
@@ -1127,7 +1134,7 @@ new_appointment_item (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, Dbu
indicator_item_t * mi_data = g_new0(indicator_item_t, 1);
- GtkMenuItem * gmi = GTK_MENU_ITEM(gtk_menu_item_new());
+ mi_data->gmi = gtk_menu_item_new();
GtkWidget * hbox = gtk_hbox_new(FALSE, 4);
@@ -1178,10 +1185,10 @@ new_appointment_item (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, Dbu
gtk_box_pack_start(GTK_BOX(hbox), mi_data->right, FALSE, FALSE, 0);
gtk_widget_show(mi_data->right);
- gtk_container_add(GTK_CONTAINER(gmi), hbox);
+ gtk_container_add(GTK_CONTAINER(mi_data->gmi), hbox);
gtk_widget_show(hbox);
- dbusmenu_gtkclient_newitem_base(DBUSMENU_GTKCLIENT(client), newitem, gmi, parent);
+ dbusmenu_gtkclient_newitem_base(DBUSMENU_GTKCLIENT(client), newitem, GTK_MENU_ITEM(mi_data->gmi), parent);
g_signal_connect(G_OBJECT(newitem), DBUSMENU_MENUITEM_SIGNAL_PROPERTY_CHANGED, G_CALLBACK(indicator_prop_change_cb), mi_data);
g_signal_connect_swapped(G_OBJECT(newitem), "destroyed", G_CALLBACK(g_free), mi_data);
@@ -1217,6 +1224,22 @@ new_calendar_item (DbusmenuMenuitem * newitem,
return TRUE;
}
+static void
+timezone_toggled_cb (GtkCheckMenuItem *checkmenuitem, DbusmenuMenuitem * dbusitem)
+{
+ /* Make sure that the displayed radio-active setting is always
+ consistent with the dbus menuitem */
+ gtk_check_menu_item_set_active(checkmenuitem,
+ dbusmenu_menuitem_property_get_bool(dbusitem, TIMEZONE_MENUITEM_PROP_RADIO));
+}
+
+static void
+timezone_destroyed_cb (DbusmenuMenuitem * dbusitem, indicator_item_t * mi_data)
+{
+ g_signal_handlers_disconnect_by_func(G_OBJECT(mi_data->gmi), G_CALLBACK(timezone_toggled_cb), dbusitem);
+ g_free(mi_data);
+}
+
static gboolean
new_timezone_item(DbusmenuMenuitem * newitem,
DbusmenuMenuitem * parent,
@@ -1230,41 +1253,36 @@ new_timezone_item(DbusmenuMenuitem * newitem,
// Menu item with a radio button and a right aligned time
indicator_item_t * mi_data = g_new0(indicator_item_t, 1);
- GtkMenuItem * gmi = GTK_MENU_ITEM(gtk_menu_item_new());
+ mi_data->gmi = gtk_check_menu_item_new();
+
+ gtk_check_menu_item_set_draw_as_radio(GTK_CHECK_MENU_ITEM(mi_data->gmi), TRUE);
+ gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(mi_data->gmi),
+ dbusmenu_menuitem_property_get_bool(newitem, TIMEZONE_MENUITEM_PROP_RADIO));
GtkWidget * hbox = gtk_hbox_new(FALSE, 4);
- mi_data->radio = gtk_radio_button_new(location_group);
- if (location_group == NULL)
- location_group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(mi_data->radio));
-
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(mi_data->radio),
- dbusmenu_menuitem_property_get_bool(newitem, TIMEZONE_MENUITEM_PROP_RADIO));
-
- gtk_box_pack_start(GTK_BOX(hbox), mi_data->radio, FALSE, FALSE, 0);
- gtk_widget_show(mi_data->radio);
-
/* Label, probably a username, chat room or mailbox name */
- mi_data->label = gtk_label_new(dbusmenu_menuitem_property_get(newitem, APPOINTMENT_MENUITEM_PROP_LABEL));
+ mi_data->label = gtk_label_new(dbusmenu_menuitem_property_get(newitem, TIMEZONE_MENUITEM_PROP_LABEL));
gtk_misc_set_alignment(GTK_MISC(mi_data->label), 0.0, 0.5);
gtk_box_pack_start(GTK_BOX(hbox), mi_data->label, TRUE, TRUE, 0);
gtk_widget_show(mi_data->label);
/* Usually either the time or the count on the individual
item. */
- mi_data->right = gtk_label_new(dbusmenu_menuitem_property_get(newitem, APPOINTMENT_MENUITEM_PROP_RIGHT));
+ mi_data->right = gtk_label_new(dbusmenu_menuitem_property_get(newitem, TIMEZONE_MENUITEM_PROP_RIGHT));
gtk_size_group_add_widget(indicator_right_group, mi_data->right);
gtk_misc_set_alignment(GTK_MISC(mi_data->right), 1.0, 0.5);
gtk_box_pack_start(GTK_BOX(hbox), mi_data->right, FALSE, FALSE, 0);
gtk_widget_show(mi_data->right);
- gtk_container_add(GTK_CONTAINER(gmi), hbox);
+ gtk_container_add(GTK_CONTAINER(mi_data->gmi), hbox);
gtk_widget_show(hbox);
- dbusmenu_gtkclient_newitem_base(DBUSMENU_GTKCLIENT(client), newitem, gmi, parent);
+ dbusmenu_gtkclient_newitem_base(DBUSMENU_GTKCLIENT(client), newitem, GTK_MENU_ITEM(mi_data->gmi), parent);
+ g_signal_connect(G_OBJECT(mi_data->gmi), "toggled", G_CALLBACK(timezone_toggled_cb), newitem);
g_signal_connect(G_OBJECT(newitem), DBUSMENU_MENUITEM_SIGNAL_PROPERTY_CHANGED, G_CALLBACK(indicator_prop_change_cb), mi_data);
- g_signal_connect_swapped(G_OBJECT(newitem), "destroyed", G_CALLBACK(g_free), mi_data);
+ g_signal_connect(G_OBJECT(newitem), "destroyed", G_CALLBACK(timezone_destroyed_cb), mi_data);
return TRUE;
}