diff options
-rw-r--r-- | data/com.canonical.indicator.datetime.gschema.xml | 8 | ||||
-rw-r--r-- | src/datetime-service.c | 322 | ||||
-rw-r--r-- | src/indicator-datetime.c | 66 |
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; } |