Merge lp:~karl-qdh/indicator-datetime/recurring-and-gsettings-fixes into lp:indicator-datetime/0.3
- recurring-and-gsettings-fixes
- Merge into trunk
Proposed by
Karl Lattimer
Status: | Merged |
---|---|
Merged at revision: | 53 |
Proposed branch: | lp:~karl-qdh/indicator-datetime/recurring-and-gsettings-fixes |
Merge into: | lp:indicator-datetime/0.3 |
Diff against target: |
589 lines (+270/-149) (has conflicts) 1 file modified
src/datetime-service.c (+270/-149) Text conflict in src/datetime-service.c |
To merge this branch: | bzr merge lp:~karl-qdh/indicator-datetime/recurring-and-gsettings-fixes |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Indicator Applet Developers | Pending | ||
Review via email: mp+52059@code.launchpad.net |
Commit message
Description of the change
Fixes bugs;
* https:/
* https:/
And part way to fixing;
* https:/
To post a comment you must log in.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'src/datetime-service.c' |
2 | --- src/datetime-service.c 2011-03-01 04:05:10 +0000 |
3 | +++ src/datetime-service.c 2011-03-03 13:01:35 +0000 |
4 | @@ -73,6 +73,7 @@ |
5 | static DbusmenuMenuitem * date = NULL; |
6 | static DbusmenuMenuitem * calendar = NULL; |
7 | static DbusmenuMenuitem * settings = NULL; |
8 | +static DbusmenuMenuitem * events_separator = NULL; |
9 | static DbusmenuMenuitem * locations_separator = NULL; |
10 | static DbusmenuMenuitem * geo_location = NULL; |
11 | static DbusmenuMenuitem * current_location = NULL; |
12 | @@ -80,6 +81,7 @@ |
13 | static DbusmenuMenuitem * add_appointment = NULL; |
14 | static GList * appointments = NULL; |
15 | static GList * dconflocations = NULL; |
16 | +static GList * comp_instances = NULL; |
17 | GSettings *conf; |
18 | |
19 | |
20 | @@ -91,6 +93,13 @@ |
21 | static gchar * current_timezone = NULL; |
22 | static gchar * geo_timezone = NULL; |
23 | |
24 | +struct comp_instance { |
25 | + ECalComponent *comp; |
26 | + time_t start; |
27 | + time_t end; |
28 | + ESource *source; |
29 | +}; |
30 | + |
31 | static void |
32 | set_timezone_label (DbusmenuMenuitem * mi, const gchar * location) |
33 | { |
34 | @@ -278,8 +287,50 @@ |
35 | return TRUE; |
36 | } |
37 | |
38 | +static guint ecaltimer = 0; |
39 | + |
40 | +static void |
41 | +start_ecal_timer(void) |
42 | +{ |
43 | + if (ecaltimer != 0) g_source_remove(ecaltimer); |
44 | + if (update_appointment_menu_items(NULL)) |
45 | + ecaltimer = g_timeout_add_seconds(60*5, update_appointment_menu_items, NULL); |
46 | +} |
47 | + |
48 | +static void |
49 | +stop_ecal_timer(void) |
50 | +{ |
51 | + if (ecaltimer != 0) g_source_remove(ecaltimer); |
52 | +} |
53 | + |
54 | +static void |
55 | +show_events_changed (void) |
56 | +{ |
57 | + if (g_settings_get_boolean(conf, SETTINGS_SHOW_EVENTS_S)) { |
58 | + dbusmenu_menuitem_property_set_bool(add_appointment, DBUSMENU_MENUITEM_PROP_VISIBLE, TRUE); |
59 | + dbusmenu_menuitem_property_set_bool(events_separator, DBUSMENU_MENUITEM_PROP_VISIBLE, TRUE); |
60 | + start_ecal_timer(); |
61 | + } else { |
62 | + dbusmenu_menuitem_property_set_bool(add_appointment, DBUSMENU_MENUITEM_PROP_VISIBLE, FALSE); |
63 | + dbusmenu_menuitem_property_set_bool(events_separator, DBUSMENU_MENUITEM_PROP_VISIBLE, FALSE); |
64 | + /* Remove all of the previous appointments */ |
65 | + if (appointments != NULL) { |
66 | + g_debug("Freeing old appointments"); |
67 | + while (appointments != NULL) { |
68 | + DbusmenuMenuitem * litem = DBUSMENU_MENUITEM(appointments->data); |
69 | + g_debug("Freeing old appointment: %p", litem); |
70 | + // Remove all the existing menu items which are in appointments. |
71 | + appointments = g_list_remove(appointments, litem); |
72 | + dbusmenu_menuitem_child_delete(root, DBUSMENU_MENUITEM(litem)); |
73 | + g_object_unref(G_OBJECT(litem)); |
74 | + } |
75 | + } |
76 | + stop_ecal_timer(); |
77 | + } |
78 | +} |
79 | + |
80 | /* Looks for the calendar application and enables the item if |
81 | - we have one */ |
82 | + we have one, starts ecal timer if events are turned on */ |
83 | static gboolean |
84 | check_for_calendar (gpointer user_data) |
85 | { |
86 | @@ -293,21 +344,26 @@ |
87 | dbusmenu_menuitem_property_set_bool(calendar, DBUSMENU_MENUITEM_PROP_ENABLED, TRUE); |
88 | dbusmenu_menuitem_property_set_bool(calendar, DBUSMENU_MENUITEM_PROP_VISIBLE, TRUE); |
89 | |
90 | - DbusmenuMenuitem * separator = dbusmenu_menuitem_new(); |
91 | - dbusmenu_menuitem_property_set(separator, DBUSMENU_MENUITEM_PROP_TYPE, DBUSMENU_CLIENT_TYPES_SEPARATOR); |
92 | - dbusmenu_menuitem_child_add_position(root, separator, 2); |
93 | - |
94 | + events_separator = dbusmenu_menuitem_new(); |
95 | + dbusmenu_menuitem_property_set(events_separator, DBUSMENU_MENUITEM_PROP_TYPE, DBUSMENU_CLIENT_TYPES_SEPARATOR); |
96 | + dbusmenu_menuitem_child_add_position(root, events_separator, 2); |
97 | add_appointment = dbusmenu_menuitem_new(); |
98 | - dbusmenu_menuitem_property_set (add_appointment, DBUSMENU_MENUITEM_PROP_LABEL, _("Add Appointment")); |
99 | + dbusmenu_menuitem_property_set (add_appointment, DBUSMENU_MENUITEM_PROP_LABEL, _("Add Appointment")); |
100 | dbusmenu_menuitem_property_set_bool(add_appointment, DBUSMENU_MENUITEM_PROP_ENABLED, TRUE); |
101 | - dbusmenu_menuitem_property_set_bool(add_appointment, DBUSMENU_MENUITEM_PROP_VISIBLE, TRUE); |
102 | g_signal_connect(G_OBJECT(add_appointment), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(activate_cb), "evolution -c calendar"); |
103 | dbusmenu_menuitem_child_add_position (root, add_appointment, 3); |
104 | |
105 | - // Update the calendar items every 5 minutes if it updates the first time |
106 | - if (update_appointment_menu_items(NULL)) |
107 | - g_timeout_add_seconds(60*5, update_appointment_menu_items, NULL); |
108 | - |
109 | + |
110 | + if (g_settings_get_boolean(conf, SETTINGS_SHOW_EVENTS_S)) { |
111 | + dbusmenu_menuitem_property_set_bool(add_appointment, DBUSMENU_MENUITEM_PROP_VISIBLE, TRUE); |
112 | + dbusmenu_menuitem_property_set_bool(events_separator, DBUSMENU_MENUITEM_PROP_VISIBLE, TRUE); |
113 | + start_ecal_timer(); |
114 | + } else { |
115 | + dbusmenu_menuitem_property_set_bool(add_appointment, DBUSMENU_MENUITEM_PROP_VISIBLE, FALSE); |
116 | + dbusmenu_menuitem_property_set_bool(events_separator, DBUSMENU_MENUITEM_PROP_VISIBLE, FALSE); |
117 | + stop_ecal_timer(); |
118 | + } |
119 | + |
120 | // Connect to event::month-changed |
121 | g_signal_connect(calendar, "event::month-changed", G_CALLBACK(month_changed_cb), NULL); |
122 | g_free(evo); |
123 | @@ -381,7 +437,11 @@ |
124 | |
125 | // Authentication function |
126 | static gchar * |
127 | -auth_func (ECal *ecal, const gchar *prompt, const gchar *key, gpointer user_data) { |
128 | +auth_func (ECal *ecal, |
129 | + const gchar *prompt, |
130 | + const gchar *key, |
131 | + gpointer user_data) |
132 | +{ |
133 | gboolean remember; // TODO: Is this useful? Should we be storing it somewhere? |
134 | ESource *source = e_cal_get_source (ecal); |
135 | gchar *auth_domain = e_source_get_duped_property (source, "auth-domain"); |
136 | @@ -407,47 +467,92 @@ |
137 | return password; |
138 | } |
139 | |
140 | - |
141 | -// Compare function for g_list_sort of ECalComponent objects |
142 | -static gint |
143 | -compare_appointment_items (ECalComponent *a, |
144 | - ECalComponent *b) { |
145 | - |
146 | - ECalComponentDateTime datetime_a, datetime_b; |
147 | - struct tm tm_a, tm_b; |
148 | - time_t t_a, t_b; |
149 | - gint retval = 0; |
150 | - |
151 | - if (a == NULL || b == NULL) return retval; |
152 | - |
153 | - ECalComponentVType vtype = e_cal_component_get_vtype (a); |
154 | - |
155 | - if (vtype != E_CAL_COMPONENT_EVENT && vtype != E_CAL_COMPONENT_TODO) return -1; |
156 | - |
157 | - if (vtype == E_CAL_COMPONENT_EVENT) |
158 | - e_cal_component_get_dtstart (a, &datetime_a); |
159 | - else |
160 | - e_cal_component_get_due (a, &datetime_a); |
161 | - tm_a = icaltimetype_to_tm(datetime_a.value); |
162 | - t_a = mktime(&tm_a); |
163 | - |
164 | - vtype = e_cal_component_get_vtype (b); |
165 | - if (vtype != E_CAL_COMPONENT_EVENT && vtype != E_CAL_COMPONENT_TODO) return 1; |
166 | - |
167 | - if (vtype == E_CAL_COMPONENT_EVENT) |
168 | - e_cal_component_get_dtstart (b, &datetime_b); |
169 | - else |
170 | - e_cal_component_get_due (b, &datetime_b); |
171 | - tm_b = icaltimetype_to_tm(datetime_b.value); |
172 | - t_b = mktime(&tm_b); |
173 | - |
174 | - // Compare datetime_a and datetime_b, newest first in this sort. |
175 | - if (t_a > t_b) retval = 1; |
176 | - else if (t_a < t_b) retval = -1; |
177 | - |
178 | - e_cal_component_free_datetime (&datetime_a); |
179 | - e_cal_component_free_datetime (&datetime_b); |
180 | - return retval; |
181 | +static gint |
182 | +compare_comp_instances (gconstpointer a, |
183 | + gconstpointer b) |
184 | +{ |
185 | + const struct comp_instance *ci_a = a; |
186 | + const struct comp_instance *ci_b = b; |
187 | + time_t d = ci_a->start - ci_b->start; |
188 | + if (d < 0) return -1; |
189 | + else if (d > 0) return 1; |
190 | + return 0; |
191 | +} |
192 | + |
193 | +static gboolean |
194 | +populate_appointment_instances (ECalComponent *comp, |
195 | + time_t instance_start, |
196 | + time_t instance_end, |
197 | + gpointer data) |
198 | +{ |
199 | + g_debug("Appending item %p", comp); |
200 | + |
201 | + ECalComponentVType vtype = e_cal_component_get_vtype (comp); |
202 | + if (vtype != E_CAL_COMPONENT_EVENT && vtype != E_CAL_COMPONENT_TODO) return FALSE; |
203 | + |
204 | + icalproperty_status status; |
205 | + e_cal_component_get_status (comp, &status); |
206 | + if (status == ICAL_STATUS_COMPLETED || status == ICAL_STATUS_CANCELLED) return FALSE; |
207 | + |
208 | + g_object_ref(comp); |
209 | + |
210 | + ECalComponentDateTime datetime; |
211 | + icaltimezone *appointment_zone = NULL; |
212 | + icaltimezone *current_zone = NULL; |
213 | + |
214 | + if (vtype == E_CAL_COMPONENT_EVENT) |
215 | + e_cal_component_get_dtstart (comp, &datetime); |
216 | + else |
217 | + e_cal_component_get_due (comp, &datetime); |
218 | + |
219 | + appointment_zone = icaltimezone_get_builtin_timezone_from_tzid(datetime.tzid); |
220 | + current_zone = icaltimezone_get_builtin_timezone_from_tzid(current_timezone); |
221 | + if (!appointment_zone || datetime.value->is_date) { // If it's today put in the current timezone? |
222 | + appointment_zone = current_zone; |
223 | + } |
224 | + |
225 | + // TODO: Convert the timezone into a 3 letter abbreviation if it's different to current_timezone |
226 | + // TODO: Add the appointment timezone to the list if it's not already there. |
227 | + |
228 | + GSList *period_list = NULL, *l; |
229 | + if (e_cal_component_has_recurrences (comp)) { |
230 | + e_cal_component_get_rdate_list (comp, &period_list); |
231 | + g_debug("ECalComponent has recurrences"); |
232 | + } else { |
233 | + g_debug("ECalComponent doesn't have recurrences"); |
234 | + } |
235 | + |
236 | + struct comp_instance *ci; |
237 | + ci = g_new (struct comp_instance, 1); |
238 | + |
239 | + // Do we get rdate_list? |
240 | + if (period_list != NULL) { |
241 | + g_debug("Got recurring periods"); |
242 | + for (l = period_list; l; l = l->next) { |
243 | + ECalComponentPeriod *period = l->data; |
244 | + struct tm tmp_tm = icaltimetype_to_tm_with_zone (&period->start, appointment_zone, current_zone); |
245 | + time_t start = mktime(&tmp_tm); |
246 | + g_debug("period time: %d", (int)start); |
247 | + |
248 | + tmp_tm = icaltimetype_to_tm_with_zone (&period->u.end, appointment_zone, current_zone); |
249 | + time_t end = mktime(&tmp_tm); |
250 | + |
251 | + if (start >= instance_start && end < instance_end) { |
252 | + ci->start = start; |
253 | + ci->end = end; |
254 | + } |
255 | + } |
256 | + } else { |
257 | + ci->start = instance_start; |
258 | + ci->end = instance_end; |
259 | + g_debug("Got no recurring periods set time to start %s, end %s", ctime(&instance_start), ctime(&instance_end)); |
260 | + } |
261 | + |
262 | + ci->comp = comp; |
263 | + ci->source = E_SOURCE(data); |
264 | + |
265 | + comp_instances = g_list_append(comp_instances, ci); |
266 | + return TRUE; |
267 | } |
268 | |
269 | /* Populate the menu with todays, next 5 appointments. |
270 | @@ -456,22 +561,36 @@ |
271 | * this is a problem mainly on the EDS side of things, not ours. |
272 | */ |
273 | static gboolean |
274 | -update_appointment_menu_items (gpointer user_data) { |
275 | +update_appointment_menu_items (gpointer user_data) |
276 | +{ |
277 | // FFR: we should take into account short term timers, for instance |
278 | // tea timers, pomodoro timers etc... that people may add, this is hinted to in the spec. |
279 | if (calendar == NULL) return FALSE; |
280 | if (!g_settings_get_boolean(conf, SETTINGS_SHOW_EVENTS_S)) return FALSE; |
281 | |
282 | +<<<<<<< TREE |
283 | gchar *query, *ad; |
284 | GList *objects = NULL, *l; |
285 | GList *allobjects = NULL; |
286 | +======= |
287 | + time_t t1, t2; |
288 | + gchar *ad; |
289 | + GList *l; |
290 | + //GList *allobjects = NULL; |
291 | +>>>>>>> MERGE-SOURCE |
292 | GSList *g; |
293 | GError *gerror = NULL; |
294 | gint i; |
295 | gint width, height; |
296 | ESourceList * sources = NULL; |
297 | |
298 | +<<<<<<< TREE |
299 | gtk_icon_size_lookup(GTK_ICON_SIZE_MENU, &width, &height); |
300 | +======= |
301 | + time(&t1); |
302 | + time(&t2); |
303 | + t2 += (time_t) (7 * 24 * 60 * 60); /* 7 days ahead of now, we actually need number_of_days_in_this_month */ |
304 | +>>>>>>> MERGE-SOURCE |
305 | |
306 | /* Remove all of the previous appointments */ |
307 | if (appointments != NULL) { |
308 | @@ -487,15 +606,29 @@ |
309 | } |
310 | |
311 | // TODO Remove all highlights from the calendar widget |
312 | +<<<<<<< TREE |
313 | |
314 | // FIXME can we put a limit on the number of results? Or if not complete, or is event/todo? Or sort it by date? |
315 | query = g_strdup_printf("(occur-in-time-range? (time-now) (time-add-day (time-now) 7))"); |
316 | +======= |
317 | +>>>>>>> MERGE-SOURCE |
318 | |
319 | if (!e_cal_get_sources(&sources, E_CAL_SOURCE_TYPE_EVENT, &gerror)) { |
320 | g_debug("Failed to get ecal sources\n"); |
321 | return FALSE; |
322 | } |
323 | - |
324 | + |
325 | + // Free comp_instances if not NULL |
326 | + if (comp_instances != NULL) { |
327 | + g_debug("Freeing comp_instances: may be an overlap\n"); |
328 | + for (l = comp_instances; l; l = l->next) { |
329 | + const struct comp_instance *ci = l->data; |
330 | + g_object_unref(ci->comp); |
331 | + g_list_free(comp_instances); |
332 | + comp_instances = NULL; |
333 | + } |
334 | + } |
335 | + |
336 | // iterate the query for all sources |
337 | for (g = e_source_list_peek_groups (sources); g; g = g->next) { |
338 | ESourceGroup *group = E_SOURCE_GROUP (g->data); |
339 | @@ -503,7 +636,7 @@ |
340 | |
341 | for (s = e_source_group_peek_sources (group); s; s = s->next) { |
342 | ESource *source = E_SOURCE (s->data); |
343 | - g_signal_connect (G_OBJECT(source), "changed", G_CALLBACK (update_appointment_menu_items), NULL); |
344 | + //g_signal_connect (G_OBJECT(source), "changed", G_CALLBACK (update_appointment_menu_items), NULL); |
345 | ECal *ecal = e_cal_new(source, E_CAL_SOURCE_TYPE_EVENT); |
346 | e_cal_set_auth_func (ecal, (ECalAuthFunc) auth_func, NULL); |
347 | |
348 | @@ -514,55 +647,36 @@ |
349 | continue; |
350 | } |
351 | |
352 | - g_debug("Getting objects with query: %s", query); |
353 | - if (!e_cal_get_object_list_as_comp(ecal, query, &objects, &gerror)) { |
354 | - g_debug("Failed to get objects\n"); |
355 | - g_free(ecal); |
356 | - gerror = NULL; |
357 | - continue; |
358 | - } |
359 | - g_debug("Number of objects returned: %d", g_list_length(objects)); |
360 | - |
361 | - if (allobjects == NULL) { |
362 | - allobjects = objects; |
363 | - } else if (objects != NULL) { |
364 | - allobjects = g_list_concat(allobjects, objects); |
365 | - g_object_unref(objects); |
366 | - } |
367 | + g_debug("Generating instances"); |
368 | + e_cal_generate_instances (ecal, t1, t2, (ECalRecurInstanceFn) populate_appointment_instances, (gpointer) source); |
369 | + g_debug("Number of objects returned: %d", g_list_length(comp_instances)); |
370 | } |
371 | } |
372 | - |
373 | - // Sort the list see above FIXME regarding queries |
374 | - g_debug("Sorting objects list"); |
375 | - allobjects = g_list_sort(allobjects, (GCompareFunc) compare_appointment_items); |
376 | + GList *sorted_comp_instances = g_list_sort(comp_instances, compare_comp_instances); |
377 | + comp_instances = NULL; |
378 | i = 0; |
379 | - for (l = allobjects; l; l = l->next) { |
380 | - ECalComponent *ecalcomp = l->data; |
381 | + |
382 | + gtk_icon_size_lookup(GTK_ICON_SIZE_MENU, &width, &height); |
383 | + if (width == 0) width = 16; |
384 | + if (height == 0) height = 16; |
385 | + |
386 | + for (l = sorted_comp_instances; l; l = l->next) { |
387 | + struct comp_instance *ci = l->data; |
388 | + ECalComponent *ecalcomp = ci->comp; |
389 | ECalComponentText valuetext; |
390 | - ECalComponentDateTime datetime; |
391 | - icaltimezone *appointment_zone = NULL; |
392 | - icaltimezone *current_zone = NULL; |
393 | - icalproperty_status status; |
394 | + //ECalComponentDateTime datetime; |
395 | gchar *summary, *cmd; |
396 | char right[20]; |
397 | //const gchar *uri; |
398 | - struct tm tmp_tm; |
399 | DbusmenuMenuitem * item; |
400 | |
401 | - g_debug("Start Object"); |
402 | - ECalComponentVType vtype = e_cal_component_get_vtype (ecalcomp); |
403 | - |
404 | - // See above FIXME regarding query result |
405 | - // If it's not an event or todo, continue no-increment |
406 | - if (vtype != E_CAL_COMPONENT_EVENT && vtype != E_CAL_COMPONENT_TODO) |
407 | - continue; |
408 | - |
409 | - // See above FIXME regarding query result |
410 | - // if the status is completed, continue no-increment |
411 | - e_cal_component_get_status (ecalcomp, &status); |
412 | - if (status == ICAL_STATUS_COMPLETED || status == ICAL_STATUS_CANCELLED) |
413 | - continue; |
414 | - |
415 | + g_debug("Start Object %p", ecalcomp); |
416 | + |
417 | + // TODO Mark days |
418 | + |
419 | + if (i >= 5) continue; |
420 | + i++; |
421 | + |
422 | item = dbusmenu_menuitem_new(); |
423 | dbusmenu_menuitem_property_set (item, DBUSMENU_MENUITEM_PROP_TYPE, APPOINTMENT_MENUITEM_TYPE); |
424 | dbusmenu_menuitem_property_set_bool (item, DBUSMENU_MENUITEM_PROP_ENABLED, TRUE); |
425 | @@ -576,97 +690,102 @@ |
426 | g_debug("Summary: %s", summary); |
427 | g_free (summary); |
428 | |
429 | - // Due text |
430 | - if (vtype == E_CAL_COMPONENT_EVENT) |
431 | - e_cal_component_get_dtstart (ecalcomp, &datetime); |
432 | - else |
433 | - e_cal_component_get_due (ecalcomp, &datetime); |
434 | - |
435 | + //appointment_zone = icaltimezone_get_builtin_timezone_from_tzid(datetime.tzid); |
436 | + //current_zone = icaltimezone_get_builtin_timezone_from_tzid(current_timezone); |
437 | + //if (!appointment_zone || datetime.value->is_date) { // If it's today put in the current timezone? |
438 | + // appointment_zone = current_zone; |
439 | + //} |
440 | // FIXME need to get the timezone of the above datetime, |
441 | // and get the icaltimezone of the geoclue timezone/selected timezone (whichever is preferred) |
442 | - if (!datetime.value) { |
443 | - g_free(item); |
444 | - continue; |
445 | - } |
446 | - |
447 | - appointment_zone = icaltimezone_get_builtin_timezone_from_tzid(datetime.tzid); |
448 | - current_zone = icaltimezone_get_builtin_timezone_from_tzid(current_timezone); |
449 | - if (!appointment_zone || datetime.value->is_date) { // If it's today put in the current timezone? |
450 | - appointment_zone = current_zone; |
451 | - } |
452 | // TODO: Convert the timezone into a 3 letter abbreviation if it's different to current_timezone |
453 | // TODO: Add the appointment timezone to the list if it's not already there. |
454 | |
455 | - tmp_tm = icaltimetype_to_tm_with_zone (datetime.value, appointment_zone, current_zone); |
456 | - |
457 | - g_debug("Generate time string"); |
458 | + //tmp_tm = icaltimetype_to_tm_with_zone (datetime.value, appointment_zone, current_zone); |
459 | + |
460 | + // Due text |
461 | + ECalComponentVType vtype = e_cal_component_get_vtype (ecalcomp); |
462 | + |
463 | // Get today |
464 | time_t curtime = time(NULL); |
465 | - struct tm* today = localtime(&curtime); |
466 | - if (today->tm_mday == tmp_tm.tm_mday && |
467 | - today->tm_mon == tmp_tm.tm_mon && |
468 | - today->tm_year == tmp_tm.tm_year) |
469 | - strftime(right, 20, "%l:%M %P", &tmp_tm); |
470 | + struct tm *today = localtime(&curtime); |
471 | + |
472 | + int mday = today->tm_mday; |
473 | + int mon = today->tm_mon; |
474 | + int year = today->tm_year; |
475 | + |
476 | + struct tm *due; |
477 | + g_debug("Start time %s", ctime(&ci->start)); |
478 | + if (vtype == E_CAL_COMPONENT_EVENT) due = localtime(&ci->start); |
479 | + else if (vtype == E_CAL_COMPONENT_TODO) due = localtime(&ci->end); |
480 | + else continue; |
481 | + |
482 | + strftime(right, 20, "%a %l:%M %p", due); |
483 | + g_debug("Start time %s -> %s", asctime(due), right); |
484 | + |
485 | + int dmday = due->tm_mday; |
486 | + int dmon = due->tm_mon; |
487 | + int dyear = due->tm_year; |
488 | + |
489 | + if ((mday == dmday) && (mon == dmon) && (year == dyear)) |
490 | + strftime(right, 20, "%l:%M %p", due); |
491 | else |
492 | - strftime(right, 20, "%a %l:%M %P", &tmp_tm); |
493 | + strftime(right, 20, "%a %l:%M %p", due); |
494 | |
495 | g_debug("Appointment time: %s", right); |
496 | - g_debug("Appointment timezone: %s", datetime.tzid); |
497 | - g_debug("Appointment timezone: %s", icaltimezone_get_tzid(appointment_zone)); // These two should be the same |
498 | + //g_debug("Appointment timezone: %s", datetime.tzid); |
499 | + //g_debug("Appointment timezone: %s", icaltimezone_get_tzid(appointment_zone)); // These two should be the same |
500 | //g_debug("Calendar timezone: %s", ecal_timezone); |
501 | |
502 | dbusmenu_menuitem_property_set (item, APPOINTMENT_MENUITEM_PROP_RIGHT, right); |
503 | |
504 | - e_cal_component_free_datetime (&datetime); |
505 | + //e_cal_component_free_datetime (&datetime); |
506 | |
507 | - ad = isodate_from_time_t(mktime(&tmp_tm)); |
508 | |
509 | // Now we pull out the URI for the calendar event and try to create a URI that'll work when we execute evolution |
510 | // FIXME Because the URI stuff is really broken, we're going to open the calendar at todays date instead |
511 | - |
512 | //e_cal_component_get_uid(ecalcomp, &uri); |
513 | + ad = isodate_from_time_t(mktime(due)); |
514 | cmd = g_strconcat("evolution calendar:///?startdate=", ad, NULL); |
515 | g_signal_connect (G_OBJECT(item), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, |
516 | G_CALLBACK (activate_cb), cmd); |
517 | |
518 | g_debug("Command to Execute: %s", cmd); |
519 | - |
520 | - // FIXME This is now more difficult to get right with more sources, as we need to keep track |
521 | - // of which ecal or source goes with each ECalComponent :/ |
522 | - |
523 | - //ESource *source = e_cal_get_source (ecal); |
524 | - //e_source_get_color (source, &source_color); api has been changed |
525 | - const gchar *color_spec = NULL; //e_source_peek_color_spec(source); |
526 | + |
527 | + const gchar *color_spec = e_source_peek_color_spec(ci->source); |
528 | g_debug("Colour to use: %s", color_spec); |
529 | |
530 | // Draw the correct icon for the appointment type and then tint it using mask fill. |
531 | // For now we'll create a circle |
532 | if (color_spec != NULL) { |
533 | - GdkColor color; |
534 | + // Fixme causes segfault, but we have colours now yay! |
535 | + /*GdkColor color; |
536 | gdk_color_parse (color_spec, &color); |
537 | - |
538 | - cairo_surface_t *cs = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height); |
539 | - cairo_t *cr = cairo_create(cs); |
540 | - cairo_arc (cr, width/2, height/2, width/2, 0, 2 * M_PI); |
541 | - gdk_cairo_set_source_color(cr, &color); |
542 | - cairo_fill(cr); |
543 | + GdkPixmap *pixmap = gdk_pixmap_new(NULL, width, height, 32); |
544 | + if (pixmap != NULL) { |
545 | + cairo_t *cr = gdk_cairo_create(pixmap); |
546 | + cairo_arc (cr, width/2, height/2, width/2, 0, 2 * M_PI); |
547 | + gdk_cairo_set_source_color(cr, &color); |
548 | + cairo_fill(cr); |
549 | |
550 | - GdkPixbuf * pixbuf = gdk_pixbuf_get_from_drawable(NULL, (GdkDrawable*)cs, |
551 | - gdk_colormap_new(gdk_drawable_get_visual((GdkDrawable*)cs), TRUE), 0,0,0,0, width, height); |
552 | - cairo_destroy(cr); |
553 | + GdkPixbuf * pixbuf = gdk_pixbuf_get_from_drawable(NULL, (GdkDrawable*)pixmap, |
554 | + gdk_colormap_new(gdk_drawable_get_visual((GdkDrawable*)pixmap), TRUE), 0,0,0,0, width, height); |
555 | + cairo_destroy(cr); |
556 | |
557 | - dbusmenu_menuitem_property_set_image (item, APPOINTMENT_MENUITEM_PROP_ICON, pixbuf); |
558 | + dbusmenu_menuitem_property_set_image (item, APPOINTMENT_MENUITEM_PROP_ICON, pixbuf); |
559 | + }*/ |
560 | } |
561 | - dbusmenu_menuitem_child_add_position (root, item, 3+i); |
562 | + dbusmenu_menuitem_child_add_position (root, item, 2+i); |
563 | appointments = g_list_append (appointments, item); // Keep track of the items here to make them east to remove |
564 | g_debug("Adding appointment: %p", item); |
565 | - |
566 | - if (i == 4) break; // See above FIXME regarding query result limit |
567 | - i++; |
568 | } |
569 | |
570 | if (gerror != NULL) g_error_free(gerror); |
571 | - g_object_unref(allobjects); |
572 | + for (l = sorted_comp_instances; l; l = l->next) { |
573 | + const struct comp_instance *ci = l->data; |
574 | + g_object_unref(ci->comp); |
575 | + g_list_free(sorted_comp_instances); |
576 | + } |
577 | + |
578 | g_debug("End of objects"); |
579 | return TRUE; |
580 | } |
581 | @@ -748,6 +867,8 @@ |
582 | check_timezone_sync(); |
583 | |
584 | g_signal_connect (conf, "changed::" SETTINGS_SHOW_LOCATIONS_S, G_CALLBACK (show_locations_changed), NULL); |
585 | + g_signal_connect (conf, "changed::" SETTINGS_LOCATIONS_S, G_CALLBACK (show_locations_changed), NULL); |
586 | + g_signal_connect (conf, "changed::" SETTINGS_SHOW_EVENTS_S, G_CALLBACK (show_events_changed), NULL); |
587 | |
588 | DbusmenuMenuitem * separator = dbusmenu_menuitem_new(); |
589 | dbusmenu_menuitem_property_set(separator, DBUSMENU_MENUITEM_PROP_TYPE, DBUSMENU_CLIENT_TYPES_SEPARATOR); |