From abe1e4017d5a095aa911b6736ca8ad0d50c9f1fb Mon Sep 17 00:00:00 2001 From: Federico Mena Quintero Date: Mon, 29 Oct 2001 22:23:20 +0000 Subject: Fix bug #12163. 2001-10-29 Federico Mena Quintero Fix bug #12163. * cal-util/cal-util.c (compute_alarm_range): Take alarm repetitions into account. (add_alarm_occurrences_cb): Add alarm repetitions. (generate_absolute_triggers): Likewise. (generate_absolute_triggers): Oops, absolute triggers are in UTC, so convert them as such. Also, pay attention to the timezones of the dtstart and dtend properties. svn path=/trunk/; revision=14369 --- calendar/ChangeLog | 12 ++++ calendar/cal-util/cal-util.c | 139 +++++++++++++++++++++++++++++++----------- calendar/gui/cal-search-bar.c | 1 + calendar/gui/calendar-model.c | 22 +------ 4 files changed, 119 insertions(+), 55 deletions(-) (limited to 'calendar') diff --git a/calendar/ChangeLog b/calendar/ChangeLog index 44fac413ca..06f853b056 100644 --- a/calendar/ChangeLog +++ b/calendar/ChangeLog @@ -1,3 +1,15 @@ +2001-10-29 Federico Mena Quintero + + Fix bug #12163. + + * cal-util/cal-util.c (compute_alarm_range): Take alarm + repetitions into account. + (add_alarm_occurrences_cb): Add alarm repetitions. + (generate_absolute_triggers): Likewise. + (generate_absolute_triggers): Oops, absolute triggers are in UTC, + so convert them as such. Also, pay attention to the timezones of + the dtstart and dtend properties. + 2001-10-29 JP Rosevear * importers/Makefile.am: include the header as a source so it gets diff --git a/calendar/cal-util/cal-util.c b/calendar/cal-util/cal-util.c index f49a9dd2f0..5cc6bbfc77 100644 --- a/calendar/cal-util/cal-util.c +++ b/calendar/cal-util/cal-util.c @@ -31,7 +31,7 @@ /** * cal_obj_instance_list_free: * @list: List of #CalObjInstance structures. - * + * * Frees a list of #CalObjInstance structures. **/ void @@ -81,13 +81,13 @@ cal_util_new_top_level (void) { icalcomponent *icalcomp; icalproperty *prop; - + icalcomp = icalcomponent_new (ICAL_VCALENDAR_COMPONENT); /* RFC 2445, section 4.7.1 */ prop = icalproperty_new_calscale ("GREGORIAN"); icalcomponent_add_property (icalcomp, prop); - + /* RFC 2445, section 4.7.3 */ prop = icalproperty_new_prodid ("-//Ximian//NONSGML Evolution Calendar//EN"); icalcomponent_add_property (icalcomp, prop); @@ -109,34 +109,43 @@ compute_alarm_range (CalComponent *comp, GList *alarm_uids, time_t start, time_t time_t *alarm_start, time_t *alarm_end) { GList *l; + time_t repeat_time; *alarm_start = start; *alarm_end = end; + repeat_time = 0; + for (l = alarm_uids; l; l = l->next) { const char *auid; CalComponentAlarm *alarm; CalAlarmTrigger trigger; struct icaldurationtype *dur; time_t dur_time; + CalAlarmRepeat repeat; auid = l->data; alarm = cal_component_get_alarm (comp, auid); g_assert (alarm != NULL); cal_component_alarm_get_trigger (alarm, &trigger); + cal_component_alarm_get_repeat (alarm, &repeat); cal_component_alarm_free (alarm); switch (trigger.type) { case CAL_ALARM_TRIGGER_NONE: case CAL_ALARM_TRIGGER_ABSOLUTE: - continue; + break; case CAL_ALARM_TRIGGER_RELATIVE_START: case CAL_ALARM_TRIGGER_RELATIVE_END: dur = &trigger.u.rel_duration; dur_time = icaldurationtype_as_int (*dur); + repeat_time = MAX (repeat_time, + (repeat.repetitions + * icaldurationtype_as_int (repeat.duration))); + if (dur->is_neg) /* If the duration is negative then dur_time * will be negative as well; that is why we @@ -153,6 +162,8 @@ compute_alarm_range (CalComponent *comp, GList *alarm_uids, time_t start, time_t } } + alarm_start -= repeat_time; + g_assert (*alarm_start <= *alarm_end); } @@ -168,6 +179,22 @@ struct alarm_occurrence_data { int n_triggers; }; +static void +add_trigger (struct alarm_occurrence_data *aod, const char *auid, time_t trigger, + time_t occur_start, time_t occur_end) +{ + CalAlarmInstance *instance; + + instance = g_new (CalAlarmInstance, 1); + instance->auid = auid; + instance->trigger = trigger; + instance->occur_start = occur_start; + instance->occur_end = occur_end; + + aod->triggers = g_slist_prepend (aod->triggers, instance); + aod->n_triggers++; +} + /* Callback used from cal_recur_generate_instances(); generates triggers for all * of a component's RELATIVE alarms. */ @@ -183,16 +210,17 @@ add_alarm_occurrences_cb (CalComponent *comp, time_t start, time_t end, gpointer const char *auid; CalComponentAlarm *alarm; CalAlarmTrigger trigger; + CalAlarmRepeat repeat; struct icaldurationtype *dur; time_t dur_time; time_t occur_time, trigger_time; - CalAlarmInstance *instance; auid = l->data; alarm = cal_component_get_alarm (comp, auid); g_assert (alarm != NULL); cal_component_alarm_get_trigger (alarm, &trigger); + cal_component_alarm_get_repeat (alarm, &repeat); cal_component_alarm_free (alarm); if (trigger.type != CAL_ALARM_TRIGGER_RELATIVE_START @@ -215,17 +243,28 @@ add_alarm_occurrences_cb (CalComponent *comp, time_t start, time_t end, gpointer trigger_time = occur_time + dur_time; - if (trigger_time < aod->start || trigger_time >= aod->end) - continue; + /* Add repeating alarms */ - instance = g_new (CalAlarmInstance, 1); - instance->auid = auid; - instance->trigger = trigger_time; - instance->occur_start = start; - instance->occur_end = end; + if (repeat.repetitions != 0) { + int i; + time_t repeat_time; - aod->triggers = g_slist_prepend (aod->triggers, instance); - aod->n_triggers++; + repeat_time = icaldurationtype_as_int (repeat.duration); + + for (i = 0; i < repeat.repetitions; i++) { + time_t t; + + t = trigger_time + (i + 1) * repeat_time; + + if (t >= aod->start && t < aod->end) + add_trigger (aod, auid, t, start, end); + } + } + + /* Add the trigger itself */ + + if (trigger_time >= aod->start && trigger_time < aod->end) + add_trigger (aod, auid, trigger_time, start, end); } return TRUE; @@ -233,7 +272,10 @@ add_alarm_occurrences_cb (CalComponent *comp, time_t start, time_t end, gpointer /* Generates the absolute triggers for a component */ static void -generate_absolute_triggers (CalComponent *comp, struct alarm_occurrence_data *aod) +generate_absolute_triggers (CalComponent *comp, struct alarm_occurrence_data *aod, + CalRecurResolveTimezoneFn resolve_tzid, + gpointer user_data, + icaltimezone *default_timezone) { GList *l; CalComponentDateTime dt_start, dt_end; @@ -244,43 +286,72 @@ generate_absolute_triggers (CalComponent *comp, struct alarm_occurrence_data *ao for (l = aod->alarm_uids; l; l = l->next) { const char *auid; CalComponentAlarm *alarm; + CalAlarmRepeat repeat; CalAlarmTrigger trigger; time_t abs_time; - CalAlarmInstance *instance; + time_t occur_start, occur_end; + icaltimezone *zone; auid = l->data; alarm = cal_component_get_alarm (comp, auid); g_assert (alarm != NULL); cal_component_alarm_get_trigger (alarm, &trigger); + cal_component_alarm_get_repeat (alarm, &repeat); cal_component_alarm_free (alarm); if (trigger.type != CAL_ALARM_TRIGGER_ABSOLUTE) continue; - abs_time = icaltime_as_timet (trigger.u.abs_time); + /* Absolute triggers are always in UTC; see RFC 2445 section 4.8.6.3 */ + zone = icaltimezone_get_utc_timezone (); - if (abs_time < aod->start || abs_time >= aod->end) - continue; - - instance = g_new (CalAlarmInstance, 1); - instance->auid = auid; - instance->trigger = abs_time; + abs_time = icaltime_as_timet_with_zone (trigger.u.abs_time, zone); /* No particular occurrence, so just use the times from the component */ - if (dt_start.value) - instance->occur_start = icaltime_as_timet (*dt_start.value); - else - instance->occur_start = -1; + if (dt_start.value) { + if (dt_start.tzid && !dt_start.value->is_date) + zone = (* resolve_tzid) (dt_start.tzid, user_data); + else + zone = default_timezone; - if (dt_end.value) - instance->occur_end = icaltime_as_timet (*dt_end.value); - else - instance->occur_end = -1; + occur_start = icaltime_as_timet_with_zone (*dt_start.value, zone); + } else + occur_start = -1; + + if (dt_end.value) { + if (dt_end.tzid && !dt_end.value->is_date) + zone = (* resolve_tzid) (dt_end.tzid, user_data); + else + zone = default_timezone; + + occur_end = icaltime_as_timet_with_zone (*dt_end.value, zone); + } else + occur_end = -1; + + /* Add repeating alarms */ + + if (repeat.repetitions != 0) { + int i; + time_t repeat_time; + + repeat_time = icaldurationtype_as_int (repeat.duration); + + for (i = 0; i < repeat.repetitions; i++) { + time_t t; + + t = abs_time + (i + 1) * repeat_time; + + if (t >= aod->start && t < aod->end) + add_trigger (aod, auid, t, occur_start, occur_end); + } + } + + /* Add the trigger itself */ - aod->triggers = g_slist_prepend (aod->triggers, instance); - aod->n_triggers++; + if (abs_time >= aod->start && abs_time < aod->end) + add_trigger (aod, auid, abs_time, occur_start, occur_end); } cal_component_free_datetime (&dt_start); @@ -349,7 +420,7 @@ cal_util_generate_alarms_for_comp (CalComponent *comp, default_timezone); /* We add the ABSOLUTE triggers separately */ - generate_absolute_triggers (comp, &aod); + generate_absolute_triggers (comp, &aod, resolve_tzid, user_data, default_timezone); if (aod.n_triggers == 0) return NULL; diff --git a/calendar/gui/cal-search-bar.c b/calendar/gui/cal-search-bar.c index 9c30a02308..3313220d58 100644 --- a/calendar/gui/cal-search-bar.c +++ b/calendar/gui/cal-search-bar.c @@ -23,6 +23,7 @@ #endif #include +#include #include #include #include diff --git a/calendar/gui/calendar-model.c b/calendar/gui/calendar-model.c index f039a3d7e1..39df6f2b32 100644 --- a/calendar/gui/calendar-model.c +++ b/calendar/gui/calendar-model.c @@ -40,6 +40,7 @@ #include "calendar-model.h" #include "evolution-activity-client.h" #include "e-cell-date-edit-text.h" +#include "misc.h" /* This specifies how often we refresh the list, so that completed tasks are hidden according to the config setting, and overdue tasks change color etc. @@ -903,27 +904,6 @@ calendar_model_value_at (ETableModel *etm, int col, int row) } } -/* Returns whether a string is NULL, empty, or full of whitespace */ -static gboolean -string_is_empty (const char *value) -{ - const char *p; - gboolean empty = TRUE; - - if (value) { - p = value; - while (*p) { - if (!isspace ((unsigned char) *p)) { - empty = FALSE; - break; - } - p++; - } - } - return empty; -} - - /* Builds a list of categories from a comma-delimited string */ static GSList * categories_from_string (const char *value) -- cgit v1.2.3