Merge from recurrences-work-branch
authorRodrigo Moya <rodrigo@novell.com>
Wed, 15 Dec 2004 18:20:37 +0000 (18:20 +0000)
committerRodrigo Moya <rodrigo@src.gnome.org>
Wed, 15 Dec 2004 18:20:37 +0000 (18:20 +0000)
2004-12-15  Rodrigo Moya <rodrigo@novell.com>

Merge from recurrences-work-branch

* libecal/e-cal.c (open_calendar): added missing calls to
e_calendar_remove_op/e_calendar_free_op.
(add_instance): enable code to set the recurrence ID on each instance.

* libedata-cal/e-data-cal.[ch] (e_data_cal_notify_object_removed): added
new argument to have backends send both the object before and after the
modification.

* libedata-cal/e-cal-backend.[ch] (e_cal_backend_modify_object):
pass correct number of arguments to e_cal_backend_notify_object_removed.
(match_query_and_notify, e_cal_backend_notify_object_modified): separated
the notification logic from e_cal_backend_notify_object_modified.
(e_cal_backend_notify_object_removed): added new argument to have
backends send both the object before and after the modification.

* libedata-cal/e-cal-backend-sync.[ch] (e_cal_backend_sync_remove_object):
added a new argument to send the object as it was before being removed.
Also, change meaning of 'object' argument to contain the object as it
is after being modified, or NULL if it was removed.
(_e_cal_backend_remove_object): adapted to change in method arguments
and pass correct number of arguments to e_data_cal_notify_object_removed.

* backends/contacts/e-cal-backend-contacts.c (contact_record_free):
pass correct number of arguments to e_cal_backend_notify_object_removed.

* backends/file/e-cal-backend-file.c (notify_removals_cb,
e_cal_backend_file_receive_objects):
pass correct number of arguments to e_cal_backend_notify_object_removed.
(remove_object_instance_cb, e_cal_backend_file_modify_object): adapted to
support detached recurrences and THISANDPRIOR/THISANDFUTURE.
(e_cal_backend_file_remove_object): adapted to method changes.

* backends/groupwise/e-cal-backend-groupwise.c (get_deltas, receive_object):
pass correct number of arguments to e_cal_backend_notify_object_removed.
(e_cal_backend_groupwise_remove_object): adapted to method changes.

* backends/http/e-cal-backend-http.c (notify_and_remove_from_cache):
pass correct number of arguments to e_cal_backend_notify_object_removed.
(e_cal_backend_http_remove_object): adapted to method changes.

12 files changed:
calendar/ChangeLog
calendar/backends/contacts/e-cal-backend-contacts.c
calendar/backends/file/e-cal-backend-file.c
calendar/backends/groupwise/e-cal-backend-groupwise.c
calendar/backends/http/e-cal-backend-http.c
calendar/libecal/e-cal.c
calendar/libedata-cal/e-cal-backend-sync.c
calendar/libedata-cal/e-cal-backend-sync.h
calendar/libedata-cal/e-cal-backend.c
calendar/libedata-cal/e-cal-backend.h
calendar/libedata-cal/e-data-cal.c
calendar/libedata-cal/e-data-cal.h

index bfbde28..21df23d 100644 (file)
@@ -1,3 +1,47 @@
+2004-12-15  Rodrigo Moya <rodrigo@novell.com>
+
+       Merge from recurrences-work-branch
+
+       * libecal/e-cal.c (open_calendar): added missing calls to
+       e_calendar_remove_op/e_calendar_free_op.
+       (add_instance): enable code to set the recurrence ID on each instance.
+
+       * libedata-cal/e-data-cal.[ch] (e_data_cal_notify_object_removed): added
+       new argument to have backends send both the object before and after the
+       modification.
+
+       * libedata-cal/e-cal-backend.[ch] (e_cal_backend_modify_object):
+       pass correct number of arguments to e_cal_backend_notify_object_removed.
+       (match_query_and_notify, e_cal_backend_notify_object_modified): separated
+       the notification logic from e_cal_backend_notify_object_modified.
+       (e_cal_backend_notify_object_removed): added new argument to have
+       backends send both the object before and after the modification.
+
+       * libedata-cal/e-cal-backend-sync.[ch] (e_cal_backend_sync_remove_object):
+       added a new argument to send the object as it was before being removed.
+       Also, change meaning of 'object' argument to contain the object as it
+       is after being modified, or NULL if it was removed.
+       (_e_cal_backend_remove_object): adapted to change in method arguments
+       and pass correct number of arguments to e_data_cal_notify_object_removed.
+
+       * backends/contacts/e-cal-backend-contacts.c (contact_record_free):
+       pass correct number of arguments to e_cal_backend_notify_object_removed.
+       
+       * backends/file/e-cal-backend-file.c (notify_removals_cb,
+       e_cal_backend_file_receive_objects):
+       pass correct number of arguments to e_cal_backend_notify_object_removed.
+       (remove_object_instance_cb, e_cal_backend_file_modify_object): adapted to
+       support detached recurrences and THISANDPRIOR/THISANDFUTURE.
+       (e_cal_backend_file_remove_object): adapted to method changes.
+
+       * backends/groupwise/e-cal-backend-groupwise.c (get_deltas, receive_object):
+       pass correct number of arguments to e_cal_backend_notify_object_removed.
+       (e_cal_backend_groupwise_remove_object): adapted to method changes.
+
+       * backends/http/e-cal-backend-http.c (notify_and_remove_from_cache):
+       pass correct number of arguments to e_cal_backend_notify_object_removed.
+       (e_cal_backend_http_remove_object): adapted to method changes.
+
 2004-12-15  Chenthill Palanisamy <pchenthill@novell.com>
 
        * backends/groupwise/e-cal-backend-groupwise-utils.c:
