From bbd56b119d18a83600c1be706078d3e0d759583d Mon Sep 17 00:00:00 2001 From: karl-qdh Date: Mon, 28 Feb 2011 16:45:59 +0000 Subject: Minor change for kenvandine to test sorting --- src/datetime-service.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/datetime-service.c b/src/datetime-service.c index 6303a98..a6e756e 100644 --- a/src/datetime-service.c +++ b/src/datetime-service.c @@ -422,8 +422,10 @@ compare_appointment_items (ECalComponent *a, ECalComponentVType vtype = e_cal_component_get_vtype (a); - if (vtype != E_CAL_COMPONENT_EVENT && vtype != E_CAL_COMPONENT_TODO) return -1; - + if (vtype != E_CAL_COMPONENT_EVENT && vtype != E_CAL_COMPONENT_TODO) { + g_debug("E-Cal Component is neither an event or a todo"); + return -1; + } if (vtype == E_CAL_COMPONENT_EVENT) e_cal_component_get_dtstart (a, &datetime_a); else @@ -432,8 +434,11 @@ compare_appointment_items (ECalComponent *a, t_a = mktime(&tm_a); vtype = e_cal_component_get_vtype (b); - if (vtype != E_CAL_COMPONENT_EVENT && vtype != E_CAL_COMPONENT_TODO) return 1; - + if (vtype != E_CAL_COMPONENT_EVENT && vtype != E_CAL_COMPONENT_TODO) { + e_cal_component_free_datetime (&datetime_a); + g_debug("E-Cal Component is neither an event or a todo"); + return -1; + } if (vtype == E_CAL_COMPONENT_EVENT) e_cal_component_get_dtstart (b, &datetime_b); else -- cgit v1.2.3 From cf5abb9ac1ec68e2e1acd8d252611d40ff244a2b Mon Sep 17 00:00:00 2001 From: karl-qdh Date: Tue, 1 Mar 2011 17:05:51 +0000 Subject: These changes should fix the problems with the recurring appointments and dconf changes for show/hide events --- src/datetime-service.c | 129 +++++++++++++++++++++++++++++++++---------------- 1 file changed, 88 insertions(+), 41 deletions(-) diff --git a/src/datetime-service.c b/src/datetime-service.c index a6e756e..fd73024 100644 --- a/src/datetime-service.c +++ b/src/datetime-service.c @@ -73,6 +73,7 @@ static DatetimeInterface * dbus = NULL; static DbusmenuMenuitem * date = NULL; 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; @@ -278,8 +279,38 @@ month_changed_cb (DbusmenuMenuitem * menuitem, GVariant *variant, guint timestam return TRUE; } +static guint ecaltimer = 0; + +static void +start_ecal_timer(void) +{ + if (ecaltimer != 0) g_source_remove(ecaltimer); + if (update_appointment_menu_items(NULL)) + ecaltimer = g_timeout_add_seconds(60*5, update_appointment_menu_items, NULL); +} + +static void +stop_ecal_timer(void) +{ + if (ecaltimer != 0) g_source_remove(ecaltimer); +} + +static void +show_events_changed (void) +{ + if (g_settings_get_boolean(conf, SETTINGS_SHOW_EVENTS_S)) { + dbusmenu_menuitem_property_set_bool(add_appointment, DBUSMENU_MENUITEM_PROP_VISIBLE, TRUE); + dbusmenu_menuitem_property_set_bool(events_separator, DBUSMENU_MENUITEM_PROP_VISIBLE, TRUE); + start_ecal_timer(); + } 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); + stop_ecal_timer(); + } +} + /* Looks for the calendar application and enables the item if - we have one */ + we have one, starts ecal timer if events are turned on */ static gboolean check_for_calendar (gpointer user_data) { @@ -293,21 +324,26 @@ check_for_calendar (gpointer user_data) dbusmenu_menuitem_property_set_bool(calendar, DBUSMENU_MENUITEM_PROP_ENABLED, TRUE); dbusmenu_menuitem_property_set_bool(calendar, DBUSMENU_MENUITEM_PROP_VISIBLE, TRUE); - 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, 2); - + 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); add_appointment = dbusmenu_menuitem_new(); - dbusmenu_menuitem_property_set (add_appointment, DBUSMENU_MENUITEM_PROP_LABEL, _("Add Appointment")); + 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 the calendar items every 5 minutes if it updates the first time - if (update_appointment_menu_items(NULL)) - g_timeout_add_seconds(60*5, update_appointment_menu_items, NULL); - + + if (g_settings_get_boolean(conf, SETTINGS_SHOW_EVENTS_S)) { + dbusmenu_menuitem_property_set_bool(add_appointment, DBUSMENU_MENUITEM_PROP_VISIBLE, TRUE); + dbusmenu_menuitem_property_set_bool(events_separator, DBUSMENU_MENUITEM_PROP_VISIBLE, TRUE); + start_ecal_timer(); + } 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); + stop_ecal_timer(); + } + // Connect to event::month-changed g_signal_connect(calendar, "event::month-changed", G_CALLBACK(month_changed_cb), NULL); g_free(evo); @@ -381,7 +417,11 @@ update_timezone_menu_items(gpointer user_data) { // Authentication function static gchar * -auth_func (ECal *ecal, const gchar *prompt, const gchar *key, gpointer user_data) { +auth_func (ECal *ecal, + const gchar *prompt, + const gchar *key, + gpointer user_data) +{ gboolean remember; // TODO: Is this useful? Should we be storing it somewhere? ESource *source = e_cal_get_source (ecal); gchar *auth_domain = e_source_get_duped_property (source, "auth-domain"); @@ -411,8 +451,8 @@ auth_func (ECal *ecal, const gchar *prompt, const gchar *key, gpointer user_data // Compare function for g_list_sort of ECalComponent objects static gint compare_appointment_items (ECalComponent *a, - ECalComponent *b) { - + ECalComponent *b) +{ ECalComponentDateTime datetime_a, datetime_b; struct tm tm_a, tm_b; time_t t_a, t_b; @@ -422,10 +462,8 @@ compare_appointment_items (ECalComponent *a, ECalComponentVType vtype = e_cal_component_get_vtype (a); - if (vtype != E_CAL_COMPONENT_EVENT && vtype != E_CAL_COMPONENT_TODO) { - g_debug("E-Cal Component is neither an event or a todo"); - return -1; - } + if (vtype != E_CAL_COMPONENT_EVENT && vtype != E_CAL_COMPONENT_TODO) return -1; + if (vtype == E_CAL_COMPONENT_EVENT) e_cal_component_get_dtstart (a, &datetime_a); else @@ -434,11 +472,8 @@ compare_appointment_items (ECalComponent *a, t_a = mktime(&tm_a); vtype = e_cal_component_get_vtype (b); - if (vtype != E_CAL_COMPONENT_EVENT && vtype != E_CAL_COMPONENT_TODO) { - e_cal_component_free_datetime (&datetime_a); - g_debug("E-Cal Component is neither an event or a todo"); - return -1; - } + if (vtype != E_CAL_COMPONENT_EVENT && vtype != E_CAL_COMPONENT_TODO) return 1; + if (vtype == E_CAL_COMPONENT_EVENT) e_cal_component_get_dtstart (b, &datetime_b); else @@ -447,12 +482,29 @@ compare_appointment_items (ECalComponent *a, t_b = mktime(&tm_b); // Compare datetime_a and datetime_b, newest first in this sort. - if (t_a > t_b) retval = 1; - else if (t_a < t_b) retval = -1; - - e_cal_component_free_datetime (&datetime_a); - e_cal_component_free_datetime (&datetime_b); - return retval; + if (t_a > t_b) return = 1; + else if (t_a < t_b) return = -1; +} + +static gboolean +populate_appointment_instances (ECalComponent *comp, + time_t instance_start, + time_t instance_end, + gpointer data) +{ + // DEBUG what is the address of "objects" from data + + // The aim here is to receive a usable pointer to the objects list + // append to it, and change the list that data points at. + // this is a crafty hack so we're able to sort the items afterwards + GList *objects = (GList *)data; + data = (GList *)g_list_append(objects, comp); + + // DEBUG objects should have changed in the resultant location too + + // TODO We also may as well use this opportunity to "mark days" in the calendar + // as we're iterating everything of interest here anyway. + return TRUE; } /* Populate the menu with todays, next 5 appointments. @@ -461,7 +513,8 @@ compare_appointment_items (ECalComponent *a, * 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 user_data) +{ // 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. if (calendar == NULL) return FALSE; @@ -481,8 +534,6 @@ update_appointment_menu_items (gpointer user_data) { time(&t2); t2 += (time_t) (7 * 24 * 60 * 60); /* 7 days ahead of now */ - is = isodate_from_time_t(t1); - ie = isodate_from_time_t(t2); gtk_icon_size_lookup(GTK_ICON_SIZE_MENU, &width, &height); @@ -502,7 +553,7 @@ update_appointment_menu_items (gpointer user_data) { // TODO Remove all highlights from the calendar widget // 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); + //query = g_strdup_printf("(occur-in-time-range? (make-time\"%s\") (make-time\"%s\"))", is, ie); if (!e_cal_get_sources(&sources, E_CAL_SOURCE_TYPE_EVENT, &gerror)) { g_debug("Failed to get ecal sources\n"); @@ -527,15 +578,10 @@ update_appointment_menu_items (gpointer user_data) { continue; } - 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); - gerror = NULL; - continue; - } + g_debug("Generating instances"); + e_cal_generate_instances (client, t1, t2, (ECalRecurInstanceFn) populate_appointment_instances, (gpointer) &objects); g_debug("Number of objects returned: %d", g_list_length(objects)); - + if (allobjects == NULL) { allobjects = objects; } else if (objects != NULL) { @@ -761,6 +807,7 @@ build_menus (DbusmenuMenuitem * root) check_timezone_sync(); g_signal_connect (conf, "changed::" SETTINGS_SHOW_LOCATIONS_S, G_CALLBACK (show_locations_changed), NULL); + g_signal_connect (conf, "changed::" SETTINGS_SHOW_EVENTS_S, G_CALLBACK (show_events_changed), NULL); DbusmenuMenuitem * separator = dbusmenu_menuitem_new(); dbusmenu_menuitem_property_set(separator, DBUSMENU_MENUITEM_PROP_TYPE, DBUSMENU_CLIENT_TYPES_SEPARATOR); -- cgit v1.2.3 From 4ebd048f21f54e01029d50d7d9fe0e9899bc25c2 Mon Sep 17 00:00:00 2001 From: karl-qdh Date: Tue, 1 Mar 2011 17:22:44 +0000 Subject: Fixes for the recurring tasks and events settings change, the pointers are currently a bit chewed up as I try to figure out the right way round to get this. --- src/datetime-service.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/datetime-service.c b/src/datetime-service.c index fd73024..33b9720 100644 --- a/src/datetime-service.c +++ b/src/datetime-service.c @@ -456,9 +456,8 @@ compare_appointment_items (ECalComponent *a, ECalComponentDateTime datetime_a, datetime_b; struct tm tm_a, tm_b; time_t t_a, t_b; - gint retval = 0; - if (a == NULL || b == NULL) return retval; + if (a == NULL || b == NULL) return 0; ECalComponentVType vtype = e_cal_component_get_vtype (a); @@ -482,8 +481,9 @@ compare_appointment_items (ECalComponent *a, t_b = mktime(&tm_b); // Compare datetime_a and datetime_b, newest first in this sort. - if (t_a > t_b) return = 1; - else if (t_a < t_b) return = -1; + if (t_a > t_b) return 1; + else if (t_a < t_b) return -1; + return 0; } static gboolean @@ -521,7 +521,7 @@ update_appointment_menu_items (gpointer user_data) if (!g_settings_get_boolean(conf, SETTINGS_SHOW_EVENTS_S)) return FALSE; time_t t1, t2; - gchar *query, *is, *ie, *ad; + gchar *ad; GList *objects = NULL, *l; GList *allobjects = NULL; GSList *g; @@ -579,7 +579,7 @@ update_appointment_menu_items (gpointer user_data) } g_debug("Generating instances"); - e_cal_generate_instances (client, t1, t2, (ECalRecurInstanceFn) populate_appointment_instances, (gpointer) &objects); + e_cal_generate_instances (ecal, t1, t2, (ECalRecurInstanceFn) populate_appointment_instances, (gpointer) objects); g_debug("Number of objects returned: %d", g_list_length(objects)); if (allobjects == NULL) { -- cgit v1.2.3 From 3abcff1218b921f7ab88ebf73c392a9c998a5df2 Mon Sep 17 00:00:00 2001 From: karl-qdh Date: Wed, 2 Mar 2011 12:16:05 +0000 Subject: Better handling of recurring items get_dtstart returns the same date for all items unfortunately --- src/datetime-service.c | 71 ++++++++++++++++++++++++++------------------------ 1 file changed, 37 insertions(+), 34 deletions(-) diff --git a/src/datetime-service.c b/src/datetime-service.c index 33b9720..d553240 100644 --- a/src/datetime-service.c +++ b/src/datetime-service.c @@ -81,6 +81,7 @@ static DbusmenuMenuitem * current_location = NULL; static DbusmenuMenuitem * add_appointment = NULL; static GList * appointments = NULL; static GList * dconflocations = NULL; +static GList * tmpobjects = NULL; GSettings *conf; @@ -449,19 +450,25 @@ auth_func (ECal *ecal, // Compare function for g_list_sort of ECalComponent objects -static gint +// Generate instances sorts them by time anyway +/*static gint compare_appointment_items (ECalComponent *a, ECalComponent *b) { + g_debug("Comparing two items from list %d %d", (int)a, (int)b); ECalComponentDateTime datetime_a, datetime_b; struct tm tm_a, tm_b; time_t t_a, t_b; + gint retval = 0; if (a == NULL || b == NULL) return 0; ECalComponentVType vtype = e_cal_component_get_vtype (a); - if (vtype != E_CAL_COMPONENT_EVENT && vtype != E_CAL_COMPONENT_TODO) return -1; + if (vtype != E_CAL_COMPONENT_EVENT && vtype != E_CAL_COMPONENT_TODO) { + g_debug("A is Not a todo or event"); + return 1; + } if (vtype == E_CAL_COMPONENT_EVENT) e_cal_component_get_dtstart (a, &datetime_a); @@ -471,7 +478,10 @@ compare_appointment_items (ECalComponent *a, t_a = mktime(&tm_a); vtype = e_cal_component_get_vtype (b); - if (vtype != E_CAL_COMPONENT_EVENT && vtype != E_CAL_COMPONENT_TODO) return 1; + if (vtype != E_CAL_COMPONENT_EVENT && vtype != E_CAL_COMPONENT_TODO) { + g_debug("B is Not a todo or event"); + return -1; + } if (vtype == E_CAL_COMPONENT_EVENT) e_cal_component_get_dtstart (b, &datetime_b); @@ -481,10 +491,16 @@ compare_appointment_items (ECalComponent *a, t_b = mktime(&tm_b); // Compare datetime_a and datetime_b, newest first in this sort. - if (t_a > t_b) return 1; - else if (t_a < t_b) return -1; + if (t_a > t_b) { + g_debug("A > B: %d > %d", (int)t_a, (int)t_b); + retval = 1; + } else if (t_a < t_b) { + g_debug("B > A: %d > %d", (int)t_b, (int)t_a); + retval = -1; + } + g_debug("A == B: %d == %d", (int)t_a, (int)t_b); return 0; -} +}*/ static gboolean populate_appointment_instances (ECalComponent *comp, @@ -492,15 +508,11 @@ populate_appointment_instances (ECalComponent *comp, time_t instance_end, gpointer data) { - // DEBUG what is the address of "objects" from data - - // The aim here is to receive a usable pointer to the objects list - // append to it, and change the list that data points at. - // this is a crafty hack so we're able to sort the items afterwards - GList *objects = (GList *)data; - data = (GList *)g_list_append(objects, comp); - - // DEBUG objects should have changed in the resultant location too + g_debug("Appending item %d", (int)comp); + ECalComponentVType vtype = e_cal_component_get_vtype (comp); + if (vtype != E_CAL_COMPONENT_EVENT && vtype != E_CAL_COMPONENT_TODO) return FALSE; + g_object_ref(comp); + tmpobjects = g_list_append(tmpobjects, comp); // TODO We also may as well use this opportunity to "mark days" in the calendar // as we're iterating everything of interest here anyway. @@ -522,17 +534,18 @@ update_appointment_menu_items (gpointer user_data) time_t t1, t2; gchar *ad; - GList *objects = NULL, *l; + GList *l; GList *allobjects = NULL; GSList *g; GError *gerror = NULL; + tmpobjects = NULL; gint i; gint width, height; ESourceList * sources = NULL; time(&t1); time(&t2); - t2 += (time_t) (7 * 24 * 60 * 60); /* 7 days ahead of now */ + t2 += (time_t) (7 * 24 * 60 * 60); /* 7 days ahead of now, we actually need number_of_days_in_this_month */ gtk_icon_size_lookup(GTK_ICON_SIZE_MENU, &width, &height); @@ -551,9 +564,6 @@ update_appointment_menu_items (gpointer user_data) } // TODO Remove all highlights from the calendar widget - - // 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); if (!e_cal_get_sources(&sources, E_CAL_SOURCE_TYPE_EVENT, &gerror)) { g_debug("Failed to get ecal sources\n"); @@ -579,21 +589,13 @@ update_appointment_menu_items (gpointer user_data) } g_debug("Generating instances"); - e_cal_generate_instances (ecal, t1, t2, (ECalRecurInstanceFn) populate_appointment_instances, (gpointer) objects); - 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_object_unref(objects); - } + e_cal_generate_instances (ecal, t1, t2, (ECalRecurInstanceFn) populate_appointment_instances, NULL); + g_debug("Number of objects returned: %d", g_list_length(tmpobjects)); } } + allobjects = tmpobjects; + tmpobjects = NULL; - // Sort the list see above FIXME regarding queries - g_debug("Sorting objects list"); - allobjects = g_list_sort(allobjects, (GCompareFunc) compare_appointment_items); i = 0; for (l = allobjects; l; l = l->next) { ECalComponent *ecalcomp = l->data; @@ -719,12 +721,13 @@ update_appointment_menu_items (gpointer user_data) 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 + + if (i == 4) break; i++; } if (gerror != NULL) g_error_free(gerror); + for (l = allobjects; l; l = l->next) g_object_unref(l->data); g_object_unref(allobjects); g_debug("End of objects"); return TRUE; -- cgit v1.2.3 From 7b2980b759af73f4ae6ac76409d10d908762d24f Mon Sep 17 00:00:00 2001 From: karl-qdh Date: Wed, 2 Mar 2011 13:31:45 +0000 Subject: * Fixed adding/removing locations not triggering update * Improved update appointment menu items code * Improved populate_appointment_instances * Opened up objects generation to include marking days --- src/datetime-service.c | 114 +++++++++++-------------------------------------- 1 file changed, 24 insertions(+), 90 deletions(-) diff --git a/src/datetime-service.c b/src/datetime-service.c index d553240..b748841 100644 --- a/src/datetime-service.c +++ b/src/datetime-service.c @@ -448,60 +448,6 @@ auth_func (ECal *ecal, return password; } - -// Compare function for g_list_sort of ECalComponent objects -// Generate instances sorts them by time anyway -/*static gint -compare_appointment_items (ECalComponent *a, - ECalComponent *b) -{ - g_debug("Comparing two items from list %d %d", (int)a, (int)b); - ECalComponentDateTime datetime_a, datetime_b; - struct tm tm_a, tm_b; - time_t t_a, t_b; - gint retval = 0; - - if (a == NULL || b == NULL) return 0; - - ECalComponentVType vtype = e_cal_component_get_vtype (a); - - if (vtype != E_CAL_COMPONENT_EVENT && vtype != E_CAL_COMPONENT_TODO) { - g_debug("A is Not a todo or event"); - return 1; - } - - if (vtype == E_CAL_COMPONENT_EVENT) - e_cal_component_get_dtstart (a, &datetime_a); - else - e_cal_component_get_due (a, &datetime_a); - tm_a = icaltimetype_to_tm(datetime_a.value); - t_a = mktime(&tm_a); - - vtype = e_cal_component_get_vtype (b); - if (vtype != E_CAL_COMPONENT_EVENT && vtype != E_CAL_COMPONENT_TODO) { - g_debug("B is Not a todo or event"); - return -1; - } - - if (vtype == E_CAL_COMPONENT_EVENT) - e_cal_component_get_dtstart (b, &datetime_b); - else - e_cal_component_get_due (b, &datetime_b); - tm_b = icaltimetype_to_tm(datetime_b.value); - t_b = mktime(&tm_b); - - // Compare datetime_a and datetime_b, newest first in this sort. - if (t_a > t_b) { - g_debug("A > B: %d > %d", (int)t_a, (int)t_b); - retval = 1; - } else if (t_a < t_b) { - g_debug("B > A: %d > %d", (int)t_b, (int)t_a); - retval = -1; - } - g_debug("A == B: %d == %d", (int)t_a, (int)t_b); - return 0; -}*/ - static gboolean populate_appointment_instances (ECalComponent *comp, time_t instance_start, @@ -511,11 +457,13 @@ populate_appointment_instances (ECalComponent *comp, g_debug("Appending item %d", (int)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); tmpobjects = g_list_append(tmpobjects, comp); - - // TODO We also may as well use this opportunity to "mark days" in the calendar - // as we're iterating everything of interest here anyway. return TRUE; } @@ -577,7 +525,7 @@ update_appointment_menu_items (gpointer user_data) for (s = e_source_group_peek_sources (group); s; s = s->next) { ESource *source = E_SOURCE (s->data); - g_signal_connect (G_OBJECT(source), "changed", G_CALLBACK (update_appointment_menu_items), NULL); + //g_signal_connect (G_OBJECT(source), "changed", G_CALLBACK (update_appointment_menu_items), NULL); ECal *ecal = e_cal_new(source, E_CAL_SOURCE_TYPE_EVENT); e_cal_set_auth_func (ecal, (ECalAuthFunc) auth_func, NULL); @@ -603,27 +551,27 @@ update_appointment_menu_items (gpointer user_data) ECalComponentDateTime datetime; icaltimezone *appointment_zone = NULL; icaltimezone *current_zone = NULL; - icalproperty_status status; gchar *summary, *cmd; char right[20]; //const gchar *uri; struct tm tmp_tm; DbusmenuMenuitem * item; - g_debug("Start Object"); + g_debug("Start Object %p", ecalcomp); ECalComponentVType vtype = e_cal_component_get_vtype (ecalcomp); - // See above FIXME regarding query result - // If it's not an event or todo, continue no-increment - if (vtype != E_CAL_COMPONENT_EVENT && vtype != E_CAL_COMPONENT_TODO) - continue; - - // See above FIXME regarding query result - // if the status is completed, continue no-increment - e_cal_component_get_status (ecalcomp, &status); - if (status == ICAL_STATUS_COMPLETED || status == ICAL_STATUS_CANCELLED) - continue; - + if (vtype == E_CAL_COMPONENT_EVENT) + e_cal_component_get_dtstart (ecalcomp, &datetime); + else + e_cal_component_get_due (ecalcomp, &datetime); + + if (!datetime.value) continue; + + // TODO Mark days with appointments in the current month + + if (i >= 5) continue; + i++; + item = dbusmenu_menuitem_new(); dbusmenu_menuitem_property_set (item, DBUSMENU_MENUITEM_PROP_TYPE, APPOINTMENT_MENUITEM_TYPE); dbusmenu_menuitem_property_set_bool (item, DBUSMENU_MENUITEM_PROP_ENABLED, TRUE); @@ -638,23 +586,13 @@ update_appointment_menu_items (gpointer user_data) g_free (summary); // Due text - if (vtype == E_CAL_COMPONENT_EVENT) - e_cal_component_get_dtstart (ecalcomp, &datetime); - else - e_cal_component_get_due (ecalcomp, &datetime); - - // FIXME need to get the timezone of the above datetime, - // and get the icaltimezone of the geoclue timezone/selected timezone (whichever is preferred) - if (!datetime.value) { - g_free(item); - 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 = current_zone; } + // FIXME need to get the timezone of the above datetime, + // and get the icaltimezone of the geoclue timezone/selected timezone (whichever is preferred) // 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. @@ -680,12 +618,11 @@ update_appointment_menu_items (gpointer user_data) e_cal_component_free_datetime (&datetime); - 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 - //e_cal_component_get_uid(ecalcomp, &uri); + ad = isodate_from_time_t(mktime(&tmp_tm)); cmd = g_strconcat("evolution calendar:///?startdate=", ad, NULL); g_signal_connect (G_OBJECT(item), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK (activate_cb), cmd); @@ -718,17 +655,13 @@ 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, 3+i); + dbusmenu_menuitem_child_add_position (root, item, 2+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; - i++; } if (gerror != NULL) g_error_free(gerror); for (l = allobjects; l; l = l->next) g_object_unref(l->data); - g_object_unref(allobjects); g_debug("End of objects"); return TRUE; } @@ -810,6 +743,7 @@ build_menus (DbusmenuMenuitem * root) check_timezone_sync(); g_signal_connect (conf, "changed::" SETTINGS_SHOW_LOCATIONS_S, G_CALLBACK (show_locations_changed), NULL); + g_signal_connect (conf, "changed::" SETTINGS_LOCATIONS_S, G_CALLBACK (show_locations_changed), NULL); g_signal_connect (conf, "changed::" SETTINGS_SHOW_EVENTS_S, G_CALLBACK (show_events_changed), NULL); DbusmenuMenuitem * separator = dbusmenu_menuitem_new(); -- cgit v1.2.3 From 44bd4d29adb79c74ffbedc551a5a2414d652e7b1 Mon Sep 17 00:00:00 2001 From: karl-qdh Date: Wed, 2 Mar 2011 14:00:41 +0000 Subject: Remove items from menu when the show events key changes --- src/datetime-service.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/datetime-service.c b/src/datetime-service.c index b748841..1983275 100644 --- a/src/datetime-service.c +++ b/src/datetime-service.c @@ -306,6 +306,18 @@ 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("Freeing old appointments"); + while (appointments != NULL) { + DbusmenuMenuitem * litem = DBUSMENU_MENUITEM(appointments->data); + g_debug("Freeing old appointment: %p", litem); + // Remove all the existing menu items which are in appointments. + appointments = g_list_remove(appointments, litem); + dbusmenu_menuitem_child_delete(root, DBUSMENU_MENUITEM(litem)); + g_object_unref(G_OBJECT(litem)); + } + } stop_ecal_timer(); } } -- cgit v1.2.3 From 64fe32bfc19ffbfcf83e9d047cd0ebc1b881a785 Mon Sep 17 00:00:00 2001 From: karl-qdh Date: Thu, 3 Mar 2011 12:45:11 +0000 Subject: This actually gets the current recurrance times etc... properly - we're close to getting colours too ;) --- src/datetime-service.c | 228 +++++++++++++++++++++++++++++++++++-------------- 1 file changed, 162 insertions(+), 66 deletions(-) diff --git a/src/datetime-service.c b/src/datetime-service.c index 1983275..2250c59 100644 --- a/src/datetime-service.c +++ b/src/datetime-service.c @@ -81,7 +81,7 @@ static DbusmenuMenuitem * current_location = NULL; static DbusmenuMenuitem * add_appointment = NULL; static GList * appointments = NULL; static GList * dconflocations = NULL; -static GList * tmpobjects = NULL; +static GList * comp_instances = NULL; GSettings *conf; @@ -93,6 +93,13 @@ static GeoclueAddress * geo_address = NULL; static gchar * current_timezone = NULL; static gchar * geo_timezone = NULL; +struct comp_instance { + ECalComponent *comp; + time_t start; + time_t end; + ESource *source; +}; + static void set_timezone_label (DbusmenuMenuitem * mi, const gchar * location) { @@ -460,13 +467,26 @@ auth_func (ECal *ecal, return password; } +static gint +compare_comp_instances (gconstpointer a, + gconstpointer b) +{ + const struct comp_instance *ci_a = a; + const struct comp_instance *ci_b = b; + time_t d = ci_a->start - ci_b->start; + if (d < 0) return -1; + else if (d > 0) return 1; + return 0; +} + static gboolean populate_appointment_instances (ECalComponent *comp, time_t instance_start, time_t instance_end, gpointer data) { - g_debug("Appending item %d", (int)comp); + g_debug("Appending item %p", comp); + ECalComponentVType vtype = e_cal_component_get_vtype (comp); if (vtype != E_CAL_COMPONENT_EVENT && vtype != E_CAL_COMPONENT_TODO) return FALSE; @@ -475,7 +495,63 @@ populate_appointment_instances (ECalComponent *comp, if (status == ICAL_STATUS_COMPLETED || status == ICAL_STATUS_CANCELLED) return FALSE; g_object_ref(comp); - tmpobjects = g_list_append(tmpobjects, 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; + } + + // 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. + + GSList *period_list = NULL, *l; + if (e_cal_component_has_recurrences (comp)) { + e_cal_component_get_rdate_list (comp, &period_list); + g_debug("ECalComponent has recurrences"); + } else { + g_debug("ECalComponent doesn't have recurrences"); + } + + struct comp_instance *ci; + ci = g_new (struct comp_instance, 1); + + // Do we get rdate_list? + if (period_list != NULL) { + g_debug("Got recurring periods"); + for (l = period_list; l; l = l->next) { + ECalComponentPeriod *period = l->data; + struct tm tmp_tm = icaltimetype_to_tm_with_zone (&period->start, appointment_zone, current_zone); + time_t start = mktime(&tmp_tm); + g_debug("period time: %d", (int)start); + + tmp_tm = icaltimetype_to_tm_with_zone (&period->u.end, appointment_zone, current_zone); + time_t end = mktime(&tmp_tm); + + if (start >= instance_start && end < instance_end) { + ci->start = start; + ci->end = end; + } + } + } else { + ci->start = instance_start; + ci->end = instance_end; + g_debug("Got no recurring periods set time to start %s, end %s", ctime(&instance_start), ctime(&instance_end)); + } + + ci->comp = comp; + ci->source = E_SOURCE(data); + + comp_instances = g_list_append(comp_instances, ci); return TRUE; } @@ -495,10 +571,9 @@ update_appointment_menu_items (gpointer user_data) time_t t1, t2; gchar *ad; GList *l; - GList *allobjects = NULL; + //GList *allobjects = NULL; GSList *g; GError *gerror = NULL; - tmpobjects = NULL; gint i; gint width, height; ESourceList * sources = NULL; @@ -507,9 +582,6 @@ update_appointment_menu_items (gpointer user_data) time(&t2); t2 += (time_t) (7 * 24 * 60 * 60); /* 7 days ahead of now, we actually need number_of_days_in_this_month */ - - gtk_icon_size_lookup(GTK_ICON_SIZE_MENU, &width, &height); - /* Remove all of the previous appointments */ if (appointments != NULL) { g_debug("Freeing old appointments"); @@ -529,7 +601,18 @@ update_appointment_menu_items (gpointer user_data) g_debug("Failed to get ecal sources\n"); return FALSE; } - + + // Free comp_instances if not NULL + if (comp_instances != NULL) { + g_debug("Freeing comp_instances: may be an overlap\n"); + for (l = comp_instances; l; l = l->next) { + const struct comp_instance *ci = l->data; + g_object_unref(ci->comp); + g_list_free(comp_instances); + comp_instances = NULL; + } + } + // 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); @@ -549,37 +632,31 @@ update_appointment_menu_items (gpointer user_data) } g_debug("Generating instances"); - e_cal_generate_instances (ecal, t1, t2, (ECalRecurInstanceFn) populate_appointment_instances, NULL); - g_debug("Number of objects returned: %d", g_list_length(tmpobjects)); + e_cal_generate_instances (ecal, t1, t2, (ECalRecurInstanceFn) populate_appointment_instances, (gpointer) source); + g_debug("Number of objects returned: %d", g_list_length(comp_instances)); } } - allobjects = tmpobjects; - tmpobjects = NULL; - + GList *sorted_comp_instances = g_list_sort(comp_instances, compare_comp_instances); + comp_instances = NULL; i = 0; - for (l = allobjects; l; l = l->next) { - ECalComponent *ecalcomp = l->data; + + gtk_icon_size_lookup(GTK_ICON_SIZE_MENU, &width, &height); + if (width == 0) width = 16; + if (height == 0) height = 16; + + for (l = sorted_comp_instances; l; l = l->next) { + struct comp_instance *ci = l->data; + ECalComponent *ecalcomp = ci->comp; ECalComponentText valuetext; - ECalComponentDateTime datetime; - icaltimezone *appointment_zone = NULL; - icaltimezone *current_zone = NULL; + //ECalComponentDateTime datetime; gchar *summary, *cmd; char right[20]; //const gchar *uri; - struct tm tmp_tm; DbusmenuMenuitem * item; g_debug("Start Object %p", ecalcomp); - ECalComponentVType vtype = e_cal_component_get_vtype (ecalcomp); - - if (vtype == E_CAL_COMPONENT_EVENT) - e_cal_component_get_dtstart (ecalcomp, &datetime); - else - e_cal_component_get_due (ecalcomp, &datetime); - - if (!datetime.value) continue; - // TODO Mark days with appointments in the current month + // TODO Mark days if (i >= 5) continue; i++; @@ -597,75 +674,89 @@ update_appointment_menu_items (gpointer user_data) g_debug("Summary: %s", summary); g_free (summary); - // Due text - 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; - } + //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; + //} // FIXME need to get the timezone of the above datetime, // and get the icaltimezone of the geoclue timezone/selected timezone (whichever is preferred) // 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); + //tmp_tm = icaltimetype_to_tm_with_zone (datetime.value, appointment_zone, current_zone); + + // Due text + ECalComponentVType vtype = e_cal_component_get_vtype (ecalcomp); - g_debug("Generate time string"); // Get today time_t curtime = time(NULL); - struct tm* today = localtime(&curtime); - if (today->tm_mday == tmp_tm.tm_mday && - today->tm_mon == tmp_tm.tm_mon && - today->tm_year == tmp_tm.tm_year) - strftime(right, 20, "%l:%M %P", &tmp_tm); + struct tm *today = localtime(&curtime); + + int mday = today->tm_mday; + int mon = today->tm_mon; + int year = today->tm_year; + + struct tm *due; + g_debug("Start time %s", ctime(&ci->start)); + if (vtype == E_CAL_COMPONENT_EVENT) due = localtime(&ci->start); + else if (vtype == E_CAL_COMPONENT_TODO) due = localtime(&ci->end); + else continue; + + strftime(right, 20, "%a %l:%M %p", due); + g_debug("Start time %s -> %s", asctime(due), right); + + int dmday = due->tm_mday; + int dmon = due->tm_mon; + int dyear = due->tm_year; + + if ((mday == dmday) && (mon == dmon) && (year == dyear)) + strftime(right, 20, "%l:%M %p", due); else - strftime(right, 20, "%a %l:%M %P", &tmp_tm); + strftime(right, 20, "%a %l:%M %p", due); 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("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); + //e_cal_component_free_datetime (&datetime); // 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 //e_cal_component_get_uid(ecalcomp, &uri); - ad = isodate_from_time_t(mktime(&tmp_tm)); + ad = isodate_from_time_t(mktime(due)); cmd = g_strconcat("evolution calendar:///?startdate=", ad, NULL); g_signal_connect (G_OBJECT(item), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK (activate_cb), cmd); g_debug("Command to Execute: %s", cmd); - - // FIXME This is now more difficult to get right with more sources, as we need to keep track - // of which ecal or source goes with each ECalComponent :/ - - //ESource *source = e_cal_get_source (ecal); - //e_source_get_color (source, &source_color); api has been changed - const gchar *color_spec = NULL; //e_source_peek_color_spec(source); + + const gchar *color_spec = e_source_peek_color_spec(ci->source); g_debug("Colour to use: %s", color_spec); // Draw the correct icon for the appointment type and then tint it using mask fill. // For now we'll create a circle if (color_spec != NULL) { - GdkColor color; + // Fixme causes segfault, but we have colours now yay! + /*GdkColor color; gdk_color_parse (color_spec, &color); - - cairo_surface_t *cs = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height); - cairo_t *cr = cairo_create(cs); - cairo_arc (cr, width/2, height/2, width/2, 0, 2 * M_PI); - gdk_cairo_set_source_color(cr, &color); - cairo_fill(cr); + GdkPixmap *pixmap = gdk_pixmap_new(NULL, width, height, 32); + if (pixmap != NULL) { + cairo_t *cr = gdk_cairo_create(pixmap); + cairo_arc (cr, width/2, height/2, width/2, 0, 2 * M_PI); + gdk_cairo_set_source_color(cr, &color); + cairo_fill(cr); - GdkPixbuf * pixbuf = gdk_pixbuf_get_from_drawable(NULL, (GdkDrawable*)cs, - gdk_colormap_new(gdk_drawable_get_visual((GdkDrawable*)cs), TRUE), 0,0,0,0, width, height); - cairo_destroy(cr); + GdkPixbuf * pixbuf = gdk_pixbuf_get_from_drawable(NULL, (GdkDrawable*)pixmap, + gdk_colormap_new(gdk_drawable_get_visual((GdkDrawable*)pixmap), TRUE), 0,0,0,0, width, height); + cairo_destroy(cr); - dbusmenu_menuitem_property_set_image (item, APPOINTMENT_MENUITEM_PROP_ICON, pixbuf); + dbusmenu_menuitem_property_set_image (item, APPOINTMENT_MENUITEM_PROP_ICON, pixbuf); + }*/ } dbusmenu_menuitem_child_add_position (root, item, 2+i); appointments = g_list_append (appointments, item); // Keep track of the items here to make them east to remove @@ -673,7 +764,12 @@ update_appointment_menu_items (gpointer user_data) } if (gerror != NULL) g_error_free(gerror); - for (l = allobjects; l; l = l->next) g_object_unref(l->data); + for (l = sorted_comp_instances; l; l = l->next) { + const struct comp_instance *ci = l->data; + g_object_unref(ci->comp); + g_list_free(sorted_comp_instances); + } + g_debug("End of objects"); return TRUE; } -- cgit v1.2.3 From 27e4da12f64cf3fbb3ae581a70503865c64e76b2 Mon Sep 17 00:00:00 2001 From: karl-qdh Date: Thu, 3 Mar 2011 13:46:29 +0000 Subject: Added decent conversion from cairo context to pixbuf and updated the colour code so it works. Currently we show a rectangle, but we could equally use a mask. --- src/datetime-service.c | 66 ++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 50 insertions(+), 16 deletions(-) diff --git a/src/datetime-service.c b/src/datetime-service.c index 2250c59..45546a0 100644 --- a/src/datetime-service.c +++ b/src/datetime-service.c @@ -641,8 +641,8 @@ update_appointment_menu_items (gpointer user_data) i = 0; gtk_icon_size_lookup(GTK_ICON_SIZE_MENU, &width, &height); - if (width == 0) width = 16; - if (height == 0) height = 16; + if (width == 0) width = 12; + if (height == 0) height = 12; for (l = sorted_comp_instances; l; l = l->next) { struct comp_instance *ci = l->data; @@ -742,21 +742,55 @@ update_appointment_menu_items (gpointer user_data) // For now we'll create a circle if (color_spec != NULL) { // Fixme causes segfault, but we have colours now yay! - /*GdkColor color; - gdk_color_parse (color_spec, &color); - GdkPixmap *pixmap = gdk_pixmap_new(NULL, width, height, 32); - if (pixmap != NULL) { - cairo_t *cr = gdk_cairo_create(pixmap); - cairo_arc (cr, width/2, height/2, width/2, 0, 2 * M_PI); - gdk_cairo_set_source_color(cr, &color); - cairo_fill(cr); - - GdkPixbuf * pixbuf = gdk_pixbuf_get_from_drawable(NULL, (GdkDrawable*)pixmap, - gdk_colormap_new(gdk_drawable_get_visual((GdkDrawable*)pixmap), TRUE), 0,0,0,0, width, height); - cairo_destroy(cr); + GdkColor color; + gdk_color_parse (color_spec, &color); + cairo_surface_t *surface = cairo_image_surface_create( CAIRO_FORMAT_ARGB32, width, height ); + + cairo_t *cr = cairo_create(surface); + gdk_cairo_set_source_color(cr, &color); + cairo_paint(cr); + cairo_set_source_rgba(cr, 0,0,0,0.5); + cairo_set_line_width(cr, 1); + cairo_rectangle (cr, 0.5, 0.5, width-1, height-1); + cairo_stroke(cr); + // Convert to pixbuf, in gtk3 this is done with gdk_pixbuf_get_from_surface + cairo_content_t content = cairo_surface_get_content (surface) | CAIRO_CONTENT_COLOR; + GdkPixbuf *pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, + !!(content & CAIRO_CONTENT_ALPHA), + 8, width, height); + + gint sstride = cairo_image_surface_get_stride( surface ); + gint dstride = gdk_pixbuf_get_rowstride (pixbuf); + guchar *spixels = cairo_image_surface_get_data( surface ); + guchar *dpixels = gdk_pixbuf_get_pixels (pixbuf); + + + int x, y; + for (y = 0; y < height; y++) { + guint32 *src = (guint32 *) spixels; + + for (x = 0; x < width; x++) { + guint alpha = src[x] >> 24; + + if (alpha == 0) { + dpixels[x * 4 + 0] = 0; + dpixels[x * 4 + 1] = 0; + dpixels[x * 4 + 2] = 0; + } else { + dpixels[x * 4 + 0] = (((src[x] & 0xff0000) >> 16) * 255 + alpha / 2) / alpha; + dpixels[x * 4 + 1] = (((src[x] & 0x00ff00) >> 8) * 255 + alpha / 2) / alpha; + dpixels[x * 4 + 2] = (((src[x] & 0x0000ff) >> 0) * 255 + alpha / 2) / alpha; + } + dpixels[x * 4 + 3] = alpha; + } + spixels += sstride; + dpixels += dstride; + } + + cairo_surface_destroy (surface); + cairo_destroy(cr); - dbusmenu_menuitem_property_set_image (item, APPOINTMENT_MENUITEM_PROP_ICON, pixbuf); - }*/ + dbusmenu_menuitem_property_set_image (item, APPOINTMENT_MENUITEM_PROP_ICON, pixbuf); } dbusmenu_menuitem_child_add_position (root, item, 2+i); appointments = g_list_append (appointments, item); // Keep track of the items here to make them east to remove -- cgit v1.2.3 From 76825a8ee0227c18fd02a30ab74ecc5a95382b6d Mon Sep 17 00:00:00 2001 From: karl-qdh Date: Thu, 3 Mar 2011 14:45:37 +0000 Subject: Added some small fixes to make sure the pixbuf redraws everytime. There may be some memory leaks corrupting data somewhere. --- src/datetime-service.c | 77 +++++++++++++++++++++++++++----------------------- 1 file changed, 41 insertions(+), 36 deletions(-) diff --git a/src/datetime-service.c b/src/datetime-service.c index 45546a0..fd14af9 100644 --- a/src/datetime-service.c +++ b/src/datetime-service.c @@ -82,6 +82,7 @@ static DbusmenuMenuitem * add_appointment = NULL; static GList * appointments = NULL; static GList * dconflocations = NULL; static GList * comp_instances = NULL; +static gboolean updating_appointments = FALSE; GSettings *conf; @@ -567,6 +568,8 @@ update_appointment_menu_items (gpointer user_data) // tea timers, pomodoro timers etc... that people may add, this is hinted to in the spec. if (calendar == NULL) return FALSE; if (!g_settings_get_boolean(conf, SETTINGS_SHOW_EVENTS_S)) return FALSE; + if (updating_appointments) return TRUE; + updating_appointments = TRUE; time_t t1, t2; gchar *ad; @@ -640,10 +643,6 @@ update_appointment_menu_items (gpointer user_data) comp_instances = NULL; i = 0; - gtk_icon_size_lookup(GTK_ICON_SIZE_MENU, &width, &height); - if (width == 0) width = 12; - if (height == 0) height = 12; - for (l = sorted_comp_instances; l; l = l->next) { struct comp_instance *ci = l->data; ECalComponent *ecalcomp = ci->comp; @@ -743,7 +742,12 @@ update_appointment_menu_items (gpointer user_data) if (color_spec != NULL) { // Fixme causes segfault, but we have colours now yay! GdkColor color; - gdk_color_parse (color_spec, &color); + gdk_color_parse (color_spec, &color); + + gtk_icon_size_lookup(GTK_ICON_SIZE_MENU, &width, &height); + if (width == 0) width = 12; + if (height == 0) height = 12; + cairo_surface_t *surface = cairo_image_surface_create( CAIRO_FORMAT_ARGB32, width, height ); cairo_t *cr = cairo_create(surface); @@ -758,39 +762,39 @@ update_appointment_menu_items (gpointer user_data) GdkPixbuf *pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, !!(content & CAIRO_CONTENT_ALPHA), 8, width, height); - - gint sstride = cairo_image_surface_get_stride( surface ); - gint dstride = gdk_pixbuf_get_rowstride (pixbuf); - guchar *spixels = cairo_image_surface_get_data( surface ); - guchar *dpixels = gdk_pixbuf_get_pixels (pixbuf); - - - int x, y; - for (y = 0; y < height; y++) { - guint32 *src = (guint32 *) spixels; - - for (x = 0; x < width; x++) { - guint alpha = src[x] >> 24; - - if (alpha == 0) { - dpixels[x * 4 + 0] = 0; - dpixels[x * 4 + 1] = 0; - dpixels[x * 4 + 2] = 0; - } else { - dpixels[x * 4 + 0] = (((src[x] & 0xff0000) >> 16) * 255 + alpha / 2) / alpha; - dpixels[x * 4 + 1] = (((src[x] & 0x00ff00) >> 8) * 255 + alpha / 2) / alpha; - dpixels[x * 4 + 2] = (((src[x] & 0x0000ff) >> 0) * 255 + alpha / 2) / alpha; + if (pixbuf != NULL) { + gint sstride = cairo_image_surface_get_stride( surface ); + gint dstride = gdk_pixbuf_get_rowstride (pixbuf); + guchar *spixels = cairo_image_surface_get_data( surface ); + guchar *dpixels = gdk_pixbuf_get_pixels (pixbuf); + + int x, y; + for (y = 0; y < height; y++) { + guint32 *src = (guint32 *) spixels; + + for (x = 0; x < width; x++) { + guint alpha = src[x] >> 24; + + if (alpha == 0) { + dpixels[x * 4 + 0] = 0; + dpixels[x * 4 + 1] = 0; + dpixels[x * 4 + 2] = 0; + } else { + dpixels[x * 4 + 0] = (((src[x] & 0xff0000) >> 16) * 255 + alpha / 2) / alpha; + dpixels[x * 4 + 1] = (((src[x] & 0x00ff00) >> 8) * 255 + alpha / 2) / alpha; + dpixels[x * 4 + 2] = (((src[x] & 0x0000ff) >> 0) * 255 + alpha / 2) / alpha; + } + dpixels[x * 4 + 3] = alpha; } - dpixels[x * 4 + 3] = alpha; - } - spixels += sstride; - dpixels += dstride; - } - - cairo_surface_destroy (surface); - cairo_destroy(cr); + spixels += sstride; + dpixels += dstride; + } + + cairo_surface_destroy (surface); + cairo_destroy(cr); - dbusmenu_menuitem_property_set_image (item, APPOINTMENT_MENUITEM_PROP_ICON, pixbuf); + dbusmenu_menuitem_property_set_image (item, APPOINTMENT_MENUITEM_PROP_ICON, pixbuf); + } } dbusmenu_menuitem_child_add_position (root, item, 2+i); appointments = g_list_append (appointments, item); // Keep track of the items here to make them east to remove @@ -804,6 +808,7 @@ update_appointment_menu_items (gpointer user_data) g_list_free(sorted_comp_instances); } + updating_appointments = FALSE; g_debug("End of objects"); return TRUE; } -- cgit v1.2.3 From 3aa4316f935bead55058441956d8b80e01146199 Mon Sep 17 00:00:00 2001 From: karl-qdh Date: Thu, 3 Mar 2011 14:59:17 +0000 Subject: Width appears to be repeatedly overwritten with zero --- src/datetime-service.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/datetime-service.c b/src/datetime-service.c index fd14af9..7b135a8 100644 --- a/src/datetime-service.c +++ b/src/datetime-service.c @@ -643,6 +643,9 @@ update_appointment_menu_items (gpointer user_data) comp_instances = NULL; i = 0; + gtk_icon_size_lookup(GTK_ICON_SIZE_MENU, &width, &height); + if (width == 0) width = 12; + if (height == 0) height = 12; for (l = sorted_comp_instances; l; l = l->next) { struct comp_instance *ci = l->data; ECalComponent *ecalcomp = ci->comp; @@ -743,13 +746,11 @@ update_appointment_menu_items (gpointer user_data) // Fixme causes segfault, but we have colours now yay! GdkColor color; gdk_color_parse (color_spec, &color); - - gtk_icon_size_lookup(GTK_ICON_SIZE_MENU, &width, &height); - if (width == 0) width = 12; - if (height == 0) height = 12; cairo_surface_t *surface = cairo_image_surface_create( CAIRO_FORMAT_ARGB32, width, height ); - + // Width keeps becoming zero!! + if (width == 0) width = 12; + if (height == 0) height = 12; cairo_t *cr = cairo_create(surface); gdk_cairo_set_source_color(cr, &color); cairo_paint(cr); @@ -759,6 +760,9 @@ update_appointment_menu_items (gpointer user_data) cairo_stroke(cr); // Convert to pixbuf, in gtk3 this is done with gdk_pixbuf_get_from_surface cairo_content_t content = cairo_surface_get_content (surface) | CAIRO_CONTENT_COLOR; + // Width keeps becoming zero!! + if (width == 0) width = 12; + if (height == 0) height = 12; GdkPixbuf *pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, !!(content & CAIRO_CONTENT_ALPHA), 8, width, height); -- cgit v1.2.3