diff options
Diffstat (limited to 'calendar/pcs')
-rw-r--r-- | calendar/pcs/cal-backend-imc.c | 186 | ||||
-rw-r--r-- | calendar/pcs/cal-backend-imc.h | 1 | ||||
-rw-r--r-- | calendar/pcs/cal-backend.c | 22 | ||||
-rw-r--r-- | calendar/pcs/cal-backend.h | 3 | ||||
-rw-r--r-- | calendar/pcs/cal.c | 133 |
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; |