index c06ed46..71badaf 100644 (file)
@@ -176,7 +176,7 @@ contact_record_free (ContactRecord *cr)
        if (cr->comp_birthday) {
                comp_str = e_cal_component_get_as_string (cr->comp_birthday);
                e_cal_component_get_uid (cr->comp_birthday, &uid);
-               e_cal_backend_notify_object_removed (E_CAL_BACKEND (cr->cbc), uid, comp_str);
+               e_cal_backend_notify_object_removed (E_CAL_BACKEND (cr->cbc), uid, comp_str, NULL);
                g_free (comp_str);
                g_object_unref (G_OBJECT (cr->comp_birthday));
        }
@@ -185,7 +185,7 @@ contact_record_free (ContactRecord *cr)
        if (cr->comp_anniversary) {
                comp_str = e_cal_component_get_as_string (cr->comp_anniversary);
                e_cal_component_get_uid (cr->comp_anniversary, &uid);
-               e_cal_backend_notify_object_removed (E_CAL_BACKEND (cr->cbc), uid, comp_str);
+               e_cal_backend_notify_object_removed (E_CAL_BACKEND (cr->cbc), uid, comp_str, NULL);
                g_free (comp_str);
                g_object_unref (G_OBJECT (cr->comp_anniversary));
        }
index 32ce33f..c185fd0 100644 (file)
@@ -682,7 +682,7 @@ notify_removals_cb (gpointer key, gpointer value, gpointer data)
                if (!old_obj_str)
                        return;
 
-               e_cal_backend_notify_object_removed (context->backend, uid, old_obj_str);
+               e_cal_backend_notify_object_removed (context->backend, uid, old_obj_str, NULL);
        }
 }
 
@@ -1721,10 +1721,56 @@ e_cal_backend_file_create_object (ECalBackendSync *backend, EDataCal *cal, char
        return GNOME_Evolution_Calendar_Success;
 }
 
