aboutsummaryrefslogtreecommitdiffstats
path: root/calendar/pcs
diff options
context:
space:
mode:
Diffstat (limited to 'calendar/pcs')
-rw-r--r--calendar/pcs/cal-backend-imc.c186
-rw-r--r--calendar/pcs/cal-backend-imc.h1
-rw-r--r--calendar/pcs/cal-backend.c22
-rw-r--r--calendar/pcs/cal-backend.h3
-rw-r--r--calendar/pcs/cal.c133
5 files changed, 319 insertions, 26 deletions
diff --git a/calendar/pcs/cal-backend-imc.c b/calendar/pcs/cal-backend-imc.c
index 792abbb4ae..9492ad1241 100644
--- a/calendar/pcs/cal-backend-imc.c
+++ b/calendar/pcs/cal-backend-imc.c
@@ -4,6 +4,7 @@
*
* Authors: Federico Mena-Quintero <federico@helixcode.com>
* Seth Alves <alves@helixcode.com>
+ * Miguel de Icaza <miguel@helixcode.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -76,6 +77,7 @@ static void cal_backend_imc_create (CalBackend *backend, GnomeVFSURI *uri);
static char *cal_backend_imc_get_object (CalBackend *backend, const char *uid);
static GList *cal_backend_imc_get_uids (CalBackend *backend, CalObjType type);
static GList *cal_backend_imc_get_events_in_range (CalBackend *backend, time_t start, time_t end);
+static GList *cal_backend_imc_get_alarms_in_range (CalBackend *backend, time_t start, time_t end);
static gboolean cal_backend_imc_update_object (CalBackend *backend, const char *uid,
const char *calobj);
static gboolean cal_backend_imc_remove_object (CalBackend *backend, const char *uid);
@@ -135,6 +137,7 @@ cal_backend_imc_class_init (CalBackendIMCClass *class)
backend_class->get_object = cal_backend_imc_get_object;
backend_class->get_uids = cal_backend_imc_get_uids;
backend_class->get_events_in_range = cal_backend_imc_get_events_in_range;
+ backend_class->get_alarms_in_range = cal_backend_imc_get_alarms_in_range;
backend_class->update_object = cal_backend_imc_update_object;
backend_class->remove_object = cal_backend_imc_remove_object;
@@ -905,6 +908,22 @@ cal_backend_imc_get_uids (CalBackend *backend, CalObjType type)
return c.uid_list;
}
+/* Allocates and fills in a new CalObjInstance structure */
+static CalObjInstance *
+build_cal_obj_instance (iCalObject *ico, time_t start, time_t end)
+{
+ CalObjInstance *icoi;
+
+ g_assert (ico->uid != NULL);
+
+ icoi = g_new (CalObjInstance, 1);
+ icoi->uid = g_strdup (ico->uid);
+ icoi->start = start;
+ icoi->end = end;
+
+ return icoi;
+}
+
struct build_event_list_closure {
CalBackendIMC *cbimc;
GList *event_list;
@@ -921,13 +940,7 @@ build_event_list (iCalObject *ico, time_t start, time_t end, void *data)
c = data;
- icoi = g_new (CalObjInstance, 1);
-
- g_assert (ico->uid != NULL);
- icoi->uid = g_strdup (ico->uid);
- icoi->start = start;
- icoi->end = end;
-
+ icoi = build_cal_obj_instance (ico, start, end);
c->event_list = g_list_prepend (c->event_list, icoi);
return TRUE;
@@ -953,11 +966,10 @@ compare_instance_func (gconstpointer a, gconstpointer b)
static GList *
cal_backend_imc_get_events_in_range (CalBackend *backend, time_t start, time_t end)
{
- struct build_event_list_closure c;
- GList *l;
-
CalBackendIMC *cbimc;
IMCPrivate *priv;
+ struct build_event_list_closure c;
+ GList *l;
cbimc = CAL_BACKEND_IMC (backend);
priv = cbimc->priv;
@@ -979,10 +991,162 @@ cal_backend_imc_get_events_in_range (CalBackend *backend, time_t start, time_t e
}
c.event_list = g_list_sort (c.event_list, compare_instance_func);
-
return c.event_list;
}
+struct build_alarm_list_closure {
+ time_t start;
+ time_t end;
+ GList *alarms;
+};
+
+/* Computes the offset in minutes from an alarm trigger to the actual event */
+static int
+compute_alarm_offset (CalendarAlarm *a)
+{
+ int ofs;
+
+ if (!a->enabled)
+ return -1;
+
+ switch (a->units) {
+ case ALARM_MINUTES:
+ ofs = a->count * 60;
+ break;
+
+ case ALARM_HOURS:
+ ofs = a->count * 3600;
+ break;
+
+ case ALARM_DAYS:
+ ofs = a->count * 24 * 3600;
+ break;
+
+ default:
+ ofs = -1;
+ g_assert_not_reached ();
+ }
+
+ return ofs;
+}
+
+/* Allocates and fills in a new CalAlarmInstance structure */
+static CalAlarmInstance *
+build_cal_alarm_instance (iCalObject *ico, enum AlarmType type, time_t trigger, time_t occur)
+{
+ CalAlarmInstance *ai;
+
+ g_assert (ico->uid != NULL);
+
+ ai = g_new (CalAlarmInstance, 1);
+ ai->uid = g_strdup (ico->uid);
+ ai->type = type;
+ ai->trigger = trigger;
+ ai->occur = occur;
+
+ return ai;
+}
+
+/* Adds the specified alarm to the list if its trigger time falls within the
+ * requested range.
+ */
+static void
+try_add_alarm (time_t occur_start, iCalObject *ico, CalendarAlarm *alarm,
+ struct build_alarm_list_closure *c)
+{
+ int ofs;
+ time_t trigger;
+ CalAlarmInstance *ai;
+
+ if (!alarm->enabled)
+ return;
+
+ ofs = compute_alarm_offset (alarm);
+ g_assert (ofs != -1);
+
+ trigger = occur_start - ofs;
+
+ if (trigger < c->start || trigger > c->end)
+ return;
+
+ ai = build_cal_alarm_instance (ico, alarm->type, trigger, occur_start);
+ c->alarms = g_list_prepend (c->alarms, ai);
+}
+
+/* Builds a list of alarm instances. Used as a callback from
+ * ical_object_generate_events().
+ */
+static int
+build_alarm_list (iCalObject *ico, time_t start, time_t end, void *data)
+{
+ struct build_alarm_list_closure *c;
+
+ c = data;
+
+ try_add_alarm (start, ico, &ico->dalarm, c);
+ try_add_alarm (start, ico, &ico->aalarm, c);
+ try_add_alarm (start, ico, &ico->palarm, c);
+ try_add_alarm (start, ico, &ico->malarm, c);
+
+ return TRUE;
+}
+
+/* Adds all the alarm triggers that occur within the specified time range */
+static GList *
+add_alarms_for_object (GList *alarms, iCalObject *ico, time_t start, time_t end)
+{
+ struct build_alarm_list_closure c;
+ int dofs, aofs, pofs, mofs;
+ int max_ofs;
+
+ dofs = compute_alarm_offset (&ico->dalarm);
+ aofs = compute_alarm_offset (&ico->aalarm);
+ pofs = compute_alarm_offset (&ico->palarm);
+ mofs = compute_alarm_offset (&ico->malarm);
+
+ max_ofs = MAX (dofs, MAX (aofs, MAX (pofs, mofs)));
+ if (max_ofs == -1)
+ return alarms;
+
+ c.start = start;
+ c.end = end;
+ c.alarms = alarms;
+
+ ical_object_generate_events (ico, start, end, build_alarm_list, &c);
+ return c.alarms;
+}
+
+/* Get_alarms_in_range handler for the IMC backend */
+static GList *
+cal_backend_imc_get_alarms_in_range (CalBackend *backend, time_t start, time_t end)
+{
+ CalBackendIMC *cbimc;
+ IMCPrivate *priv;
+ GList *l;
+ GList *alarms;
+
+ cbimc = CAL_BACKEND_IMC (backend);
+ priv = cbimc->priv;
+
+ g_return_val_if_fail (priv->loaded, NULL);
+
+ g_return_val_if_fail (start != -1 && end != -1, NULL);
+ g_return_val_if_fail (start <= end, NULL);
+
+ /* Only VEVENT and VTODO components can have alarms */
+
+ alarms = NULL;
+
+ for (l = priv->events; l; l = l->next)
+ alarms = add_alarms_for_object (alarms, (iCalObject *) l->data, start, end);
+
+ for (l = priv->todos; l; l = l->next)
+ alarms = add_alarms_for_object (alarms, (iCalObject *) l->data, start, end);
+
+ alarms = g_list_sort (alarms, compare_instance_func);
+ return alarms;
+}
+
/* Notifies a backend's clients that an object was updated */
static void
notify_update (CalBackendIMC *cbimc, const char *uid)
diff --git a/calendar/pcs/cal-backend-imc.h b/calendar/pcs/cal-backend-imc.h
index b0fa93611e..954bbc52cc 100644
--- a/calendar/pcs/cal-backend-imc.h
+++ b/calendar/pcs/cal-backend-imc.h
@@ -4,6 +4,7 @@
*
* Authors: Federico Mena-Quintero <federico@helixcode.com>
* Seth Alves <alves@helixcode.com>
+ * Miguel de Icaza <miguel@helixcode.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/calendar/pcs/cal-backend.c b/calendar/pcs/cal-backend.c
index 335d7ff591..e9c18d6f86 100644
--- a/calendar/pcs/cal-backend.c
+++ b/calendar/pcs/cal-backend.c
@@ -245,6 +245,28 @@ cal_backend_get_events_in_range (CalBackend *backend, time_t start, time_t end)
}
/**
+ * cal_backend_get_alarms_in_range:
+ * @backend: A calendar backend.
+ * @start: Start time for query.
+ * @end: End time for query.
+ *
+ * Builds a sorted list of the alarms that trigger in the specified time range.
+ *
+ * Return value: A list of #CalAlarmInstance structures, sorted by trigger time.
+ **/
+GList *
+cal_backend_get_alarms_in_range (CalBackend *backend, time_t start, time_t end)
+{
+ g_return_val_if_fail (backend != NULL, NULL);
+ g_return_val_if_fail (IS_CAL_BACKEND (backend), NULL);
+ g_return_val_if_fail (start != -1 && end != -1, NULL);
+ g_return_val_if_fail (start <= end, NULL);
+
+ g_assert (CLASS (backend)->get_alarms_in_range != NULL);
+ return (* CLASS (backend)->get_alarms_in_range) (backend, start, end);
+}
+
+/**
* cal_backend_update_object:
* @backend: A calendar backend.
* @uid: Unique identifier of the object to update.
diff --git a/calendar/pcs/cal-backend.h b/calendar/pcs/cal-backend.h
index d3697f3e14..5ce9027415 100644
--- a/calendar/pcs/cal-backend.h
+++ b/calendar/pcs/cal-backend.h
@@ -67,6 +67,7 @@ struct _CalBackendClass {
char *(* get_object) (CalBackend *backend, const char *uid);
GList *(* get_uids) (CalBackend *backend, CalObjType type);
GList *(* get_events_in_range) (CalBackend *backend, time_t start, time_t end);
+ GList *(* get_alarms_in_range) (CalBackend *backend, time_t start, time_t end);
gboolean (* update_object) (CalBackend *backend, const char *uid, const char *calobj);
gboolean (* remove_object) (CalBackend *backend, const char *uid);
};
@@ -87,6 +88,8 @@ GList *cal_backend_get_uids (CalBackend *backend, CalObjType type);
GList *cal_backend_get_events_in_range (CalBackend *backend, time_t start, time_t end);
+GList *cal_backend_get_alarms_in_range (CalBackend *backend, time_t start, time_t end);
+
gboolean cal_backend_update_object (CalBackend *backend, const char *uid, const char *calobj);
gboolean cal_backend_remove_object (CalBackend *backend, const char *uid);
diff --git a/calendar/pcs/cal.c b/calendar/pcs/cal.c
index e1d3623ccf..8fc1de51b2 100644
--- a/calendar/pcs/cal.c
+++ b/calendar/pcs/cal.c
@@ -250,6 +250,40 @@ Cal_get_uids (PortableServer_Servant servant,
return seq;
}
+/* Builds a CORBA sequence of calendar object instances from a CalObjInstance
+ * list.
+ */
+static Evolution_Calendar_CalObjInstanceSeq *
+build_object_instance_seq (GList *list)
+{
+ GList *l;
+ int n, i;
+ Evolution_Calendar_CalObjInstanceSeq *seq;
+
+ n = g_list_length (list);
+
+ seq = Evolution_Calendar_CalObjInstanceSeq__alloc ();
+ CORBA_sequence_set_release (seq, TRUE);
+ seq->_length = n;
+ seq->_buffer = CORBA_sequence_Evolution_Calendar_CalObjInstance_allocbuf (n);
+
+ /* Fill the sequence */
+
+ for (i = 0, l = list; l; i++, l = l->next) {
+ CalObjInstance *icoi;
+ Evolution_Calendar_CalObjInstance *corba_icoi;
+
+ icoi = l->data;
+ corba_icoi = &seq->_buffer[i];
+
+ corba_icoi->uid = CORBA_string_dup (icoi->uid);
+ corba_icoi->start = icoi->start;
+ corba_icoi->end = icoi->end;
+ }
+
+ return seq;
+}
+
/* Cal::get_events_in_range method */
static Evolution_Calendar_CalObjInstanceSeq *
Cal_get_events_in_range (PortableServer_Servant servant,
@@ -261,8 +295,7 @@ Cal_get_events_in_range (PortableServer_Servant servant,
CalPrivate *priv;
time_t t_start, t_end;
Evolution_Calendar_CalObjInstanceSeq *seq;
- GList *elist, *l;
- int n, i;
+ GList *elist;
cal = CAL (bonobo_object_from_servant (servant));
priv = cal->priv;
@@ -280,30 +313,99 @@ Cal_get_events_in_range (PortableServer_Servant servant,
/* Figure out the list and allocate the sequence */
elist = cal_backend_get_events_in_range (priv->backend, t_start, t_end);
- n = g_list_length (elist);
+ seq = build_object_instance_seq (elist);
+ cal_obj_instance_list_free (elist);
- seq = Evolution_Calendar_CalObjInstanceSeq__alloc ();
+ return seq;
+}
+
+/* Translates an enum AlarmType to its CORBA representation */
+static Evolution_Calendar_AlarmType
+corba_alarm_type (enum AlarmType type)
+{
+ switch (type) {
+ case ALARM_MAIL:
+ return Evolution_Calendar_MAIL;
+
+ case ALARM_PROGRAM:
+ return Evolution_Calendar_PROGRAM;
+
+ case ALARM_DISPLAY:
+ return Evolution_Calendar_DISPLAY;
+
+ case ALARM_AUDIO:
+ return Evolution_Calendar_AUDIO;
+
+ default:
+ g_assert_not_reached ();
+ return Evolution_Calendar_DISPLAY;
+ }
+}
+
+/* Builds a CORBA sequence of alarm instances from a CalAlarmInstance list. */
+static Evolution_Calendar_CalAlarmInstanceSeq *
+build_alarm_instance_seq (GList *alarms)
+{
+ GList *l;
+ int n, i;
+ Evolution_Calendar_CalAlarmInstanceSeq *seq;
+
+ n = g_list_length (alarms);
+
+ seq = Evolution_Calendar_CalAlarmInstanceSeq__alloc ();
CORBA_sequence_set_release (seq, TRUE);
seq->_length = n;
- seq->_buffer = CORBA_sequence_Evolution_Calendar_CalObjInstance_allocbuf (n);
+ seq->_buffer = CORBA_sequence_Evolution_Calendar_CalAlarmInstance_allocbuf (n);
/* Fill the sequence */
- for (i = 0, l = elist; l; i++, l = l->next) {
- CalObjInstance *icoi;
- Evolution_Calendar_CalObjInstance *corba_icoi;
+ for (i = 0, l = alarms; l; i++, l = l->next) {
+ CalAlarmInstance *ai;
+ Evolution_Calendar_CalAlarmInstance *corba_ai;
- icoi = l->data;
- corba_icoi = &seq->_buffer[i];
+ ai = l->data;
+ corba_ai = &seq->_buffer[i];
- corba_icoi->uid = CORBA_string_dup (icoi->uid);
- corba_icoi->start = icoi->start;
- corba_icoi->end = icoi->end;
+ corba_ai->uid = CORBA_string_dup (ai->uid);
+ corba_ai->type = corba_alarm_type (ai->type);
+ corba_ai->trigger = ai->trigger;
+ corba_ai->occur = ai->occur;
}
- /* Done */
+ return seq;
+}
- cal_obj_instance_list_free (elist);
+/* Cal::get_alarms_in_range method */
+static Evolution_Calendar_CalAlarmInstanceSeq *
+Cal_get_alarms_in_range (PortableServer_Servant servant,
+ const Evolution_Calendar_Time_t start,
+ const Evolution_Calendar_Time_t end,
+ CORBA_Environment *ev)
+{
+ Cal *cal;
+ CalPrivate *priv;
+ time_t t_start, t_end;
+ Evolution_Calendar_CalAlarmInstanceSeq *seq;
+ GList *alarms;
+
+ cal = CAL (bonobo_object_from_servant (servant));
+ priv = cal->priv;
+
+ t_start = (time_t) start;
+ t_end = (time_t) end;
+
+ if (t_start > t_end || t_start == -1 || t_end == -1) {
+ CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
+ ex_Evolution_Calendar_Cal_InvalidRange,
+ NULL);
+ return NULL;
+ }
+
+ /* Figure out the list and allocate the sequence */
+
+ alarms = cal_backend_get_alarms_in_range (priv->backend, t_start, t_end);
+ seq = build_alarm_instance_seq (alarms);
+ cal_alarm_instance_list_free (alarms);
return seq;
}
@@ -363,6 +465,7 @@ cal_get_epv (void)
epv->get_object = Cal_get_object;
epv->get_uids = Cal_get_uids;
epv->get_events_in_range = Cal_get_events_in_range;
+ epv->get_alarms_in_range = Cal_get_alarms_in_range;
epv->update_object = Cal_update_object;
epv->remove_object = Cal_remove_object;