aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/datetime-service.c229
1 files changed, 94 insertions, 135 deletions
diff --git a/src/datetime-service.c b/src/datetime-service.c
index c7b2f69..c59c05b 100644
--- a/src/datetime-service.c
+++ b/src/datetime-service.c
@@ -82,9 +82,6 @@ static DbusmenuMenuitem * calendar = NULL;
static DbusmenuMenuitem * settings = NULL;
static DbusmenuMenuitem * events_separator = 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;
static GList * appointments = NULL;
static GList * location_menu_items = NULL;
@@ -110,112 +107,69 @@ struct comp_instance {
ESource *source;
};
-static void
-set_current_timezone_label (DbusmenuMenuitem * mi, const gchar * location)
-{
- gchar * name = get_current_zone_name (location);
-
- dbusmenu_menuitem_property_set (mi, TIMEZONE_MENUITEM_PROP_NAME, name);
- dbusmenu_menuitem_property_set (mi, TIMEZONE_MENUITEM_PROP_ZONE, location);
-
- g_free (name);
-}
-
/**
* A temp struct used by update_location_menu_items() for pruning duplicates.
*/
-struct NameAndOffset
+struct TimeLocation
{
- gchar * name;
gint32 offset;
+ gchar * zone;
+ gchar * name;
};
static void
-name_and_offset_free (struct NameAndOffset * nao)
+time_location_free (struct TimeLocation * loc)
{
- g_free (nao->name);
- g_free (nao);
+ g_free (loc->name);
+ g_free (loc->zone);
+ g_free (loc);
}
-static struct NameAndOffset*
-name_and_offset_new (const char * zone, const char * name)
+static struct TimeLocation*
+time_location_new (const char * zone, const char * name)
{
- struct NameAndOffset * nao = g_new (struct NameAndOffset, 1);
- nao->name = g_strdup (name);
+ struct TimeLocation * loc = g_new (struct TimeLocation, 1);
GTimeZone * tz = g_time_zone_new (zone);
- nao->offset = g_time_zone_get_offset (tz, 0);
+ loc->offset = g_time_zone_get_offset (tz, 0);
+ loc->zone = g_strdup (zone);
+ loc->name = g_strdup (name);
g_time_zone_unref (tz);
- return nao;
-}
-static struct NameAndOffset*
-name_and_offset_new_from_item (DbusmenuMenuitem * mi)
-{
- const char * zone = dbusmenu_menuitem_property_get (mi, TIMEZONE_MENUITEM_PROP_ZONE);
- const char * name = dbusmenu_menuitem_property_get (mi, TIMEZONE_MENUITEM_PROP_NAME);
- return name_and_offset_new (zone, name);
+ return loc;
}
static int
-name_and_offset_compare (const struct NameAndOffset * a, const struct NameAndOffset * b)
+time_location_compare (const struct TimeLocation * a, const struct TimeLocation * b)
{
+ int ret;
if (a->offset != b->offset)
- return a->offset - b->offset;
- return g_strcmp0 (a->name, b->name);
+ ret = a->offset - b->offset;
+ else
+ ret = g_strcmp0 (a->name, b->name);
+ g_debug ("%s comparing '%s' (%d) to '%s' (%d), returning %d", G_STRLOC, a->name, (int)a->offset, b->name, (int)b->offset, ret);
+ return ret;
}
+static GSList*
+locations_add (GSList * locations, const char * zone, const char * name)
+{
+ struct TimeLocation * loc = time_location_new (zone, name);
+ if (g_slist_find_custom (locations, loc, (GCompareFunc)time_location_compare) == NULL) {
+ g_debug ("%s Adding zone '%s', name '%s'", G_STRLOC, zone, name);
+ locations = g_slist_prepend (locations, loc);
+ } else {
+ g_debug("%s Skipping duplicate zone '%s' name '%s'", G_STRLOC, zone, name);
+ time_location_free (loc);
+ }
+ return locations;
+}
-/* Update the timezone entries: geo_location, current_location,
- and the user-supplied custom locations */
+/* Update the timezone entries */
static void
update_location_menu_items (void)
{
- if (get_greeter_mode ())
+ if (locations_separator == NULL)
return;
- g_return_if_fail (locations_separator != NULL);
- g_return_if_fail (geo_location != NULL);
- g_return_if_fail (current_location != NULL);
-
- GSList * visible_locations = NULL;
- gchar ** locations = g_settings_get_strv(conf, SETTINGS_LOCATIONS_S);
- const guint location_count = locations ? g_strv_length(locations) : 0;
- g_debug ("%s Found %u locations from %s", G_STRLOC, location_count, SETTINGS_LOCATIONS_S);
-
- const gboolean show_all = g_settings_get_boolean (conf, SETTINGS_SHOW_LOCATIONS_S);
-
- /* the timezones are in sync if they don't disagree with each other */
- const gboolean in_sync = !geo_timezone
- || !current_timezone
- || !g_strcmp0 (geo_timezone, current_timezone);
-
- /* decide whether or not to show the builtin locations */
- gboolean show_sep;
- gboolean show_geo;
- gboolean show_cur;
- if (in_sync && !location_count) {
- /* if the builtin timezones match, and there aren't any user user-specified locations,
- then there's nothing interesting going on ... don't show anything */
- show_sep = FALSE;
- show_geo = FALSE;
- show_cur = FALSE;
- } else {
- /* if there are user-specified locations, show at least one builtin.
- if the two builtins disagree, show both of them. */
- show_sep = TRUE;
- show_geo = geo_timezone != NULL;
- show_cur = (current_timezone != NULL) && (!in_sync || !show_geo);
- }
-
- /* maybe add the builtin locations */
- if (show_geo) {
- g_debug ("%s showing geo_timezone '%s'", G_STRLOC, geo_timezone);
- set_current_timezone_label (geo_location, geo_timezone);
- visible_locations = g_slist_prepend (visible_locations, name_and_offset_new_from_item (geo_location));
- }
- if (show_cur) {
- g_debug ("%s showing current_timezone '%s'", G_STRLOC, current_timezone);
- set_current_timezone_label (current_location, current_timezone);
- visible_locations = g_slist_prepend (visible_locations, name_and_offset_new_from_item (current_location));
- }
+ GSList * locations = NULL;
- /* remove the previous user-specified locations */
+ /* remove the previous locations */
while (location_menu_items != NULL) {
DbusmenuMenuitem * item = DBUSMENU_MENUITEM(location_menu_items->data);
location_menu_items = g_list_remove(location_menu_items, item);
@@ -223,50 +177,70 @@ update_location_menu_items (void)
g_object_unref(G_OBJECT(item));
}
- /* add the user-specified locations */
- if (locations != NULL) {
+ /***
+ **** Build a list of locations to add: use geo_timezone,
+ **** current_timezone, and SETTINGS_LOCATIONS_S, but omit duplicates.
+ ***/
+
+ /* maybe add geo_timezone */
+ if (geo_timezone != NULL) {
+ gchar * name = get_current_zone_name (geo_timezone);
+ locations = locations_add (locations, geo_timezone, name);
+ g_free (name);
+ }
+
+ /* maybe add current_timezone */
+ if (current_timezone != NULL) {
+ gchar * name = get_current_zone_name (current_timezone);
+ locations = locations_add (locations, current_timezone, name);
+ g_free (name);
+ }
+
+ /* maybe add the user-specified custom locations */
+ gchar ** user_locations = g_settings_get_strv(conf, SETTINGS_LOCATIONS_S);
+ if (user_locations != NULL) {
gint i;
- gint offset = dbusmenu_menuitem_get_position (current_location, root)+1;
+ const guint location_count = g_strv_length(user_locations);
+ g_debug ("%s Found %u user-specified locations", G_STRLOC, location_count);
for (i=0; i<location_count; i++) {
gchar * zone;
gchar * name;
- const char * location = locations[i];
- split_settings_location (location, &zone, &name);
-
- /* if it doesn't duplicate one that we've already got, add it */
- struct NameAndOffset * nao = name_and_offset_new (zone, name);
- if (g_slist_find_custom (visible_locations, nao, (GCompareFunc)name_and_offset_compare) != NULL) {
- g_debug("%s Skipping duplicate timezone '%s'", G_STRLOC, location);
- name_and_offset_free (nao);
- } else {
- g_debug("%s Adding timezone '%s'", G_STRLOC, location);
- DbusmenuMenuitem * item = dbusmenu_menuitem_new();
- dbusmenu_menuitem_property_set (item, DBUSMENU_MENUITEM_PROP_TYPE, TIMEZONE_MENUITEM_TYPE);
- dbusmenu_menuitem_property_set (item, TIMEZONE_MENUITEM_PROP_NAME, name);
- dbusmenu_menuitem_property_set (item, TIMEZONE_MENUITEM_PROP_ZONE, zone);
- 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, show_all);
- 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);
- visible_locations = g_slist_prepend (visible_locations, nao);
- location_menu_items = g_list_append (location_menu_items, item);
- }
-
+ split_settings_location (user_locations[i], &zone, &name);
+ locations = locations_add (locations, zone, name);
g_free (name);
g_free (zone);
}
- g_strfreev (locations);
+ g_strfreev (user_locations);
+ user_locations = NULL;
}
- g_slist_free_full (visible_locations, (GDestroyNotify)name_and_offset_free);
-
- dbusmenu_menuitem_property_set_bool (locations_separator, DBUSMENU_MENUITEM_PROP_VISIBLE, show_all && show_sep);
- dbusmenu_menuitem_property_set_bool (geo_location, TIMEZONE_MENUITEM_PROP_RADIO, TRUE);
- dbusmenu_menuitem_property_set_bool (geo_location, DBUSMENU_MENUITEM_PROP_ENABLED, TRUE);
- dbusmenu_menuitem_property_set_bool (geo_location, DBUSMENU_MENUITEM_PROP_VISIBLE, show_all && show_geo);
- dbusmenu_menuitem_property_set_bool (current_location, TIMEZONE_MENUITEM_PROP_RADIO, TRUE);
- dbusmenu_menuitem_property_set_bool (current_location, DBUSMENU_MENUITEM_PROP_ENABLED, TRUE);
- dbusmenu_menuitem_property_set_bool (current_location, DBUSMENU_MENUITEM_PROP_VISIBLE, show_all && show_cur);
+
+ /* sort the list by timezone offset */
+ locations = g_slist_sort (locations, (GCompareFunc)time_location_compare);
+
+ /* finally create menuitems for each location */
+ gint offset = dbusmenu_menuitem_get_position (locations_separator, root)+1;
+ const gboolean show_locations = g_settings_get_boolean (conf, SETTINGS_SHOW_LOCATIONS_S);
+ GSList * l;
+ for (l=locations; l!=NULL; l=l->next) {
+ struct TimeLocation * loc = l->data;
+ g_debug("%s Adding location: zone '%s', name '%s'", G_STRLOC, loc->zone, loc->name);
+ DbusmenuMenuitem * item = dbusmenu_menuitem_new();
+ dbusmenu_menuitem_property_set (item, DBUSMENU_MENUITEM_PROP_TYPE, TIMEZONE_MENUITEM_TYPE);
+ dbusmenu_menuitem_property_set (item, TIMEZONE_MENUITEM_PROP_NAME, loc->name);
+ dbusmenu_menuitem_property_set (item, TIMEZONE_MENUITEM_PROP_ZONE, loc->zone);
+ 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, show_locations);
+ 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);
+ location_menu_items = g_list_append (location_menu_items, item);
+ time_location_free (loc);
+ }
+ g_slist_free (locations);
+ locations = NULL;
+
+ /* if there's at least one item being shown, show the separator too */
+ dbusmenu_menuitem_property_set_bool (locations_separator, DBUSMENU_MENUITEM_PROP_VISIBLE, show_locations && (location_menu_items!=NULL));
}
/* Update the current timezone */
@@ -1135,21 +1109,6 @@ build_menus (DbusmenuMenuitem * root)
dbusmenu_menuitem_property_set_bool (locations_separator, DBUSMENU_MENUITEM_PROP_VISIBLE, FALSE);
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);
- set_current_timezone_label (geo_location, "");
- 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);
- set_current_timezone_label (current_location, "");
- dbusmenu_menuitem_property_set_bool (current_location, DBUSMENU_MENUITEM_PROP_ENABLED, FALSE);
- dbusmenu_menuitem_property_set_bool (current_location, DBUSMENU_MENUITEM_PROP_VISIBLE, FALSE);
- dbusmenu_menuitem_child_append(root, current_location);
-
update_location_menu_items();
g_signal_connect (conf, "changed::" SETTINGS_SHOW_LOCATIONS_S, G_CALLBACK (show_locations_changed), NULL);