+typedef struct {
+       ECalBackendFile *cbfile;
+       ECalBackendFileObject *obj_data;
+       const char *rid;
+       CalObjModType mod;
+} RemoveRecurrenceData;
+
+static gboolean
+remove_object_instance_cb (gpointer key, gpointer value, gpointer user_data)
+{
+       time_t fromtt, instancett;
+       GSList *categories;
+       char *rid = key;
+       ECalComponent *instance = value;
+       RemoveRecurrenceData *rrdata = user_data;
+
+       fromtt = icaltime_as_timet (icaltime_from_string (rrdata->rid));
+       instancett = icaltime_as_timet (get_rid_icaltime (instance));
+
+       if (fromtt > 0 && instancett > 0) {
+               if ((rrdata->mod == CALOBJ_MOD_THISANDPRIOR && instancett <= fromtt) ||
+                   (rrdata->mod == CALOBJ_MOD_THISANDFUTURE && instancett >= fromtt)) {
+                       /* remove the component from our data */
+                       icalcomponent_remove_component (rrdata->cbfile->priv->icalcomp,
+                                                       e_cal_component_get_icalcomponent (instance));
+                       rrdata->cbfile->priv->comp = g_list_remove (rrdata->cbfile->priv->comp, instance);
+
+                       rrdata->obj_data->recurrences_list = g_list_remove (rrdata->obj_data->recurrences_list, instance);
+
+                       /* update the set of categories */
+                       e_cal_component_get_categories_list (instance, &categories);
+                       e_cal_backend_unref_categories (E_CAL_BACKEND (rrdata->cbfile), categories);
+                       e_cal_component_free_categories_list (categories);
+
+                       /* free memory */
+                       g_free (rid);
+                       g_object_unref (instance);
+
+                       return TRUE;
+               }
+       }
+
+       return FALSE;
+}
+
 static ECalBackendSyncStatus
 e_cal_backend_file_modify_object (ECalBackendSync *backend, EDataCal *cal, const char *calobj, 
                                  CalObjModType mod, char **old_object)
 {
+       RemoveRecurrenceData rrdata;
        ECalBackendFile *cbfile;
        ECalBackendFilePrivate *priv;
        icalcomponent *icalcomp;
@@ -1820,9 +1866,7 @@ e_cal_backend_file_modify_object (ECalBackendSync *backend, EDataCal *cal, const
                        e_cal_util_remove_instances (e_cal_component_get_icalcomponent (obj_data->full_object),
                                                     get_rid_icaltime (comp),
                                                     mod);
-
-                       new = e_cal_component_get_as_string (obj_data->full_object);
-
+                       new = e_cal_component_get_as_string (comp);
                        e_cal_backend_notify_object_modified (E_CAL_BACKEND (backend), old, new);
 
                        if (old_object)
@@ -1833,14 +1877,80 @@ e_cal_backend_file_modify_object (ECalBackendSync *backend, EDataCal *cal, const
                }
 
                /* add the detached instance */
+               icalcomponent_set_recurrenceid (e_cal_component_get_icalcomponent (comp),
+                                               icaltime_from_string (rid));
                g_hash_table_insert (obj_data->recurrences, 
                                     g_strdup (e_cal_component_get_recurid_as_string (comp)),
                                     comp);
+               icalcomponent_add_component (priv->icalcomp,
+                                            e_cal_component_get_icalcomponent (comp));
+               priv->comp = g_list_append (priv->comp, comp);
                obj_data->recurrences_list = g_list_append (obj_data->recurrences_list, comp);
                break;
        case CALOBJ_MOD_THISANDPRIOR :
-               break;
        case CALOBJ_MOD_THISANDFUTURE :
+               rid = e_cal_component_get_recurid_as_string (comp);
+               if (!rid || !*rid) {
+                       if (old_object)
+                               *old_object = e_cal_component_get_as_string (obj_data->full_object);
+
+                       remove_component (cbfile, obj_data->full_object);
+
+                       /* Add the new object */
+                       add_component (cbfile, comp, TRUE);
+                       break;
+               }
+
+               /* remove the component from our data, temporarily */
+               icalcomponent_remove_component (priv->icalcomp,
+                                               e_cal_component_get_icalcomponent (obj_data->full_object));
+               priv->comp = g_list_remove (priv->comp, obj_data->full_object);
+
+               /* now deal with the detached recurrence */
+               if (g_hash_table_lookup_extended (obj_data->recurrences, rid,
+                                                 &real_rid, &recurrence)) {
+                       if (old_object)
+                               *old_object = e_cal_component_get_as_string (recurrence);
+
+                       /* remove the component from our data */
+                       icalcomponent_remove_component (priv->icalcomp,
+                                                       e_cal_component_get_icalcomponent (recurrence));
+                       priv->comp = g_list_remove (priv->comp, recurrence);
+                       g_hash_table_remove (obj_data->recurrences, rid);
+                       obj_data->recurrences_list = g_list_remove (obj_data->recurrences_list, recurrence);
+
+                       /* free memory */
+                       g_free (real_rid);
+               } else {
+                       if (old_object)
+                               *old_object = e_cal_component_get_as_string (obj_data->full_object);
+               }
+
+               /* remove all affected recurrences */
+               e_cal_util_remove_instances (e_cal_component_get_icalcomponent (obj_data->full_object),
+                                            icaltime_from_string (rid), mod);
+
+               rrdata.cbfile = cbfile;
+               rrdata.obj_data = obj_data;
+               rrdata.rid = rid;
+               rrdata.mod = mod;
+               g_hash_table_foreach_remove (obj_data->recurrences, (GHRFunc) remove_object_instance_cb, &rrdata);
+
+               /* add the modified object to the beginning of the list,
+                  so that it's always before any detached instance we
+                  might have */
+               icalcomponent_add_component (priv->icalcomp,
+                                            e_cal_component_get_icalcomponent (obj_data->full_object));
+               priv->comp = g_list_prepend (priv->comp, obj_data->full_object);
+
+               /* add the new detached recurrence */
+               g_hash_table_insert (obj_data->recurrences, 
+                                    g_strdup (e_cal_component_get_recurid_as_string (comp)),
+                                    comp);
+               icalcomponent_add_component (priv->icalcomp,
+                                            e_cal_component_get_icalcomponent (comp));
+               priv->comp = g_list_append (priv->comp, comp);
+               obj_data->recurrences_list = g_list_append (obj_data->recurrences_list, comp);
                break;
        case CALOBJ_MOD_ALL :
                /* in this case, we blow away all recurrences, and start over
@@ -1907,62 +2017,17 @@ remove_instance (ECalBackendFile *cbfile, ECalBackendFileObject *obj_data, const
        cbfile->priv->comp = g_list_prepend (cbfile->priv->comp, obj_data->full_object);
 }
 
-typedef struct {
-       ECalBackendFile *cbfile;
-       ECalBackendFileObject *obj_data;
-       const char *rid;
-       CalObjModType mod;
-} RemoveRecurrenceData;
-
-static gboolean
-remove_object_instance_cb (gpointer key, gpointer value, gpointer user_data)
-{
-       time_t fromtt, instancett;
-       GSList *categories;
-       char *rid = key;
-       ECalComponent *instance = value;
-       RemoveRecurrenceData *rrdata = user_data;
-
-       fromtt = icaltime_as_timet (icaltime_from_string (rrdata->rid));
-       instancett = icaltime_as_timet (get_rid_icaltime (instance));
-
-       if (fromtt > 0 && instancett > 0) {
-               if ((rrdata->mod == CALOBJ_MOD_THISANDPRIOR && instancett <= fromtt) ||
-                   (rrdata->mod == CALOBJ_MOD_THISANDFUTURE && instancett >= fromtt)) {
-                       /* remove the component from our data */
-                       icalcomponent_remove_component (rrdata->cbfile->priv->icalcomp,
-                                                       e_cal_component_get_icalcomponent (instance));
-                       rrdata->cbfile->priv->comp = g_list_remove (rrdata->cbfile->priv->comp, instance);
-
-                       rrdata->obj_data->recurrences_list = g_list_remove (rrdata->obj_data->recurrences_list, instance);
-
-                       /* update the set of categories */
-                       e_cal_component_get_categories_list (instance, &categories);
-                       e_cal_backend_unref_categories (E_CAL_BACKEND (rrdata->cbfile), categories);
-                       e_cal_component_free_categories_list (categories);
-
-                       /* free memory */
-                       g_free (rid);
-                       g_object_unref (instance);
-
-                       return TRUE;
-               }
-       }
-
-       return FALSE;
-}
-
 /* Remove_object handler for the file backend */
 static ECalBackendSyncStatus
 e_cal_backend_file_remove_object (ECalBackendSync *backend, EDataCal *cal,
                                  const char *uid, const char *rid,
-                                 CalObjModType mod, char **object)
+                                 CalObjModType mod, char **old_object,
+                                 char **object)
 {
        ECalBackendFile *cbfile;
        ECalBackendFilePrivate *priv;
        ECalBackendFileObject *obj_data;
        ECalComponent *comp;
-       GSList *categories;
        RemoveRecurrenceData rrdata;
 
        cbfile = E_CAL_BACKEND_FILE (backend);
@@ -1971,6 +2036,8 @@ e_cal_backend_file_remove_object (ECalBackendSync *backend, EDataCal *cal,
        g_return_val_if_fail (priv->icalcomp != NULL, GNOME_Evolution_Calendar_NoSuchCal);
        g_return_val_if_fail (uid != NULL, GNOME_Evolution_Calendar_ObjectNotFound);
 
+       *old_object = *object = NULL;
+
        obj_data = g_hash_table_lookup (priv->comp_uid_hash, uid);
        if (!obj_data)
                return GNOME_Evolution_Calendar_ObjectNotFound;
@@ -1979,10 +2046,19 @@ e_cal_backend_file_remove_object (ECalBackendSync *backend, EDataCal *cal,
 
        switch (mod) {
        case CALOBJ_MOD_ALL :
-               *object = e_cal_component_get_as_string (comp);
+               *old_object = e_cal_component_get_as_string (comp);
                remove_component (cbfile, comp);
+               *object = NULL;
                break;
        case CALOBJ_MOD_THIS :
+               *old_object = e_cal_component_get_as_string (comp);
+               if (!rid || !*rid) {
+                       remove_component (cbfile, comp);
+                       *object = NULL;
+               } else {
+                       remove_instance (cbfile, obj_data, rid);
+                       *object = e_cal_component_get_as_string (obj_data->full_object);
+               }
                *object = e_cal_component_get_as_string (comp);
                if (!rid || !*rid)
                        remove_component (cbfile, comp);
@@ -1994,7 +2070,7 @@ e_cal_backend_file_remove_object (ECalBackendSync *backend, EDataCal *cal,
                if (!rid || !*rid)
                        return GNOME_Evolution_Calendar_ObjectNotFound;
 
-               *object = e_cal_component_get_as_string (comp);
+               *old_object = e_cal_component_get_as_string (comp);
 
                /* remove the component from our data, temporarily */
                icalcomponent_remove_component (priv->icalcomp,
@@ -2015,6 +2091,8 @@ e_cal_backend_file_remove_object (ECalBackendSync *backend, EDataCal *cal,
                   so that it's always before any detached instance we
                   might have */
                priv->comp = g_list_prepend (priv->comp, comp);
+
+               *object = e_cal_component_get_as_string (obj_data->full_object);
                break;
        }
 
@@ -2199,11 +2277,19 @@ e_cal_backend_file_receive_objects (ECalBackendSync *backend, EDataCal *cal, con
                case ICAL_METHOD_CANCEL:
                        if (cancel_received_object (cbfile, subcomp)) {
                                object = (char *) icalcomponent_as_ical_string (subcomp);
-                               e_cal_backend_notify_object_removed (E_CAL_BACKEND (backend), uid, object);
+                               old_comp = lookup_component (cbfile, uid);
+                               if (old_comp)
+                                       old_object = e_cal_component_get_as_string (old_comp);
+                               else
+                                       old_object = NULL;
+
+                               e_cal_backend_notify_object_removed (E_CAL_BACKEND (backend), uid, old_object, object);
 
                                /* remove the component from the toplevel VCALENDAR */
                                icalcomponent_remove_component (toplevel_comp, subcomp);
                                icalcomponent_free (subcomp);
+
+                               g_free (old_object);
                        }
                        break;
                default:
index c402031..2867d18 100644 (file)
@@ -321,7 +321,7 @@ get_deltas (gpointer handle)
                                (vtype == E_CAL_COMPONENT_TODO)) {
                        comp_str = e_cal_component_get_as_string (comp);
                        e_cal_backend_notify_object_removed (E_CAL_BACKEND (cbgw), 
-                                                               (char *) l->data, comp_str);
+                                                            (char *) l->data, comp_str, NULL);
                        e_cal_backend_cache_remove_component (cache, (const char *) l->data, NULL);
                        g_free (comp_str);
                }
@@ -1413,7 +1413,8 @@ e_cal_backend_groupwise_modify_object (ECalBackendSync *backend, EDataCal *cal,
 static ECalBackendSyncStatus
 e_cal_backend_groupwise_remove_object (ECalBackendSync *backend, EDataCal *cal,
                                       const char *uid, const char *rid,
-                                      CalObjModType mod, char **object)
+                                      CalObjModType mod, char **old_object,
+                                      char **object)
 {
        ECalBackendGroupwise *cbgw;
         ECalBackendGroupwisePrivate *priv;
@@ -1422,6 +1423,8 @@ e_cal_backend_groupwise_remove_object (ECalBackendSync *backend, EDataCal *cal,
        cbgw = E_CAL_BACKEND_GROUPWISE (backend);
        priv = cbgw->priv;
 
+       *old_object = *object = NULL;
+
        /* if online, remove the item from the server */
        if (priv->mode == CAL_MODE_REMOTE) {
                ECalBackendSyncStatus status;
@@ -1433,6 +1436,8 @@ e_cal_backend_groupwise_remove_object (ECalBackendSync *backend, EDataCal *cal,
                if (status != GNOME_Evolution_Calendar_Success)
                        return status;
 
+               *old_object = calobj;
+
                icalcomp = icalparser_parse_string (calobj);
                if (!icalcomp) {
                        g_free (calobj);
@@ -1517,7 +1522,8 @@ receive_object (ECalBackendGroupwise *cbgw, EDataCal *cal, icalcomponent *icalco
                        
                        e_cal_component_get_uid (comp, (const char **) &uid);
                        e_cal_backend_cache_remove_component (priv->cache, uid, NULL);
-                       e_cal_backend_notify_object_removed (E_CAL_BACKEND (cbgw), uid, e_cal_component_get_as_string (comp));
+                       e_cal_backend_notify_object_removed (E_CAL_BACKEND (cbgw), uid, e_cal_component_get_as_string (comp), NULL);
+                       g_free (comp);
                }
                else {
                        char *cache_comp = NULL, *temp, *new_comp = NULL;
index ec7580d..9b9d9ed 100644 (file)
@@ -200,7 +200,7 @@ notify_and_remove_from_cache (gpointer key, gpointer value, gpointer user_data)
        const char *calobj = value;
        ECalBackendHttp *cbhttp = E_CAL_BACKEND_HTTP (user_data);
 
-       e_cal_backend_notify_object_removed (E_CAL_BACKEND (cbhttp), uid, calobj);
+       e_cal_backend_notify_object_removed (E_CAL_BACKEND (cbhttp), uid, calobj, NULL);
 
        return TRUE;
 }
@@ -788,7 +788,8 @@ e_cal_backend_http_modify_object (ECalBackendSync *backend, EDataCal *cal, const
 static ECalBackendSyncStatus
 e_cal_backend_http_remove_object (ECalBackendSync *backend, EDataCal *cal,
                                const char *uid, const char *rid,
-                               CalObjModType mod, char **object)
+                               CalObjModType mod, char **old_object,
+                               char **object)
 {
        ECalBackendHttp *cbhttp;
        ECalBackendHttpPrivate *priv;
@@ -798,6 +799,8 @@ e_cal_backend_http_remove_object (ECalBackendSync *backend, EDataCal *cal,
 
        g_return_val_if_fail (uid != NULL, GNOME_Evolution_Calendar_ObjectNotFound);
 
+       *old_object = *object = NULL;
+
        return GNOME_Evolution_Calendar_PermissionDenied;
 }
 
index c3893a3..6ead1e5 100644 (file)
@@ -1507,14 +1507,18 @@ open_calendar (ECal *ecal, gboolean only_if_exists, GError **error, ECalendarSta
                priv->load_state = E_CAL_LOAD_AUTHENTICATING;
 
                if (priv->auth_func == NULL) {
+                       e_calendar_remove_op (ecal, our_op);
                        g_mutex_unlock (our_op->mutex);
+                       e_calendar_free_op (our_op);
                        *status = E_CALENDAR_STATUS_AUTHENTICATION_REQUIRED;
                        E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_AUTHENTICATION_REQUIRED, error);
                }
 
                username = e_source_get_property (priv->source, "username");
                if (!username) {
+                       e_calendar_remove_op (ecal, our_op);
                        g_mutex_unlock (our_op->mutex);
+                       e_calendar_free_op (our_op);
                        *status = E_CALENDAR_STATUS_AUTHENTICATION_REQUIRED;
                        E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_AUTHENTICATION_REQUIRED, error);
                }
@@ -1526,7 +1530,9 @@ open_calendar (ECal *ecal, gboolean only_if_exists, GError **error, ECalendarSta
 
                password = priv->auth_func (ecal, prompt, key, priv->auth_user_data);
                if (!password) {
+                       e_calendar_remove_op (ecal, our_op);
                        g_mutex_unlock (our_op->mutex);
+                       e_calendar_free_op (our_op);
                        *status = E_CALENDAR_STATUS_AUTHENTICATION_REQUIRED; 
                        E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_AUTHENTICATION_REQUIRED, error);
                }
@@ -2903,7 +2909,7 @@ add_instance (ECalComponent *comp, time_t start, time_t end, gpointer data)
 {
        GList **list;
        struct comp_instance *ci;
-       struct icaltimetype itt_start;
+       struct icaltimetype itt, itt_start;
        icalcomponent *icalcomp;
 
        list = data;
@@ -2913,7 +2919,6 @@ add_instance (ECalComponent *comp, time_t start, time_t end, gpointer data)
        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))) {
@@ -2921,12 +2926,10 @@ add_instance (ECalComponent *comp, time_t start, time_t end, gpointer data)
                        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;
index eca725c..1b13800 100644 (file)
@@ -128,13 +128,14 @@ e_cal_backend_sync_modify_object (ECalBackendSync *backend, EDataCal *cal, const
 
 ECalBackendSyncStatus
 e_cal_backend_sync_remove_object (ECalBackendSync *backend, EDataCal *cal, const char *uid, const char *rid,
-                                 CalObjModType mod, char **object)
+                                 CalObjModType mod, char **old_object, char **object)
 {
        g_return_val_if_fail (backend && E_IS_CAL_BACKEND_SYNC (backend), GNOME_Evolution_Calendar_OtherError);
        g_return_val_if_fail (E_CAL_BACKEND_SYNC_GET_CLASS (backend)->remove_object_sync != NULL,
                              GNOME_Evolution_Calendar_UnsupportedMethod);
 
-       return (* E_CAL_BACKEND_SYNC_GET_CLASS (backend)->remove_object_sync) (backend, cal, uid, rid, mod, object);
+       return (* E_CAL_BACKEND_SYNC_GET_CLASS (backend)->remove_object_sync) (backend, cal, uid, rid, mod,
+                                                                              old_object, object);
 }
 
 ECalBackendSyncStatus
@@ -375,21 +376,21 @@ static void
 _e_cal_backend_remove_object (ECalBackend *backend, EDataCal *cal, const char *uid, const char *rid, CalObjModType mod)
 {
        ECalBackendSyncStatus status;
-       char *object = NULL;
+       char *object = NULL, *old_object = NULL;
        
-       status = e_cal_backend_sync_remove_object (E_CAL_BACKEND_SYNC (backend), cal, uid, rid, mod, &object);
+       status = e_cal_backend_sync_remove_object (E_CAL_BACKEND_SYNC (backend), cal, uid, rid, mod, &old_object, &object);
 
        if (status == GNOME_Evolution_Calendar_Success) {
                char *calobj = NULL;
 
                if (e_cal_backend_sync_get_object (E_CAL_BACKEND_SYNC (backend), cal, uid, NULL, &calobj)
                    == GNOME_Evolution_Calendar_Success) {
-                       e_data_cal_notify_object_modified (cal, status, object, calobj);
+                       e_data_cal_notify_object_modified (cal, status, old_object, calobj);
                        g_free (calobj);
                } else
-                       e_data_cal_notify_object_removed (cal, status, uid, object);
+                       e_data_cal_notify_object_removed (cal, status, uid, old_object, object);
        } else
-               e_data_cal_notify_object_removed (cal, status, uid, object);
+               e_data_cal_notify_object_removed (cal, status, uid, old_object, object);
 
        g_free (object);
 }
index 57e7503..c5547f6 100644 (file)
@@ -44,7 +44,7 @@ struct _ECalBackendSyncClass {
 
        ECalBackendSyncStatus (*create_object_sync)  (ECalBackendSync *backend, EDataCal *cal, char **calobj, char **uid);
        ECalBackendSyncStatus (*modify_object_sync)  (ECalBackendSync *backend, EDataCal *cal, const char *calobj, CalObjModType mod, char **old_object);
-       ECalBackendSyncStatus (*remove_object_sync)  (ECalBackendSync *backend, EDataCal *cal, const char *uid, const char *rid, CalObjModType mod, char **object);
+       ECalBackendSyncStatus (*remove_object_sync)  (ECalBackendSync *backend, EDataCal *cal, const char *uid, const char *rid, CalObjModType mod, char **old_object, char **object);
 
        ECalBackendSyncStatus (*discard_alarm_sync)  (ECalBackendSync *backend, EDataCal *cal, const char *uid, const char *auid);
 
@@ -110,6 +110,7 @@ ECalBackendSyncStatus e_cal_backend_sync_remove_object           (ECalBackendSyn
                                                               const char      *uid,
                                                               const char      *rid,
                                                               CalObjModType    mod,
+                                                              char **old_object,
                                                               char **object);
 ECalBackendSyncStatus e_cal_backend_sync_discard_alarm (ECalBackendSync *backend, EDataCal *cal, const char *uid, const char *auid);
 
index 4b4300d..faa75ed 100644 (file)
@@ -824,7 +824,7 @@ e_cal_backend_modify_object (ECalBackend *backend, EDataCal *cal, const char *ca
        if (CLASS (backend)->modify_object)
                (* CLASS (backend)->modify_object) (backend, cal, calobj, mod);
        else
-               e_data_cal_notify_object_removed (cal, GNOME_Evolution_Calendar_PermissionDenied, NULL, NULL);
+               e_data_cal_notify_object_removed (cal, GNOME_Evolution_Calendar_PermissionDenied, NULL, NULL, NULL);
 }
 
 /**
@@ -1006,6 +1006,28 @@ e_cal_backend_notify_object_created (ECalBackend *backend, const char *calobj)
        g_object_unref (iter);
 }
 
+static void
+match_query_and_notify (EDataCalView *query, const char *old_object, const char *object)
+{
+       gboolean old_match, new_match;
+
+       old_match = e_data_cal_view_object_matches (query, old_object);
+       new_match = e_data_cal_view_object_matches (query, object);
+       if (old_match && new_match)
+               e_data_cal_view_notify_objects_modified_1 (query, object);
+       else if (new_match)
+               e_data_cal_view_notify_objects_added_1 (query, object);
+       else if (old_match) {
+               icalcomponent *icalcomp;
+       
+               icalcomp = icalcomponent_new_from_string ((char *) old_object);
+               if (icalcomp) {
+                       e_data_cal_view_notify_objects_removed_1 (query, icalcomponent_get_uid (icalcomp));
+                       icalcomponent_free (icalcomp);
+               }
+       }
+}
+
 /**
  * e_cal_backend_notify_object_modified:
  * @backend: A calendar backend.
@@ -1020,13 +1042,12 @@ e_cal_backend_notify_object_created (ECalBackend *backend, const char *calobj)
  **/
 void
 e_cal_backend_notify_object_modified (ECalBackend *backend, 
-                                   const char *old_object, const char *object)
+                                     const char *old_object, const char *object)
 {
        ECalBackendPrivate *priv;
        EList *queries;
        EIterator *iter;
        EDataCalView *query;
-       gboolean old_match, new_match;
 
        priv = backend->priv;
 
@@ -1040,23 +1061,9 @@ e_cal_backend_notify_object_modified (ECalBackend *backend,
 
        while (e_iterator_is_valid (iter)) {
                query = QUERY (e_iterator_get (iter));
-               
-               bonobo_object_ref (query);
-
-               old_match = e_data_cal_view_object_matches (query, old_object);
-               new_match = e_data_cal_view_object_matches (query, object);
-               if (old_match && new_match)
-                       e_data_cal_view_notify_objects_modified_1 (query, object);
-               else if (new_match)
-                       e_data_cal_view_notify_objects_added_1 (query, object);
-               else if (old_match) {
-                       icalcomponent *comp;
-
-                       comp = icalcomponent_new_from_string ((char *)old_object);
-                       e_data_cal_view_notify_objects_removed_1 (query, icalcomponent_get_uid (comp));
-                       icalcomponent_free (comp);
-               }
 
+               bonobo_object_ref (query);
+               match_query_and_notify (query, old_object, object);
                bonobo_object_unref (query);
 
                e_iterator_next (iter);
@@ -1069,6 +1076,9 @@ e_cal_backend_notify_object_modified (ECalBackend *backend,
  * @backend: A calendar backend.
  * @uid: the UID of the removed object
  * @old_object: iCalendar representation of the removed object
+ * @new_object: iCalendar representation of the object after the removal. This
+ * only applies to recurrent appointments that had an instance removed. In that
+ * case, this function notifies a modification instead of a removal.
  *
  * Notifies each of the backend's listeners about a removed object.
  *
@@ -1078,7 +1088,7 @@ e_cal_backend_notify_object_modified (ECalBackend *backend,
  **/
 void
 e_cal_backend_notify_object_removed (ECalBackend *backend, const char *uid,
-                                    const char *old_object)
+                                    const char *old_object, const char *object)
 {
        ECalBackendPrivate *priv;
        EList *queries;
@@ -1088,7 +1098,7 @@ e_cal_backend_notify_object_removed (ECalBackend *backend, const char *uid,
        priv = backend->priv;
 
        if (priv->notification_proxy) {
-               e_cal_backend_notify_object_removed (priv->notification_proxy, uid, old_object);
+               e_cal_backend_notify_object_removed (priv->notification_proxy, uid, old_object, object);
                return;
        }
 
@@ -1099,8 +1109,15 @@ e_cal_backend_notify_object_removed (ECalBackend *backend, const char *uid,
                query = QUERY (e_iterator_get (iter));
 
                bonobo_object_ref (query);
-               if (e_data_cal_view_object_matches (query, old_object))
-                       e_data_cal_view_notify_objects_removed_1 (query, uid);
+
+               if (object == NULL) {
+                       /* if object == NULL, it means the object has been completely
+                          removed from the backend */
+                       if (e_data_cal_view_object_matches (query, old_object))
+                               e_data_cal_view_notify_objects_removed_1 (query, uid);
+               } else
+                       match_query_and_notify (query, old_object, object);
+
                bonobo_object_unref (query);
 
                e_iterator_next (iter);
index 7b4880a..8ebafa9 100644 (file)
@@ -165,7 +165,7 @@ void e_cal_backend_last_client_gone (ECalBackend *backend);
 void e_cal_backend_set_notification_proxy (ECalBackend *backend, ECalBackend *proxy);
 void e_cal_backend_notify_object_created  (ECalBackend *backend, const char *calobj);
 void e_cal_backend_notify_object_modified (ECalBackend *backend, const char *old_object, const char *object);
-void e_cal_backend_notify_object_removed  (ECalBackend *backend, const char *uid, const char *old_object);
+void e_cal_backend_notify_object_removed  (ECalBackend *backend, const char *uid, const char *old_object, const char *object);
 
 void e_cal_backend_notify_mode      (ECalBackend *backend,
                                     GNOME_Evolution_Calendar_CalListener_SetModeStatus status, 
index 628e994..75b59f0 100644 (file)
@@ -851,7 +851,7 @@ e_data_cal_notify_object_modified (EDataCal *cal, GNOME_Evolution_Calendar_CallS
 
 void
 e_data_cal_notify_object_removed (EDataCal *cal, GNOME_Evolution_Calendar_CallStatus status, 
-                                 const char *uid, const char *object)
+                                 const char *uid, const char *old_object, const char *object)
 {
        EDataCalPrivate *priv;
        CORBA_Environment ev;
@@ -863,7 +863,7 @@ e_data_cal_notify_object_removed (EDataCal *cal, GNOME_Evolution_Calendar_CallSt
        g_return_if_fail (priv->listener != CORBA_OBJECT_NIL);
 
        if (status == GNOME_Evolution_Calendar_Success)
-               e_cal_backend_notify_object_removed (priv->backend, uid, object);
+               e_cal_backend_notify_object_removed (priv->backend, uid, old_object, object);
 
        CORBA_exception_init (&ev);
        GNOME_Evolution_Calendar_CalListener_notifyObjectRemoved (priv->listener, status, &ev);
index d3fb360..d0674cc 100644 (file)
@@ -83,7 +83,7 @@ void e_data_cal_notify_object_created  (EDataCal *cal, GNOME_Evolution_Calendar_
 void e_data_cal_notify_object_modified (EDataCal *cal, GNOME_Evolution_Calendar_CallStatus status, 
                                        const char *old_object, const char *object);
 void e_data_cal_notify_object_removed  (EDataCal *cal, GNOME_Evolution_Calendar_CallStatus status, 
-                                       const char *uid, const char *object);
+                                       const char *uid, const char *old_object, const char *object);
 void e_data_cal_notify_alarm_discarded (EDataCal *cal, GNOME_Evolution_Calendar_CallStatus status);
 
 void e_data_cal_notify_objects_received (EDataCal *cal, GNOME_Evolution_Calendar_CallStatus status);