diff options
| author | Tristan Van Berkom <tristan.van.berkom@gmail.com> | 2011-10-15 11:34:32 -0400 |
|---|---|---|
| committer | Tristan Van Berkom <tristan.van.berkom@gmail.com> | 2011-10-18 22:37:41 -0400 |
| commit | 466623351e070410d7cc1e0a3cfb485210d6015a (patch) | |
| tree | fafbb9dd2634f6b5e5be442365eaebcadbc514dd | |
| parent | 359ed29118c57f01231cf1103f0f9393dd4677a5 (diff) | |
| download | evolution-data-server-466623351e070410d7cc1e0a3cfb485210d6015a.tar.gz | |
Really implement e_cal_client_view_set_fields_of_interest().
As discussed on bug https://bugzilla.gnome.org/show_bug.cgi?id=652180,
this patch adds many '_component' variants to functions that are named
with '_object', all the '_component' variants take an 'icalcomponent *'
instead of an ical string.
The magic filtering happens in e_data_cal_view_get_component_string()
which creates an ical string representation while omitting properties
that are not mentioned in the fields of interest.
| -rw-r--r-- | calendar/backends/caldav/e-cal-backend-caldav.c | 167 | ||||
| -rw-r--r-- | calendar/backends/contacts/e-cal-backend-contacts.c | 11 | ||||
| -rw-r--r-- | calendar/backends/file/e-cal-backend-file.c | 302 | ||||
| -rw-r--r-- | calendar/backends/http/e-cal-backend-http.c | 46 | ||||
| -rw-r--r-- | calendar/libedata-cal/e-cal-backend-sync.c | 115 | ||||
| -rw-r--r-- | calendar/libedata-cal/e-cal-backend-sync.h | 12 | ||||
| -rw-r--r-- | calendar/libedata-cal/e-cal-backend.c | 294 | ||||
| -rw-r--r-- | calendar/libedata-cal/e-cal-backend.h | 6 | ||||
| -rw-r--r-- | calendar/libedata-cal/e-data-cal-view.c | 316 | ||||
| -rw-r--r-- | calendar/libedata-cal/e-data-cal-view.h | 8 | ||||
| -rw-r--r-- | calendar/libedata-cal/e-data-cal.c | 40 | ||||
| -rw-r--r-- | calendar/libedata-cal/e-data-cal.h | 6 |
12 files changed, 1015 insertions, 308 deletions
diff --git a/calendar/backends/caldav/e-cal-backend-caldav.c b/calendar/backends/caldav/e-cal-backend-caldav.c index facdd523a..c6b071c7f 100644 --- a/calendar/backends/caldav/e-cal-backend-caldav.c +++ b/calendar/backends/caldav/e-cal-backend-caldav.c @@ -3524,11 +3524,11 @@ replace_master (ECalBackendCalDAV *cbdav, /* a busy_lock is supposed to be locked already, when calling this function */ static void -do_create_object (ECalBackendCalDAV *cbdav, - const gchar *in_calobj, - gchar **uid, - gchar **new_calobj, - GError **perror) +do_create_object (ECalBackendCalDAV *cbdav, + const gchar *in_calobj, + gchar **uid, + icalcomponent **new_component, + GError **perror) { ECalComponent *comp; gboolean online, did_put = FALSE; @@ -3610,13 +3610,15 @@ do_create_object (ECalBackendCalDAV *cbdav, icalcomponent *master = get_master_comp (cbdav, icalcomp); if (!master) - *new_calobj = e_cal_component_get_as_string (comp); + *new_component = + icalcomponent_new_clone (e_cal_component_get_icalcomponent (comp)); else - *new_calobj = icalcomponent_as_ical_string_r (master); + *new_component = icalcomponent_new_clone (master); icalcomponent_free (icalcomp); } else { - *new_calobj = e_cal_component_get_as_string (comp); + *new_component = + icalcomponent_new_clone (e_cal_component_get_icalcomponent (comp)); } } @@ -3626,11 +3628,11 @@ do_create_object (ECalBackendCalDAV *cbdav, /* a busy_lock is supposed to be locked already, when calling this function */ static void do_modify_object (ECalBackendCalDAV *cbdav, - const gchar *calobj, - CalObjModType mod, - gchar **old_object, - gchar **new_object, - GError **error) + const gchar *calobj, + CalObjModType mod, + icalcomponent **old_component, + icalcomponent **new_component, + GError **error) { ECalBackendCalDAVPrivate *priv; ECalComponent *comp; @@ -3642,8 +3644,8 @@ do_modify_object (ECalBackendCalDAV *cbdav, priv = cbdav->priv; - if (new_object) - *new_object = NULL; + if (new_component) + *new_component = NULL; if (!check_state (cbdav, &online, error)) return; @@ -3689,26 +3691,28 @@ do_modify_object (ECalBackendCalDAV *cbdav, /*ecalcomp_set_synch_state (comp, ECALCOMP_LOCALLY_MODIFIED);*/ } - if (old_object) { - *old_object = NULL; + if (old_component) { + *old_component = NULL; if (e_cal_component_is_instance (comp)) { /* set detached instance as the old object, if any */ ECalComponent *old_instance = e_cal_backend_store_get_component (priv->store, id->uid, id->rid); + /* This will give a reference to 'old_component' */ if (old_instance) { - *old_object = e_cal_component_get_as_string (old_instance); + *old_component = + icalcomponent_new_clone (e_cal_component_get_icalcomponent + (old_instance)); g_object_unref (old_instance); } } - if (!*old_object) { + if (!*old_component) { icalcomponent *master = get_master_comp (cbdav, cache_comp); - if (master) { - /* set full component as the old object */ - *old_object = icalcomponent_as_ical_string_r (master); - } + if (master) + /* set full component as the old object */ + *old_component = icalcomponent_new_clone (master); } } @@ -3719,8 +3723,8 @@ do_modify_object (ECalBackendCalDAV *cbdav, icalcomponent *new_comp = e_cal_component_get_icalcomponent (comp); /* new object is only this instance */ - if (new_object) - *new_object = e_cal_component_get_as_string (comp); + if (new_component) + *new_component = icalcomponent_new_clone (new_comp); /* add the detached instance */ if (icalcomponent_isa (cache_comp) == ICAL_VCALENDAR_COMPONENT) { @@ -3774,7 +3778,7 @@ do_modify_object (ECalBackendCalDAV *cbdav, } if (did_put) { - if (new_object && !*new_object) { + if (new_component && !*new_component) { /* read the comp from cache again, as some servers can modify it on put */ icalcomponent *newcomp = get_comp_from_cache (cbdav, id->uid, NULL, NULL, NULL), *master; @@ -3784,7 +3788,7 @@ do_modify_object (ECalBackendCalDAV *cbdav, master = get_master_comp (cbdav, newcomp); if (master) - *new_object = icalcomponent_as_ical_string_r (master); + *new_component = icalcomponent_new_clone (master); if (cache_comp != newcomp) icalcomponent_free (newcomp); @@ -3801,12 +3805,12 @@ do_modify_object (ECalBackendCalDAV *cbdav, /* a busy_lock is supposed to be locked already, when calling this function */ static void do_remove_object (ECalBackendCalDAV *cbdav, - const gchar *uid, - const gchar *rid, - CalObjModType mod, - gchar **old_object, - gchar **object, - GError **perror) + const gchar *uid, + const gchar *rid, + CalObjModType mod, + icalcomponent **old_component, + icalcomponent **component, + GError **perror) { ECalBackendCalDAVPrivate *priv; icalcomponent *cache_comp; @@ -3815,8 +3819,8 @@ do_remove_object (ECalBackendCalDAV *cbdav, priv = cbdav->priv; - if (object) - *object = NULL; + if (component) + *component = NULL; if (!check_state (cbdav, &online, perror)) return; @@ -3828,17 +3832,18 @@ do_remove_object (ECalBackendCalDAV *cbdav, return; } - if (old_object) { + if (old_component) { ECalComponent *old = e_cal_backend_store_get_component (priv->store, uid, rid); if (old) { - *old_object = e_cal_component_get_as_string (old); + *old_component = + icalcomponent_new_clone (e_cal_component_get_icalcomponent (old)); g_object_unref (old); } else { icalcomponent *master = get_master_comp (cbdav, cache_comp); if (master) - *old_object = icalcomponent_as_ical_string_r (master); + *old_component = icalcomponent_new_clone (master); } } @@ -3848,11 +3853,11 @@ do_remove_object (ECalBackendCalDAV *cbdav, if (rid && *rid) { /* remove one instance from the component */ if (remove_instance (cbdav, cache_comp, icaltime_from_string (rid), mod, mod != CALOBJ_MOD_ONLY_THIS)) { - if (object) { + if (component) { icalcomponent *master = get_master_comp (cbdav, cache_comp); if (master) - *object = icalcomponent_as_ical_string_r (master); + *component = icalcomponent_new_clone (master); } } else { /* this was the last instance, thus delete whole component */ @@ -4012,60 +4017,69 @@ process_object (ECalBackendCalDAV *cbdav, is_declined = e_cal_backend_user_declined (e_cal_component_get_icalcomponent (ecomp)); if (is_in_cache) { if (!is_declined) { - gchar *new_object = NULL, *old_object = NULL; + icalcomponent *new_component = NULL, *old_component = NULL; - do_modify_object (cbdav, new_obj_str, mod, &old_object, &new_object, &err); + do_modify_object (cbdav, new_obj_str, mod, + &old_component, &new_component, &err); if (!err) { - if (!old_object) - e_cal_backend_notify_object_created (backend, new_object); + if (!old_component) + e_cal_backend_notify_component_created (backend, new_component); else - e_cal_backend_notify_object_modified (backend, old_object, new_object); + e_cal_backend_notify_component_modified (backend, old_component, new_component); } - g_free (new_object); - g_free (old_object); + if (new_component) + icalcomponent_free (new_component); + if (old_component) + icalcomponent_free (old_component); } else { - gchar *new_object = NULL, *old_object = NULL; + icalcomponent *new_component = NULL, *old_component = NULL; - do_remove_object (cbdav, id->uid, id->rid, mod, &old_object, &new_object, &err); + do_remove_object (cbdav, id->uid, id->rid, mod, &old_component, &new_component, &err); if (!err) { - if (new_object) { - e_cal_backend_notify_object_modified (backend, old_object, new_object); + if (new_component) { + e_cal_backend_notify_component_modified (backend, old_component, new_component); } else { - e_cal_backend_notify_object_removed (backend, id, old_object, NULL); + e_cal_backend_notify_component_removed (backend, id, old_component, NULL); } } - g_free (new_object); - g_free (old_object); + if (new_component) + icalcomponent_free (new_component); + if (old_component) + icalcomponent_free (old_component); } } else if (!is_declined) { - gchar *new_object = new_obj_str; + icalcomponent *new_component = NULL; + + do_create_object (cbdav, new_obj_str, NULL, &new_component, &err); - do_create_object (cbdav, new_object, NULL, &new_object, &err); if (!err) { - e_cal_backend_notify_object_created (backend, new_object); + e_cal_backend_notify_component_created (backend, new_component); } - if (new_object != new_obj_str) - g_free (new_object); + if (new_component) + icalcomponent_free (new_component); + } break; case ICAL_METHOD_CANCEL: if (is_in_cache) { - gchar *old_object = NULL, *new_object = NULL; + icalcomponent *new_component = NULL, *old_component = NULL; - do_remove_object (cbdav, id->uid, id->rid, CALOBJ_MOD_THIS, &old_object, &new_object, &err); + do_remove_object (cbdav, id->uid, id->rid, CALOBJ_MOD_THIS, &old_component, &new_component, &err); if (!err) { - if (new_object) { - e_cal_backend_notify_object_modified (backend, old_object, new_object); + if (new_component) { + e_cal_backend_notify_component_modified (backend, old_component, new_component); } else { - e_cal_backend_notify_object_removed (backend, id, old_object, NULL); + e_cal_backend_notify_component_removed (backend, id, old_component, NULL); } } - g_free (old_object); - g_free (new_object); + if (new_component) + icalcomponent_free (new_component); + if (old_component) + icalcomponent_free (old_component); } else { err = EDC_ERROR (ObjectNotFound); } @@ -4142,7 +4156,6 @@ do_receive_objects (ECalBackendSync *backend, } process_object (cbdav, ecomp, online, method, &err); - g_object_unref (ecomp); } @@ -4193,13 +4206,13 @@ caldav_busy_stub ( GCancellable *cancellable, const gchar *in_calobj, gchar **uid, - gchar **new_calobj, + icalcomponent **new_component, GError **perror), do_create_object, (cbdav, in_calobj, uid, - new_calobj, + new_component, perror)) caldav_busy_stub ( @@ -4209,15 +4222,15 @@ caldav_busy_stub ( GCancellable *cancellable, const gchar *calobj, CalObjModType mod, - gchar **old_object, - gchar **new_object, + icalcomponent **old_component, + icalcomponent **new_component, GError **perror), do_modify_object, (cbdav, calobj, mod, - old_object, - new_object, + old_component, + new_component, perror)) caldav_busy_stub ( @@ -4228,16 +4241,16 @@ caldav_busy_stub ( const gchar *uid, const gchar *rid, CalObjModType mod, - gchar **old_object, - gchar **object, + icalcomponent **old_component, + icalcomponent **component, GError **perror), do_remove_object, (cbdav, uid, rid, mod, - old_object, - object, + old_component, + component, perror)) caldav_busy_stub ( diff --git a/calendar/backends/contacts/e-cal-backend-contacts.c b/calendar/backends/contacts/e-cal-backend-contacts.c index 81b09e896..fd86ad655 100644 --- a/calendar/backends/contacts/e-cal-backend-contacts.c +++ b/calendar/backends/contacts/e-cal-backend-contacts.c @@ -1260,12 +1260,11 @@ e_cal_backend_contacts_init (ECalBackendContacts *cbc) static void e_cal_backend_contacts_create_object (ECalBackendSync *backend, - EDataCal *cal, - GCancellable *cancellable, - const gchar *calobj, - gchar **uid, - gchar **new_calobj, - GError **perror) + EDataCal *cal, + GCancellable *cancellable, + const gchar *calobj, gchar **uid, + icalcomponent **new_component, + GError **perror) { g_propagate_error (perror, EDC_ERROR (PermissionDenied)); } diff --git a/calendar/backends/file/e-cal-backend-file.c b/calendar/backends/file/e-cal-backend-file.c index 0c5954209..ba1fcf074 100644 --- a/calendar/backends/file/e-cal-backend-file.c +++ b/calendar/backends/file/e-cal-backend-file.c @@ -128,6 +128,7 @@ static void free_refresh_data (ECalBackendFile *cbfile); static icaltimezone * e_cal_backend_file_internal_get_timezone (ECalBackend *backend, const gchar *tzid); + /* g_hash_table_foreach() callback to destroy a ECalBackendFileObject */ static void free_object_data (gpointer data) @@ -1097,18 +1098,16 @@ notify_adds_modifies_cb (gpointer key, if (!new_icomp) return; - new_obj_str = icalcomponent_as_ical_string_r (new_icomp); - if (!new_obj_str) - return; - - e_cal_backend_notify_object_created (context->backend, new_obj_str); - g_free (new_obj_str); + e_cal_backend_notify_component_created (context->backend, new_icomp); } else { old_icomp = e_cal_component_get_icalcomponent (old_obj_data->full_object); new_icomp = e_cal_component_get_icalcomponent (new_obj_data->full_object); if (!old_icomp || !new_icomp) return; + /* There should be better ways to compare an icalcomponent + * than serializing and comparing the strings... + */ old_obj_str = icalcomponent_as_ical_string_r (old_icomp); new_obj_str = icalcomponent_as_ical_string_r (new_icomp); if (!old_obj_str || !new_obj_str) @@ -1116,8 +1115,7 @@ notify_adds_modifies_cb (gpointer key, if (strcmp (old_obj_str, new_obj_str)) { /* Object was modified */ - - e_cal_backend_notify_object_modified (context->backend, old_obj_str, new_obj_str); + e_cal_backend_notify_component_modified (context->backend, old_icomp, new_icomp); } g_free (old_obj_str); g_free (new_obj_str); @@ -1590,8 +1588,24 @@ typedef struct { const gchar *query; ECalBackendSExp *obj_sexp; ECalBackend *backend; + EDataCalView *view; } MatchObjectData; + +static GSList * +prepend_component (GSList *list, MatchObjectData *match_data, icalcomponent *icalcomp) +{ + gchar *str; + + if (match_data->view) + str = e_data_cal_view_get_component_string (match_data->view, icalcomp); + else + str = icalcomponent_as_ical_string_r (icalcomp); + + return g_slist_prepend (list, str); +} + + static void match_object_sexp_to_component (gpointer value, gpointer data) @@ -1601,6 +1615,8 @@ match_object_sexp_to_component (gpointer value, const gchar *uid; ECalBackendFile *cbfile; ECalBackendFilePrivate *priv; + icalcomponent *icalcomp; + e_cal_component_get_uid (comp, &uid); g_return_if_fail (comp != NULL); @@ -1613,9 +1629,11 @@ match_object_sexp_to_component (gpointer value, g_return_if_fail (priv != NULL); + icalcomp = e_cal_component_get_icalcomponent (comp); + if ((!match_data->search_needed) || (e_cal_backend_sexp_match_comp (match_data->obj_sexp, comp, match_data->backend))) { - match_data->obj_list = g_slist_append (match_data->obj_list, e_cal_component_get_as_string (comp)); + match_data->obj_list = prepend_component (match_data->obj_list, match_data, icalcomp); } } @@ -1625,11 +1643,14 @@ match_recurrence_sexp (gpointer key, gpointer data) { ECalComponent *comp = value; + icalcomponent *icalcomp; MatchObjectData *match_data = data; + icalcomp = e_cal_component_get_icalcomponent (comp); + if ((!match_data->search_needed) || (e_cal_backend_sexp_match_comp (match_data->obj_sexp, comp, match_data->backend))) { - match_data->obj_list = g_slist_append (match_data->obj_list, e_cal_component_get_as_string (comp)); + match_data->obj_list = prepend_component (match_data->obj_list, match_data, icalcomp); } } @@ -1643,8 +1664,13 @@ match_object_sexp (gpointer key, if (obj_data->full_object) { if ((!match_data->search_needed) || - (e_cal_backend_sexp_match_comp (match_data->obj_sexp, obj_data->full_object, match_data->backend))) { - match_data->obj_list = g_slist_append (match_data->obj_list, e_cal_component_get_as_string (obj_data->full_object)); + (e_cal_backend_sexp_match_comp (match_data->obj_sexp, + obj_data->full_object, + match_data->backend))) { + icalcomponent *icalcomp = + e_cal_component_get_icalcomponent (obj_data->full_object); + + match_data->obj_list = prepend_component (match_data->obj_list, match_data, icalcomp); } } @@ -1665,7 +1691,7 @@ e_cal_backend_file_get_object_list (ECalBackendSync *backend, { ECalBackendFile *cbfile; ECalBackendFilePrivate *priv; - MatchObjectData match_data; + MatchObjectData match_data = { 0, }; time_t occur_start = -1, occur_end = -1; gboolean prunning_by_time; GList * objs_occuring_in_tw; @@ -1709,7 +1735,7 @@ e_cal_backend_file_get_object_list (ECalBackendSync *backend, g_static_rec_mutex_unlock (&priv->idle_save_rmutex); - *objects = match_data.obj_list; + *objects = g_slist_reverse (match_data.obj_list); if (objs_occuring_in_tw) { g_list_foreach (objs_occuring_in_tw, (GFunc) g_object_unref, NULL); @@ -1850,7 +1876,7 @@ e_cal_backend_file_start_view (ECalBackend *backend, { ECalBackendFile *cbfile; ECalBackendFilePrivate *priv; - MatchObjectData match_data; + MatchObjectData match_data = { 0, }; time_t occur_start = -1, occur_end = -1; gboolean prunning_by_time; GList * objs_occuring_in_tw; @@ -1865,6 +1891,7 @@ e_cal_backend_file_start_view (ECalBackend *backend, match_data.obj_list = NULL; match_data.backend = backend; match_data.obj_sexp = e_data_cal_view_get_object_sexp (query); + match_data.view = query; if (!strcmp (match_data.query, "#t")) match_data.search_needed = FALSE; @@ -1908,6 +1935,8 @@ e_cal_backend_file_start_view (ECalBackend *backend, /* notify listeners of all objects */ if (match_data.obj_list) { + match_data.obj_list = g_slist_reverse (match_data.obj_list); + e_data_cal_view_notify_objects_added (query, match_data.obj_list); /* free memory */ @@ -2169,7 +2198,7 @@ e_cal_backend_file_create_object (ECalBackendSync *backend, GCancellable *cancellable, const gchar *in_calobj, gchar **uid, - gchar **new_object, + icalcomponent **new_component, GError **error) { ECalBackendFile *cbfile; @@ -2184,7 +2213,7 @@ e_cal_backend_file_create_object (ECalBackendSync *backend, e_return_data_cal_error_if_fail (priv->icalcomp != NULL, NoSuchCal); e_return_data_cal_error_if_fail (in_calobj != NULL, ObjectNotFound); - e_return_data_cal_error_if_fail (new_object != NULL, ObjectNotFound); + e_return_data_cal_error_if_fail (new_component != NULL, ObjectNotFound); /* Parse the icalendar text */ icalcomp = icalparser_parse_string (in_calobj); @@ -2250,7 +2279,8 @@ e_cal_backend_file_create_object (ECalBackendSync *backend, /* Return the UID and the modified component */ if (uid) *uid = g_strdup (comp_uid); - *new_object = e_cal_component_get_as_string (comp); + + *new_component = icalcomponent_new_clone (icalcomp); g_static_rec_mutex_unlock (&priv->idle_save_rmutex); } @@ -2297,8 +2327,8 @@ e_cal_backend_file_modify_object (ECalBackendSync *backend, GCancellable *cancellable, const gchar *calobj, CalObjModType mod, - gchar **old_object, - gchar **new_object, + icalcomponent **old_component, + icalcomponent **new_component, GError **error) { RemoveRecurrenceData rrdata; @@ -2372,8 +2402,11 @@ e_cal_backend_file_modify_object (ECalBackendSync *backend, switch (mod) { case CALOBJ_MOD_THIS : if (!rid || !*rid) { - if (old_object && obj_data->full_object) - *old_object = e_cal_component_get_as_string (obj_data->full_object); + if (old_component && obj_data->full_object) { + icalcomponent *old_icalcomp = + e_cal_component_get_icalcomponent (obj_data->full_object); + *old_component = icalcomponent_new_clone (old_icalcomp); + } /* replace only the full object */ if (obj_data->full_object) { @@ -2393,8 +2426,11 @@ e_cal_backend_file_modify_object (ECalBackendSync *backend, save (cbfile); - if (new_object) - *new_object = e_cal_component_get_as_string (comp); + if (new_component) { + icalcomponent *new_icalcomp = + e_cal_component_get_icalcomponent (comp); + *new_component = icalcomponent_new_clone (new_icalcomp); + } g_static_rec_mutex_unlock (&priv->idle_save_rmutex); g_free (rid); @@ -2402,8 +2438,11 @@ e_cal_backend_file_modify_object (ECalBackendSync *backend, } if (g_hash_table_lookup_extended (obj_data->recurrences, rid, (gpointer *) &real_rid, (gpointer *) &recurrence)) { - if (old_object) - *old_object = e_cal_component_get_as_string (recurrence); + if (old_component) { + icalcomponent *old_icalcomp = + e_cal_component_get_icalcomponent (recurrence); + *old_component = icalcomponent_new_clone (old_icalcomp); + } /* remove the component from our data */ icalcomponent_remove_component (priv->icalcomp, @@ -2426,8 +2465,12 @@ e_cal_backend_file_modify_object (ECalBackendSync *backend, case CALOBJ_MOD_THISANDPRIOR : case CALOBJ_MOD_THISANDFUTURE : if (!rid || !*rid) { - if (old_object && obj_data->full_object) - *old_object = e_cal_component_get_as_string (obj_data->full_object); + + if (old_component && obj_data->full_object) { + icalcomponent *old_icalcomp = + e_cal_component_get_icalcomponent (obj_data->full_object); + *old_component = icalcomponent_new_clone (old_icalcomp); + } remove_component (cbfile, comp_uid, obj_data); @@ -2448,8 +2491,12 @@ e_cal_backend_file_modify_object (ECalBackendSync *backend, /* now deal with the detached recurrence */ if (g_hash_table_lookup_extended (obj_data->recurrences, rid, (gpointer *) &real_rid, (gpointer *) &recurrence)) { - if (old_object) - *old_object = e_cal_component_get_as_string (recurrence); + + if (old_component) { + icalcomponent *old_icalcomp = + e_cal_component_get_icalcomponent (recurrence); + *old_component = icalcomponent_new_clone (old_icalcomp); + } /* remove the component from our data */ icalcomponent_remove_component (priv->icalcomp, @@ -2458,8 +2505,12 @@ e_cal_backend_file_modify_object (ECalBackendSync *backend, obj_data->recurrences_list = g_list_remove (obj_data->recurrences_list, recurrence); g_hash_table_remove (obj_data->recurrences, rid); } else { - if (old_object && obj_data->full_object) - *old_object = e_cal_component_get_as_string (obj_data->full_object); + + if (old_component && obj_data->full_object) { + icalcomponent *old_icalcomp = + e_cal_component_get_icalcomponent (obj_data->full_object); + *old_component = icalcomponent_new_clone (old_icalcomp); + } } rrdata.cbfile = cbfile; @@ -2489,8 +2540,11 @@ e_cal_backend_file_modify_object (ECalBackendSync *backend, break; case CALOBJ_MOD_ALL : /* Remove the old version */ - if (old_object && obj_data->full_object) - *old_object = e_cal_component_get_as_string (obj_data->full_object); + if (old_component && obj_data->full_object) { + icalcomponent *old_icalcomp = + e_cal_component_get_icalcomponent (obj_data->full_object); + *old_component = icalcomponent_new_clone (old_icalcomp); + } if (obj_data->recurrences_list) { /* has detached components, preserve them */ @@ -2534,8 +2588,11 @@ e_cal_backend_file_modify_object (ECalBackendSync *backend, save (cbfile); g_free (rid); - if (new_object) - *new_object = e_cal_component_get_as_string (comp); + if (new_component) { + icalcomponent *new_icalcomp = + e_cal_component_get_icalcomponent (comp); + *new_component = icalcomponent_new_clone (new_icalcomp); + } g_static_rec_mutex_unlock (&priv->idle_save_rmutex); } @@ -2560,8 +2617,8 @@ remove_instance (ECalBackendFile *cbfile, const gchar *uid, const gchar *rid, CalObjModType mod, - gchar **old_object, - gchar **object, + icalcomponent **old_component, + icalcomponent **component, GError **error) { gchar *hash_rid; @@ -2578,9 +2635,13 @@ remove_instance (ECalBackendFile *cbfile, (gpointer *) &hash_rid, (gpointer *) &comp)) { /* Removing without parent or not modifying parent? * Report removal to caller. */ - if (old_object && - (!obj_data->full_object || mod == CALOBJ_MOD_ONLY_THIS)) - *old_object = e_cal_component_get_as_string (comp); + if (old_component && + (!obj_data->full_object || mod == CALOBJ_MOD_ONLY_THIS)) { + icalcomponent *icalcomp = + e_cal_component_get_icalcomponent (comp); + + *old_component = icalcomponent_new_clone (icalcomp); + } /* Reporting parent modification to caller? * Report directly instead of going via caller. */ @@ -2629,8 +2690,13 @@ remove_instance (ECalBackendFile *cbfile, cbfile->priv->comp = g_list_remove (cbfile->priv->comp, obj_data->full_object); /* add EXDATE or EXRULE to parent, report as update */ - if (old_object) - *old_object = e_cal_component_get_as_string (obj_data->full_object); + if (old_component) { + icalcomponent *icalcomp = + e_cal_component_get_icalcomponent (obj_data->full_object); + + *old_component = icalcomponent_new_clone (icalcomp); + } + e_cal_util_remove_instances (e_cal_component_get_icalcomponent (obj_data->full_object), icaltime_from_string (rid), CALOBJ_MOD_THIS); @@ -2640,8 +2706,12 @@ remove_instance (ECalBackendFile *cbfile, e_cal_component_set_last_modified (obj_data->full_object, ¤t); /* report update */ - if (object) - *object = e_cal_component_get_as_string (obj_data->full_object); + if (component) { + icalcomponent *icalcomp = + e_cal_component_get_icalcomponent (obj_data->full_object); + + *component = icalcomponent_new_clone (icalcomp); + } /* add the modified object to the beginning of the list, * so that it's always before any detached instance we @@ -2670,8 +2740,12 @@ remove_instance (ECalBackendFile *cbfile, cbfile->priv->comp = g_list_remove (cbfile->priv->comp, obj_data->full_object); /* remove parent, report as removal */ - if (old_object) - *old_object = e_cal_component_get_as_string (obj_data->full_object); + if (old_component) { + icalcomponent *icalcomp = + e_cal_component_get_icalcomponent (obj_data->full_object); + + *old_component = icalcomponent_new_clone (icalcomp); + } g_object_unref (obj_data->full_object); obj_data->full_object = NULL; @@ -2686,29 +2760,30 @@ remove_instance (ECalBackendFile *cbfile, return obj_data; } -static gchar * -get_object_string_from_fileobject (ECalBackendFileObject *obj_data, - const gchar *rid) +static icalcomponent * +clone_icalcomp_from_fileobject (ECalBackendFileObject *obj_data, const gchar *rid) { ECalComponent *comp = obj_data->full_object; - gchar *real_rid; + icalcomponent *icalcomp = NULL; + gchar *real_rid; if (!comp) return NULL; if (!rid) { - return e_cal_component_get_as_string (comp); + icalcomp = e_cal_component_get_icalcomponent (comp); } else { - if (g_hash_table_lookup_extended (obj_data->recurrences, rid, (gpointer *) &real_rid, (gpointer *) &comp)) - return e_cal_component_get_as_string (comp); + if (g_hash_table_lookup_extended (obj_data->recurrences, rid, + (gpointer *) &real_rid, (gpointer *) &comp)) + icalcomp = e_cal_component_get_icalcomponent (comp); else { /* FIXME remove this once we delete an instance from master object through * modify request by setting exception */ - return e_cal_component_get_as_string (comp); + icalcomp = e_cal_component_get_icalcomponent (comp); } } - return NULL; + return icalcomp ? icalcomponent_new_clone (icalcomp) : NULL; } static void @@ -2742,8 +2817,8 @@ e_cal_backend_file_remove_object (ECalBackendSync *backend, const gchar *uid, const gchar *rid, CalObjModType mod, - gchar **old_object, - gchar **object, + icalcomponent **old_component, + icalcomponent **component, GError **error) { ECalBackendFile *cbfile; @@ -2758,6 +2833,7 @@ e_cal_backend_file_remove_object (ECalBackendSync *backend, e_return_data_cal_error_if_fail (priv->icalcomp != NULL, NoSuchCal); e_return_data_cal_error_if_fail (uid != NULL, ObjectNotFound); + switch (mod) { case CALOBJ_MOD_THIS: case CALOBJ_MOD_THISANDPRIOR: @@ -2770,7 +2846,7 @@ e_cal_backend_file_remove_object (ECalBackendSync *backend, return; } - *old_object = *object = NULL; + *old_component = *component = NULL; g_static_rec_mutex_lock (&priv->idle_save_rmutex); @@ -2786,16 +2862,17 @@ e_cal_backend_file_remove_object (ECalBackendSync *backend, switch (mod) { case CALOBJ_MOD_ALL : - *old_object = get_object_string_from_fileobject (obj_data, recur_id); + *old_component = clone_icalcomp_from_fileobject (obj_data, recur_id); if (obj_data->recurrences_list) g_list_foreach (obj_data->recurrences_list, notify_comp_removed_cb, cbfile); remove_component (cbfile, uid, obj_data); - *object = NULL; + *component = NULL; break; case CALOBJ_MOD_ONLY_THIS: case CALOBJ_MOD_THIS : - obj_data = remove_instance (cbfile, obj_data, uid, recur_id, mod, old_object, object, error); + obj_data = remove_instance (cbfile, obj_data, uid, recur_id, mod, + old_component, component, error); break; case CALOBJ_MOD_THISANDPRIOR : case CALOBJ_MOD_THISANDFUTURE : @@ -2808,7 +2885,9 @@ e_cal_backend_file_remove_object (ECalBackendSync *backend, } if (comp) { - *old_object = e_cal_component_get_as_string (comp); + icalcomponent *icalcomp = + e_cal_component_get_icalcomponent (comp); + *old_component = icalcomponent_new_clone (icalcomp); /* remove the component from our data, temporarily */ icalcomponent_remove_component (priv->icalcomp, @@ -2832,8 +2911,12 @@ e_cal_backend_file_remove_object (ECalBackendSync *backend, if (comp) priv->comp = g_list_prepend (priv->comp, comp); - if (obj_data->full_object) - *object = e_cal_component_get_as_string (obj_data->full_object); + if (obj_data->full_object) { + icalcomponent *icalcomp = + e_cal_component_get_icalcomponent (obj_data->full_object); + + *component = icalcomponent_new_clone (icalcomp); + } break; } @@ -2845,8 +2928,8 @@ e_cal_backend_file_remove_object (ECalBackendSync *backend, static gboolean cancel_received_object (ECalBackendFile *cbfile, icalcomponent *icalcomp, - gchar **old_object, - gchar **new_object) + icalcomponent **old_icalcomp, + icalcomponent **new_icalcomp) { ECalBackendFileObject *obj_data; ECalBackendFilePrivate *priv; @@ -2856,8 +2939,8 @@ cancel_received_object (ECalBackendFile *cbfile, priv = cbfile->priv; - *old_object = NULL; - *new_object = NULL; + *old_icalcomp = NULL; + *new_icalcomp = NULL; /* Find the old version of the component. */ obj_data = g_hash_table_lookup (priv->comp_uid_hash, uid); @@ -2873,13 +2956,20 @@ cancel_received_object (ECalBackendFile *cbfile, rid = e_cal_component_get_recurid_as_string (comp); if (rid && *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); + obj_data = remove_instance (cbfile, obj_data, uid, rid, CALOBJ_MOD_THIS, + old_icalcomp, new_icalcomp, NULL); + if (obj_data && obj_data->full_object) { + icalcomponent *tmp_icalcomp = + e_cal_component_get_icalcomponent (obj_data->full_object); + *new_icalcomp = icalcomponent_new_clone (tmp_icalcomp); + } } 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); + /* report as removal by keeping *new_component NULL */ + if (obj_data->full_object) { + icalcomponent *tmp_icalcomp = + e_cal_component_get_icalcomponent (obj_data->full_object); + *old_icalcomp = icalcomponent_new_clone (tmp_icalcomp); + } remove_component (cbfile, uid, obj_data); } @@ -3078,8 +3168,10 @@ e_cal_backend_file_receive_objects (ECalBackendSync *backend, /* Now we manipulate the components we care about */ for (l = comps; l; l = l->next) { + icalcomponent *old_component = NULL; + icalcomponent *component = NULL; const gchar *uid; - gchar *object, *old_object = NULL, *rid, *new_object; + gchar *rid; ECalBackendFileObject *obj_data; gboolean is_declined; @@ -3113,40 +3205,53 @@ e_cal_backend_file_receive_objects (ECalBackendSync *backend, fetch_attachments (backend, comp); obj_data = g_hash_table_lookup (priv->comp_uid_hash, uid); if (obj_data) { + if (rid) { + icalcomponent *ignore_icalcomp = NULL; + remove_instance (cbfile, obj_data, uid, rid, CALOBJ_MOD_THIS, - &old_object, &new_object, NULL); + &old_component, &ignore_icalcomp, NULL); + + if (ignore_icalcomp) + icalcomponent_free (ignore_icalcomp); } else { - if (obj_data->full_object) - old_object = e_cal_component_get_as_string (obj_data->full_object); + if (obj_data->full_object) { + icalcomponent *full_icalcomp = + e_cal_component_get_icalcomponent (obj_data->full_object); + old_component = icalcomponent_new_clone (full_icalcomp); + } remove_component (cbfile, uid, obj_data); } if (!is_declined) add_component (cbfile, comp, FALSE); - object = e_cal_component_get_as_string (comp); + + component = icalcomponent_new_clone (e_cal_component_get_icalcomponent (comp)); if (!is_declined) - e_cal_backend_notify_object_modified (E_CAL_BACKEND (backend), old_object, object); + e_cal_backend_notify_component_modified (E_CAL_BACKEND (backend), + old_component, component); else { ECalComponentId *id = e_cal_component_get_id (comp); - if (rid) - e_cal_backend_notify_object_removed (E_CAL_BACKEND (backend), id, old_object, object); - else - e_cal_backend_notify_object_removed (E_CAL_BACKEND (backend), id, old_object, NULL); + e_cal_backend_notify_component_removed (E_CAL_BACKEND (backend), + id, old_component, + rid ? component : NULL); e_cal_component_free_id (id); } - g_free (object); - g_free (old_object); + if (component) + icalcomponent_free (component); + if (old_component) + icalcomponent_free (old_component); + } else if (!is_declined) { add_component (cbfile, comp, FALSE); - object = e_cal_component_get_as_string (comp); - e_cal_backend_notify_object_created (E_CAL_BACKEND (backend), object); - g_free (object); + component = e_cal_component_get_icalcomponent (comp); + + e_cal_backend_notify_component_created (E_CAL_BACKEND (backend), component); } g_free (rid); break; @@ -3167,22 +3272,25 @@ e_cal_backend_file_receive_objects (ECalBackendSync *backend, goto error; break; case ICAL_METHOD_CANCEL: - old_object = NULL; - new_object = NULL; - if (cancel_received_object (cbfile, subcomp, &old_object, &new_object)) { + old_component = NULL; + component = NULL; + if (cancel_received_object (cbfile, subcomp, &old_component, &component)) { ECalComponentId *id; id = e_cal_component_get_id (comp); - e_cal_backend_notify_object_removed (E_CAL_BACKEND (backend), id, old_object, new_object); + e_cal_backend_notify_component_removed (E_CAL_BACKEND (backend), + id, old_component, component); /* remove the component from the toplevel VCALENDAR */ icalcomponent_remove_component (toplevel_comp, subcomp); icalcomponent_free (subcomp); e_cal_component_free_id (id); - g_free (new_object); - g_free (old_object); + if (component) + icalcomponent_free (component); + if (old_component) + icalcomponent_free (old_component); } g_free (rid); break; @@ -3485,7 +3593,7 @@ test_query_by_scanning_all_objects (ECalBackendFile *cbfile, g_static_rec_mutex_unlock (&priv->idle_save_rmutex); - *objects = match_data.obj_list; + *objects = g_slist_reverse (match_data.obj_list); g_object_unref (match_data.obj_sexp); } diff --git a/calendar/backends/http/e-cal-backend-http.c b/calendar/backends/http/e-cal-backend-http.c index e564eb96e..6d6efd37b 100644 --- a/calendar/backends/http/e-cal-backend-http.c +++ b/calendar/backends/http/e-cal-backend-http.c @@ -1262,26 +1262,26 @@ e_cal_backend_http_get_free_busy (ECalBackendSync *backend, } static void -e_cal_backend_http_create_object (ECalBackendSync *backend, - EDataCal *cal, - GCancellable *cancellable, - const gchar *calobj, - gchar **uid, - gchar **new_calobj, - GError **perror) +e_cal_backend_http_create_object (ECalBackendSync *backend, + EDataCal *cal, + GCancellable *cancellable, + const gchar *calobj, + gchar **uid, + icalcomponent **new_component, + GError **perror) { g_propagate_error (perror, EDC_ERROR (PermissionDenied)); } static void e_cal_backend_http_modify_object (ECalBackendSync *backend, - EDataCal *cal, - GCancellable *cancellable, - const gchar *calobj, - CalObjModType mod, - gchar **old_object, - gchar **new_object, - GError **perror) + EDataCal *cal, + GCancellable *cancellable, + const gchar *calobj, + CalObjModType mod, + icalcomponent **old_component, + icalcomponent **component, + GError **perror) { g_propagate_error (perror, EDC_ERROR (PermissionDenied)); } @@ -1289,16 +1289,16 @@ e_cal_backend_http_modify_object (ECalBackendSync *backend, /* Remove_object handler for the file backend */ static void e_cal_backend_http_remove_object (ECalBackendSync *backend, - EDataCal *cal, - GCancellable *cancellable, - const gchar *uid, - const gchar *rid, - CalObjModType mod, - gchar **old_object, - gchar **object, - GError **perror) + EDataCal *cal, + GCancellable *cancellable, + const gchar *uid, + const gchar *rid, + CalObjModType mod, + icalcomponent **old_component, + icalcomponent **component, + GError **perror) { - *old_object = *object = NULL; + *old_component = *component = NULL; g_propagate_error (perror, EDC_ERROR (PermissionDenied)); } diff --git a/calendar/libedata-cal/e-cal-backend-sync.c b/calendar/libedata-cal/e-cal-backend-sync.c index 27a9c1858..de043e7cb 100644 --- a/calendar/libedata-cal/e-cal-backend-sync.c +++ b/calendar/libedata-cal/e-cal-backend-sync.c @@ -309,24 +309,24 @@ e_cal_backend_sync_get_free_busy (ECalBackendSync *backend, * @cancellable: a #GCancellable for the operation * @calobj: The object to be added. * @uid: Placeholder for server-generated UID. - * @new_object: Placeholder for server-calobj, if it changed. Can be left as is if it's same as @calobj. + * @new_component: (out) (transfer full): Placeholder for returned #icalcomponent. * @error: Out parameter for a #GError. * * Calls the create_object_sync method on the given backend. */ void e_cal_backend_sync_create_object (ECalBackendSync *backend, - EDataCal *cal, - GCancellable *cancellable, - const gchar *calobj, - gchar **uid, - gchar **new_object, - GError **error) + EDataCal *cal, + GCancellable *cancellable, + const gchar *calobj, + gchar **uid, + icalcomponent **new_component, + GError **error) { e_return_data_cal_error_if_fail (backend && E_IS_CAL_BACKEND_SYNC (backend), InvalidArg); e_return_data_cal_error_if_fail (E_CAL_BACKEND_SYNC_GET_CLASS (backend)->create_object_sync != NULL, UnsupportedMethod); - LOCK_WRAPPER (create_object_sync, (backend, cal, cancellable, calobj, uid, new_object, error)); + LOCK_WRAPPER (create_object_sync, (backend, cal, cancellable, calobj, uid, new_component, error)); } /** @@ -336,9 +336,9 @@ e_cal_backend_sync_create_object (ECalBackendSync *backend, * @cancellable: a #GCancellable for the operation * @calobj: Object to be modified. * @mod: Type of modification to be done. - * @old_object: Placeholder for returning the old object as it was stored on the + * @old_component: (out) (transfer full): Placeholder for returning the old component as it was stored on the * backend. - * @new_object: Placeholder for returning the new object as it has been stored + * @new_component: (out) (transfer full): Placeholder for returning the new component as it has been stored * on the backend. * @error: Out parameter for a #GError. * @@ -346,18 +346,18 @@ e_cal_backend_sync_create_object (ECalBackendSync *backend, */ void e_cal_backend_sync_modify_object (ECalBackendSync *backend, - EDataCal *cal, - GCancellable *cancellable, - const gchar *calobj, - CalObjModType mod, - gchar **old_object, - gchar **new_object, - GError **error) + EDataCal *cal, + GCancellable *cancellable, + const gchar *calobj, + CalObjModType mod, + icalcomponent **old_component, + icalcomponent **new_component, + GError **error) { e_return_data_cal_error_if_fail (backend && E_IS_CAL_BACKEND_SYNC (backend), InvalidArg); e_return_data_cal_error_if_fail (E_CAL_BACKEND_SYNC_GET_CLASS (backend)->modify_object_sync != NULL, UnsupportedMethod); - LOCK_WRAPPER (modify_object_sync, (backend, cal, cancellable, calobj, mod, old_object, new_object, error)); + LOCK_WRAPPER (modify_object_sync, (backend, cal, cancellable, calobj, mod, old_component, new_component, error)); } /** @@ -369,30 +369,30 @@ e_cal_backend_sync_modify_object (ECalBackendSync *backend, * @rid: Recurrence ID of the instance to remove, or NULL if removing the * whole object. * @mod: Type of removal. - * @old_object: Placeholder for returning the old object as it was stored on the + * @old_component: (out) (transfer full): Placeholder for returning the old component as it was stored on the * backend. - * @new_object: Placeholder for returning the object after it has been modified (when - * removing individual instances). If removing the whole object, this will be - * NULL. + * @new_component: (out) (transfer full): Placeholder for returning the new component as it has been stored + * on the backend (when removing individual instances). If removing the whole object, + * this will be set to %NULL. * @error: Out parameter for a #GError. * * Calls the remove_object_sync method on the given backend. */ void e_cal_backend_sync_remove_object (ECalBackendSync *backend, - EDataCal *cal, - GCancellable *cancellable, - const gchar *uid, - const gchar *rid, - CalObjModType mod, - gchar **old_object, - gchar **new_object, - GError **error) + EDataCal *cal, + GCancellable *cancellable, + const gchar *uid, + const gchar *rid, + CalObjModType mod, + icalcomponent **old_component, + icalcomponent **new_component, + GError **error) { e_return_data_cal_error_if_fail (backend && E_IS_CAL_BACKEND_SYNC (backend), InvalidArg); e_return_data_cal_error_if_fail (E_CAL_BACKEND_SYNC_GET_CLASS (backend)->remove_object_sync != NULL, UnsupportedMethod); - LOCK_WRAPPER (remove_object_sync, (backend, cal, cancellable, uid, rid, mod, old_object, new_object, error)); + LOCK_WRAPPER (remove_object_sync, (backend, cal, cancellable, uid, rid, mod, old_component, new_component, error)); } /** @@ -732,14 +732,20 @@ cal_backend_create_object (ECalBackend *backend, const gchar *calobj) { GError *error = NULL; - gchar *uid = NULL, *new_object = NULL; + gchar *uid = NULL; + icalcomponent *new_component = NULL; + + e_cal_backend_sync_create_object (E_CAL_BACKEND_SYNC (backend), cal, cancellable, calobj, &uid, &new_component, &error); - e_cal_backend_sync_create_object (E_CAL_BACKEND_SYNC (backend), cal, cancellable, calobj, &uid, &new_object, &error); + if (!new_component) + new_component = icalparser_parse_string (calobj); - e_data_cal_respond_create_object (cal, opid, error, uid, new_object ? new_object : calobj); + e_data_cal_respond_create_object (cal, opid, error, uid, new_component); g_free (uid); - g_free (new_object); + + if (new_component) + icalcomponent_free (new_component); } static void @@ -751,38 +757,47 @@ cal_backend_modify_object (ECalBackend *backend, CalObjModType mod) { GError *error = NULL; - gchar *old_object = NULL, *new_object = NULL; + icalcomponent *old_component = NULL, *new_component = NULL; + + e_cal_backend_sync_modify_object (E_CAL_BACKEND_SYNC (backend), cal, cancellable, calobj, mod, &old_component, &new_component, &error); + + if (!old_component) + old_component = icalparser_parse_string (calobj); - e_cal_backend_sync_modify_object (E_CAL_BACKEND_SYNC (backend), cal, cancellable, calobj, mod, &old_object, &new_object, &error); + e_data_cal_respond_modify_object (cal, opid, error, old_component, new_component); - e_data_cal_respond_modify_object (cal, opid, error, old_object ? old_object : calobj, new_object); + if (old_component) + icalcomponent_free (old_component); - g_free (old_object); - g_free (new_object); + if (new_component) + icalcomponent_free (new_component); } static void -cal_backend_remove_object (ECalBackend *backend, - EDataCal *cal, - guint32 opid, +cal_backend_remove_object (ECalBackend *backend, + EDataCal *cal, + guint32 opid, GCancellable *cancellable, - const gchar *uid, - const gchar *rid, + const gchar *uid, + const gchar *rid, CalObjModType mod) { GError *error = NULL; - gchar *old_object = NULL, *new_object = NULL; + icalcomponent *old_component = NULL, *new_component = NULL; ECalComponentId compid; compid.uid = (gchar *) uid; compid.rid = (gchar *) ((mod == CALOBJ_MOD_THIS || mod == CALOBJ_MOD_ONLY_THIS) ? rid : NULL); - e_cal_backend_sync_remove_object (E_CAL_BACKEND_SYNC (backend), cal, cancellable, uid, rid, mod, &old_object, &new_object, &error); + e_cal_backend_sync_remove_object (E_CAL_BACKEND_SYNC (backend), cal, cancellable, uid, rid, mod, &old_component, &new_component, &error); + + e_data_cal_respond_remove_object (cal, opid, error, &compid, old_component, new_component); - e_data_cal_respond_remove_object (cal, opid, error, &compid, old_object, new_object); + if (old_component) + icalcomponent_free (old_component); - g_free (old_object); - g_free (new_object); + if (new_component) + icalcomponent_free (new_component); } static void diff --git a/calendar/libedata-cal/e-cal-backend-sync.h b/calendar/libedata-cal/e-cal-backend-sync.h index 1b64a50c6..c6fa3d1cf 100644 --- a/calendar/libedata-cal/e-cal-backend-sync.h +++ b/calendar/libedata-cal/e-cal-backend-sync.h @@ -39,9 +39,9 @@ struct _ECalBackendSyncClass { void (* get_object_sync) (ECalBackendSync *backend, EDataCal *cal, GCancellable *cancellable, const gchar *uid, const gchar *rid, gchar **calobj, GError **error); void (* get_object_list_sync) (ECalBackendSync *backend, EDataCal *cal, GCancellable *cancellable, const gchar *sexp, GSList **calobjs, GError **error); void (* get_free_busy_sync) (ECalBackendSync *backend, EDataCal *cal, GCancellable *cancellable, const GSList *users, time_t start, time_t end, GSList **freebusyobjs, GError **error); - void (* create_object_sync) (ECalBackendSync *backend, EDataCal *cal, GCancellable *cancellable, const gchar *calobj, gchar **uid, gchar **new_object, GError **error); - void (* modify_object_sync) (ECalBackendSync *backend, EDataCal *cal, GCancellable *cancellable, const gchar *calobj, CalObjModType mod, gchar **old_object, gchar **new_object, GError **error); - void (* remove_object_sync) (ECalBackendSync *backend, EDataCal *cal, GCancellable *cancellable, const gchar *uid, const gchar *rid, CalObjModType mod, gchar **old_object, gchar **new_object, GError **error); + void (* create_object_sync) (ECalBackendSync *backend, EDataCal *cal, GCancellable *cancellable, const gchar *calobj, gchar **uid, icalcomponent **new_component, GError **error); + void (* modify_object_sync) (ECalBackendSync *backend, EDataCal *cal, GCancellable *cancellable, const gchar *calobj, CalObjModType mod, icalcomponent **old_component, icalcomponent **new_component, GError **error); + void (* remove_object_sync) (ECalBackendSync *backend, EDataCal *cal, GCancellable *cancellable, const gchar *uid, const gchar *rid, CalObjModType mod, icalcomponent **old_component, icalcomponent **new_component, GError **error); void (* receive_objects_sync) (ECalBackendSync *backend, EDataCal *cal, GCancellable *cancellable, const gchar *calobj, GError **error); void (* send_objects_sync) (ECalBackendSync *backend, EDataCal *cal, GCancellable *cancellable, const gchar *calobj, GSList **users, gchar **modified_calobj, GError **error); void (* get_attachment_uris_sync) (ECalBackendSync *backend, EDataCal *cal, GCancellable *cancellable, const gchar *uid, const gchar *rid, GSList **attachments, GError **error); @@ -64,9 +64,9 @@ gboolean e_cal_backend_sync_set_backend_property (ECalBackendSync *backend, EDat void e_cal_backend_sync_get_object (ECalBackendSync *backend, EDataCal *cal, GCancellable *cancellable, const gchar *uid, const gchar *rid, gchar **calobj, GError **error); void e_cal_backend_sync_get_object_list (ECalBackendSync *backend, EDataCal *cal, GCancellable *cancellable, const gchar *sexp, GSList **calobjs, GError **error); void e_cal_backend_sync_get_free_busy (ECalBackendSync *backend, EDataCal *cal, GCancellable *cancellable, const GSList *users, time_t start, time_t end, GSList **freebusyobjs, GError **error); -void e_cal_backend_sync_create_object (ECalBackendSync *backend, EDataCal *cal, GCancellable *cancellable, const gchar *calobj, gchar **uid, gchar **new_object, GError **error); -void e_cal_backend_sync_modify_object (ECalBackendSync *backend, EDataCal *cal, GCancellable *cancellable, const gchar *calobj, CalObjModType mod, gchar **old_object, gchar **new_object, GError **error); -void e_cal_backend_sync_remove_object (ECalBackendSync *backend, EDataCal *cal, GCancellable *cancellable, const gchar *uid, const gchar *rid, CalObjModType mod, gchar **old_object, gchar **new_object, GError **error); +void e_cal_backend_sync_create_object (ECalBackendSync *backend, EDataCal *cal, GCancellable *cancellable, const gchar *calobj, gchar **uid, icalcomponent **new_component, GError **error); +void e_cal_backend_sync_modify_object (ECalBackendSync *backend, EDataCal *cal, GCancellable *cancellable, const gchar *calobj, CalObjModType mod, icalcomponent **old_component, icalcomponent **new_component, GError **error); +void e_cal_backend_sync_remove_object (ECalBackendSync *backend, EDataCal *cal, GCancellable *cancellable, const gchar *uid, const gchar *rid, CalObjModType mod, icalcomponent **old_component, icalcomponent **new_component, GError **error); void e_cal_backend_sync_receive_objects (ECalBackendSync *backend, EDataCal *cal, GCancellable *cancellable, const gchar *calobj, GError **error); void e_cal_backend_sync_send_objects (ECalBackendSync *backend, EDataCal *cal, GCancellable *cancellable, const gchar *calobj, GSList **users, gchar **modified_calobj, GError **error); void e_cal_backend_sync_get_attachment_uris (ECalBackendSync *backend, EDataCal *cal, GCancellable *cancellable, const gchar *uid, const gchar *rid, GSList **attachments, GError **error); diff --git a/calendar/libedata-cal/e-cal-backend.c b/calendar/libedata-cal/e-cal-backend.c index ccfb57f0b..4c3dcc7d1 100644 --- a/calendar/libedata-cal/e-cal-backend.c +++ b/calendar/libedata-cal/e-cal-backend.c @@ -1373,9 +1373,263 @@ e_cal_backend_stop_view (ECalBackend *backend, } static gboolean -object_created_cb (EDataCalView *view, - gpointer calobj) +component_created_cb (EDataCalView *view, gpointer data) { + ECalComponent *comp = (ECalComponent *)data; + icalcomponent *icalcomp = e_cal_component_get_icalcomponent (comp); + + if (e_data_cal_view_component_matches (view, comp)) + e_data_cal_view_notify_components_added_1 (view, icalcomp); + + return TRUE; +} + +static ECalComponent * +ecal_comp_from_icalcomp (const icalcomponent *component) +{ + ECalComponent *comp = NULL; + icalcomponent *icalclone; + + if (component) { + comp = e_cal_component_new (); + icalclone = icalcomponent_new_clone ((icalcomponent *)component); + + if (!e_cal_component_set_icalcomponent (comp, icalclone)) { + g_warning ("ecal_comp_from_icalcomp failed to set icalcomponent"); + + icalcomponent_free (icalclone); + g_object_unref (comp); + comp = NULL; + } + } + + return comp; +} + +/** + * e_cal_backend_notify_component_created: + * @backend: an #ECalBackend + * @component: the newly created #icalcomponent + * + * Notifies each of the backend's listeners about a new object. + * + * Like e_cal_backend_notify_object_created() except takes an #icalcomponent + * instead of an ical string representation and uses the #EDataCalView's fields-of-interest + * to filter out unwanted information from ical strings sent over the bus. + * + * Since: 3.4 + **/ +void +e_cal_backend_notify_component_created (ECalBackend *backend, + const icalcomponent *component) +{ + ECalBackendPrivate *priv; + ECalComponent *comp; + + priv = backend->priv; + + if (priv->notification_proxy) { + e_cal_backend_notify_component_created (priv->notification_proxy, component); + return; + } + + comp = ecal_comp_from_icalcomp (component); + + e_cal_backend_foreach_view (backend, component_created_cb, (gpointer) comp); + g_object_unref (comp); +} + +/** + * e_cal_backend_notify_components_added: + * + * Like e_cal_backend_notify_objects_added() except take a list of #icalcomponents + * instead of ical string representations and uses the #EDataCalView's fields-of-interest + * to filter out unwanted information from ical strings sent over the bus. + * + * Since: 3.4 + **/ +void +e_cal_backend_notify_components_added (ECalBackend *backend, + EDataCalView *view, + const GSList *objects) +{ + e_data_cal_view_notify_components_added (view, objects); +} + +static void +match_view_and_notify_component (EDataCalView *view, + ECalComponent *old_component, + ECalComponent *component) +{ + gboolean old_match = FALSE, new_match = FALSE; + icalcomponent *icalcomp; + + if (old_component) + old_match = e_data_cal_view_component_matches (view, old_component); + + new_match = e_data_cal_view_component_matches (view, component); + icalcomp = e_cal_component_get_icalcomponent (component); + + if (old_match && new_match) + e_data_cal_view_notify_components_modified_1 (view, icalcomp); + else if (new_match) + e_data_cal_view_notify_components_added_1 (view, icalcomp); + else if (old_match) { + + ECalComponentId *id = e_cal_component_get_id (old_component); + + e_data_cal_view_notify_objects_removed_1 (view, id); + + e_cal_component_free_id (id); + } +} + +struct component_call_data { + ECalComponent *old_component; + ECalComponent *component; + const ECalComponentId *id; +}; + +static gboolean +call_match_and_notify_component (EDataCalView *view, gpointer user_data) +{ + struct component_call_data *cd = user_data; + + g_return_val_if_fail (user_data != NULL, FALSE); + + match_view_and_notify_component (view, cd->old_component, cd->component); + + return TRUE; +} + +/** + * e_cal_backend_notify_component_modified: + * @backend: an #ECalBackend + * @old_component: the #icalcomponent before the modification + * @component: the #icalcomponent after the modification + * + * Notifies each of the backend's listeners about a modified object. + * + * Like e_cal_backend_notify_object_modified() except takes an #icalcomponent + * instead of an ical string representation and uses the #EDataCalView's fields-of-interest + * to filter out unwanted information from ical strings sent over the bus. + * + * Since: 3.4 + **/ +void +e_cal_backend_notify_component_modified (ECalBackend *backend, + const icalcomponent *old_component, + const icalcomponent *component) +{ + ECalBackendPrivate *priv; + struct component_call_data cd; + + priv = backend->priv; + + if (priv->notification_proxy) { + e_cal_backend_notify_component_modified (priv->notification_proxy, old_component, component); + return; + } + + cd.old_component = ecal_comp_from_icalcomp (old_component); + cd.component = ecal_comp_from_icalcomp (component); + cd.id = NULL; + + e_cal_backend_foreach_view (backend, call_match_and_notify_component, &cd); + + if (cd.old_component) + g_object_unref (cd.old_component); + + if (cd.component) + g_object_unref (cd.component); +} + +/** + * e_cal_backend_notify_components_modified: + * + * Like e_cal_backend_notify_objects_modified() except takes a list of #icalcomponents + * instead of a ical string representations and uses the #EDataCalView's fields-of-interest + * to filter out unwanted information from ical strings sent over the bus. + * + * Since: 3.4 + **/ +void +e_cal_backend_notify_components_modified (ECalBackend *backend, + EDataCalView *view, + const GSList *objects) +{ + e_data_cal_view_notify_components_modified (view, objects); +} + +static gboolean +component_removed_cb (EDataCalView *view, gpointer user_data) +{ + struct component_call_data *cd = user_data; + + g_return_val_if_fail (user_data != NULL, FALSE); + + if (cd->component == NULL) { + /* if object == NULL, it means the object has been completely + removed from the backend */ + if (!cd->old_component || e_data_cal_view_component_matches (view, cd->old_component)) + e_data_cal_view_notify_objects_removed_1 (view, cd->id); + } else + match_view_and_notify_component (view, cd->old_component, cd->component); + + return TRUE; +} + +/** + * e_cal_backend_notify_component_removed: + * @backend: an #ECalBackend + * @id: the Id of the removed object + * @old_component: the removed component + * @component: the component 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. + * + * Like e_cal_backend_notify_object_removed() except takes an #icalcomponent + * instead of an ical string representation and uses the #EDataCalView's fields-of-interest + * to filter out unwanted information from ical strings sent over the bus. + * + * Since: 3.4 + **/ +void +e_cal_backend_notify_component_removed (ECalBackend *backend, + const ECalComponentId *id, + const icalcomponent *old_component, + const icalcomponent *component) +{ + ECalBackendPrivate *priv; + struct component_call_data cd; + + priv = backend->priv; + + if (priv->notification_proxy) { + e_cal_backend_notify_component_removed (priv->notification_proxy, id, old_component, component); + return; + } + + cd.old_component = ecal_comp_from_icalcomp (old_component); + cd.component = ecal_comp_from_icalcomp (component); + cd.id = id; + + e_cal_backend_foreach_view (backend, component_removed_cb, &cd); + + if (cd.old_component) + g_object_unref (cd.old_component); + + if (cd.component) + g_object_unref (cd.component); +} + +static gboolean +object_created_cb (EDataCalView *view, gpointer data) +{ + const gchar *calobj = data; + if (e_data_cal_view_object_matches (view, calobj)) e_data_cal_view_notify_objects_added_1 (view, calobj); @@ -1385,7 +1639,7 @@ object_created_cb (EDataCalView *view, /** * e_cal_backend_notify_object_created: * @backend: an #ECalBackend - * @calobj: iCalendar representation of new object + * @calobj: the newly created object * * Notifies each of the backend's listeners about a new object. * @@ -1423,9 +1677,9 @@ e_cal_backend_notify_objects_added (ECalBackend *backend, } static void -match_view_and_notify (EDataCalView *view, - const gchar *old_object, - const gchar *object) +match_view_and_notify_object (EDataCalView *view, + const gchar *old_object, + const gchar *object) { gboolean old_match = FALSE, new_match = FALSE; @@ -1452,21 +1706,20 @@ match_view_and_notify (EDataCalView *view, } } -struct call_data { +struct object_call_data { const gchar *old_object; const gchar *object; const ECalComponentId *id; }; static gboolean -call_match_and_notify (EDataCalView *view, - gpointer user_data) +call_match_and_notify_object (EDataCalView *view, gpointer user_data) { - struct call_data *cd = user_data; + struct object_call_data *cd = user_data; g_return_val_if_fail (user_data != NULL, FALSE); - match_view_and_notify (view, cd->old_object, cd->object); + match_view_and_notify_object (view, cd->old_object, cd->object); return TRUE; } @@ -1489,7 +1742,7 @@ e_cal_backend_notify_object_modified (ECalBackend *backend, const gchar *object) { ECalBackendPrivate *priv; - struct call_data cd; + struct object_call_data cd; priv = backend->priv; @@ -1502,7 +1755,7 @@ e_cal_backend_notify_object_modified (ECalBackend *backend, cd.object = object; cd.id = NULL; - e_cal_backend_foreach_view (backend, call_match_and_notify, &cd); + e_cal_backend_foreach_view (backend, call_match_and_notify_object, &cd); } /** @@ -1522,7 +1775,7 @@ static gboolean object_removed_cb (EDataCalView *view, gpointer user_data) { - struct call_data *cd = user_data; + struct object_call_data *cd = user_data; g_return_val_if_fail (user_data != NULL, FALSE); @@ -1532,7 +1785,7 @@ object_removed_cb (EDataCalView *view, if (!cd->old_object || e_data_cal_view_object_matches (view, cd->old_object)) e_data_cal_view_notify_objects_removed_1 (view, cd->id); } else - match_view_and_notify (view, cd->old_object, cd->object); + match_view_and_notify_object (view, cd->old_object, cd->object); return TRUE; } @@ -1559,7 +1812,7 @@ e_cal_backend_notify_object_removed (ECalBackend *backend, const gchar *object) { ECalBackendPrivate *priv; - struct call_data cd; + struct object_call_data cd; priv = backend->priv; @@ -1868,17 +2121,16 @@ e_cal_backend_empty_cache (ECalBackend *backend, for (comps_in_cache = e_cal_backend_cache_get_components (cache); comps_in_cache; comps_in_cache = comps_in_cache->next) { - gchar *comp_str; ECalComponentId *id; - ECalComponent *comp = comps_in_cache->data; + ECalComponent *comp = comps_in_cache->data; + icalcomponent *icalcomp = e_cal_component_get_icalcomponent (comp); id = e_cal_component_get_id (comp); - comp_str = e_cal_component_get_as_string (comp); e_cal_backend_cache_remove_component (cache, id->uid, id->rid); - e_cal_backend_notify_object_removed (backend, id, comp_str, NULL); - g_free (comp_str); + e_cal_backend_notify_component_removed (backend, id, icalcomp, NULL); + e_cal_component_free_id (id); g_object_unref (comp); } diff --git a/calendar/libedata-cal/e-cal-backend.h b/calendar/libedata-cal/e-cal-backend.h index 73198c6ec..e566110f6 100644 --- a/calendar/libedata-cal/e-cal-backend.h +++ b/calendar/libedata-cal/e-cal-backend.h @@ -214,6 +214,12 @@ icaltimezone * e_cal_backend_internal_get_timezone (ECalBackend *backend, const void e_cal_backend_start_view (ECalBackend *backend, EDataCalView *view); void e_cal_backend_stop_view (ECalBackend *backend, EDataCalView *view); +void e_cal_backend_notify_component_created (ECalBackend *backend, const icalcomponent *component); +void e_cal_backend_notify_components_added (ECalBackend *backend, EDataCalView *view, const GSList *components); +void e_cal_backend_notify_component_modified (ECalBackend *backend, const icalcomponent *old_component, const icalcomponent *new_component); +void e_cal_backend_notify_components_modified(ECalBackend *backend, EDataCalView *view, const GSList *components); +void e_cal_backend_notify_component_removed (ECalBackend *backend, const ECalComponentId *id, const icalcomponent *old_component, const icalcomponent *component); + void e_cal_backend_notify_object_created (ECalBackend *backend, const gchar *calobj); void e_cal_backend_notify_objects_added (ECalBackend *backend, EDataCalView *view, const GSList *objects); void e_cal_backend_notify_object_modified (ECalBackend *backend, const gchar *old_object, const gchar *object); diff --git a/calendar/libedata-cal/e-data-cal-view.c b/calendar/libedata-cal/e-data-cal-view.c index 6a6301772..24b25897f 100644 --- a/calendar/libedata-cal/e-data-cal-view.c +++ b/calendar/libedata-cal/e-data-cal-view.c @@ -270,7 +270,7 @@ ensure_pending_flush_timeout (EDataCalView *view) static void notify_add (EDataCalView *view, - gchar *obj) + gchar *obj) { EDataCalViewPrivate *priv = view->priv; ECalComponent *comp; @@ -293,8 +293,37 @@ notify_add (EDataCalView *view, } static void -notify_change (EDataCalView *view, - gchar *obj) +notify_add_component (EDataCalView *view, icalcomponent *icalcomp) +{ + EDataCalViewPrivate *priv = view->priv; + icalcomponent *icalclone; + ECalComponent *comp; + gchar *obj; + + obj = e_data_cal_view_get_component_string (view, icalcomp); + + send_pending_changes (view); + send_pending_removes (view); + + if (priv->adds->len == THRESHOLD_ITEMS) { + send_pending_adds (view); + } + g_array_append_val (priv->adds, obj); + + comp = e_cal_component_new (); + icalclone = icalcomponent_new_clone (icalcomp); + e_cal_component_set_icalcomponent (comp, icalclone); + + g_hash_table_insert (priv->ids, + e_cal_component_get_id (comp), + GUINT_TO_POINTER (1)); + g_object_unref (comp); + + ensure_pending_flush_timeout (view); +} + +static void +notify_change (EDataCalView *view, gchar *obj) { EDataCalViewPrivate *priv = view->priv; @@ -311,8 +340,17 @@ notify_change (EDataCalView *view, } static void -notify_remove (EDataCalView *view, - ECalComponentId *id) +notify_change_component (EDataCalView *view, icalcomponent *comp) +{ + gchar *obj; + + obj = e_data_cal_view_get_component_string (view, comp); + + notify_change (view, obj); +} + +static void +notify_remove (EDataCalView *view, ECalComponentId *id) { EDataCalViewPrivate *priv = view->priv; gchar *ids; @@ -672,6 +710,32 @@ e_data_cal_view_object_matches (EDataCalView *view, } /** + * e_data_cal_view_component_matches: + * @view: A view object. + * @component: the #ECalComponent object to match. + * + * Compares the given @component to the regular expression used for the + * given view. + * + * Returns: TRUE if the object matches the expression, FALSE if not. + * + * Since: 3.4 + */ +gboolean +e_data_cal_view_component_matches (EDataCalView *view, ECalComponent *component) +{ + EDataCalViewPrivate *priv; + + g_return_val_if_fail (view != NULL, FALSE); + g_return_val_if_fail (E_IS_DATA_CAL_VIEW (view), FALSE); + g_return_val_if_fail (E_IS_CAL_COMPONENT (component), FALSE); + + priv = view->priv; + + return e_cal_backend_sexp_match_comp (priv->sexp, component, priv->backend); +} + +/** * e_data_cal_view_is_started: * @view: A view object. * @@ -748,12 +812,245 @@ e_data_cal_view_get_fields_of_interest (EDataCalView *view) return view->priv->fields_of_interest; } +static gboolean +filter_component (icalcomponent *icomponent, GHashTable *fields_of_interest, GString *string) +{ + gchar *str; + + /* RFC 2445 explicitly says that the newline is *ALWAYS* a \r\n (CRLF)!!!! */ + const gchar newline[] = "\r\n"; + + icalcomponent_kind kind; + const gchar *kind_string; + icalproperty *prop; + icalcomponent *icomp; + gboolean fail = FALSE; + + /* Open iCalendar string */ + g_string_append (string, "BEGIN:"); + + kind = icalcomponent_isa (icomponent); + + /* if (kind != ICAL_X_COMPONENT) { */ + /* kind_string = icalcomponent_kind_to_string (kind); */ + /* } else { */ + /* kind_string = icomponent->x_name; */ + /* } */ + + kind_string = icalcomponent_kind_to_string (kind); + + g_string_append (string, kind_string); + g_string_append (string, newline); + + for (prop = icalcomponent_get_first_property (icomponent, ICAL_ANY_PROPERTY); + prop; + prop = icalcomponent_get_next_property (icomponent, ICAL_ANY_PROPERTY)) { + const gchar *name; + gboolean is_field_of_interest; + + name = icalproperty_get_property_name (prop); + + if (!name) { + g_warning ("NULL ical property name encountered while serializing component"); + fail = TRUE; + break; + } + + is_field_of_interest = GPOINTER_TO_INT (g_hash_table_lookup (fields_of_interest, name)); + + /* Append any name that is mentioned in the fields-of-interest */ + if (is_field_of_interest) { + str = icalproperty_as_ical_string_r (prop); + g_string_append (string, str); + g_free (str); + } + } + + for (icomp = icalcomponent_get_first_component (icomponent, ICAL_ANY_COMPONENT); + fail == FALSE && icomp; + icomp = icalcomponent_get_next_component (icomponent, ICAL_ANY_COMPONENT)) { + + if (!filter_component (icomp, fields_of_interest, string)) { + fail = TRUE; + break; + } + } + + g_string_append (string, "END:"); + g_string_append (string, icalcomponent_kind_to_string (kind)); + g_string_append (string, newline); + + return fail == FALSE; +} + +/** + * e_data_cal_view_get_component_string: + * @view: A view object. + * @component: The #icalcomponent to get the string for. + * + * This function is similar to e_cal_component_get_as_string() except + * that it takes into account the fields-of-interest that @view is + * configured with and filters out any unneeded fields. + * + * Returns: (transfer full): A newly allocated string representation of @component suitable for @view. + * + * Since: 3.4 + */ +gchar * +e_data_cal_view_get_component_string (EDataCalView *view, icalcomponent *component) +{ + g_return_val_if_fail (E_IS_DATA_CAL_VIEW (view), NULL); + g_return_val_if_fail (component != NULL, NULL); + + if (view->priv->fields_of_interest) { + GString *string = g_string_new (""); + + if (filter_component (component, view->priv->fields_of_interest, string)) + return g_string_free (string, FALSE); + + g_string_free (string, TRUE); + } + + return icalcomponent_as_ical_string_r (component); +} + +/** + * e_data_cal_view_notify_components_added: + * @view: A view object. + * @components: List of components that have been added. + * + * Notifies all view listeners of the addition of a list of components. + * + * Like e_data_cal_view_notify_objects_added() except takes a list + * of #icalcomponents instead of ical string representations and uses the + * #EDataCalView's fields-of-interest to filter out unwanted information + * from ical strings sent over the bus. + * + * Since: 3.4 + */ +void +e_data_cal_view_notify_components_added (EDataCalView *view, + const GSList *components) +{ + EDataCalViewPrivate *priv; + const GSList *l; + + g_return_if_fail (view && E_IS_DATA_CAL_VIEW (view)); + priv = view->priv; + + if (components == NULL) + return; + + g_mutex_lock (priv->pending_mutex); + + for (l = components; l; l = l->next) { + icalcomponent *comp = l->data; + + notify_add_component (view, comp); + } + + g_mutex_unlock (priv->pending_mutex); +} + +/** + * e_data_cal_view_notify_components_added_1: + * @view: A view object. + * @component: The #icalcomponent that has been added. + * + * Notifies all the view listeners of the addition of a single object. + * + * Like e_data_cal_view_notify_objects_added_1() except takes an #icalcomponent + * instead of an ical string representation and uses the #EDataCalView's fields-of-interest + * to filter out unwanted information from ical strings sent over the bus. + * + * Since: 3.4 + */ +void +e_data_cal_view_notify_components_added_1 (EDataCalView *view, + const icalcomponent *component) +{ + GSList l = {NULL,}; + + g_return_if_fail (E_IS_DATA_CAL_VIEW (view)); + g_return_if_fail (component != NULL); + + l.data = (gpointer) component; + e_data_cal_view_notify_components_added (view, &l); +} + +/** + * e_data_cal_view_notify_components_modified: + * @view: A view object. + * @components: List of modified components. + * + * Notifies all view listeners of the modification of a list of components. + * + * Like e_data_cal_view_notify_objects_modified() except takes a list of #icalcomponents + * instead of a ical string representations and uses the #EDataCalView's fields-of-interest + * to filter out unwanted information from ical strings sent over the bus. + * + * Since: 3.4 + */ +void +e_data_cal_view_notify_components_modified (EDataCalView *view, + const GSList *components) +{ + EDataCalViewPrivate *priv; + const GSList *l; + + g_return_if_fail (view && E_IS_DATA_CAL_VIEW (view)); + priv = view->priv; + + if (components == NULL) + return; + + g_mutex_lock (priv->pending_mutex); + + for (l = components; l; l = l->next) { + /* TODO: send add/remove/change as relevant, based on ->ids */ + icalcomponent *comp = l->data; + + notify_change_component (view, comp); + } + + g_mutex_unlock (priv->pending_mutex); +} + +/** + * e_data_cal_view_notify_components_modified_1: + * @view: A view object. + * @component: The modified #icalcomponent. + * + * Notifies all view listeners of the modification of @component. + * + * Like e_data_cal_view_notify_objects_modified_1() except takes an #icalcomponent + * instead of an ical string representation and uses the #EDataCalView's fields-of-interest + * to filter out unwanted information from ical strings sent over the bus. + * + * Since: 3.4 + */ +void +e_data_cal_view_notify_components_modified_1 (EDataCalView *view, + const icalcomponent *component) +{ + GSList l = {NULL,}; + + g_return_if_fail (E_IS_DATA_CAL_VIEW (view)); + g_return_if_fail (component != NULL); + + l.data = (gpointer) component; + e_data_cal_view_notify_components_modified (view, &l); +} + /** * e_data_cal_view_notify_objects_added: * @view: A view object. * @objects: List of objects that have been added. * * Notifies all view listeners of the addition of a list of objects. + * + * If possible e_data_cal_view_notify_components_added() should be used + * instead. */ void e_data_cal_view_notify_objects_added (EDataCalView *view, @@ -783,6 +1080,9 @@ e_data_cal_view_notify_objects_added (EDataCalView *view, * @object: The object that has been added. * * Notifies all the view listeners of the addition of a single object. + * + * If possible e_data_cal_view_notify_components_added_1() should be used + * instead. */ void e_data_cal_view_notify_objects_added_1 (EDataCalView *view, @@ -803,6 +1103,9 @@ e_data_cal_view_notify_objects_added_1 (EDataCalView *view, * @objects: List of modified objects. * * Notifies all view listeners of the modification of a list of objects. + * + * If possible e_data_cal_view_notify_components_modified() should be used + * instead. */ void e_data_cal_view_notify_objects_modified (EDataCalView *view, @@ -833,6 +1136,9 @@ e_data_cal_view_notify_objects_modified (EDataCalView *view, * @object: The modified object. * * Notifies all view listeners of the modification of a single object. + * + * If possible e_data_cal_view_notify_components_modified_1() should be used + * instead. */ void e_data_cal_view_notify_objects_modified_1 (EDataCalView *view, diff --git a/calendar/libedata-cal/e-data-cal-view.h b/calendar/libedata-cal/e-data-cal-view.h index 06a0f2e76..bfe80e57b 100644 --- a/calendar/libedata-cal/e-data-cal-view.h +++ b/calendar/libedata-cal/e-data-cal-view.h @@ -52,11 +52,19 @@ guint e_data_cal_view_register_gdbus_object (EDataCalView *view, GDBusConnect const gchar * e_data_cal_view_get_text (EDataCalView *view); ECalBackendSExp * e_data_cal_view_get_object_sexp (EDataCalView *view); gboolean e_data_cal_view_object_matches (EDataCalView *view, const gchar *object); +gboolean e_data_cal_view_component_matches (EDataCalView *view, ECalComponent *component); gboolean e_data_cal_view_is_started (EDataCalView *view); gboolean e_data_cal_view_is_completed (EDataCalView *view); gboolean e_data_cal_view_is_stopped (EDataCalView *view); GHashTable * e_data_cal_view_get_fields_of_interest (EDataCalView *view); +gchar *e_data_cal_view_get_component_string (EDataCalView *view, icalcomponent *component); + +void e_data_cal_view_notify_components_added (EDataCalView *view, const GSList *objects); +void e_data_cal_view_notify_components_added_1 (EDataCalView *view, const icalcomponent *component); +void e_data_cal_view_notify_components_modified (EDataCalView *view, const GSList *objects); +void e_data_cal_view_notify_components_modified_1 (EDataCalView *view, const icalcomponent *component); + void e_data_cal_view_notify_objects_added (EDataCalView *view, const GSList *objects); void e_data_cal_view_notify_objects_added_1 (EDataCalView *view, const gchar *object); void e_data_cal_view_notify_objects_modified (EDataCalView *view, const GSList *objects); diff --git a/calendar/libedata-cal/e-data-cal.c b/calendar/libedata-cal/e-data-cal.c index b78fa9807..52ca24ef6 100644 --- a/calendar/libedata-cal/e-data-cal.c +++ b/calendar/libedata-cal/e-data-cal.c @@ -1167,18 +1167,18 @@ e_data_cal_respond_get_free_busy (EDataCal *cal, * @cal: A calendar client interface. * @error: Operation error, if any, automatically freed if passed it. * @uid: UID of the object created. - * @object: The object created as an iCalendar string. + * @component: The newly created #icalcomponent. * * Notifies listeners of the completion of the create_object method call. * * Since: 3.2 */ void -e_data_cal_respond_create_object (EDataCal *cal, - guint32 opid, - GError *error, - const gchar *uid, - const gchar *object) +e_data_cal_respond_create_object (EDataCal *cal, + guint32 opid, + GError *error, + const gchar *uid, + icalcomponent *component) { gchar *gdbus_uid = NULL; @@ -1193,26 +1193,26 @@ e_data_cal_respond_create_object (EDataCal *cal, if (error) g_error_free (error); else - e_cal_backend_notify_object_created (cal->priv->backend, object); + e_cal_backend_notify_component_created (cal->priv->backend, component); } /** * e_data_cal_respond_modify_object: * @cal: A calendar client interface. * @error: Operation error, if any, automatically freed if passed it. - * @old_object: The old object as an iCalendar string. - * @object: The modified object as an iCalendar string. + * @old_component: The old #icalcomponent. + * @component: The new #icalcomponent. * * Notifies listeners of the completion of the modify_object method call. * * Since: 3.2 */ void -e_data_cal_respond_modify_object (EDataCal *cal, - guint32 opid, - GError *error, - const gchar *old_object, - const gchar *object) +e_data_cal_respond_modify_object (EDataCal *cal, + guint32 opid, + GError *error, + icalcomponent *old_component, + icalcomponent *component) { op_complete (cal, opid); @@ -1224,7 +1224,7 @@ e_data_cal_respond_modify_object (EDataCal *cal, if (error) g_error_free (error); else - e_cal_backend_notify_object_modified (cal->priv->backend, old_object, object); + e_cal_backend_notify_component_modified (cal->priv->backend, old_component, component); } /** @@ -1232,8 +1232,8 @@ e_data_cal_respond_modify_object (EDataCal *cal, * @cal: A calendar client interface. * @error: Operation error, if any, automatically freed if passed it. * @uid: UID of the removed object. - * @old_object: The old object as an iCalendar string. - * @object: The new object as an iCalendar string. This will not be NULL only + * @old_component: The old #icalcomponent. + * @component: The new #icalcomponent. This will not be NULL only * when removing instances of a recurring appointment. * * Notifies listeners of the completion of the remove_object method call. @@ -1245,8 +1245,8 @@ e_data_cal_respond_remove_object (EDataCal *cal, guint32 opid, GError *error, const ECalComponentId *id, - const gchar *old_object, - const gchar *object) + icalcomponent *old_component, + icalcomponent *component) { op_complete (cal, opid); @@ -1258,7 +1258,7 @@ e_data_cal_respond_remove_object (EDataCal *cal, if (error) g_error_free (error); else - e_cal_backend_notify_object_removed (cal->priv->backend, id, old_object, object); + e_cal_backend_notify_component_removed (cal->priv->backend, id, old_component, component); } /** diff --git a/calendar/libedata-cal/e-data-cal.h b/calendar/libedata-cal/e-data-cal.h index 4bb97884a..9f3e5f422 100644 --- a/calendar/libedata-cal/e-data-cal.h +++ b/calendar/libedata-cal/e-data-cal.h @@ -136,9 +136,9 @@ void e_data_cal_respond_set_backend_property (EDataCal *cal, guint32 opid, GEr void e_data_cal_respond_get_object (EDataCal *cal, guint32 opid, GError *error, const gchar *object); void e_data_cal_respond_get_object_list (EDataCal *cal, guint32 opid, GError *error, const GSList *objects); void e_data_cal_respond_get_free_busy (EDataCal *cal, guint32 opid, GError *error); -void e_data_cal_respond_create_object (EDataCal *cal, guint32 opid, GError *error, const gchar *uid, const gchar *object); -void e_data_cal_respond_modify_object (EDataCal *cal, guint32 opid, GError *error, const gchar *old_object, const gchar *object); -void e_data_cal_respond_remove_object (EDataCal *cal, guint32 opid, GError *error, const ECalComponentId *id, const gchar *old_object, const gchar *object); +void e_data_cal_respond_create_object (EDataCal *cal, guint32 opid, GError *error, const gchar *uid, icalcomponent *component); +void e_data_cal_respond_modify_object (EDataCal *cal, guint32 opid, GError *error, icalcomponent *old_component, icalcomponent *component); +void e_data_cal_respond_remove_object (EDataCal *cal, guint32 opid, GError *error, const ECalComponentId *id, icalcomponent *old_component, icalcomponent *component); void e_data_cal_respond_receive_objects (EDataCal *cal, guint32 opid, GError *error); void e_data_cal_respond_send_objects (EDataCal *cal, guint32 opid, GError *error, const GSList *users, const gchar *calobj); void e_data_cal_respond_get_attachment_uris (EDataCal *cal, guint32 opid, GError *error, const GSList *attachments); |
