aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--calendar/ChangeLog16
-rw-r--r--calendar/cal-util/cal-util.c302
-rw-r--r--calendar/cal-util/cal-util.h16
-rw-r--r--calendar/pcs/cal-backend-db.c261
-rw-r--r--calendar/pcs/cal-backend-file.c320
5 files changed, 372 insertions, 543 deletions
diff --git a/calendar/ChangeLog b/calendar/ChangeLog
index eecd0e4e9b..f36523caf8 100644
--- a/calendar/ChangeLog
+++ b/calendar/ChangeLog
@@ -1,3 +1,19 @@
+2001-08-20 Rodrigo Moya <rodrigo@ximian.com>
+
+ * cal-util/cal-util.[ch] (cal_util_generate_alarms_for_list):
+ (cal_util_generate_alarms_for_comp):
+ new functions moved from the CalBackendFile, to allow its use outside
+ of it. The signature has changed a little bit, since these functions
+ need a way to get the timezones from the callers, so a callback
+ function to resolve the timezones has been added to the list of
+ parameters
+
+ * pcs/cal-backend-file.c (generate_alarms_for_list):
+ (generate_alarms_for_comp): moved to cal-util, with all their related
+ functions/structures
+
+ * pcs/cal-backend-db.c: removed functions that were moved to cal-util
+
2001-08-20 Damon Chaplin <damon@ximian.com>
* gui/dialogs/comp-editor.c (pixmaps): use Delete icon in menu, and
diff --git a/calendar/cal-util/cal-util.c b/calendar/cal-util/cal-util.c
index bb1b8a2f51..1df57bacec 100644
--- a/calendar/cal-util/cal-util.c
+++ b/calendar/cal-util/cal-util.c
@@ -98,3 +98,305 @@ cal_util_new_top_level (void)
return icalcomp;
}
+
+/* Computes the range of time in which recurrences should be generated for a
+ * component in order to compute alarm trigger times.
+ */
+static void
+compute_alarm_range (CalComponent *comp, GList *alarm_uids, time_t start, time_t end,
+ time_t *alarm_start, time_t *alarm_end)
+{
+ GList *l;
+
+ *alarm_start = start;
+ *alarm_end = end;
+
+ for (l = alarm_uids; l; l = l->next) {
+ const char *auid;
+ CalComponentAlarm *alarm;
+ CalAlarmTrigger trigger;
+ struct icaldurationtype *dur;
+ time_t dur_time;
+
+ auid = l->data;
+ alarm = cal_component_get_alarm (comp, auid);
+ g_assert (alarm != NULL);
+
+ cal_component_alarm_get_trigger (alarm, &trigger);
+ cal_component_alarm_free (alarm);
+
+ switch (trigger.type) {
+ case CAL_ALARM_TRIGGER_NONE:
+ case CAL_ALARM_TRIGGER_ABSOLUTE:
+ continue;
+
+ case CAL_ALARM_TRIGGER_RELATIVE_START:
+ case CAL_ALARM_TRIGGER_RELATIVE_END:
+ dur = &trigger.u.rel_duration;
+ dur_time = icaldurationtype_as_int (*dur);
+
+ if (dur->is_neg)
+ /* If the duration is negative then dur_time
+ * will be negative as well; that is why we
+ * subtract to expand the range.
+ */
+ *alarm_end = MAX (*alarm_end, end - dur_time);
+ else
+ *alarm_start = MIN (*alarm_start, start - dur_time);
+
+ break;
+
+ default:
+ g_assert_not_reached ();
+ }
+ }
+
+ g_assert (*alarm_start <= *alarm_end);
+}
+
+/* Closure data to generate alarm occurrences */
+struct alarm_occurrence_data {
+ /* These are the info we have */
+ GList *alarm_uids;
+ time_t start;
+ time_t end;
+
+ /* This is what we compute */
+ GSList *triggers;
+ int n_triggers;
+};
+
+/* Callback used from cal_recur_generate_instances(); generates triggers for all
+ * of a component's RELATIVE alarms.
+ */
+static gboolean
+add_alarm_occurrences_cb (CalComponent *comp, time_t start, time_t end, gpointer data)
+{
+ struct alarm_occurrence_data *aod;
+ GList *l;
+
+ aod = data;
+
+ for (l = aod->alarm_uids; l; l = l->next) {
+ const char *auid;
+ CalComponentAlarm *alarm;
+ CalAlarmTrigger trigger;
+ 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_free (alarm);
+
+ if (trigger.type != CAL_ALARM_TRIGGER_RELATIVE_START
+ && trigger.type != CAL_ALARM_TRIGGER_RELATIVE_END)
+ continue;
+
+ dur = &trigger.u.rel_duration;
+ dur_time = icaldurationtype_as_int (*dur);
+
+ if (trigger.type == CAL_ALARM_TRIGGER_RELATIVE_START)
+ occur_time = start;
+ else
+ occur_time = end;
+
+ /* If dur->is_neg is true then dur_time will already be
+ * negative. So we do not need to test for dur->is_neg here; we
+ * can simply add the dur_time value to the occur_time and get
+ * the correct result.
+ */
+
+ trigger_time = occur_time + dur_time;
+
+ if (trigger_time < aod->start || trigger_time >= aod->end)
+ continue;
+
+ instance = g_new (CalAlarmInstance, 1);
+ instance->auid = auid;
+ instance->trigger = trigger_time;
+ instance->occur_start = start;
+ instance->occur_end = end;
+
+ aod->triggers = g_slist_prepend (aod->triggers, instance);
+ aod->n_triggers++;
+ }
+
+ return TRUE;
+}
+
+/* Generates the absolute triggers for a component */
+static void
+generate_absolute_triggers (CalComponent *comp, struct alarm_occurrence_data *aod)
+{
+ GList *l;
+ CalComponentDateTime dt_start, dt_end;
+
+ cal_component_get_dtstart (comp, &dt_start);
+ cal_component_get_dtend (comp, &dt_end);
+
+ for (l = aod->alarm_uids; l; l = l->next) {
+ const char *auid;
+ CalComponentAlarm *alarm;
+ CalAlarmTrigger trigger;
+ time_t abs_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_free (alarm);
+
+ if (trigger.type != CAL_ALARM_TRIGGER_ABSOLUTE)
+ continue;
+
+ abs_time = icaltime_as_timet (trigger.u.abs_time);
+
+ if (abs_time < aod->start || abs_time >= aod->end)
+ continue;
+
+ instance = g_new (CalAlarmInstance, 1);
+ instance->auid = auid;
+ instance->trigger = abs_time;
+
+ /* 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_end.value)
+ instance->occur_end = icaltime_as_timet (*dt_end.value);
+ else
+ instance->occur_end = -1;
+
+ aod->triggers = g_slist_prepend (aod->triggers, instance);
+ aod->n_triggers++;
+ }
+
+ cal_component_free_datetime (&dt_start);
+ cal_component_free_datetime (&dt_end);
+}
+
+/* Compares two alarm instances; called from g_slist_sort() */
+static gint
+compare_alarm_instance (gconstpointer a, gconstpointer b)
+{
+ const CalAlarmInstance *aia, *aib;
+
+ aia = a;
+ aib = b;
+
+ if (aia->trigger < aib->trigger)
+ return -1;
+ else if (aia->trigger > aib->trigger)
+ return 1;
+ else
+ return 0;
+}
+
+/**
+ * cal_util_generate_alarms_for_comp
+ * @comp: the CalComponent to generate alarms from
+ * @start: start time
+ * @end: end time
+ * @resolve_tzid: callback for resolving timezones
+ * @user_data: data to be passed to the resolve_tzid callback
+ *
+ * Generates alarm instances for a calendar component. Returns the instances
+ * structure, or NULL if no alarm instances occurred in the specified time
+ * range.
+ */
+CalComponentAlarms *
+cal_util_generate_alarms_for_comp (CalComponent *comp,
+ time_t start,
+ time_t end,
+ CalRecurResolveTimezoneFn resolve_tzid,
+ gpointer user_data)
+{
+ GList *alarm_uids;
+ time_t alarm_start, alarm_end;
+ struct alarm_occurrence_data aod;
+ CalComponentAlarms *alarms;
+
+ if (!cal_component_has_alarms (comp))
+ return NULL;
+
+ alarm_uids = cal_component_get_alarm_uids (comp);
+ compute_alarm_range (comp, alarm_uids, start, end, &alarm_start, &alarm_end);
+
+ aod.alarm_uids = alarm_uids;
+ aod.start = start;
+ aod.end = end;
+ aod.triggers = NULL;
+ aod.n_triggers = 0;
+
+ cal_recur_generate_instances (comp, alarm_start, alarm_end,
+ add_alarm_occurrences_cb, &aod,
+ resolve_tzid, user_data);
+
+ /* We add the ABSOLUTE triggers separately */
+ generate_absolute_triggers (comp, &aod);
+
+ if (aod.n_triggers == 0)
+ return NULL;
+
+ /* Create the component alarm instances structure */
+
+ alarms = g_new (CalComponentAlarms, 1);
+ alarms->comp = comp;
+ gtk_object_ref (GTK_OBJECT (alarms->comp));
+ alarms->alarms = g_slist_sort (aod.triggers, compare_alarm_instance);
+
+ return alarms;
+}
+
+/**
+ * cal_util_generate_alarms_for_list
+ * @comps: list of CalComponent's
+ * @start: start time
+ * @end: end time
+ * @comp_alarms: list to be returned
+ * @resolve_tzid: callback for resolving timezones
+ * @user_data: data to be passed to the resolve_tzid callback
+ *
+ * Iterates through all the components in the comps list and generates alarm
+ * instances for them; putting them in the comp_alarms list.
+ *
+ * Returns: the number of elements it added to that list.
+ */
+int
+cal_util_generate_alarms_for_list (GList *comps,
+ time_t start,
+ time_t end,
+ GSList **comp_alarms,
+ CalRecurResolveTimezoneFn resolve_tzid,
+ gpointer user_data)
+{
+ GList *l;
+ int n;
+
+ n = 0;
+
+ for (l = comps; l; l = l->next) {
+ CalComponent *comp;
+ CalComponentAlarms *alarms;
+
+ comp = CAL_COMPONENT (l->data);
+ alarms = cal_util_generate_alarms_for_comp (comp, start, end, resolve_tzid, user_data);
+
+ if (alarms) {
+ *comp_alarms = g_slist_prepend (*comp_alarms, alarms);
+ n++;
+ }
+ }
+
+ return n;
+}
diff --git a/calendar/cal-util/cal-util.h b/calendar/cal-util/cal-util.h
index 1333bc3334..943f048d35 100644
--- a/calendar/cal-util/cal-util.h
+++ b/calendar/cal-util/cal-util.h
@@ -27,6 +27,8 @@
#include <ical.h>
#include <time.h>
#include <glib.h>
+#include <cal-util/cal-component.h>
+#include <cal-util/cal-recur.h>
BEGIN_GNOME_DECLS
@@ -55,6 +57,20 @@ void cal_obj_uid_list_free (GList *list);
icalcomponent *cal_util_new_top_level (void);
+CalComponentAlarms *cal_util_generate_alarms_for_comp (CalComponent *comp,
+ time_t start,
+ time_t end,
+ CalRecurResolveTimezoneFn resolve_tzid,
+ gpointer user_data);
+int cal_util_generate_alarms_for_list (GList *comps,
+ time_t start,
+ time_t end,
+ GSList **comp_alarms,
+ CalRecurResolveTimezoneFn resolve_tzid,
+ gpointer user_data);
+
+icaltimezone *cal_util_resolve_tzid (const char *tzid, gpointer data);
+
END_GNOME_DECLS
#endif
diff --git a/calendar/pcs/cal-backend-db.c b/calendar/pcs/cal-backend-db.c
index 73aef5d054..bbb4590fc2 100644
--- a/calendar/pcs/cal-backend-db.c
+++ b/calendar/pcs/cal-backend-db.c
@@ -958,234 +958,6 @@ cal_backend_db_get_changes (CalBackend *backend, CalObjType type, const char *ch
return NULL;
}
-/* computes the range of time in which recurrences should be generated for a
- * component in order to compute alarm trigger times.
- */
-static void
-compute_alarm_range (CalComponent *comp,
- GList *alarm_uids,
- time_t start,
- time_t end,
- time_t *alarm_start,
- time_t *alarm_end)
-{
- GList *l;
-
- *alarm_start = start;
- *alarm_end = end;
-
- for (l = alarm_uids; l; l = l->next) {
- const char *auid;
- CalComponentAlarm *alarm;
- CalAlarmTrigger trigger;
- struct icaldurationtype *dur;
- time_t dur_time;
-
- auid = l->data;
- alarm = cal_component_get_alarm (comp, auid);
- g_assert (alarm != NULL);
-
- cal_component_alarm_get_trigger (alarm, &trigger);
- cal_component_alarm_free (alarm);
-
- switch (trigger.type) {
- case CAL_ALARM_TRIGGER_NONE:
- case CAL_ALARM_TRIGGER_ABSOLUTE:
- continue;
- case CAL_ALARM_TRIGGER_RELATIVE_START:
- case CAL_ALARM_TRIGGER_RELATIVE_END:
- dur = &trigger.u.rel_duration;
- dur_time = icaldurationtype_as_int (*dur);
-
- if (dur->is_neg)
- /* If the duration is negative then dur_time
- * will be negative as well; that is why we
- * subtract to expand the range.
- */
- *alarm_end = MAX (*alarm_end, end - dur_time);
- else
- *alarm_start = MIN (*alarm_start, start - dur_time);
-
- break;
- default:
- g_assert_not_reached ();
- }
- }
-
- g_assert (*alarm_start <= *alarm_end);
-}
-
-/* closure data to generate alarm occurrences */
-struct alarm_occurrence_data {
- /* these are the info we have */
- GList *alarm_uids;
- time_t start;
- time_t end;
-
- /* this is what we compute */
- GSList *triggers;
- int n_triggers;
-};
-
-/* callback used from cal_recur_generate_instances(); generates triggers for all
- * of a component's RELATIVE alarms.
- */
-static gboolean
-add_alarm_occurrences_cb (CalComponent *comp, time_t start, time_t end, gpointer data)
-{
- struct alarm_occurrence_data *aod;
- GList *l;
-
- aod = data;
-
- for (l = aod->alarm_uids; l; l = l->next) {
- const char *auid;
- CalComponentAlarm *alarm;
- CalAlarmTrigger trigger;
- 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_free (alarm);
-
- if (trigger.type != CAL_ALARM_TRIGGER_RELATIVE_START
- && trigger.type != CAL_ALARM_TRIGGER_RELATIVE_END)
- continue;
-
- dur = &trigger.u.rel_duration;
- dur_time = icaldurationtype_as_int (*dur);
-
- if (trigger.type == CAL_ALARM_TRIGGER_RELATIVE_START)
- occur_time = start;
- else
- occur_time = end;
-
- /* If dur->is_neg is true then dur_time will already be
- * negative. So we do not need to test for dur->is_neg here; we
- * can simply add the dur_time value to the occur_time and get
- * the correct result.
- */
-
- trigger_time = occur_time + dur_time;
-
- if (trigger_time < aod->start || trigger_time >= aod->end)
- continue;
-
- instance = g_new (CalAlarmInstance, 1);
- instance->auid = auid;
- instance->trigger = trigger_time;
- instance->occur = occur_time;
-
- aod->triggers = g_slist_prepend (aod->triggers, instance);
- aod->n_triggers++;
- }
-
- return TRUE;
-}
-
-/* generates the absolute triggers for a component */
-static void
-generate_absolute_triggers (CalComponent *comp, struct alarm_occurrence_data *aod)
-{
- GList *l;
-
- for (l = aod->alarm_uids; l; l = l->next) {
- const char *auid;
- CalComponentAlarm *alarm;
- CalAlarmTrigger trigger;
- time_t abs_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_free (alarm);
-
- if (trigger.type != CAL_ALARM_TRIGGER_ABSOLUTE)
- continue;
-
- abs_time = icaltime_as_timet (trigger.u.abs_time);
-
- if (abs_time < aod->start || abs_time >= aod->end)
- continue;
-
- instance = g_new (CalAlarmInstance, 1);
- instance->auid = auid;
- instance->trigger = abs_time;
- instance->occur = abs_time; /* No particular occurrence, so just use the same time */
-
- aod->triggers = g_slist_prepend (aod->triggers, instance);
- aod->n_triggers++;
- }
-}
-
-/* compares two alarm instances; called from g_slist_sort() */
-static gint
-compare_alarm_instance (gconstpointer a, gconstpointer b)
-{
- const CalAlarmInstance *aia, *aib;
-
- aia = a;
- aib = b;
-
- if (aia->trigger < aib->trigger)
- return -1;
- else if (aia->trigger > aib->trigger)
- return 1;
- else
- return 0;
-}
-
-/* generates alarm instances for a calendar component. Returns the instances
- * structure, or NULL if no alarm instances occurred in the specified time
- * range.
- */
-static CalComponentAlarms *
-generate_alarms_for_comp (CalComponent *comp, time_t start, time_t end)
-{
- CalComponentAlarms *alarms = NULL;
- GList *alarm_uids;
- time_t alarm_start, alarm_end;
- struct alarm_occurrence_data aod;
-
- g_return_val_if_fail(IS_CAL_COMPONENT(comp), NULL);
-
- if (!cal_component_has_alarms(comp))
- return NULL;
-
- alarm_uids = cal_component_get_alarm_uids(comp);
- compute_alarm_range(comp, alarm_uids, start, end, &alarm_start, &alarm_end);
-
- aod.alarm_uids = alarm_uids;
- aod.start = start;
- aod.end = end;
- aod.triggers = NULL;
- aod.n_triggers = 0;
- cal_recur_generate_instances(comp, alarm_start, alarm_end, add_alarm_occurrences_cb, &aod);
-
- /* we add the ABSOLUTE triggers separately */
- generate_absolute_triggers(comp, &aod);
-
- if (aod.n_triggers == 0)
- return NULL;
-
- /* create the component alarm instances structure */
- alarms = g_new (CalComponentAlarms, 1);
- alarms->comp = comp;
- gtk_object_ref (GTK_OBJECT (alarms->comp));
- alarms->alarms = g_slist_sort (aod.triggers, compare_alarm_instance);
-
- return alarms;
-}
-
/* retrieve list of alarms */
static GSList *
get_list_of_alarms (CalBackendDBCursor *cursor, time_t start, time_t end)
@@ -1203,26 +975,27 @@ get_list_of_alarms (CalBackendDBCursor *cursor, time_t start, time_t end)
data = (DBT *) node->data;
if (data) {
icalcomp = icalparser_parse_string((char *) data->data);
- if (icalcomp) {
- /* per RFC 2445, only VEVENTs and VTODOs can have alarms */
- kind = icalcomponent_isa(icalcomp);
- if (kind == ICAL_VEVENT_COMPONENT || kind == ICAL_VTODO_COMPONENT) {
- CalComponent *comp;
- CalComponentAlarms *alarms;
+ if (!icalcomp)
+ continue;
+
+ /* per RFC 2445, only VEVENTs and VTODOs can have alarms */
+ kind = icalcomponent_isa(icalcomp);
+ if (kind == ICAL_VEVENT_COMPONENT || kind == ICAL_VTODO_COMPONENT) {
+ CalComponent *comp;
+ CalComponentAlarms *alarms;
- /* create the CalComponent to compute the alarms */
- comp = cal_component_new();
- cal_component_set_icalcomponent(comp, icalcomp);
+ /* create the CalComponent to compute the alarms */
+ comp = cal_component_new();
+ cal_component_set_icalcomponent(comp, icalcomp);
- alarms = generate_alarms_for_comp(comp, start, end);
- if (alarms)
- list = g_slist_prepend(list, (gpointer) alarms);
-
- gtk_object_unref(GTK_OBJECT(comp));
- }
+ alarms = cal_util_generate_alarms_for_comp (comp, start, end);
+ if (alarms)
+ list = g_slist_prepend(list, (gpointer) alarms);
- icalcomponent_free(icalcomp);
+ gtk_object_unref(GTK_OBJECT(comp));
}
+
+ icalcomponent_free(icalcomp);
}
}
diff --git a/calendar/pcs/cal-backend-file.c b/calendar/pcs/cal-backend-file.c
index 9e090a6781..81d2739123 100644
--- a/calendar/pcs/cal-backend-file.c
+++ b/calendar/pcs/cal-backend-file.c
@@ -1065,6 +1065,20 @@ cal_backend_file_get_uids (CalBackend *backend, CalObjType type)
return list;
}
+/* function to resolve timezones */
+static icaltimezone *
+resolve_tzid (const char *tzid, gpointer user_data)
+{
+ icalcomponent *vcalendar_comp = user_data;
+
+ if (!tzid || !tzid[0])
+ return NULL;
+ else if (!strcmp (tzid, "UTC"))
+ return icaltimezone_get_utc_timezone ();
+
+ return icalcomponent_get_timezone (vcalendar_comp, tzid);
+}
+
/* Callback used from cal_recur_generate_instances(); adds the component's UID
* to our hash table.
*/
@@ -1092,21 +1106,6 @@ add_instance (CalComponent *comp, time_t start, time_t end, gpointer data)
return FALSE;
}
-
-static icaltimezone*
-resolve_tzid (const char *tzid, gpointer data)
-{
- icalcomponent *vcalendar_comp = data;
-
- if (!tzid || !tzid[0])
- return NULL;
- else if (!strcmp (tzid, "UTC"))
- return icaltimezone_get_utc_timezone ();
- else
- return icalcomponent_get_timezone (vcalendar_comp, tzid);
-}
-
-
/* Populates a hash table with the UIDs of the components that occur or recur
* within a specific time range.
*/
@@ -1396,287 +1395,6 @@ cal_backend_file_get_changes (CalBackend *backend, CalObjType type, const char *
return cal_backend_file_compute_changes (backend, type, change_id);
}
-/* Computes the range of time in which recurrences should be generated for a
- * component in order to compute alarm trigger times.
- */
-static void
-compute_alarm_range (CalComponent *comp, GList *alarm_uids, time_t start, time_t end,
- time_t *alarm_start, time_t *alarm_end)
-{
- GList *l;
-
- *alarm_start = start;
- *alarm_end = end;
-
- for (l = alarm_uids; l; l = l->next) {
- const char *auid;
- CalComponentAlarm *alarm;
- CalAlarmTrigger trigger;
- struct icaldurationtype *dur;
- time_t dur_time;
-
- auid = l->data;
- alarm = cal_component_get_alarm (comp, auid);
- g_assert (alarm != NULL);
-
- cal_component_alarm_get_trigger (alarm, &trigger);
- cal_component_alarm_free (alarm);
-
- switch (trigger.type) {
- case CAL_ALARM_TRIGGER_NONE:
- case CAL_ALARM_TRIGGER_ABSOLUTE:
- continue;
-
- case CAL_ALARM_TRIGGER_RELATIVE_START:
- case CAL_ALARM_TRIGGER_RELATIVE_END:
- dur = &trigger.u.rel_duration;
- dur_time = icaldurationtype_as_int (*dur);
-
- if (dur->is_neg)
- /* If the duration is negative then dur_time
- * will be negative as well; that is why we
- * subtract to expand the range.
- */
- *alarm_end = MAX (*alarm_end, end - dur_time);
- else
- *alarm_start = MIN (*alarm_start, start - dur_time);
-
- break;
-
- default:
- g_assert_not_reached ();
- }
- }
-
- g_assert (*alarm_start <= *alarm_end);
-}
-
-/* Closure data to generate alarm occurrences */
-struct alarm_occurrence_data {
- /* These are the info we have */
- GList *alarm_uids;
- time_t start;
- time_t end;
-
- /* This is what we compute */
- GSList *triggers;
- int n_triggers;
-};
-
-/* Callback used from cal_recur_generate_instances(); generates triggers for all
- * of a component's RELATIVE alarms.
- */
-static gboolean
-add_alarm_occurrences_cb (CalComponent *comp, time_t start, time_t end, gpointer data)
-{
- struct alarm_occurrence_data *aod;
- GList *l;
-
- aod = data;
-
- for (l = aod->alarm_uids; l; l = l->next) {
- const char *auid;
- CalComponentAlarm *alarm;
- CalAlarmTrigger trigger;
- 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_free (alarm);
-
- if (trigger.type != CAL_ALARM_TRIGGER_RELATIVE_START
- && trigger.type != CAL_ALARM_TRIGGER_RELATIVE_END)
- continue;
-
- dur = &trigger.u.rel_duration;
- dur_time = icaldurationtype_as_int (*dur);
-
- if (trigger.type == CAL_ALARM_TRIGGER_RELATIVE_START)
- occur_time = start;
- else
- occur_time = end;
-
- /* If dur->is_neg is true then dur_time will already be
- * negative. So we do not need to test for dur->is_neg here; we
- * can simply add the dur_time value to the occur_time and get
- * the correct result.
- */
-
- trigger_time = occur_time + dur_time;
-
- if (trigger_time < aod->start || trigger_time >= aod->end)
- continue;
-
- instance = g_new (CalAlarmInstance, 1);
- instance->auid = auid;
- instance->trigger = trigger_time;
- instance->occur_start = start;
- instance->occur_end = end;
-
- aod->triggers = g_slist_prepend (aod->triggers, instance);
- aod->n_triggers++;
- }
-
- return TRUE;
-}
-
-/* Generates the absolute triggers for a component */
-static void
-generate_absolute_triggers (CalComponent *comp, struct alarm_occurrence_data *aod)
-{
- GList *l;
- CalComponentDateTime dt_start, dt_end;
-
- cal_component_get_dtstart (comp, &dt_start);
- cal_component_get_dtend (comp, &dt_end);
-
- for (l = aod->alarm_uids; l; l = l->next) {
- const char *auid;
- CalComponentAlarm *alarm;
- CalAlarmTrigger trigger;
- time_t abs_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_free (alarm);
-
- if (trigger.type != CAL_ALARM_TRIGGER_ABSOLUTE)
- continue;
-
- abs_time = icaltime_as_timet (trigger.u.abs_time);
-
- if (abs_time < aod->start || abs_time >= aod->end)
- continue;
-
- instance = g_new (CalAlarmInstance, 1);
- instance->auid = auid;
- instance->trigger = abs_time;
-
- /* 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_end.value)
- instance->occur_end = icaltime_as_timet (*dt_end.value);
- else
- instance->occur_end = -1;
-
- aod->triggers = g_slist_prepend (aod->triggers, instance);
- aod->n_triggers++;
- }
-
- cal_component_free_datetime (&dt_start);
- cal_component_free_datetime (&dt_end);
-}
-
-/* Compares two alarm instances; called from g_slist_sort() */
-static gint
-compare_alarm_instance (gconstpointer a, gconstpointer b)
-{
- const CalAlarmInstance *aia, *aib;
-
- aia = a;
- aib = b;
-
- if (aia->trigger < aib->trigger)
- return -1;
- else if (aia->trigger > aib->trigger)
- return 1;
- else
- return 0;
-}
-
-/* Generates alarm instances for a calendar component. Returns the instances
- * structure, or NULL if no alarm instances occurred in the specified time
- * range.
- */
-static CalComponentAlarms *
-generate_alarms_for_comp (CalComponent *comp, time_t start, time_t end)
-{
- GList *alarm_uids;
- time_t alarm_start, alarm_end;
- struct alarm_occurrence_data aod;
- CalComponentAlarms *alarms;
- icalcomponent *icalcomp, *vcalendar_comp;
-
- if (!cal_component_has_alarms (comp))
- return NULL;
-
- alarm_uids = cal_component_get_alarm_uids (comp);
- compute_alarm_range (comp, alarm_uids, start, end, &alarm_start, &alarm_end);
-
- aod.alarm_uids = alarm_uids;
- aod.start = start;
- aod.end = end;
- aod.triggers = NULL;
- aod.n_triggers = 0;
-
- /* Get the parent VCALENDAR component, so we can resolve TZIDs. */
- icalcomp = cal_component_get_icalcomponent (comp);
- vcalendar_comp = icalcomponent_get_parent (icalcomp);
- g_assert (vcalendar_comp != NULL);
-
- cal_recur_generate_instances (comp, alarm_start, alarm_end,
- add_alarm_occurrences_cb, &aod,
- resolve_tzid, vcalendar_comp);
-
- /* We add the ABSOLUTE triggers separately */
- generate_absolute_triggers (comp, &aod);
-
- if (aod.n_triggers == 0)
- return NULL;
-
- /* Create the component alarm instances structure */
-
- alarms = g_new (CalComponentAlarms, 1);
- alarms->comp = comp;
- gtk_object_ref (GTK_OBJECT (alarms->comp));
- alarms->alarms = g_slist_sort (aod.triggers, compare_alarm_instance);
-
- return alarms;
-}
-
-/* Iterates through all the components in the comps list and generates alarm
- * instances for them; putting them in the comp_alarms list. Returns the number
- * of elements it added to that list.
- */
-static int
-generate_alarms_for_list (GList *comps, time_t start, time_t end, GSList **comp_alarms)
-{
- GList *l;
- int n;
-
- n = 0;
-
- for (l = comps; l; l = l->next) {
- CalComponent *comp;
- CalComponentAlarms *alarms;
-
- comp = CAL_COMPONENT (l->data);
- alarms = generate_alarms_for_comp (comp, start, end);
-
- if (alarms) {
- *comp_alarms = g_slist_prepend (*comp_alarms, alarms);
- n++;
- }
- }
-
- return n;
-}
-
/* Fills a CORBA sequence of alarm instances */
static void
fill_alarm_instances_seq (GNOME_Evolution_Calendar_CalAlarmInstanceSeq *seq, GSList *alarms)
@@ -1730,8 +1448,12 @@ cal_backend_file_get_alarms_in_range (CalBackend *backend, time_t start, time_t
n_comp_alarms = 0;
comp_alarms = NULL;
- n_comp_alarms += generate_alarms_for_list (priv->events, start, end, &comp_alarms);
- n_comp_alarms += generate_alarms_for_list (priv->todos, start, end, &comp_alarms);
+ n_comp_alarms += cal_util_generate_alarms_for_list (priv->events, start, end,
+ &comp_alarms, resolve_tzid,
+ priv->icalcomp);
+ n_comp_alarms += cal_util_generate_alarms_for_list (priv->todos, start, end,
+ &comp_alarms, resolve_tzid,
+ priv->icalcomp);
seq = GNOME_Evolution_Calendar_CalComponentAlarmsSeq__alloc ();
CORBA_sequence_set_release (seq, TRUE);
@@ -1795,7 +1517,7 @@ cal_backend_file_get_alarms_for_object (CalBackend *backend, const char *uid,
corba_alarms->calobj = CORBA_string_dup (comp_str);
g_free (comp_str);
- alarms = generate_alarms_for_comp (comp, start, end);
+ alarms = cal_util_generate_alarms_for_comp (comp, start, end, resolve_tzid, priv->icalcomp);
if (alarms) {
fill_alarm_instances_seq (&corba_alarms->alarms, alarms->alarms);
cal_component_alarms_free (alarms);