aboutsummaryrefslogtreecommitdiffstats
path: root/calendar
diff options
context:
space:
mode:
Diffstat (limited to 'calendar')
-rw-r--r--calendar/ChangeLog70
-rw-r--r--calendar/cal-client/cal-client.c146
-rw-r--r--calendar/cal-client/cal-client.h6
-rw-r--r--calendar/cal-util/cal-component.c190
-rw-r--r--calendar/cal-util/cal-component.h95
-rw-r--r--calendar/cal-util/cal-util.c25
-rw-r--r--calendar/cal-util/cal-util.h12
-rw-r--r--calendar/gui/gnome-cal.c12
-rw-r--r--calendar/idl/evolution-calendar.idl64
-rw-r--r--calendar/pcs/cal-backend-file.c378
-rw-r--r--calendar/pcs/cal-backend.c58
-rw-r--r--calendar/pcs/cal-backend.h31
-rw-r--r--calendar/pcs/cal.c109
13 files changed, 828 insertions, 368 deletions
diff --git a/calendar/ChangeLog b/calendar/ChangeLog
index e1af0879af..5219852ecf 100644
--- a/calendar/ChangeLog
+++ b/calendar/ChangeLog
@@ -1,3 +1,73 @@
+2000-12-18 Federico Mena Quintero <federico@helixcode.com>
+
+ Alarm instance generation support for the Wombat.
+
+ * idl/evolution-calendar.idl (Cal::CalAlarmInstance): Changed to
+ have an alarm UID, the trigger time, and the actual occurrence
+ time.
+ (Cal::CalComponentAlarms): New structure to hold a pair of a
+ component and its alarms that trigger in a particular range of
+ time.
+ (Cal::getAlarmsInRange): Changed to return a CalComponentAlarmsSeq.
+
+ * cal-util/cal-component.h (CalAlarmInstance): New C-side
+ structure to match the one on the IDL.
+ (CalComponentAlarms): Ditto.
+ (CalAlarmAction): Renamed from CalComponentAlarmAction.
+ (CalAlarmTriggerType): Renamed from CalComponentAlarmTriggerType.
+ Encoded the START and END parameters for the RELATED parameter in
+ this enum, too. Added a NONE value for invalid or missing trigger
+ specifications.
+ (CalComponentAlarmTriggerRelated): Removed.
+ (CalAlarmTrigger): Renamed from CalComponentAlarmTrigger. Renamed
+ the duration/time fields to rel_duration/abs_time, respectively.
+
+ * cal-util/cal-component.c (cal_component_alarm_get_trigger):
+ Changed to use the new trigger structure.
+ (cal_component_alarm_set_trigger): Likewise.
+ (cal_component_alarm_free_trigger): Removed function.
+ (cal_component_has_alarms): Count the elements in the
+ alarm_uid_hash instead of trying to fetch the first alarm subcomponent.
+ (cal_component_alarms_free): New function to free a
+ CalComponentAlarms structure.
+ (CalComponentAlarmPrivate): Added an uid property pointer.
+ (scan_alarm_property): Scan for the our extension UID property.
+ (cal_component_alarm_get_uid): New function.
+
+ * pcs/cal-backend.h (CalBackendClass): Changed the signatures of
+ the ::get_alarms_in_range() and ::get_alarms_for_object() methods.
+
+ * pcs/cal-backend.c (cal_backend_get_alarms_in_range): Changed
+ signature; use the new method.
+ (cal_backend_get_alarms_for_object): Likewise.
+
+ * pcs/cal-backend-file.c (compute_alarm_range): New spiffy
+ function to compute a range of time for alarm occurrences.
+ (add_alarm_occurrences_cb): New function to add alarms for a
+ particular occurrence of the component.
+ (generate_absolute_triggers): New function to add the absolute
+ alarm triggers.
+ (generate_alarms_for_comp): New function to generate all the alarm
+ instances for a component.
+ (cal_backend_file_get_alarms_in_range): Implemented.
+
+ * pcs/cal.c (Cal_get_alarms_in_range): Use the new CalBackend API.
+ (Cal_get_alarms_for_object): Likewise.
+ (build_alarm_instance_seq): Removed old function.
+
+ * cal-util/cal-util.c (cal_alarm_instance_list_free): Removed
+ function.
+
+ * cal-client/cal-client.c (build_component_alarms_list): New
+ function to demarshal the component alarms sequence.
+ (build_alarm_instance_list): New function to demarshal the alarm
+ instances sequence.
+ (cal_client_get_alarms_in_range): Updated for the new API.
+ (cal_client_get_alarms_for_object): Updated for the new API.
+
+ * gui/gnome-cal.c: Temporary #ifdef-ing out of alarm-related stuff
+ to make it build.
+
2000-12-15 Federico Mena Quintero <federico@helixcode.com>
* cal-util/timeutil.[ch] (time_from_isodate): Removed unused
diff --git a/calendar/cal-client/cal-client.c b/calendar/cal-client/cal-client.c
index a75912275f..b3e8cd507d 100644
--- a/calendar/cal-client/cal-client.c
+++ b/calendar/cal-client/cal-client.c
@@ -622,7 +622,7 @@ cal_client_get_object (CalClient *client, const char *uid, CalComponent **comp)
{
CalClientPrivate *priv;
CORBA_Environment ev;
- GNOME_Evolution_Calendar_CalObj calobj_str;
+ GNOME_Evolution_Calendar_CalObj comp_str;
CalClientGetStatus retval;
icalcomponent *icalcomp;
@@ -639,7 +639,7 @@ cal_client_get_object (CalClient *client, const char *uid, CalComponent **comp)
*comp = NULL;
CORBA_exception_init (&ev);
- calobj_str = GNOME_Evolution_Calendar_Cal_getObject (priv->cal, (char *) uid, &ev);
+ comp_str = GNOME_Evolution_Calendar_Cal_getObject (priv->cal, (char *) uid, &ev);
if (ev._major == CORBA_USER_EXCEPTION
&& strcmp (CORBA_exception_id (&ev), ex_GNOME_Evolution_Calendar_Cal_NotFound) == 0)
@@ -649,8 +649,8 @@ cal_client_get_object (CalClient *client, const char *uid, CalComponent **comp)
goto out;
}
- icalcomp = icalparser_parse_string (calobj_str);
- CORBA_free (calobj_str);
+ icalcomp = icalparser_parse_string (comp_str);
+ CORBA_free (comp_str);
if (!icalcomp) {
retval = CAL_CLIENT_GET_SYNTAX_ERROR;
@@ -1160,61 +1160,81 @@ cal_client_generate_instances (CalClient *client, CalObjType type,
g_list_free (instances);
}
-
-#if 0
-/* Translates the CORBA representation of an AlarmType */
-static enum AlarmType
-uncorba_alarm_type (Evolution_Calendar_AlarmType corba_type)
+/* Builds a list of CalAlarmInstance structures */
+static GSList *
+build_alarm_instance_list (CalComponent *comp, GNOME_Evolution_Calendar_CalAlarmInstanceSeq *seq)
{
- switch (corba_type) {
- case Evolution_Calendar_MAIL:
- return ALARM_MAIL;
+ GSList *alarms;
+ int i;
- case Evolution_Calendar_PROGRAM:
- return ALARM_PROGRAM;
+ alarms = NULL;
- case Evolution_Calendar_DISPLAY:
- return ALARM_DISPLAY;
+ for (i = 0; i < seq->_length; i++) {
+ GNOME_Evolution_Calendar_CalAlarmInstance *corba_instance;
+ CalComponentAlarm *alarm;
+ const char *auid;
+ CalAlarmInstance *instance;
- case Evolution_Calendar_AUDIO:
- return ALARM_AUDIO;
+ corba_instance = seq->_buffer + i;
- default:
- g_assert_not_reached ();
- return ALARM_DISPLAY;
+ /* Since we want the in-commponent auid, we look for the alarm
+ * in the component and fetch its "real" auid.
+ */
+
+ alarm = cal_component_get_alarm (comp, corba_instance->auid);
+ if (!alarm)
+ continue;
+
+ auid = cal_component_alarm_get_uid (alarm);
+ cal_component_alarm_free (alarm);
+
+ instance = g_new (CalAlarmInstance, 1);
+ instance->auid = auid;
+ instance->trigger = corba_instance->trigger;
+ instance->occur = corba_instance->occur;
+
+ alarms = g_slist_prepend (alarms, instance);
}
+
+ return g_slist_reverse (alarms);
}
-#endif
-/* Builds a GList of CalAlarmInstance structures from the CORBA sequence */
-static GList *
-build_alarm_instance_list (GNOME_Evolution_Calendar_CalAlarmInstanceSeq *seq)
+/* Builds a list of CalComponentAlarms structures */
+static GSList *
+build_component_alarms_list (GNOME_Evolution_Calendar_CalComponentAlarmsSeq *seq)
{
- GList *list;
+ GSList *comp_alarms;
int i;
- /* Create the list in reverse order */
+ comp_alarms = NULL;
- list = NULL;
for (i = 0; i < seq->_length; i++) {
- GNOME_Evolution_Calendar_CalAlarmInstance *corba_ai;
- CalAlarmInstance *ai;
+ GNOME_Evolution_Calendar_CalComponentAlarms *corba_alarms;
+ CalComponent *comp;
+ CalComponentAlarms *alarms;
+ icalcomponent *icalcomp;
- corba_ai = &seq->_buffer[i];
- ai = g_new (CalAlarmInstance, 1);
+ corba_alarms = seq->_buffer + i;
- ai->uid = g_strdup (corba_ai->uid);
-#if 0
- ai->type = uncorba_alarm_type (corba_ai->type);
-#endif
- ai->trigger = corba_ai->trigger;
- ai->occur = corba_ai->occur;
+ icalcomp = icalparser_parse_string (corba_alarms->calobj);
+ if (!icalcomp)
+ continue;
+
+ comp = cal_component_new ();
+ if (!cal_component_set_icalcomponent (comp, icalcomp)) {
+ icalcomponent_free (icalcomp);
+ gtk_object_unref (GTK_OBJECT (comp));
+ continue;
+ }
+
+ alarms = g_new (CalComponentAlarms, 1);
+ alarms->comp = comp;
+ alarms->alarms = build_alarm_instance_list (comp, &corba_alarms->alarms);
- list = g_list_prepend (list, ai);
+ comp_alarms = g_slist_prepend (comp_alarms, alarms);
}
- list = g_list_reverse (list);
- return list;
+ return comp_alarms;
}
/**
@@ -1226,15 +1246,16 @@ build_alarm_instance_list (GNOME_Evolution_Calendar_CalAlarmInstanceSeq *seq)
* Queries a calendar for the alarms that trigger in the specified range of
* time.
*
- * Return value: A list of #CalAlarmInstance structures.
+ * Return value: A list of #CalComponentAlarms structures. This should be freed
+ * using the cal_client_free_alarms() function.
**/
-GList *
+GSList *
cal_client_get_alarms_in_range (CalClient *client, time_t start, time_t end)
{
CalClientPrivate *priv;
CORBA_Environment ev;
- GNOME_Evolution_Calendar_CalAlarmInstanceSeq *seq;
- GList *alarms;
+ GNOME_Evolution_Calendar_CalComponentAlarmsSeq *seq;
+ GSList *alarms;
g_return_val_if_fail (client != NULL, NULL);
g_return_val_if_fail (IS_CAL_CLIENT (client), NULL);
@@ -1255,7 +1276,7 @@ cal_client_get_alarms_in_range (CalClient *client, time_t start, time_t end)
}
CORBA_exception_free (&ev);
- alarms = build_alarm_instance_list (seq);
+ alarms = build_component_alarms_list (seq);
CORBA_free (seq);
return alarms;
@@ -1264,10 +1285,11 @@ cal_client_get_alarms_in_range (CalClient *client, time_t start, time_t end)
/**
* cal_client_get_alarms_for_object:
* @client: A calendar client.
- * @uid: Unique identifier for a calendar object.
+ * @uid: Unique identifier for a calendar component.
* @start: Start time for query.
* @end: End time for query.
- * @alarms: Return value for the list of alarm instances.
+ * @alarms: Return value for the component's alarm instances. Will return NULL
+ * if no instances occur within the specified time range.
*
* Queries a calendar for the alarms of a particular object that trigger in the
* specified range of time.
@@ -1277,12 +1299,14 @@ cal_client_get_alarms_in_range (CalClient *client, time_t start, time_t end)
gboolean
cal_client_get_alarms_for_object (CalClient *client, const char *uid,
time_t start, time_t end,
- GList **alarms)
+ CalComponentAlarms **alarms)
{
CalClientPrivate *priv;
CORBA_Environment ev;
- GNOME_Evolution_Calendar_CalAlarmInstanceSeq *seq;
+ GNOME_Evolution_Calendar_CalComponentAlarms *corba_alarms;
gboolean retval;
+ icalcomponent *icalcomp;
+ CalComponent *comp;
g_return_val_if_fail (client != NULL, FALSE);
g_return_val_if_fail (IS_CAL_CLIENT (client), FALSE);
@@ -1300,7 +1324,8 @@ cal_client_get_alarms_for_object (CalClient *client, const char *uid,
CORBA_exception_init (&ev);
- seq = GNOME_Evolution_Calendar_Cal_getAlarmsForObject (priv->cal, (char *) uid, start, end, &ev);
+ corba_alarms = GNOME_Evolution_Calendar_Cal_getAlarmsForObject (priv->cal, (char *) uid,
+ start, end, &ev);
if (ev._major == CORBA_USER_EXCEPTION
&& strcmp (CORBA_exception_id (&ev), ex_GNOME_Evolution_Calendar_Cal_NotFound) == 0)
goto out;
@@ -1309,14 +1334,27 @@ cal_client_get_alarms_for_object (CalClient *client, const char *uid,
goto out;
}
+ icalcomp = icalparser_parse_string (corba_alarms->calobj);
+ if (!icalcomp)
+ goto out;
+
+ comp = cal_component_new ();
+ if (!cal_component_set_icalcomponent (comp, icalcomp)) {
+ icalcomponent_free (icalcomp);
+ gtk_object_unref (GTK_OBJECT (comp));
+ goto out;
+ }
+
retval = TRUE;
- *alarms = build_alarm_instance_list (seq);
- CORBA_free (seq);
+
+ *alarms = g_new (CalComponentAlarms, 1);
+ (*alarms)->comp = comp;
+ (*alarms)->alarms = build_alarm_instance_list (comp, &corba_alarms->alarms);
+ CORBA_free (corba_alarms);
out:
CORBA_exception_free (&ev);
return retval;
-
}
/**
diff --git a/calendar/cal-client/cal-client.h b/calendar/cal-client/cal-client.h
index b30c0a7d32..ecf714a9a4 100644
--- a/calendar/cal-client/cal-client.h
+++ b/calendar/cal-client/cal-client.h
@@ -102,11 +102,13 @@ void cal_client_generate_instances (CalClient *client, CalObjType type,
time_t start, time_t end,
CalRecurInstanceFn cb, gpointer cb_data);
-GList *cal_client_get_alarms_in_range (CalClient *client, time_t start, time_t end);
+GSList *cal_client_get_alarms_in_range (CalClient *client, time_t start, time_t end);
+
+void cal_client_free_alarms (GSList *alarms);
gboolean cal_client_get_alarms_for_object (CalClient *client, const char *uid,
time_t start, time_t end,
- GList **alarms);
+ CalComponentAlarms **alarms);
gboolean cal_client_update_object (CalClient *client, CalComponent *comp);
diff --git a/calendar/cal-util/cal-component.c b/calendar/cal-util/cal-component.c
index c7a1e6e324..1ece361da7 100644
--- a/calendar/cal-util/cal-component.c
+++ b/calendar/cal-util/cal-component.c
@@ -118,6 +118,9 @@ struct _CalComponentAlarm {
/* Alarm icalcomponent we wrap */
icalcomponent *icalcomp;
+ /* Our extension UID property */
+ icalproperty *uid;
+
/* Properties */
icalproperty *action;
@@ -3433,7 +3436,6 @@ gboolean
cal_component_has_alarms (CalComponent *comp)
{
CalComponentPrivate *priv;
- icalcomponent *subcomp;
g_return_val_if_fail (comp != NULL, FALSE);
g_return_val_if_fail (IS_CAL_COMPONENT (comp), FALSE);
@@ -3441,9 +3443,7 @@ cal_component_has_alarms (CalComponent *comp)
priv = comp->priv;
g_return_val_if_fail (priv->icalcomp != NULL, FALSE);
- subcomp = icalcomponent_get_first_component (priv->icalcomp, ICAL_VALARM_COMPONENT);
-
- return subcomp != NULL ? TRUE : FALSE;
+ return g_hash_table_size (priv->alarm_uid_hash) != 0;
}
/* Scans an icalproperty from a calendar component and adds its mapping to our
@@ -3453,6 +3453,7 @@ static void
scan_alarm_property (CalComponentAlarm *alarm, icalproperty *prop)
{
icalproperty_kind kind;
+ const char *xname;
kind = icalproperty_isa (prop);
@@ -3465,6 +3466,15 @@ scan_alarm_property (CalComponentAlarm *alarm, icalproperty *prop)
alarm->trigger = prop;
break;
+ case ICAL_X_PROPERTY:
+ xname = icalproperty_get_x_name (prop);
+ g_assert (xname != NULL);
+
+ if (strcmp (xname, EVOLUTION_ALARM_UID_PROPERTY) == 0)
+ alarm->uid = prop;
+
+ break;
+
default:
break;
}
@@ -3481,12 +3491,15 @@ make_alarm (CalComponent *comp, icalcomponent *subcomp)
alarm->parent = comp;
alarm->icalcomp = subcomp;
+ alarm->uid = NULL;
for (prop = icalcomponent_get_first_property (subcomp, ICAL_ANY_PROPERTY);
prop;
prop = icalcomponent_get_next_property (subcomp, ICAL_ANY_PROPERTY))
scan_alarm_property (alarm, prop);
+ g_assert (alarm->uid != NULL);
+
return alarm;
}
@@ -3589,6 +3602,50 @@ cal_component_alarm_free (CalComponentAlarm *alarm)
}
/**
+ * cal_component_alarms_free:
+ * @alarms: Component alarms structure.
+ *
+ * Frees a #CalComponentAlarms structure.
+ **/
+void
+cal_component_alarms_free (CalComponentAlarms *alarms)
+{
+ GSList *l;
+
+ g_return_if_fail (alarms != NULL);
+
+ g_assert (alarms->comp != NULL);
+ gtk_object_unref (GTK_OBJECT (alarms->comp));
+
+ for (l = alarms->alarms; l; l = l->next) {
+ CalAlarmInstance *instance;
+
+ instance = l->data;
+ g_assert (instance != NULL);
+ g_free (instance);
+ }
+
+ g_free (alarms->alarms);
+ g_free (alarms);
+}
+
+/**
+ * cal_component_alarm_get_uid:
+ * @alarm: An alarm subcomponent.
+ *
+ * Queries the unique identifier of an alarm subcomponent.
+ *
+ * Return value: UID of the alarm.
+ **/
+const char *
+cal_component_alarm_get_uid (CalComponentAlarm *alarm)
+{
+ g_return_val_if_fail (alarm != NULL, NULL);
+
+ return alarm_uid_from_prop (alarm->uid);
+}
+
+/**
* cal_component_alarm_get_action:
* @alarm: An alarm.
* @action: Return value for the alarm's action type.
@@ -3596,7 +3653,7 @@ cal_component_alarm_free (CalComponentAlarm *alarm)
* Queries the action type of an alarm.
**/
void
-cal_component_alarm_get_action (CalComponentAlarm *alarm, CalComponentAlarmAction *action)
+cal_component_alarm_get_action (CalComponentAlarm *alarm, CalAlarmAction *action)
{
const char *str;
@@ -3606,22 +3663,22 @@ cal_component_alarm_get_action (CalComponentAlarm *alarm, CalComponentAlarmActio
g_assert (alarm->icalcomp != NULL);
if (!alarm->action) {
- *action = CAL_COMPONENT_ALARM_NONE;
+ *action = CAL_ALARM_NONE;
return;
}
str = icalproperty_get_action (alarm->action);
if (strcasecmp (str, "AUDIO") == 0)
- *action = CAL_COMPONENT_ALARM_AUDIO;
+ *action = CAL_ALARM_AUDIO;
else if (strcasecmp (str, "DISPLAY") == 0)
- *action = CAL_COMPONENT_ALARM_DISPLAY;
+ *action = CAL_ALARM_DISPLAY;
else if (strcasecmp (str, "EMAIL") == 0)
- *action = CAL_COMPONENT_ALARM_EMAIL;
+ *action = CAL_ALARM_EMAIL;
else if (strcasecmp (str, "PROCEDURE") == 0)
- *action = CAL_COMPONENT_ALARM_PROCEDURE;
+ *action = CAL_ALARM_PROCEDURE;
else
- *action = CAL_COMPONENT_ALARM_UNKNOWN;
+ *action = CAL_ALARM_UNKNOWN;
}
/**
@@ -3632,30 +3689,30 @@ cal_component_alarm_get_action (CalComponentAlarm *alarm, CalComponentAlarmActio
* Sets the action type for an alarm.
**/
void
-cal_component_alarm_set_action (CalComponentAlarm *alarm, CalComponentAlarmAction action)
+cal_component_alarm_set_action (CalComponentAlarm *alarm, CalAlarmAction action)
{
char *str;
g_return_if_fail (alarm != NULL);
- g_return_if_fail (action != CAL_COMPONENT_ALARM_NONE);
- g_return_if_fail (action != CAL_COMPONENT_ALARM_UNKNOWN);
+ g_return_if_fail (action != CAL_ALARM_NONE);
+ g_return_if_fail (action != CAL_ALARM_UNKNOWN);
g_assert (alarm->icalcomp != NULL);
switch (action) {
- case CAL_COMPONENT_ALARM_AUDIO:
+ case CAL_ALARM_AUDIO:
str = "AUDIO";
break;
- case CAL_COMPONENT_ALARM_DISPLAY:
+ case CAL_ALARM_DISPLAY:
str = "DISPLAY";
break;
- case CAL_COMPONENT_ALARM_EMAIL:
+ case CAL_ALARM_EMAIL:
str = "EMAIL";
break;
- case CAL_COMPONENT_ALARM_PROCEDURE:
+ case CAL_ALARM_PROCEDURE:
str = "PROCEDURE";
break;
@@ -3675,16 +3732,16 @@ cal_component_alarm_set_action (CalComponentAlarm *alarm, CalComponentAlarmActio
/**
* cal_component_alarm_get_trigger:
* @alarm: An alarm.
- * @trigger: Return value for the trigger time. This should be freed using the
- * cal_component_alarm_free_trigger() function.
+ * @trigger: Return value for the trigger time.
*
* Queries the trigger time for an alarm.
**/
void
-cal_component_alarm_get_trigger (CalComponentAlarm *alarm, CalComponentAlarmTrigger **trigger)
+cal_component_alarm_get_trigger (CalComponentAlarm *alarm, CalAlarmTrigger *trigger)
{
icalparameter *param;
union icaltriggertype t;
+ gboolean relative;
g_return_if_fail (alarm != NULL);
g_return_if_fail (trigger != NULL);
@@ -3692,16 +3749,13 @@ cal_component_alarm_get_trigger (CalComponentAlarm *alarm, CalComponentAlarmTrig
g_assert (alarm->icalcomp != NULL);
if (!alarm->trigger) {
- *trigger = NULL;
+ trigger->type = CAL_ALARM_TRIGGER_NONE;
return;
}
- *trigger = g_new (CalComponentAlarmTrigger, 1);
-
/* Get trigger type */
param = icalproperty_get_first_parameter (alarm->trigger, ICAL_VALUE_PARAMETER);
-
if (param) {
icalparameter_value value;
@@ -3709,30 +3763,29 @@ cal_component_alarm_get_trigger (CalComponentAlarm *alarm, CalComponentAlarmTrig
switch (value) {
case ICAL_VALUE_DURATION:
- (*trigger)->type = CAL_COMPONENT_ALARM_TRIGGER_RELATIVE;
+ relative = TRUE;
break;
case ICAL_VALUE_DATETIME:
- (*trigger)->type = CAL_COMPONENT_ALARM_TRIGGER_ABSOLUTE;
+ relative = FALSE;
break;
default:
g_message ("cal_component_alarm_get_trigger(): Unknown value for trigger "
"value %d; using RELATIVE", value);
- (*trigger)->type = CAL_COMPONENT_ALARM_TRIGGER_RELATIVE;
+ relative = TRUE;
break;
}
} else
- (*trigger)->type = CAL_COMPONENT_ALARM_TRIGGER_RELATIVE;
+ relative = TRUE;
/* Get trigger value and the RELATED parameter */
t = icalproperty_get_trigger (alarm->trigger);
- switch ((*trigger)->type) {
- case CAL_COMPONENT_ALARM_TRIGGER_RELATIVE:
- (*trigger)->u.relative.duration = t.duration;
+ if (relative) {
+ trigger->u.rel_duration = t.duration;
param = icalproperty_get_first_parameter (alarm->trigger, ICAL_RELATED_PARAMETER);
if (param) {
@@ -3742,29 +3795,21 @@ cal_component_alarm_get_trigger (CalComponentAlarm *alarm, CalComponentAlarmTrig
switch (rel) {
case ICAL_RELATED_START:
- (*trigger)->u.relative.related =
- CAL_COMPONENT_ALARM_TRIGGER_RELATED_START;
+ trigger->type = CAL_ALARM_TRIGGER_RELATIVE_START;
break;
case ICAL_RELATED_END:
- (*trigger)->u.relative.related =
- CAL_COMPONENT_ALARM_TRIGGER_RELATED_END;
+ trigger->type = CAL_ALARM_TRIGGER_RELATIVE_END;
break;
default:
g_assert_not_reached ();
}
} else
- (*trigger)->u.relative.related = CAL_COMPONENT_ALARM_TRIGGER_RELATED_START;
-
- break;
-
- case CAL_COMPONENT_ALARM_TRIGGER_ABSOLUTE:
- (*trigger)->u.absolute = t.time;
- break;
-
- default:
- g_assert_not_reached ();
+ trigger->type = CAL_ALARM_TRIGGER_RELATIVE_START;
+ } else {
+ trigger->u.abs_time = t.time;
+ trigger->type = CAL_ALARM_TRIGGER_ABSOLUTE;
}
}
@@ -3776,7 +3821,7 @@ cal_component_alarm_get_trigger (CalComponentAlarm *alarm, CalComponentAlarmTrig
* Sets the trigger time of an alarm.
**/
void
-cal_component_alarm_set_trigger (CalComponentAlarm *alarm, CalComponentAlarmTrigger *trigger)
+cal_component_alarm_set_trigger (CalComponentAlarm *alarm, CalAlarmTrigger trigger)
{
union icaltriggertype t;
icalparameter *param;
@@ -3784,7 +3829,7 @@ cal_component_alarm_set_trigger (CalComponentAlarm *alarm, CalComponentAlarmTrig
icalparameter_related related;
g_return_if_fail (alarm != NULL);
- g_return_if_fail (trigger != NULL);
+ g_return_if_fail (trigger.type != CAL_ALARM_TRIGGER_NONE);
g_assert (alarm->icalcomp != NULL);
@@ -3798,32 +3843,23 @@ cal_component_alarm_set_trigger (CalComponentAlarm *alarm, CalComponentAlarmTrig
/* Set the value */
- value_type = ICAL_DURATION_VALUE; /* Keep GCC happy */
- related = ICAL_RELATED_START; /* Ditto */
+ related = ICAL_RELATED_START; /* Keep GCC happy */
- switch (trigger->type) {
- case CAL_COMPONENT_ALARM_TRIGGER_RELATIVE:
- t.duration = trigger->u.relative.duration;
+ switch (trigger.type) {
+ case CAL_ALARM_TRIGGER_RELATIVE_START:
+ t.duration = trigger.u.rel_duration;
value_type = ICAL_DURATION_VALUE;
+ related = ICAL_RELATED_START;
+ break;
- switch (trigger->u.relative.related) {
- case CAL_COMPONENT_ALARM_TRIGGER_RELATED_START:
- related = ICAL_RELATED_START;
- break;
-
- case CAL_COMPONENT_ALARM_TRIGGER_RELATED_END:
- related = ICAL_RELATED_END;
- break;
-
- default:
- g_assert_not_reached ();
- return;
- }
-
+ case CAL_ALARM_TRIGGER_RELATIVE_END:
+ t.duration = trigger.u.rel_duration;
+ value_type = ICAL_DURATION_VALUE;
+ related = ICAL_RELATED_END;
break;
- case CAL_COMPONENT_ALARM_TRIGGER_ABSOLUTE:
- t.time = trigger->u.absolute;
+ case CAL_ALARM_TRIGGER_ABSOLUTE:
+ t.time = trigger.u.abs_time;
value_type = ICAL_DATETIME_VALUE;
break;
@@ -3847,7 +3883,7 @@ cal_component_alarm_set_trigger (CalComponentAlarm *alarm, CalComponentAlarmTrig
/* Related parameter */
- if (trigger->type == CAL_COMPONENT_ALARM_TRIGGER_RELATIVE) {
+ if (trigger.type != CAL_ALARM_TRIGGER_ABSOLUTE) {
param = icalproperty_get_first_parameter (alarm->trigger, ICAL_RELATED_PARAMETER);
if (param)
@@ -3858,17 +3894,3 @@ cal_component_alarm_set_trigger (CalComponentAlarm *alarm, CalComponentAlarmTrig
}
}
}
-
-/**
- * cal_component_alarm_free_trigger:
- * @trigger: A #CalComponentAlarmTrigger structure.
- *
- * Frees a #CalComponentAlarmTrigger structure.
- **/
-void
-cal_component_alarm_free_trigger (CalComponentAlarmTrigger *trigger)
-{
- g_return_if_fail (trigger != NULL);
-
- g_free (trigger);
-}
diff --git a/calendar/cal-util/cal-component.h b/calendar/cal-util/cal-component.h
index f59bb33a7b..893e066f52 100644
--- a/calendar/cal-util/cal-component.h
+++ b/calendar/cal-util/cal-component.h
@@ -51,7 +51,9 @@ typedef enum {
CAL_COMPONENT_TIMEZONE
} CalComponentVType;
-/* Field identifiers for a calendar component */
+/* Field identifiers for a calendar component; these are used by the data model
+ * for ETable.
+ */
typedef enum {
CAL_COMPONENT_FIELD_CATEGORIES, /* concatenation of the categories list */
CAL_COMPONENT_FIELD_CLASSIFICATION,
@@ -74,8 +76,9 @@ typedef enum {
CAL_COMPONENT_FIELD_NUM_FIELDS
} CalComponentField;
-/* Structures to return properties and their parameters */
+/* Structures and enumerations to return properties and their parameters */
+/* CLASSIFICATION property */
typedef enum {
CAL_COMPONENT_CLASS_NONE,
CAL_COMPONENT_CLASS_PUBLIC,
@@ -84,6 +87,7 @@ typedef enum {
CAL_COMPONENT_CLASS_UNKNOWN
} CalComponentClassification;
+/* Properties that have time and timezone information */
typedef struct {
/* Actual date/time value */
struct icaltimetype *value;
@@ -92,11 +96,13 @@ typedef struct {
const char *tzid;
} CalComponentDateTime;
+/* Way in which a period of time is specified */
typedef enum {
CAL_COMPONENT_PERIOD_DATETIME,
CAL_COMPONENT_PERIOD_DURATION
} CalComponentPeriodType;
+/* Period of time, can have explicit start/end times or start/duration instead */
typedef struct {
CalComponentPeriodType type;
@@ -108,6 +114,7 @@ typedef struct {
} u;
} CalComponentPeriod;
+/* Text properties */
typedef struct {
/* Description string */
const char *value;
@@ -116,6 +123,7 @@ typedef struct {
const char *altrep;
} CalComponentText;
+/* Time transparency */
typedef enum {
CAL_COMPONENT_TRANSP_NONE,
CAL_COMPONENT_TRANSP_TRANSPARENT,
@@ -123,7 +131,7 @@ typedef enum {
CAL_COMPONENT_TRANSP_UNKNOWN
} CalComponentTransparency;
-typedef struct _CalComponentAlarm CalComponentAlarm;
+/* Main calendar component object */
typedef struct _CalComponent CalComponent;
typedef struct _CalComponentClass CalComponentClass;
@@ -262,37 +270,58 @@ void cal_component_free_text_list (GSList *text_list);
/* Alarms */
-typedef enum {
- CAL_COMPONENT_ALARM_NONE,
- CAL_COMPONENT_ALARM_AUDIO,
- CAL_COMPONENT_ALARM_DISPLAY,
- CAL_COMPONENT_ALARM_EMAIL,
- CAL_COMPONENT_ALARM_PROCEDURE,
- CAL_COMPONENT_ALARM_UNKNOWN
-} CalComponentAlarmAction;
+/* Opaque structure used to represent alarm subcomponents */
+typedef struct _CalComponentAlarm CalComponentAlarm;
-typedef enum {
- CAL_COMPONENT_ALARM_TRIGGER_RELATIVE,
- CAL_COMPONENT_ALARM_TRIGGER_ABSOLUTE
-} CalComponentAlarmTriggerType;
+/* An alarm occurrence, i.e. a trigger instance */
+typedef struct {
+ /* UID of the alarm that triggered */
+ const char *auid;
+
+ /* Trigger time, i.e. "5 minutes before the appointment" */
+ time_t trigger;
+ /* Actual event occurrence to which this trigger corresponds */
+ time_t occur;
+} CalAlarmInstance;
+
+/* Alarm trigger instances for a particular component */
+typedef struct {
+ /* The actual component */
+ CalComponent *comp;
+
+ /* List of CalAlarmInstance structures */
+ GSList *alarms;
+} CalComponentAlarms;
+
+/* Alarm types */
+typedef enum {
+ CAL_ALARM_NONE,
+ CAL_ALARM_AUDIO,
+ CAL_ALARM_DISPLAY,
+ CAL_ALARM_EMAIL,
+ CAL_ALARM_PROCEDURE,
+ CAL_ALARM_UNKNOWN
+} CalAlarmAction;
+
+/* Whether a trigger is relative to the start or end of an event occurrence, or
+ * whether it is specified to occur at an absolute time.
+ */
typedef enum {
- CAL_COMPONENT_ALARM_TRIGGER_RELATED_START,
- CAL_COMPONENT_ALARM_TRIGGER_RELATED_END
-} CalComponentAlarmTriggerRelated;
+ CAL_ALARM_TRIGGER_NONE,
+ CAL_ALARM_TRIGGER_RELATIVE_START,
+ CAL_ALARM_TRIGGER_RELATIVE_END,
+ CAL_ALARM_TRIGGER_ABSOLUTE
+} CalAlarmTriggerType;
typedef struct {
- CalComponentAlarmTriggerType type;
+ CalAlarmTriggerType type;
union {
- struct {
- struct icaldurationtype duration;
- CalComponentAlarmTriggerRelated related;
- } relative;
-
- struct icaltimetype absolute;
+ struct icaldurationtype rel_duration;
+ struct icaltimetype abs_time;
} u;
-} CalComponentAlarmTrigger;
+} CalAlarmTrigger;
gboolean cal_component_has_alarms (CalComponent *comp);
GList *cal_component_get_alarm_uids (CalComponent *comp);
@@ -300,12 +329,16 @@ CalComponentAlarm *cal_component_get_alarm (CalComponent *comp, const char *auid
void cal_component_alarm_free (CalComponentAlarm *alarm);
-void cal_component_alarm_get_action (CalComponentAlarm *alarm, CalComponentAlarmAction *action);
-void cal_component_alarm_set_action (CalComponentAlarm *alarm, CalComponentAlarmAction action);
+void cal_component_alarms_free (CalComponentAlarms *alarms);
+
+const char *cal_component_alarm_get_uid (CalComponentAlarm *alarm);
+
+void cal_component_alarm_get_action (CalComponentAlarm *alarm, CalAlarmAction *action);
+void cal_component_alarm_set_action (CalComponentAlarm *alarm, CalAlarmAction action);
+
+void cal_component_alarm_get_trigger (CalComponentAlarm *alarm, CalAlarmTrigger *trigger);
+void cal_component_alarm_set_trigger (CalComponentAlarm *alarm, CalAlarmTrigger trigger);
-void cal_component_alarm_get_trigger (CalComponentAlarm *alarm, CalComponentAlarmTrigger **trigger);
-void cal_component_alarm_set_trigger (CalComponentAlarm *alarm, CalComponentAlarmTrigger *trigger);
-void cal_component_alarm_free_trigger (CalComponentAlarmTrigger *trigger);
diff --git a/calendar/cal-util/cal-util.c b/calendar/cal-util/cal-util.c
index 092fd79889..c75a65d7d5 100644
--- a/calendar/cal-util/cal-util.c
+++ b/calendar/cal-util/cal-util.c
@@ -51,31 +51,6 @@ cal_obj_instance_list_free (GList *list)
}
/**
- * cal_alarm_instance_list_free:
- * @list: List of #CalAlarmInstance structures.
- *
- * Frees a list of #CalAlarmInstance structures.
- **/
-void
-cal_alarm_instance_list_free (GList *list)
-{
- CalAlarmInstance *i;
- GList *l;
-
- for (l = list; l; l = l->next) {
- i = l->data;
-
- g_assert (i != NULL);
- g_assert (i->uid != NULL);
-
- g_free (i->uid);
- g_free (i);
- }
-
- g_list_free (list);
-}
-
-/**
* cal_obj_uid_list_free:
* @list: List of strings with unique identifiers.
*
diff --git a/calendar/cal-util/cal-util.h b/calendar/cal-util/cal-util.h
index 5c640a2d89..ac7838885e 100644
--- a/calendar/cal-util/cal-util.h
+++ b/calendar/cal-util/cal-util.h
@@ -41,18 +41,6 @@ typedef struct {
void cal_obj_instance_list_free (GList *list);
-/* Instance of an alarm trigger */
-typedef struct {
- char *uid; /* UID of object */
-#if 0
- enum AlarmType type; /* Type of alarm */
-#endif
- time_t trigger; /* Alarm trigger time */
- time_t occur; /* Occurrence time */
-} CalAlarmInstance;
-
-void cal_alarm_instance_list_free (GList *list);
-
/* Used for multiple UID queries */
typedef enum {
CALOBJ_TYPE_EVENT = 1 << 0,
diff --git a/calendar/gui/gnome-cal.c b/calendar/gui/gnome-cal.c
index e64ecbe706..ac43fbe438 100644
--- a/calendar/gui/gnome-cal.c
+++ b/calendar/gui/gnome-cal.c
@@ -786,8 +786,6 @@ program_notification (char *command, int close_standard)
sigaction (SIGQUIT, &save_quit, NULL);
}
-#endif
-
/* Queues a snooze alarm */
static void
snooze (GnomeCalendar *gcal, CalComponent *comp, time_t occur, int snooze_mins, gboolean audio)
@@ -1040,10 +1038,13 @@ midnight_refresh_cb (gpointer alarm_id, time_t trigger, gpointer data)
load_alarms (cal);
}
+#endif
+
/* Loads and queues the alarms from the current time up to midnight. */
static void
load_alarms (GnomeCalendar *gcal)
{
+#if 0
GnomeCalendarPrivate *priv;
time_t now;
time_t end_of_day;
@@ -1070,6 +1071,7 @@ load_alarms (GnomeCalendar *gcal)
g_message ("load_alarms(): Could not set up the midnight refresh alarm!");
/* FIXME: what to do? */
}
+#endif
}
/* Loads the initial data into the calendar; this should be called right after
@@ -1086,6 +1088,7 @@ initial_load (GnomeCalendar *gcal)
tag_calendar_by_client (priv->date_navigator, priv->client);
}
+#if 0
/* Removes any queued alarms for the specified UID */
static void
remove_alarms_for_object (GnomeCalendar *gcal, const char *uid)
@@ -1142,6 +1145,7 @@ add_alarms_for_object (GnomeCalendar *gcal, const char *uid)
cal_alarm_instance_list_free (alarms);
}
+#endif
/* Displays an error to indicate that loading a calendar failed */
static void
@@ -1276,8 +1280,10 @@ obj_updated_cb (CalClient *client, const char *uid, gpointer data)
gcal = GNOME_CALENDAR (data);
priv = gcal->priv;
+#if 0
remove_alarms_for_object (gcal, uid);
add_alarms_for_object (gcal, uid);
+#endif
tag_calendar_by_client (priv->date_navigator, priv->client);
}
@@ -1292,7 +1298,9 @@ obj_removed_cb (CalClient *client, const char *uid, gpointer data)
gcal = GNOME_CALENDAR (data);
priv = gcal->priv;
+#if 0
remove_alarms_for_object (gcal, uid);
+#endif
tag_calendar_by_client (priv->date_navigator, priv->client);
}
diff --git a/calendar/idl/evolution-calendar.idl b/calendar/idl/evolution-calendar.idl
index bee377c76a..3e64e07888 100644
--- a/calendar/idl/evolution-calendar.idl
+++ b/calendar/idl/evolution-calendar.idl
@@ -16,17 +16,20 @@ module GNOME {
module Evolution {
module Calendar {
- /* A calendar object (event/todo/journal/etc), represented as an
+ /* A calendar component (event/todo/journal/etc), represented as an
* iCalendar string.
*/
typedef string CalObj;
- /* An unique identifier for a calendar object */
+ /* A unique identifier for a calendar component */
typedef string CalObjUID;
/* Sequence of unique identifiers */
typedef sequence<CalObjUID> CalObjUIDSeq;
+ /* A unique identifier for an alarm subcomponent */
+ typedef string CalAlarmUID;
+
/* Flags for getting UID sequences */
typedef long CalObjType;
const CalObjType TYPE_EVENT = 1 << 0;
@@ -51,11 +54,11 @@ module Calendar {
/* Used to store a time_t */
typedef unsigned long Time_t;
- /* An instance of a calendar object that actually occurs. These are
+ /* An instance of a calendar component that actually occurs. These are
* "virtual" objects in that they are used to represent instances of
* recurring events and alarms. "Real" objects just contain the
* information required to figure out the times at which they recur or
- * trigger.
+ * trigger.
*/
struct CalObjInstance {
CalObjUID uid;
@@ -63,6 +66,7 @@ module Calendar {
Time_t end;
};
+ /* Used to transfer a list of component occurrences */
typedef sequence<CalObjInstance> CalObjInstanceSeq;
/* An object change */
@@ -71,18 +75,28 @@ module Calendar {
CalObjChangeType type;
};
+ /* Used to transfer a list of changed components */
typedef sequence<CalObjChange> CalObjChangeSeq;
/* An alarm trigger instance */
struct CalAlarmInstance {
- CalObjUID uid;
- AlarmType type;
+ CalAlarmUID auid;
Time_t trigger;
Time_t occur;
};
+ /* Used to represent a list of alarm triggers for a single component */
typedef sequence<CalAlarmInstance> CalAlarmInstanceSeq;
+ /* Alarms for a component */
+ struct CalComponentAlarms {
+ CalObj calobj;
+ CalAlarmInstanceSeq alarms;
+ };
+
+ /* Used to represent a list of components plus their triggers */
+ typedef sequence<CalComponentAlarms> CalComponentAlarmsSeq;
+
interface Listener;
/* Calendar client interface */
@@ -94,48 +108,46 @@ module Calendar {
/* A calendar is identified by its URI */
readonly attribute string uri;
- /* Gets the number of objects of the specified types */
+ /* Gets the number of components of the specified types */
long countObjects (in CalObjType type);
- /* Gets an object based on its URI */
+ /* Gets a component based on its URI */
CalObj getObject (in CalObjUID uid)
raises (NotFound);
- /* Gets a list of UIDs based on object type */
+ /* Gets a list of UIDs based on component type */
CalObjUIDSeq getUIds (in CalObjType type);
- /* Gets a list of objects that changed based on object type */
+ /* Gets a list of components that changed based on object type */
CalObjChangeSeq getChanges (in CalObjType type, in string change_id);
- /* Gets a list of objects that occur or recur in the specified time range */
+ /* Gets a list of components that occur or recur in the specified time range */
CalObjUIDSeq getObjectsInRange (in CalObjType type,
in Time_t start, in Time_t end)
raises (InvalidRange);
- /*
- * Gets the objects whose alarms trigger in the specified time
- * range.
+ /* Gets a list of the components that have alarms that trigger
+ * in the specified range of time, and the trigger/occurrence
+ * structures themselves.
*/
- CalAlarmInstanceSeq getAlarmsInRange (in Time_t start, in Time_t end)
+ CalComponentAlarmsSeq getAlarmsInRange (in Time_t start, in Time_t end)
raises (InvalidRange);
- /*
- * Gets the alarms for the specified object that trigger in the
- * specified time range.
+ /* Gets the alarms for the specified component that trigger in
+ * the specified time range.
*/
- CalAlarmInstanceSeq getAlarmsForObject (in CalObjUID uid,
- in Time_t start, in Time_t end)
+ CalComponentAlarms getAlarmsForObject (in CalObjUID uid,
+ in Time_t start, in Time_t end)
raises (NotFound, InvalidRange);
- /*
- * Updates an object by adding it if it does not exist or by
- * changing an existing one.
+ /* Updates a component by adding it if it does not exist or by
+ * changing an existing one.
*/
void updateObject (in CalObjUID uid, in CalObj calobj)
raises (InvalidObject);
- /* Removes an object */
+ /* Removes a component */
void removeObject (in CalObjUID uid)
raises (NotFound);
};
@@ -157,10 +169,10 @@ module Calendar {
*/
void notifyCalLoaded (in LoadStatus status, in Cal cal);
- /* Called from a Calendar when an object is added or changed */
+ /* Called from a Calendar when a component is added or changed */
void notifyObjUpdated (in CalObjUID uid);
- /* Called from a Calendar when an object is removed */
+ /* Called from a Calendar when a component is removed */
void notifyObjRemoved (in CalObjUID uid);
};
diff --git a/calendar/pcs/cal-backend-file.c b/calendar/pcs/cal-backend-file.c
index c63e690246..85026a861a 100644
--- a/calendar/pcs/cal-backend-file.c
+++ b/calendar/pcs/cal-backend-file.c
@@ -74,10 +74,14 @@ static CalObjType cal_backend_file_get_type_by_uid (CalBackend *backend, const c
static GList *cal_backend_file_get_uids (CalBackend *backend, CalObjType type);
static GList *cal_backend_file_get_objects_in_range (CalBackend *backend, CalObjType type,
time_t start, time_t end);
-static GList *cal_backend_file_get_alarms_in_range (CalBackend *backend, time_t start, time_t end);
-static gboolean cal_backend_file_get_alarms_for_object (CalBackend *backend, const char *uid,
- time_t start, time_t end,
- GList **alarms);
+
+static GNOME_Evolution_Calendar_CalComponentAlarmsSeq *cal_backend_file_get_alarms_in_range (
+ CalBackend *backend, time_t start, time_t end);
+
+static GNOME_Evolution_Calendar_CalComponentAlarms *cal_backend_file_get_alarms_for_object (
+ CalBackend *backend, const char *uid,
+ time_t start, time_t end, gboolean *object_found);
+
static gboolean cal_backend_file_update_object (CalBackend *backend, const char *uid,
const char *calobj);
static gboolean cal_backend_file_remove_object (CalBackend *backend, const char *uid);
@@ -922,12 +926,300 @@ cal_backend_file_get_objects_in_range (CalBackend *backend, CalObjType type,
return event_list;
}
+/* 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:
+ dur = &trigger.u.rel_duration;
+ dur_time = icaldurationtype_as_timet (*dur);
+
+ if (dur->is_neg)
+ *alarm_start = MIN (*alarm_start, start - dur_time);
+ else
+ *alarm_end = MAX (*alarm_end, start + dur_time);
+
+ break;
+
+ case CAL_ALARM_TRIGGER_RELATIVE_END:
+ dur = &trigger.u.rel_duration;
+ dur_time = icaldurationtype_as_timet (*dur);
+
+ if (dur->is_neg)
+ *alarm_start = MIN (*alarm_start, end - dur_time);
+ else
+ *alarm_end = MAX (*alarm_end, end + 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_timet (*dur);
+
+ if (trigger.type == CAL_ALARM_TRIGGER_RELATIVE_START)
+ occur_time = start;
+ else
+ occur_time = end;
+
+ if (dur->is_neg)
+ trigger_time = occur_time - dur_time;
+ else
+ 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)
+{
+ 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);
+
+ /* 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)
+{
+ int n_alarms;
+ GSList *l;
+ int i;
+
+ n_alarms = g_slist_length (alarms);
+
+ CORBA_sequence_set_release (seq, TRUE);
+ seq->_length = n_alarms;
+ seq->_buffer = CORBA_sequence_GNOME_Evolution_Calendar_CalAlarmInstance_allocbuf (n_alarms);
+
+ for (l = alarms, i = 0; l; l = l->next, i++) {
+ CalAlarmInstance *instance;
+ GNOME_Evolution_Calendar_CalAlarmInstance *corba_instance;
+
+ instance = l->data;
+ corba_instance = seq->_buffer + i;
+
+ corba_instance->auid = CORBA_string_dup (instance->auid);
+ corba_instance->trigger = (long) instance->trigger;
+ corba_instance->occur = (long) instance->occur;
+ }
+}
+
/* Get_alarms_in_range handler for the file backend */
-static GList *
+static GNOME_Evolution_Calendar_CalComponentAlarmsSeq *
cal_backend_file_get_alarms_in_range (CalBackend *backend, time_t start, time_t end)
{
CalBackendFile *cbfile;
CalBackendFilePrivate *priv;
+ int n_comp_alarms;
+ GSList *comp_alarms;
+ GSList *l;
+ int i;
+ GNOME_Evolution_Calendar_CalComponentAlarmsSeq *seq;
cbfile = CAL_BACKEND_FILE (backend);
priv = cbfile->priv;
@@ -937,35 +1229,81 @@ cal_backend_file_get_alarms_in_range (CalBackend *backend, time_t start, time_t
g_return_val_if_fail (start != -1 && end != -1, NULL);
g_return_val_if_fail (start <= end, NULL);
- /* FIXME: have to deal with an unknown number of alarms; we can't just
- * do the same thing as in cal-backend-imc.
- */
- return NULL;
+ /* Per RFC 2445, only VEVENTs and VTODOs can have alarms */
+
+ 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);
+
+ seq = GNOME_Evolution_Calendar_CalComponentAlarmsSeq__alloc ();
+ CORBA_sequence_set_release (seq, TRUE);
+ seq->_length = n_comp_alarms;
+ seq->_buffer = CORBA_sequence_GNOME_Evolution_Calendar_CalComponentAlarms_allocbuf (
+ n_comp_alarms);
+
+ for (l = comp_alarms, i = 0; l; l = l->next, i++) {
+ CalComponentAlarms *alarms;
+ char *comp_str;
+
+ alarms = l->data;
+
+ comp_str = cal_component_get_as_string (alarms->comp);
+ seq->_buffer[i].calobj = CORBA_string_dup (comp_str);
+ g_free (comp_str);
+
+ fill_alarm_instances_seq (&seq->_buffer[i].alarms, alarms->alarms);
+
+ cal_component_alarms_free (alarms);
+ }
+
+ g_slist_free (comp_alarms);
+
+ return seq;
}
/* Get_alarms_for_object handler for the file backend */
-static gboolean
+static GNOME_Evolution_Calendar_CalComponentAlarms *
cal_backend_file_get_alarms_for_object (CalBackend *backend, const char *uid,
- time_t start, time_t end,
- GList **alarms)
+ time_t start, time_t end, gboolean *object_found)
{
CalBackendFile *cbfile;
CalBackendFilePrivate *priv;
+ CalComponent *comp;
+ char *comp_str;
+ GNOME_Evolution_Calendar_CalComponentAlarms *corba_alarms;
+ CalComponentAlarms *alarms;
cbfile = CAL_BACKEND_FILE (backend);
priv = cbfile->priv;
- g_return_val_if_fail (priv->icalcomp != NULL, FALSE);
+ g_return_val_if_fail (priv->icalcomp != NULL, NULL);
- g_return_val_if_fail (uid != NULL, FALSE);
- g_return_val_if_fail (start != -1 && end != -1, FALSE);
- g_return_val_if_fail (start <= end, FALSE);
- g_return_val_if_fail (alarms != NULL, FALSE);
+ g_return_val_if_fail (uid != NULL, NULL);
+ g_return_val_if_fail (start != -1 && end != -1, NULL);
+ g_return_val_if_fail (start <= end, NULL);
+ g_return_val_if_fail (object_found != NULL, NULL);
- /* FIXME */
+ comp = lookup_component (cbfile, uid);
+ if (!comp) {
+ *object_found = FALSE;
+ return NULL;
+ }
- *alarms = NULL;
- return FALSE;
+ *object_found = TRUE;
+
+ comp_str = cal_component_get_as_string (comp);
+ corba_alarms = GNOME_Evolution_Calendar_CalComponentAlarms__alloc ();
+
+ corba_alarms->calobj = CORBA_string_dup (comp_str);
+ g_free (comp_str);
+
+ alarms = generate_alarms_for_comp (comp, start, end);
+ fill_alarm_instances_seq (&corba_alarms->alarms, alarms->alarms);
+ cal_component_alarms_free (alarms);
+
+ return corba_alarms;
}
/* Notifies a backend's clients that an object was updated */
diff --git a/calendar/pcs/cal-backend.c b/calendar/pcs/cal-backend.c
index ce9604e418..9570b85d7f 100644
--- a/calendar/pcs/cal-backend.c
+++ b/calendar/pcs/cal-backend.c
@@ -464,21 +464,29 @@ cal_backend_get_objects_in_range (CalBackend *backend, CalObjType type,
* @backend: A calendar backend.
* @start: Start time for query.
* @end: End time for query.
+ * @valid_range: Return value that says whether the range is valid or not.
*
* 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.
+ * Return value: A sequence of component alarm instances structures, or NULL
+ * if @valid_range returns FALSE.
**/
-GList *
-cal_backend_get_alarms_in_range (CalBackend *backend, time_t start, time_t end)
+GNOME_Evolution_Calendar_CalComponentAlarmsSeq *
+cal_backend_get_alarms_in_range (CalBackend *backend, time_t start, time_t end, gboolean *valid_range)
{
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_return_val_if_fail (valid_range != NULL, NULL);
g_assert (CLASS (backend)->get_alarms_in_range != NULL);
- return (* CLASS (backend)->get_alarms_in_range) (backend, start, end);
+
+ if (!(start != -1 && end != -1 && start <= end)) {
+ *valid_range = FALSE;
+ return NULL;
+ } else {
+ *valid_range = TRUE;
+ return (* CLASS (backend)->get_alarms_in_range) (backend, start, end);
+ }
}
/**
@@ -487,27 +495,43 @@ cal_backend_get_alarms_in_range (CalBackend *backend, time_t start, time_t end)
* @uid: Unique identifier for a calendar object.
* @start: Start time for query.
* @end: End time for query.
- * @alarms: Return value for the list of alarm instances.
+ * @result: Return value for the result code for the operation.
*
* Builds a sorted list of the alarms of the specified event that trigger in a
* particular time range.
*
- * Return value: TRUE on success, FALSE if the object was not found.
+ * Return value: A structure of the component's alarm instances, or NULL if @result
+ * returns something other than #CAL_BACKEND_GET_ALARMS_SUCCESS.
**/
-gboolean
+GNOME_Evolution_Calendar_CalComponentAlarms *
cal_backend_get_alarms_for_object (CalBackend *backend, const char *uid,
time_t start, time_t end,
- GList **alarms)
+ CalBackendGetAlarmsForObjectResult *result)
{
- g_return_val_if_fail (backend != NULL, FALSE);
- g_return_val_if_fail (IS_CAL_BACKEND (backend), FALSE);
- g_return_val_if_fail (uid != NULL, FALSE);
- g_return_val_if_fail (start != -1 && end != -1, FALSE);
- g_return_val_if_fail (start <= end, FALSE);
- g_return_val_if_fail (alarms != NULL, FALSE);
+ g_return_val_if_fail (backend != NULL, NULL);
+ g_return_val_if_fail (IS_CAL_BACKEND (backend), NULL);
+ g_return_val_if_fail (uid != NULL, NULL);
+ g_return_val_if_fail (result != NULL, NULL);
g_assert (CLASS (backend)->get_alarms_for_object != NULL);
- return (* CLASS (backend)->get_alarms_for_object) (backend, uid, start, end, alarms);
+
+ if (!(start != -1 && end != -1 && start <= end)) {
+ *result = CAL_BACKEND_GET_ALARMS_INVALID_RANGE;
+ return NULL;
+ } else {
+ gboolean object_found;
+ GNOME_Evolution_Calendar_CalComponentAlarms *alarms;
+
+ alarms = (* CLASS (backend)->get_alarms_for_object) (backend, uid, start, end,
+ &object_found);
+
+ if (object_found)
+ *result = CAL_BACKEND_GET_ALARMS_SUCCESS;
+ else
+ *result = CAL_BACKEND_GET_ALARMS_NOT_FOUND;
+
+ return alarms;
+ }
}
/**
diff --git a/calendar/pcs/cal-backend.h b/calendar/pcs/cal-backend.h
index e2d5c6c880..6194630b43 100644
--- a/calendar/pcs/cal-backend.h
+++ b/calendar/pcs/cal-backend.h
@@ -27,7 +27,7 @@
#include <libgnomevfs/gnome-vfs.h>
#include <cal-util/cal-util.h>
#include <cal-util/cal-component.h>
-#include "calendar/pcs/evolution-calendar.h"
+#include "evolution-calendar.h"
#include "cal-common.h"
#include "cal.h"
@@ -48,6 +48,13 @@ typedef enum {
CAL_BACKEND_LOAD_ERROR /* We need better error reporting in libversit */
} CalBackendLoadStatus;
+/* Result codes for ::get_alarms_in_range() */
+typedef enum {
+ CAL_BACKEND_GET_ALARMS_SUCCESS,
+ CAL_BACKEND_GET_ALARMS_NOT_FOUND,
+ CAL_BACKEND_GET_ALARMS_INVALID_RANGE
+} CalBackendGetAlarmsForObjectResult;
+
struct _CalBackend {
GtkObject object;
@@ -70,12 +77,16 @@ struct _CalBackendClass {
char *(* get_object) (CalBackend *backend, const char *uid);
CalObjType(* get_type_by_uid) (CalBackend *backend, const char *uid);
GList *(* get_uids) (CalBackend *backend, CalObjType type);
+
GList *(* get_objects_in_range) (CalBackend *backend, CalObjType type,
time_t start, time_t end);
- GList *(* get_alarms_in_range) (CalBackend *backend, time_t start, time_t end);
- gboolean (* get_alarms_for_object) (CalBackend *backend, const char *uid,
- time_t start, time_t end,
- GList **alarms);
+
+ GNOME_Evolution_Calendar_CalComponentAlarmsSeq *(* get_alarms_in_range) (
+ CalBackend *backend, time_t start, time_t end);
+ GNOME_Evolution_Calendar_CalComponentAlarms *(* get_alarms_for_object) (
+ CalBackend *backend, const char *uid,
+ time_t start, time_t end, gboolean *object_found);
+
gboolean (* update_object) (CalBackend *backend, const char *uid, const char *calobj);
gboolean (* remove_object) (CalBackend *backend, const char *uid);
};
@@ -101,11 +112,13 @@ GNOME_Evolution_Calendar_CalObjChangeSeq * cal_backend_get_changes (CalBackend *
GList *cal_backend_get_objects_in_range (CalBackend *backend, CalObjType type,
time_t start, time_t end);
-GList *cal_backend_get_alarms_in_range (CalBackend *backend, time_t start, time_t end);
+GNOME_Evolution_Calendar_CalComponentAlarmsSeq *cal_backend_get_alarms_in_range (
+ CalBackend *backend, time_t start, time_t end, gboolean *valid_range);
-gboolean cal_backend_get_alarms_for_object (CalBackend *backend, const char *uid,
- time_t start, time_t end,
- GList **alarms);
+GNOME_Evolution_Calendar_CalComponentAlarms *cal_backend_get_alarms_for_object (
+ CalBackend *backend, const char *uid,
+ time_t start, time_t end,
+ CalBackendGetAlarmsForObjectResult *result);
gboolean cal_backend_update_object (CalBackend *backend, const char *uid, const char *calobj);
diff --git a/calendar/pcs/cal.c b/calendar/pcs/cal.c
index 179c850475..77f18806d9 100644
--- a/calendar/pcs/cal.c
+++ b/calendar/pcs/cal.c
@@ -334,68 +334,8 @@ Cal_get_objects_in_range (PortableServer_Servant servant,
return seq;
}
-#if 0
-/* 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;
- }
-}
-#endif
-
-/* Builds a CORBA sequence of alarm instances from a CalAlarmInstance list. */
-static GNOME_Evolution_Calendar_CalAlarmInstanceSeq *
-build_alarm_instance_seq (GList *alarms)
-{
- GList *l;
- int n, i;
- GNOME_Evolution_Calendar_CalAlarmInstanceSeq *seq;
-
- n = g_list_length (alarms);
-
- seq = GNOME_Evolution_Calendar_CalAlarmInstanceSeq__alloc ();
- CORBA_sequence_set_release (seq, TRUE);
- seq->_length = n;
- seq->_buffer = CORBA_sequence_GNOME_Evolution_Calendar_CalAlarmInstance_allocbuf (n);
-
- /* Fill the sequence */
-
- for (i = 0, l = alarms; l; i++, l = l->next) {
- CalAlarmInstance *ai;
- GNOME_Evolution_Calendar_CalAlarmInstance *corba_ai;
-
- ai = l->data;
- corba_ai = &seq->_buffer[i];
-
- corba_ai->uid = CORBA_string_dup (ai->uid);
-#if 0
- corba_ai->type = corba_alarm_type (ai->type);
-#endif
- corba_ai->trigger = ai->trigger;
- corba_ai->occur = ai->occur;
- }
-
- return seq;
-}
-
/* Cal::get_alarms_in_range method */
-static GNOME_Evolution_Calendar_CalAlarmInstanceSeq *
+static GNOME_Evolution_Calendar_CalComponentAlarmsSeq *
Cal_get_alarms_in_range (PortableServer_Servant servant,
GNOME_Evolution_Calendar_Time_t start,
GNOME_Evolution_Calendar_Time_t end,
@@ -404,8 +344,8 @@ Cal_get_alarms_in_range (PortableServer_Servant servant,
Cal *cal;
CalPrivate *priv;
time_t t_start, t_end;
- GNOME_Evolution_Calendar_CalAlarmInstanceSeq *seq;
- GList *alarms;
+ gboolean valid_range;
+ GNOME_Evolution_Calendar_CalComponentAlarmsSeq *seq;
cal = CAL (bonobo_object_from_servant (servant));
priv = cal->priv;
@@ -413,36 +353,30 @@ Cal_get_alarms_in_range (PortableServer_Servant servant,
t_start = (time_t) start;
t_end = (time_t) end;
- if (t_start > t_end || t_start == -1 || t_end == -1) {
+ seq = cal_backend_get_alarms_in_range (priv->backend, t_start, t_end, &valid_range);
+ if (!valid_range) {
CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
ex_GNOME_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;
}
/* Cal::get_alarms_for_object method */
-static GNOME_Evolution_Calendar_CalAlarmInstanceSeq *
+static GNOME_Evolution_Calendar_CalComponentAlarms *
Cal_get_alarms_for_object (PortableServer_Servant servant,
const GNOME_Evolution_Calendar_CalObjUID uid,
GNOME_Evolution_Calendar_Time_t start,
GNOME_Evolution_Calendar_Time_t end,
- CORBA_Environment *ev)
+ CORBA_Environment * ev)
{
Cal *cal;
CalPrivate *priv;
time_t t_start, t_end;
- GNOME_Evolution_Calendar_CalAlarmInstanceSeq *seq;
- GList *alarms;
- gboolean result;
+ GNOME_Evolution_Calendar_CalComponentAlarms *alarms;
+ CalBackendGetAlarmsForObjectResult result;
cal = CAL (bonobo_object_from_servant (servant));
priv = cal->priv;
@@ -450,25 +384,28 @@ Cal_get_alarms_for_object (PortableServer_Servant servant,
t_start = (time_t) start;
t_end = (time_t) end;
- if (t_start > t_end || t_start == -1 || t_end == -1) {
+ alarms = cal_backend_get_alarms_for_object (priv->backend, uid, t_start, t_end, &result);
+
+ switch (result) {
+ case CAL_BACKEND_GET_ALARMS_SUCCESS:
+ return alarms;
+
+ case CAL_BACKEND_GET_ALARMS_NOT_FOUND:
CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
- ex_GNOME_Evolution_Calendar_Cal_InvalidRange,
+ ex_GNOME_Evolution_Calendar_Cal_NotFound,
NULL);
return NULL;
- }
- result = cal_backend_get_alarms_for_object (priv->backend, uid, t_start, t_end, &alarms);
- if (!result) {
+ case CAL_BACKEND_GET_ALARMS_INVALID_RANGE:
CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
- ex_GNOME_Evolution_Calendar_Cal_NotFound,
+ ex_GNOME_Evolution_Calendar_Cal_InvalidRange,
NULL);
return NULL;
- }
-
- seq = build_alarm_instance_seq (alarms);
- cal_alarm_instance_list_free (alarms);
- return seq;
+ default:
+ g_assert_not_reached ();
+ return NULL;
+ }
}
/* Cal::update_object method */