[evolution-patches] patch for adding e_cal_generate_instances_for_object
- From: Rodrigo Moya <rodrigo ximian com>
- To: Evolution Patches <evolution-patches ximian com>
- Subject: [evolution-patches] patch for adding e_cal_generate_instances_for_object
- Date: Tue, 11 May 2004 19:43:57 +0200
The attached patch includes some fixes from the recurrences-work-branch
that makes the e_cal_generate_instances function deal correctly with
detached instances (even if we don't support them fully, there might be
remote calendars containing detached instances) and adds the
e_cal_generate_instances_for_object function, which I added to the
branch in order to replace the e_cal_recur_generate_instances_for_object
function that is used in the views.
cheers
? libical/src/libicalss/icalssyacc.output
Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/evolution-data-server/calendar/ChangeLog,v
retrieving revision 1.257
diff -u -p -r1.257 ChangeLog
--- ChangeLog 7 May 2004 16:04:17 -0000 1.257
+++ ChangeLog 11 May 2004 17:36:50 -0000
@@ -1,3 +1,12 @@
+2004-05-11 Rodrigo Moya <rodrigo ximian com>
+
+ * libecal/e-cal.c (e_cal_generate_instances): fixed gtk-doc comments,
+ and process correctly detached instances.
+ (e_cal_generate_instances_for_object): new function.
+ (e_cal_set_default_timezone): set the internal default timezone when
+ the call to the backend is successful.
+ (process_detached_instances): process correctly the detached instances.
+
2004-05-07 JP Rosevear <jpr ximian com>
Fixes #57908
Index: libecal/e-cal.c
===================================================================
RCS file: /cvs/gnome/evolution-data-server/calendar/libecal/e-cal.c,v
retrieving revision 1.59
diff -u -p -r1.59 e-cal.c
--- libecal/e-cal.c 6 May 2004 04:06:19 -0000 1.59
+++ libecal/e-cal.c 11 May 2004 17:36:52 -0000
@@ -2752,13 +2752,30 @@ add_instance (ECalComponent *comp, time_
{
GList **list;
struct comp_instance *ci;
+ struct icaltimetype itt, itt_start;
+ icalcomponent *icalcomp;
list = data;
ci = g_new (struct comp_instance, 1);
- ci->comp = comp;
- g_object_ref (G_OBJECT (ci->comp));
+ icalcomp = icalcomponent_new_clone (e_cal_component_get_icalcomponent (comp));
+ itt_start = icalcomponent_get_dtstart (icalcomp);
+
+#if 0
+ /* set the RECUR-ID for the instance */
+ if (e_cal_util_component_has_recurrences (icalcomp)) {
+ if (!(icalcomponent_get_first_property (icalcomp, ICAL_RECURRENCEID_PROPERTY))) {
+ itt = icaltime_from_timet (start, itt_start.is_date);
+ icalcomponent_set_recurrenceid (icalcomp, itt);
+ }
+ }
+#endif
+
+ /* add the instance to the list */
+ ci->comp = e_cal_component_new ();
+ e_cal_component_set_icalcomponent (ci->comp, icalcomp);
+
ci->start = start;
ci->end = end;
@@ -2785,19 +2802,22 @@ compare_comp_instance (gconstpointer a,
static GList *
process_detached_instances (GList *instances, GList *detached_instances)
{
- struct comp_instance *ci;
- GList *dl, *instances_to_remove = NULL;
+ struct comp_instance *ci, *cid;
+ GList *dl, *unprocessed_instances = NULL;
for (dl = detached_instances; dl != NULL; dl = dl->next) {
GList *il;
const char *uid;
+ gboolean processed;
ECalComponentRange recur_id, instance_recur_id;
- ECalComponent *comp = dl->data;
- e_cal_component_get_uid (comp, &uid);
- e_cal_component_get_recurid (comp, &recur_id);
+ processed = FALSE;
+
+ cid = dl->data;
+ e_cal_component_get_uid (cid->comp, &uid);
+ e_cal_component_get_recurid (cid->comp, &recur_id);
- /* search for coincident instances */
+ /* search for coincident instances already expanded */
for (il = instances; il != NULL; il = il->next) {
const char *instance_uid;
int cmp;
@@ -2806,38 +2826,49 @@ process_detached_instances (GList *insta
e_cal_component_get_uid (ci->comp, &instance_uid);
e_cal_component_get_recurid (ci->comp, &instance_recur_id);
if (strcmp (uid, instance_uid) == 0) {
- /* replace it */
- if (strcmp (e_cal_component_get_recurid_as_string (comp),
- e_cal_component_get_recurid_as_string (ci->comp)) == 0) {
+ if (strcmp (e_cal_component_get_recurid_as_string (ci->comp),
+ e_cal_component_get_recurid_as_string (cid->comp)) == 0) {
g_object_unref (ci->comp);
- ci->comp = g_object_ref (comp);
- continue;
- }
-
- /* mark other instances based on the detached instance's type as delete */
- cmp = icaltime_compare (*instance_recur_id.datetime.value,
- *recur_id.datetime.value);
- switch (recur_id.type) {
- case E_CAL_COMPONENT_RANGE_THISPRIOR :
- if (cmp <= 0)
- instances_to_remove = g_list_prepend (instances_to_remove, ci);
- break;
- case E_CAL_COMPONENT_RANGE_THISFUTURE :
- if (cmp >= 0)
- instances_to_remove = g_list_prepend (instances_to_remove, ci);
- break;
+ ci->comp = g_object_ref (cid->comp);
+ ci->start = cid->start;
+ ci->end = cid->end;
+
+ processed = TRUE;
+ } else {
+ cmp = icaltime_compare (*instance_recur_id.datetime.value,
+ *recur_id.datetime.value);
+ if ((recur_id.type == E_CAL_COMPONENT_RANGE_THISPRIOR && cmp <= 0) ||
+ (recur_id.type == E_CAL_COMPONENT_RANGE_THISFUTURE && cmp >= 0)) {
+ ECalComponent *comp;
+
+ comp = e_cal_component_new ();
+ e_cal_component_set_icalcomponent (
+ comp,
+ icalcomponent_new_clone (e_cal_component_get_icalcomponent (cid->comp)));
+ e_cal_component_set_recurid (comp, &instance_recur_id);
+
+ /* replace the generated instances */
+ g_object_unref (ci->comp);
+ ci->comp = comp;
+ }
}
}
}
+
+ if (!processed)
+ unprocessed_instances = g_list_prepend (unprocessed_instances, cid);
}
- /* remove all duplicated instances */
- for (dl = instances_to_remove; dl; dl = dl->next) {
- ci = dl->data;
+ /* add the unprocessed instances (ie, detached instances with no master object */
+ while (unprocessed_instances != NULL) {
+ cid = unprocessed_instances->data;
+ ci = g_new0 (struct comp_instance, 1);
+ ci->comp = g_object_ref (cid->comp);
+ ci->start = cid->start;
+ ci->end = cid->end;
+ instances = g_list_append (instances, ci);
- instances = g_list_remove (instances, ci);
- g_object_unref (G_OBJECT (ci->comp));
- g_free (ci);
+ unprocessed_instances = g_list_remove (unprocessed_instances, cid);
}
return instances;
@@ -2846,7 +2877,6 @@ process_detached_instances (GList *insta
/**
* e_cal_generate_instances:
* @ecal: A calendar ecal.
- * @type: Bitmask with types of objects to return.
* @start: Start time for query.
* @end: End time for query.
* @cb: Callback for each generated instance.
@@ -2880,7 +2910,15 @@ e_cal_generate_instances (ECal *ecal, ti
g_return_if_fail (cb != NULL);
iso_start = isodate_from_time_t (start);
- iso_end = isodate_from_time_t (end);
+ if (!iso_start)
+ return;
+
+ iso_end = isodate_from_time_t (end);
+ if (!iso_end) {
+ g_free (iso_start);
+ return;
+ }
+
/* Generate objects */
query = g_strdup_printf ("(occur-in-time-range? (make-time \"%s\") (make-time \"%s\"))",
iso_start, iso_end);
@@ -2899,8 +2937,12 @@ e_cal_generate_instances (ECal *ecal, ti
comp = l->data;
if (e_cal_component_is_instance (comp)) {
- /* if we get a detached instance, keep it apart to process it later */
- detached_instances = g_list_prepend (detached_instances, comp);
+ /* keep the detached instances apart */
+ e_cal_recur_generate_instances (comp, start, end, add_instance, &detached_instances,
+ e_cal_resolve_tzid_cb, ecal,
+ priv->default_zone);
+
+ g_object_unref (comp);
} else {
e_cal_recur_generate_instances (comp, start, end, add_instance, &instances,
e_cal_resolve_tzid_cb, ecal,
@@ -2941,10 +2983,91 @@ e_cal_generate_instances (ECal *ecal, ti
g_list_free (instances);
- g_list_foreach (detached_instances, (GFunc) g_object_unref, NULL);
+ for (l = detached_instances; l; l = l->next) {
+ struct comp_instance *ci;
+
+ ci = l->data;
+ g_object_unref (G_OBJECT (ci->comp));
+ g_free (ci);
+ }
+
g_list_free (detached_instances);
}
+/**
+ * e_cal_generate_instances_for_object:
+ * @ecal: A calendar ecal.
+ * @icalcomp: Object to generate instances from.
+ * @start: Start time for query.
+ * @end: End time for query.
+ * @cb: Callback for each generated instance.
+ * @cb_data: Closure data for the callback.
+ *
+ * Does a combination of e_cal_get_object_list () and
+ * cal_recur_generate_instances(), like e_cal_generate_instances(), but
+ * for a single object.
+ *
+ * The callback function should do a g_object_ref() of the calendar component
+ * it gets passed if it intends to keep it around.
+ **/
+void
+e_cal_generate_instances_for_object (ECal *ecal, icalcomponent *icalcomp,
+ time_t start, time_t end,
+ ECalRecurInstanceFn cb, gpointer cb_data)
+{
+ ECalPrivate *priv;
+ ECalComponent *comp;
+ const char *uid, *rid;
+ gboolean result;
+ GList *instances = NULL;
+
+ g_return_if_fail (E_IS_CAL (ecal));
+ g_return_if_fail (start != -1 && end != -1);
+ g_return_if_fail (start <= end);
+ g_return_if_fail (cb != NULL);
+
+ priv = ecal->priv;
+
+ comp = e_cal_component_new ();
+ e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (icalcomp));
+
+ /* generate all instances in the given time range */
+ e_cal_generate_instances (ecal, start, end, add_instance, &instances);
+
+ /* now only return back the instances for the given object */
+ e_cal_component_get_uid (comp, &uid);
+ rid = e_cal_component_get_recurid_as_string (comp);
+
+ result = TRUE;
+ while (instances != NULL) {
+ struct comp_instance *ci;
+ const char *instance_uid, *instance_rid;
+
+ ci = instances->data;
+
+ if (result) {
+ e_cal_component_get_uid (ci->comp, &instance_uid);
+ instance_rid = e_cal_component_get_recurid_as_string (ci->comp);
+
+ if (instance_uid && strcmp (uid, instance_uid) == 0) {
+ if (rid && *rid) {
+ if (instance_rid && *instance_rid && strcmp (rid, instance_rid) == 0)
+ result = (* cb) (ci->comp, ci->start, ci->end, cb_data);
+ } else
+ result = (* cb) (ci->comp, ci->start, ci->end, cb_data);
+ }
+ }
+
+ /* remove instance from list */
+ instances = g_list_remove (instances, ci);
+ g_object_unref (ci->comp);
+ g_free (ci);
+ }
+
+ /* clean up */
+ g_object_unref (comp);
+}
+
/* Builds a list of ECalComponentAlarms structures */
static GSList *
build_component_alarms_list (ECal *ecal, GList *object_list, time_t start, time_t end)
@@ -4088,6 +4211,13 @@ e_cal_set_default_timezone (ECal *ecal,
g_cond_wait (our_op->cond, our_op->mutex);
status = our_op->status;
+
+ /* set the default timezone internally if successful */
+ if (our_op->status == E_CALENDAR_STATUS_OK) {
+ g_mutex_lock (priv->mutex);
+ priv->default_zone = zone;
+ g_mutex_unlock (priv->mutex);
+ }
e_calendar_remove_op (ecal, our_op);
g_mutex_unlock (our_op->mutex);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]