[evolution-data-server] calendar file backend: removal notification for detached recurrence, part 1



commit 88c1996b6626e884b68dc98a76272827bc8680a0
Author: Patrick Ohly <patrick ohly intel com>
Date:   Thu May 12 11:05:59 2011 +0200

    calendar file backend: removal notification for detached recurrence, part 1
    
    If e_cal_remove_object_with_mod() was called for an appointment where
    only a detached recurrence existed, no "objects-removed" signal was
    triggered although it should have been.
    
    Apparently Evolution avoids the problem by calling
    e_cal_remove_component() instead in this case. Fixing the problem
    makes writing clients easier (no special cases).
    
    With this patch, remove_instance() itself decides what it reports back
    to the caller. Note that it cannot report back both a modification and
    a removal at the moment.

 calendar/backends/file/e-cal-backend-file.c |   56 ++++++++++++++++++---------
 1 files changed, 37 insertions(+), 19 deletions(-)
---
diff --git a/calendar/backends/file/e-cal-backend-file.c b/calendar/backends/file/e-cal-backend-file.c
index 564304c..0caf5a0 100644
--- a/calendar/backends/file/e-cal-backend-file.c
+++ b/calendar/backends/file/e-cal-backend-file.c
@@ -2422,14 +2422,22 @@ e_cal_backend_file_modify_object (ECalBackendSync *backend, EDataCal *cal, GCanc
  * Remove one and only one instance. The object may be empty
  * afterwards, in which case it will be removed completely.
  *
+ * @mod    CALOBJ_MOD_THIS or CAL_OBJ_MOD_ONLY_THIS: the later only removes
+ *         the instance, the former also adds an EXDATE if rid is set
+ *         TODO: CAL_OBJ_MOD_ONLY_THIS
  * @uid    pointer to UID which must remain valid even if the object gets
  *         removed
  * @rid    NULL, "", or non-empty string when manipulating a specific recurrence;
  *         also must remain valid
+ * @error  may be NULL if caller is not interested in errors
  * @return modified object or NULL if it got removed
  */
 static ECalBackendFileObject *
-remove_instance (ECalBackendFile *cbfile, ECalBackendFileObject *obj_data, const gchar *uid, const gchar *rid)
+remove_instance (ECalBackendFile *cbfile, ECalBackendFileObject *obj_data,
+		 const gchar *uid, const gchar *rid,
+		 CalObjModType mod,
+		 gchar **old_object, gchar **object,
+		 GError **error)
 {
 	gchar *hash_rid;
 	ECalComponent *comp;
@@ -2443,6 +2451,10 @@ remove_instance (ECalBackendFile *cbfile, ECalBackendFileObject *obj_data, const
 		/* remove recurrence */
 		if (g_hash_table_lookup_extended (obj_data->recurrences, rid,
 		                                  (gpointer *)&hash_rid, (gpointer *)&comp)) {
+			/* Removing without parent? Report as removal. */
+			if (old_object && !obj_data->full_object)
+				*old_object = e_cal_component_get_as_string (comp);
+
 			/* remove the component from our data */
 			icalcomponent_remove_component (cbfile->priv->icalcomp,
 							e_cal_component_get_icalcomponent (comp));
@@ -2467,7 +2479,9 @@ remove_instance (ECalBackendFile *cbfile, ECalBackendFileObject *obj_data, const
 						e_cal_component_get_icalcomponent (obj_data->full_object));
 		cbfile->priv->comp = g_list_remove (cbfile->priv->comp, obj_data->full_object);
 
-		/* add EXDATE or EXRULE to parent */
+		/* add EXDATE or EXRULE to parent, report as update */
+		if (old_object)
+			*old_object = e_cal_component_get_as_string (obj_data->full_object);
 		e_cal_util_remove_instances (e_cal_component_get_icalcomponent (obj_data->full_object),
 					     icaltime_from_string (rid), CALOBJ_MOD_THIS);
 
@@ -2476,6 +2490,10 @@ remove_instance (ECalBackendFile *cbfile, ECalBackendFileObject *obj_data, const
 		current = icaltime_current_time_with_zone (icaltimezone_get_utc_timezone ());
 		e_cal_component_set_last_modified (obj_data->full_object, &current);
 
+		/* report update */
+		if (object)
+			*object = e_cal_component_get_as_string (obj_data->full_object);
+
 		/* add the modified object to the beginning of the list,
 		   so that it's always before any detached instance we
 		   might have */
@@ -2493,7 +2511,9 @@ remove_instance (ECalBackendFile *cbfile, ECalBackendFileObject *obj_data, const
 						e_cal_component_get_icalcomponent (obj_data->full_object));
 		cbfile->priv->comp = g_list_remove (cbfile->priv->comp, obj_data->full_object);
 
-		/* remove parent */
+		/* remove parent, report as removal */
+		if (old_object)
+			*old_object = e_cal_component_get_as_string (obj_data->full_object);
 		g_object_unref (obj_data->full_object);
 		obj_data->full_object = NULL;
 
@@ -2587,11 +2607,7 @@ e_cal_backend_file_remove_object (ECalBackendSync *backend, EDataCal *cal, GCanc
 		/* not reached, keep compiler happy */
 		break;
 	case CALOBJ_MOD_THIS :
-		*old_object = get_object_string_from_fileobject (obj_data, recur_id);
-
-		obj_data = remove_instance (cbfile, obj_data, uid, recur_id);
-		if (obj_data && obj_data->full_object)
-			*object = e_cal_component_get_as_string (obj_data->full_object);
+		obj_data = remove_instance (cbfile, obj_data, uid, recur_id, mod, old_object, object, error);
 		break;
 	case CALOBJ_MOD_THISANDPRIOR :
 	case CALOBJ_MOD_THISANDFUTURE :
@@ -2664,17 +2680,17 @@ cancel_received_object (ECalBackendFile *cbfile, icalcomponent *icalcomp, gchar
 		return FALSE;
 	}
 
-	if (obj_data->full_object)
-		*old_object = e_cal_component_get_as_string (obj_data->full_object);
-
-	/* new_object is kept NULL if not removing the instance */
 	rid = e_cal_component_get_recurid_as_string (comp);
 	if (rid && *rid) {
-		obj_data = remove_instance (cbfile, obj_data, uid, rid);
+		obj_data = remove_instance (cbfile, obj_data, uid, rid, CALOBJ_MOD_THIS, old_object, new_object, NULL);
 		if (obj_data && obj_data->full_object)
 			*new_object = e_cal_component_get_as_string (obj_data->full_object);
-	} else
+	} else {
+		/* report as removal by keeping *new_object NULL */
+		if (obj_data->full_object)
+			*old_object = e_cal_component_get_as_string (obj_data->full_object);
 		remove_component (cbfile, uid, obj_data);
+	}
 
 	g_free (rid);
 
@@ -2912,12 +2928,14 @@ e_cal_backend_file_receive_objects (ECalBackendSync *backend, EDataCal *cal, GCa
 				fetch_attachments (backend, comp);
 			obj_data = g_hash_table_lookup (priv->comp_uid_hash, uid);
 			if (obj_data) {
-				if (obj_data->full_object)
-					old_object = e_cal_component_get_as_string (obj_data->full_object);
-				if (rid)
-					remove_instance (cbfile, obj_data, uid, rid);
-				else
+				if (rid) {
+					remove_instance (cbfile, obj_data, uid, rid, CALOBJ_MOD_THIS,
+							 &old_object, &new_object, NULL);
+				} else {
+					if (obj_data->full_object)
+						old_object = e_cal_component_get_as_string (obj_data->full_object);
 					remove_component (cbfile, uid, obj_data);
+				}
 
 				if (!is_declined)
 					add_component (cbfile, comp, FALSE);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]