From 82b87171839e3dc3b5011dfff5ff92c96fd1c2c3 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Wed, 3 Oct 2012 17:08:14 -0500 Subject: fix populate_appointment_instances() to use ECalComponents instead of ECalClients. --- src/datetime-service.c | 62 ++++++++++++++++---------------------------------- 1 file changed, 19 insertions(+), 43 deletions(-) (limited to 'src/datetime-service.c') diff --git a/src/datetime-service.c b/src/datetime-service.c index ccdfe14..441cbf0 100644 --- a/src/datetime-service.c +++ b/src/datetime-service.c @@ -636,53 +636,29 @@ comp_instance_free (struct comp_instance* ci) } static gboolean -populate_appointment_instances (ECalClient * client, +populate_appointment_instances (ECalComponent * comp, time_t start, time_t end, gpointer data) { - GSList *ecalcomps, *comp_item; - - if (e_cal_client_get_object_list_as_comps_sync (client, - NULL, - &ecalcomps, - NULL, NULL)) { - - for (comp_item = ecalcomps; comp_item; comp_item = g_slist_next(comp_item)) { - ECalComponent *comp = comp_item->data; - - g_debug("Appending item %p", e_cal_component_get_as_string(comp)); - - ECalComponentVType vtype = e_cal_component_get_vtype (comp); - if (vtype != E_CAL_COMPONENT_EVENT && vtype != E_CAL_COMPONENT_TODO) return FALSE; - - icalproperty_status status; - e_cal_component_get_status (comp, &status); - if (status == ICAL_STATUS_COMPLETED || status == ICAL_STATUS_CANCELLED) return FALSE; - - g_object_ref(comp); - - ECalComponentDateTime datetime; - icaltimezone *appointment_zone = NULL; - icaltimezone *current_zone = NULL; - - if (vtype == E_CAL_COMPONENT_EVENT) - e_cal_component_get_dtstart (comp, &datetime); - else - e_cal_component_get_due (comp, &datetime); - - 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 = current_zone; - } + const ECalComponentVType vtype = e_cal_component_get_vtype (comp); + + if ((vtype == E_CAL_COMPONENT_EVENT) || (vtype == E_CAL_COMPONENT_TODO)) + { + icalproperty_status status; + e_cal_component_get_status (comp, &status); + + if ((status != ICAL_STATUS_COMPLETED) && (status != ICAL_STATUS_CANCELLED)) + { + gchar * str = e_cal_component_get_as_string (comp); + g_debug("Appending item %s", str); + struct comp_instance *ci = comp_instance_new (comp, start, end, E_SOURCE(data)); + comp_instances = g_list_append (comp_instances, ci); + g_free (str); + } + } - struct comp_instance *ci = comp_instance_new (comp, start, end, E_SOURCE(data)); - comp_instances = g_list_append (comp_instances, ci); - } - return TRUE; - } - return FALSE; + return TRUE; /* tell ecal to keep iterating */ } /* Populate the menu with todays, next 5 appointments. @@ -691,7 +667,7 @@ populate_appointment_instances (ECalClient * client, * this is a problem mainly on the EDS side of things, not ours. */ static gboolean -update_appointment_menu_items (gpointer user_data) +update_appointment_menu_items (gpointer unused) { // FFR: we should take into account short term timers, for instance // tea timers, pomodoro timers etc... that people may add, this is hinted to in the spec. -- cgit v1.2.3 From bf4edf2bc976a6ac8459d7f8583269c6a3ca6f2a Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Wed, 3 Oct 2012 17:51:58 -0500 Subject: don't use gconf to see if evolution accounts are installed -- we can have calendars even if gconf returns empty --- src/datetime-service.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) (limited to 'src/datetime-service.c') diff --git a/src/datetime-service.c b/src/datetime-service.c index 441cbf0..0064519 100644 --- a/src/datetime-service.c +++ b/src/datetime-service.c @@ -29,7 +29,6 @@ with this program. If not, see . #include #include #include -#include #include #include @@ -91,7 +90,6 @@ static GList * comp_instances = NULL; static gboolean updating_appointments = FALSE; static time_t start_time_appointments = (time_t) 0; static GSettings * conf = NULL; -static GConfClient * gconf = NULL; /* Geoclue trackers */ @@ -537,12 +535,20 @@ calendar_app_is_usable (void) g_debug ("found calendar app: '%s'", evo); g_free (evo); - /* confirm that it's got an account set up... */ - GSList *accounts_list = gconf_client_get_list (gconf, "/apps/evolution/mail/accounts", GCONF_VALUE_STRING, NULL); - const guint n = g_slist_length (accounts_list); - g_debug ("found %u evolution accounts", n); - g_slist_free_full (accounts_list, g_free); - return n > 0; + /* see if there are any enabled calendars */ + gboolean has_enabled_calendar_source = FALSE; + ESourceRegistry * registry = e_source_registry_new_sync (NULL, NULL); + if (registry != NULL) { + GList * l = NULL; + GList * sources = NULL; + sources = e_source_registry_list_sources (registry, E_SOURCE_EXTENSION_CALENDAR); + for (l=sources; !has_enabled_calendar_source && l!=NULL; l=l->next) + has_enabled_calendar_source = e_source_get_enabled (E_SOURCE(l->data)); + g_list_free_full (sources, g_object_unref); + g_object_unref (registry); + } + + return has_enabled_calendar_source; } /* Looks for the calendar application and enables the item if @@ -1410,8 +1416,6 @@ main (int argc, char ** argv) /* Set up GSettings */ conf = g_settings_new(SETTINGS_INTERFACE); - /* Set up gconf for getting evolution enabled calendars */ - gconf = gconf_client_get_default(); // TODO Add a signal handler to catch gsettings changes and respond to them /* Building the base menu */ -- cgit v1.2.3 From 0048385ecec65c6bbfad527261ac9d8ac180d0ef Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Wed, 3 Oct 2012 22:56:10 -0500 Subject: Our client code for EDS 3.5 is triggering a periodic loop of rebuilds: 1. We create an ESource and listen for its "changed" signal. 2. EDS appears to be emitting a "changed" idly after the source is created. 3. We handle the changed event by rebuilding our source list... goto 1. This commit breaks the loop by building the appointment source list once on startup and keeping it as a private field. It adds upkeep code to rebuild the list when the EDS registry tells us that sources have been added or removed. --- src/datetime-service.c | 84 ++++++++++++++++++++++++++++++++------------------ 1 file changed, 54 insertions(+), 30 deletions(-) (limited to 'src/datetime-service.c') diff --git a/src/datetime-service.c b/src/datetime-service.c index 0064519..6d3c56a 100644 --- a/src/datetime-service.c +++ b/src/datetime-service.c @@ -90,6 +90,8 @@ static GList * comp_instances = NULL; static gboolean updating_appointments = FALSE; static time_t start_time_appointments = (time_t) 0; static GSettings * conf = NULL; +static ESourceRegistry * source_registry = NULL; +static GList * appointment_sources = NULL; /* Geoclue trackers */ @@ -535,20 +537,8 @@ calendar_app_is_usable (void) g_debug ("found calendar app: '%s'", evo); g_free (evo); - /* see if there are any enabled calendars */ - gboolean has_enabled_calendar_source = FALSE; - ESourceRegistry * registry = e_source_registry_new_sync (NULL, NULL); - if (registry != NULL) { - GList * l = NULL; - GList * sources = NULL; - sources = e_source_registry_list_sources (registry, E_SOURCE_EXTENSION_CALENDAR); - for (l=sources; !has_enabled_calendar_source && l!=NULL; l=l->next) - has_enabled_calendar_source = e_source_get_enabled (E_SOURCE(l->data)); - g_list_free_full (sources, g_object_unref); - g_object_unref (registry); - } - - return has_enabled_calendar_source; + /* see if there are any calendar sources */ + return appointment_sources > 0; } /* Looks for the calendar application and enables the item if @@ -688,7 +678,6 @@ update_appointment_menu_items (gpointer unused) GError *gerror = NULL; gint i; gint width = 0, height = 0; - ESourceRegistry * src_registry = NULL; GList * sources = NULL; // Get today & work out query times @@ -733,19 +722,10 @@ update_appointment_menu_items (gpointer unused) g_list_free_full (comp_instances, (GDestroyNotify)comp_instance_free); comp_instances = NULL; - src_registry = e_source_registry_new_sync (NULL, &gerror); - if (!src_registry) { - g_debug("Failed to get access to source registry: %s\n", gerror->message); - return FALSE; - } - - sources = e_source_registry_list_sources(src_registry, E_SOURCE_EXTENSION_CALENDAR); - // Generate instances for all sources - for (s = g_list_first (sources); s; s = g_list_next (s)) { + for (s=appointment_sources; s!=NULL; s=s->next) { ESource *source = E_SOURCE (s->data); - g_signal_connect (G_OBJECT(source), "changed", G_CALLBACK (update_appointment_menu_items), NULL); ECalClient *ecal = e_cal_client_new(source, E_CAL_CLIENT_SOURCE_TYPE_EVENTS, &gerror); icaltimezone* current_zone = icaltimezone_get_builtin_timezone(current_timezone); @@ -767,14 +747,14 @@ update_appointment_menu_items (gpointer unused) continue; } - e_cal_client_generate_instances (ecal, t1, t2, NULL, - (ECalRecurInstanceFn) populate_appointment_instances, - (gpointer) source, - NULL); + e_cal_client_generate_instances_sync (ecal, + t1, + t2, + populate_appointment_instances, + source); } g_object_unref(ecal); } - g_list_free_full (sources, g_object_unref); g_debug("Number of ECalComponents returned: %d", g_list_length(comp_instances)); GList *sorted_comp_instances = g_list_sort(comp_instances, compare_comp_instances); @@ -1398,6 +1378,34 @@ service_shutdown (IndicatorService * service, gpointer user_data) return; } +static void +free_appointment_sources (void) +{ + g_list_free_full (appointment_sources, g_object_unref); + appointment_sources = NULL; +} + +static void +init_appointment_sources (void) +{ + GList * l; + + appointment_sources = e_source_registry_list_sources (source_registry, E_SOURCE_EXTENSION_CALENDAR); + + for (l=appointment_sources; l!=NULL; l=l->next) + g_signal_connect (G_OBJECT(l->data), "changed", G_CALLBACK (update_appointment_menu_items), NULL); +} + +/* rebuilds both the appointment sources and menu */ +static void +update_appointments (void) +{ + free_appointment_sources (); + init_appointment_sources (); + + update_appointment_menu_items (NULL); +} + /* Function to build everything up. Entry point from asm. */ int main (int argc, char ** argv) @@ -1418,6 +1426,19 @@ main (int argc, char ** argv) conf = g_settings_new(SETTINGS_INTERFACE); // TODO Add a signal handler to catch gsettings changes and respond to them + /* Build our list of appointment calendar sources. + When a source changes, update our menu items. + When sources are added or removed, update our list and menu items. */ + source_registry = e_source_registry_new_sync (NULL, NULL); + g_object_connect (source_registry, + "signal::source-added", update_appointments, + "signal::source-removed", update_appointments, + "signal::source-changed", update_appointment_menu_items, + "signal::source-disabled", update_appointment_menu_items, + "signal::source-enabled", update_appointment_menu_items, + NULL); + init_appointment_sources (); + /* Building the base menu */ server = dbusmenu_server_new(MENU_OBJ); root = dbusmenu_menuitem_new(); @@ -1458,12 +1479,15 @@ main (int argc, char ** argv) mainloop = g_main_loop_new(NULL, FALSE); g_main_loop_run(mainloop); + free_appointment_sources(); + 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)); + g_object_unref(G_OBJECT(source_registry)); icaltimezone_free_builtin_timezones(); -- cgit v1.2.3 From 33e222af5379438fd002f1c816baf8f27c36a880 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Wed, 3 Oct 2012 23:42:04 -0500 Subject: a timing issue was causing the appointment menuitems to be grouped into the wrong section. Resolve this by creating them at the same time as the 'Add Event...' menuitem in the same group. --- src/datetime-service.c | 96 +++++++++++++++++++++----------------------------- 1 file changed, 40 insertions(+), 56 deletions(-) (limited to 'src/datetime-service.c') diff --git a/src/datetime-service.c b/src/datetime-service.c index 6d3c56a..bac7d7c 100644 --- a/src/datetime-service.c +++ b/src/datetime-service.c @@ -54,6 +54,8 @@ with this program. If not, see . /* how often to check for clock skew */ #define SKEW_CHECK_INTERVAL_SEC 10 +#define MAX_APPOINTMENT_MENUITEMS 5 + #define SKEW_DIFF_THRESHOLD_SEC (SKEW_CHECK_INTERVAL_SEC + 5) #ifdef HAVE_CCPANEL @@ -84,7 +86,7 @@ static DbusmenuMenuitem * settings = NULL; static DbusmenuMenuitem * events_separator = NULL; static DbusmenuMenuitem * locations_separator = NULL; static DbusmenuMenuitem * add_appointment = NULL; -static GList * appointments = NULL; +static DbusmenuMenuitem * appointments[MAX_APPOINTMENT_MENUITEMS]; static GSList * location_menu_items = NULL; static GList * comp_instances = NULL; static gboolean updating_appointments = FALSE; @@ -392,6 +394,15 @@ update_appointment_menu_items_idle (gpointer user_data) return FALSE; } +static void +hide_all_appointments (void) +{ + int i; + + for (i=0; idata); - dbusmenu_menuitem_property_set_bool(mi, DBUSMENU_MENUITEM_PROP_ENABLED, FALSE); - } + hide_all_appointments (); g_idle_add(update_appointment_menu_items_idle, NULL); return TRUE; @@ -439,11 +446,7 @@ day_selected_cb (DbusmenuMenuitem * menuitem, gchar *name, GVariant *variant, gu } } - GList * appointment; - for (appointment = appointments; appointment != NULL; appointment = g_list_next(appointment)) { - DbusmenuMenuitem * mi = DBUSMENU_MENUITEM(appointment->data); - dbusmenu_menuitem_property_set_bool(mi, DBUSMENU_MENUITEM_PROP_ENABLED, FALSE); - } + hide_all_appointments (); start_time_appointments = new_time; @@ -512,17 +515,7 @@ show_events_changed (void) } else { dbusmenu_menuitem_property_set_bool(add_appointment, DBUSMENU_MENUITEM_PROP_VISIBLE, FALSE); dbusmenu_menuitem_property_set_bool(events_separator, DBUSMENU_MENUITEM_PROP_VISIBLE, FALSE); - /* Remove all of the previous appointments */ - if (appointments != NULL) { - g_debug("Hiding old appointments"); - GList * appointment; - for (appointment = appointments; appointment != NULL; appointment = g_list_next(appointment)) { - DbusmenuMenuitem * litem = DBUSMENU_MENUITEM(appointment->data); - g_debug("Hiding old appointment: %p", litem); - // Remove all the existing menu items which are in appointments. - dbusmenu_menuitem_property_set_bool(DBUSMENU_MENUITEM(litem), DBUSMENU_MENUITEM_PROP_VISIBLE, FALSE); - } - } + hide_all_appointments (); stop_ecal_timer(); } } @@ -551,19 +544,32 @@ check_for_calendar (gpointer user_data) dbusmenu_menuitem_property_set_bool(date, DBUSMENU_MENUITEM_PROP_ENABLED, TRUE); if (!get_greeter_mode () && calendar_app_is_usable()) { + + int i; + int pos = 2; g_signal_connect (G_OBJECT(date), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK (activate_cb), "evolution -c calendar"); events_separator = dbusmenu_menuitem_new(); dbusmenu_menuitem_property_set(events_separator, DBUSMENU_MENUITEM_PROP_TYPE, DBUSMENU_CLIENT_TYPES_SEPARATOR); - dbusmenu_menuitem_child_add_position(root, events_separator, 2); + dbusmenu_menuitem_child_add_position(root, events_separator, pos++); + + for (i=0; idata); - g_debug("Hiding old appointment: %p", litem); - // Remove all the existing menu items which are in appointments. - dbusmenu_menuitem_property_set_bool(DBUSMENU_MENUITEM(litem), DBUSMENU_MENUITEM_PROP_VISIBLE, FALSE); - } - } + + hide_all_appointments (); gtk_icon_size_lookup(GTK_ICON_SIZE_MENU, &width, &height); if (width <= 0) width = 12; @@ -796,7 +792,6 @@ update_appointment_menu_items (gpointer unused) g_variant_builder_init (&markeddays, G_VARIANT_TYPE ("ai")); i = 0; - GList * cached_appointment = appointments; for (l = sorted_comp_instances; l; l = l->next) { struct comp_instance *ci = l->data; ECalComponent *ecalcomp = ci->comp; @@ -828,28 +823,17 @@ update_appointment_menu_items (gpointer unused) } else if (vtype == E_CAL_COMPONENT_TODO) { if (ci->end < start_time_appointments) continue; } - - if (i >= 5) continue; + + if (i >= MAX_APPOINTMENT_MENUITEMS) continue; i++; - if (cached_appointment == NULL) { - g_debug("Create menu item"); - - item = dbusmenu_menuitem_new(); - dbusmenu_menuitem_property_set (item, DBUSMENU_MENUITEM_PROP_TYPE, APPOINTMENT_MENUITEM_TYPE); - - dbusmenu_menuitem_child_add_position (root, item, 2+i); - appointments = g_list_append (appointments, item); // Keep track of the items here to make them easy to remove - } else { - item = DBUSMENU_MENUITEM(cached_appointment->data); - cached_appointment = g_list_next(cached_appointment); + item = appointments[i]; - /* Remove the icon as we might not replace it on error */ - dbusmenu_menuitem_property_remove(item, APPOINTMENT_MENUITEM_PROP_ICON); + /* Remove the icon as we might not replace it on error */ + dbusmenu_menuitem_property_remove(item, APPOINTMENT_MENUITEM_PROP_ICON); - /* Remove the activate handler */ - g_signal_handlers_disconnect_matched(G_OBJECT(item), G_SIGNAL_MATCH_FUNC, 0, 0, NULL, G_CALLBACK(activate_cb), NULL); - } + /* Remove the activate handler */ + g_signal_handlers_disconnect_matched(G_OBJECT(item), G_SIGNAL_MATCH_FUNC, 0, 0, NULL, G_CALLBACK(activate_cb), NULL); dbusmenu_menuitem_property_set_bool (item, DBUSMENU_MENUITEM_PROP_ENABLED, TRUE); dbusmenu_menuitem_property_set_bool (item, DBUSMENU_MENUITEM_PROP_VISIBLE, TRUE); -- cgit v1.2.3 From 938d25fd79ce9fed522c1fc7233aaa0c95120b38 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Thu, 4 Oct 2012 00:11:32 -0500 Subject: copyediting: tweak indentation --- src/datetime-service.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'src/datetime-service.c') diff --git a/src/datetime-service.c b/src/datetime-service.c index bac7d7c..217a779 100644 --- a/src/datetime-service.c +++ b/src/datetime-service.c @@ -824,9 +824,10 @@ update_appointment_menu_items (gpointer unused) if (ci->end < start_time_appointments) continue; } - if (i >= MAX_APPOINTMENT_MENUITEMS) continue; - i++; + if (i >= MAX_APPOINTMENT_MENUITEMS) + continue; + i++; item = appointments[i]; /* Remove the icon as we might not replace it on error */ @@ -1411,8 +1412,8 @@ main (int argc, char ** argv) // TODO Add a signal handler to catch gsettings changes and respond to them /* Build our list of appointment calendar sources. - When a source changes, update our menu items. - When sources are added or removed, update our list and menu items. */ + When a source changes, update our menu items. + When sources are added or removed, update our list and menu items. */ source_registry = e_source_registry_new_sync (NULL, NULL); g_object_connect (source_registry, "signal::source-added", update_appointments, @@ -1471,7 +1472,7 @@ main (int argc, char ** argv) g_object_unref(G_OBJECT(service)); g_object_unref(G_OBJECT(server)); g_object_unref(G_OBJECT(root)); - g_object_unref(G_OBJECT(source_registry)); + g_object_unref(G_OBJECT(source_registry)); icaltimezone_free_builtin_timezones(); -- cgit v1.2.3