[evolution-data-server] Bug 670457: Add bulk methods to ECalClient
- From: Christophe Dumez <cdumez src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-data-server] Bug 670457: Add bulk methods to ECalClient
- Date: Tue, 27 Mar 2012 18:31:33 +0000 (UTC)
commit 4a3f2b0930e236580f9044217d77536170f48ab5
Author: Christophe Dumez <christophe dumez intel com>
Date: Tue Feb 21 09:38:43 2012 +0200
Bug 670457: Add bulk methods to ECalClient
Add e_cal_client_create_objects*() / e_cal_client_modify_objects*() /
e_cal_client_remove_objects*() bulk methods to ECalClient.
calendar/backends/caldav/e-cal-backend-caldav.c | 252 ++++----
.../backends/contacts/e-cal-backend-contacts.c | 16 +-
calendar/backends/file/e-cal-backend-file.c | 713 +++++++++++---------
calendar/backends/http/e-cal-backend-http.c | 57 +-
calendar/libecal/e-cal-client.c | 476 +++++++++++++-
calendar/libecal/e-cal-client.h | 12 +
calendar/libecal/e-cal-util.h | 27 +
calendar/libecal/e-cal.c | 35 +-
calendar/libedata-cal/e-cal-backend-sync.c | 203 +++---
calendar/libedata-cal/e-cal-backend-sync.h | 12 +-
calendar/libedata-cal/e-cal-backend.c | 92 ++--
calendar/libedata-cal/e-cal-backend.h | 12 +-
calendar/libedata-cal/e-data-cal.c | 201 +++---
calendar/libedata-cal/e-data-cal.h | 6 +-
calendar/libegdbus/e-gdbus-cal.c | 271 +++++----
calendar/libegdbus/e-gdbus-cal.h | 50 +-
configure.ac | 6 +-
libedataserver/e-data-server-util.c | 20 +
libedataserver/e-data-server-util.h | 1 +
tests/libecal/client/Makefile.am | 3 +
tests/libecal/client/test-client-bulk-methods.c | 253 +++++++
21 files changed, 1823 insertions(+), 895 deletions(-)
---
diff --git a/calendar/backends/caldav/e-cal-backend-caldav.c b/calendar/backends/caldav/e-cal-backend-caldav.c
index 323d228..8df9121 100644
--- a/calendar/backends/caldav/e-cal-backend-caldav.c
+++ b/calendar/backends/caldav/e-cal-backend-caldav.c
@@ -3562,21 +3562,29 @@ get_ecalcomp_master_from_cache_or_fallback (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,
- ECalComponent **new_component,
- GError **perror)
+do_create_objects (ECalBackendCalDAV *cbdav,
+ const GSList *in_calobjs,
+ GSList **uids,
+ GSList **new_components,
+ GError **perror)
{
ECalComponent *comp;
gboolean online, did_put = FALSE;
struct icaltimetype current;
icalcomponent *icalcomp;
+ const gchar *in_calobj = in_calobjs->data;
const gchar *comp_uid;
if (!check_state (cbdav, &online, perror))
return;
+ /* We make the assumption that the in_calobjs list we're passed is always exactly one element long, since we haven't specified "bulk-adds"
+ * in our static capability list. This simplifies a lot of the logic, especially around asynchronous results. */
+ if (in_calobjs->next != NULL) {
+ g_propagate_error (perror, e_data_cal_create_error (UnsupportedMethod, _("CalDAV does not support bulk additions")));
+ return;
+ }
+
comp = e_cal_component_new_from_string (in_calobj);
if (comp == NULL) {
@@ -3639,11 +3647,11 @@ do_create_object (ECalBackendCalDAV *cbdav,
}
if (did_put) {
- if (uid)
- *uid = g_strdup (comp_uid);
+ if (uids)
+ *uids = g_slist_prepend (*uids, g_strdup (comp_uid));
- if (new_component)
- *new_component = get_ecalcomp_master_from_cache_or_fallback (cbdav, comp_uid, NULL, comp);
+ if (new_components)
+ *new_components = g_slist_prepend(*new_components, get_ecalcomp_master_from_cache_or_fallback (cbdav, comp_uid, NULL, comp));
}
g_object_unref (comp);
@@ -3651,12 +3659,12 @@ 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,
- ECalComponent **old_component,
- ECalComponent **new_component,
- GError **error)
+do_modify_objects (ECalBackendCalDAV *cbdav,
+ const GSList *calobjs,
+ CalObjModType mod,
+ GSList **old_components,
+ GSList **new_components,
+ GError **error)
{
ECalComponent *comp;
icalcomponent *cache_comp;
@@ -3664,13 +3672,21 @@ do_modify_object (ECalBackendCalDAV *cbdav,
ECalComponentId *id;
struct icaltimetype current;
gchar *href = NULL, *etag = NULL;
+ const gchar *calobj = calobjs->data;
- if (new_component)
- *new_component = NULL;
+ if (new_components)
+ *new_components = NULL;
if (!check_state (cbdav, &online, error))
return;
+ /* We make the assumption that the calobjs list we're passed is always exactly one element long, since we haven't specified "bulk-modifies"
+ * in our static capability list. This simplifies a lot of the logic, especially around asynchronous results. */
+ if (calobjs->next != NULL) {
+ g_propagate_error (error, e_data_cal_create_error (UnsupportedMethod, _("CalDAV does not support bulk modifications")));
+ return;
+ }
+
comp = e_cal_component_new_from_string (calobj);
if (comp == NULL) {
@@ -3712,8 +3728,8 @@ do_modify_object (ECalBackendCalDAV *cbdav,
/*ecalcomp_set_synch_state (comp, ECALCOMP_LOCALLY_MODIFIED);*/
}
- if (old_component) {
- *old_component = NULL;
+ if (old_components) {
+ *old_components = NULL;
if (e_cal_component_is_instance (comp)) {
/* set detached instance as the old object, if any */
@@ -3721,17 +3737,17 @@ do_modify_object (ECalBackendCalDAV *cbdav,
/* This will give a reference to 'old_component' */
if (old_instance) {
- *old_component = e_cal_component_clone (old_instance);
+ *old_components = g_slist_prepend (*old_components, e_cal_component_clone (old_instance));
g_object_unref (old_instance);
}
}
- if (!*old_component) {
+ if (!*old_components) {
icalcomponent *master = get_master_comp (cbdav, cache_comp);
if (master) {
/* set full component as the old object */
- *old_component = e_cal_component_new_from_icalcomponent (icalcomponent_new_clone (master));
+ *old_components = g_slist_prepend (*old_components, e_cal_component_new_from_icalcomponent (icalcomponent_new_clone (master)));
}
}
}
@@ -3743,8 +3759,8 @@ do_modify_object (ECalBackendCalDAV *cbdav,
icalcomponent *new_comp = e_cal_component_get_icalcomponent (comp);
/* new object is only this instance */
- if (new_component)
- *new_component = e_cal_component_clone (comp);
+ if (new_components)
+ *new_components = g_slist_prepend (*new_components, e_cal_component_clone (comp));
/* add the detached instance */
if (icalcomponent_isa (cache_comp) == ICAL_VCALENDAR_COMPONENT) {
@@ -3798,11 +3814,9 @@ do_modify_object (ECalBackendCalDAV *cbdav,
}
if (did_put) {
- if (new_component && !*new_component) {
+ if (new_components && !*new_components) {
/* read the comp from cache again, as some servers can modify it on put */
- *new_component = get_ecalcomp_master_from_cache_or_fallback (cbdav, id->uid, id->rid, NULL);
-
- g_warn_if_fail (*new_component != NULL);
+ *new_components = g_slist_prepend (*new_components, get_ecalcomp_master_from_cache_or_fallback (cbdav, id->uid, id->rid, NULL));
}
}
@@ -3815,24 +3829,32 @@ 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,
- ECalComponent **old_component,
- ECalComponent **new_component,
- GError **perror)
+do_remove_objects (ECalBackendCalDAV *cbdav,
+ const GSList *ids,
+ CalObjModType mod,
+ GSList **old_components,
+ GSList **new_components,
+ GError **perror)
{
icalcomponent *cache_comp;
gboolean online;
gchar *href = NULL, *etag = NULL;
+ const gchar *uid = ((ECalComponentId *)ids->data)->uid;
+ const gchar *rid = ((ECalComponentId *)ids->data)->rid;
- if (new_component)
- *new_component = NULL;
+ if (new_components)
+ *new_components = NULL;
if (!check_state (cbdav, &online, perror))
return;
+ /* We make the assumption that the ids list we're passed is always exactly one element long, since we haven't specified "bulk-removes"
+ * in our static capability list. This simplifies a lot of the logic, especially around asynchronous results. */
+ if (ids->next != NULL) {
+ g_propagate_error (perror, e_data_cal_create_error (UnsupportedMethod, _("CalDAV does not support bulk removals")));
+ return;
+ }
+
cache_comp = get_comp_from_cache (cbdav, uid, NULL, &href, &etag);
if (cache_comp == NULL) {
@@ -3840,17 +3862,16 @@ do_remove_object (ECalBackendCalDAV *cbdav,
return;
}
- if (old_component) {
+ if (old_components) {
ECalComponent *old = e_cal_backend_store_get_component (cbdav->priv->store, uid, rid);
if (old) {
- *old_component = e_cal_component_clone (old);
+ *old_components = g_slist_prepend (*old_components, e_cal_component_clone (old));
g_object_unref (old);
} else {
icalcomponent *master = get_master_comp (cbdav, cache_comp);
-
if (master) {
- *old_component = e_cal_component_new_from_icalcomponent (icalcomponent_new_clone (master));
+ *old_components = g_slist_prepend (*old_components, e_cal_component_new_from_icalcomponent (icalcomponent_new_clone (master)));
}
}
}
@@ -3861,11 +3882,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 (new_component) {
+ if (new_components) {
icalcomponent *master = get_master_comp (cbdav, cache_comp);
-
- if (master)
- *new_component = e_cal_component_new_from_icalcomponent (icalcomponent_new_clone (master));
+ if (master) {
+ *new_components = g_slist_prepend (*new_components, e_cal_component_new_from_icalcomponent (icalcomponent_new_clone (master)));
+ }
}
} else {
/* this was the last instance, thus delete whole component */
@@ -4022,69 +4043,72 @@ process_object (ECalBackendCalDAV *cbdav,
is_declined = e_cal_backend_user_declined (e_cal_component_get_icalcomponent (ecomp));
if (is_in_cache) {
if (!is_declined) {
- ECalComponent *new_component = NULL, *old_component = NULL;
-
- do_modify_object (cbdav, new_obj_str, mod,
- &old_component, &new_component, &err);
- if (!err) {
- if (!old_component)
- e_cal_backend_notify_component_created (backend, new_component);
- else
- e_cal_backend_notify_component_modified (backend, old_component, new_component);
+ GSList *new_components = NULL, *old_components = NULL;
+ GSList new_obj_strs = {0,};
+
+ new_obj_strs.data = new_obj_str;
+ do_modify_objects (cbdav, &new_obj_strs, mod,
+ &old_components, &new_components, &err);
+ if (!err && new_components && new_components->data) {
+ if (!old_components || !old_components->data) {
+ e_cal_backend_notify_component_created (backend, new_components->data);
+ } else {
+ e_cal_backend_notify_component_modified (backend, old_components->data, new_components->data);
+ }
}
- if (new_component)
- g_object_unref (new_component);
- if (old_component)
- g_object_unref (old_component);
+ e_util_free_nullable_object_slist (old_components);
+ e_util_free_nullable_object_slist (new_components);
} else {
- ECalComponent *new_component = NULL, *old_component = NULL;
-
- do_remove_object (cbdav, id->uid, id->rid, mod, &old_component, &new_component, &err);
- if (!err) {
- if (new_component) {
- e_cal_backend_notify_component_modified (backend, old_component, new_component);
+ GSList *new_components = NULL, *old_components = NULL;
+ GSList ids = {0,};
+
+ ids.data = id;
+ do_remove_objects (cbdav, &ids, mod, &old_components, &new_components, &err);
+ if (!err && old_components && old_components->data) {
+ if (new_components && new_components->data) {
+ e_cal_backend_notify_component_modified (backend, old_components->data, new_components->data);
} else {
- e_cal_backend_notify_component_removed (backend, id, old_component, NULL);
+ e_cal_backend_notify_component_removed (backend, id, old_components->data, NULL);
}
}
- if (new_component)
- g_object_unref (new_component);
- if (old_component)
- g_object_unref (old_component);
+ e_util_free_nullable_object_slist (old_components);
+ e_util_free_nullable_object_slist (new_components);
}
} else if (!is_declined) {
- ECalComponent *new_component = NULL;
+ GSList *new_components = NULL;
+ GSList new_objs = {0,};
- do_create_object (cbdav, new_obj_str, NULL, &new_component, &err);
+ new_objs.data = new_obj_str;
+
+ do_create_objects (cbdav, &new_objs, NULL, &new_components, &err);
if (!err) {
- e_cal_backend_notify_component_created (backend, new_component);
+ if (new_components && new_components->data)
+ e_cal_backend_notify_component_created (backend, new_components->data);
}
- if (new_component)
- g_object_unref (new_component);
-
+ e_util_free_nullable_object_slist (new_components);
}
break;
case ICAL_METHOD_CANCEL:
if (is_in_cache) {
- ECalComponent *new_component = NULL, *old_component = NULL;
-
- do_remove_object (cbdav, id->uid, id->rid, CALOBJ_MOD_THIS, &old_component, &new_component, &err);
- if (!err) {
- if (new_component) {
- e_cal_backend_notify_component_modified (backend, old_component, new_component);
+ GSList *new_components = NULL, *old_components = NULL;
+ GSList ids = {0,};
+
+ ids.data = id;
+ do_remove_objects (cbdav, &ids, CALOBJ_MOD_THIS, &old_components, &new_components, &err);
+ if (!err && old_components && old_components->data) {
+ if (new_components && new_components->data) {
+ e_cal_backend_notify_component_modified (backend, old_components->data, new_components->data);
} else {
- e_cal_backend_notify_component_removed (backend, id, old_component, NULL);
+ e_cal_backend_notify_component_removed (backend, id, old_components->data, NULL);
}
}
- if (new_component)
- g_object_unref (new_component);
- if (old_component)
- g_object_unref (old_component);
+ e_util_free_nullable_object_slist (old_components);
+ e_util_free_nullable_object_slist (new_components);
} else {
err = EDC_ERROR (ObjectNotFound);
}
@@ -4203,57 +4227,55 @@ _func_name _params \
}
caldav_busy_stub (
- caldav_create_object,
+ caldav_create_objects,
(ECalBackendSync *backend,
EDataCal *cal,
GCancellable *cancellable,
- const gchar *in_calobj,
- gchar **uid,
- ECalComponent **new_component,
+ const GSList *in_calobjs,
+ GSList **uids,
+ GSList **new_components,
GError **perror),
- do_create_object,
+ do_create_objects,
(cbdav,
- in_calobj,
- uid,
- new_component,
+ in_calobjs,
+ uids,
+ new_components,
perror))
caldav_busy_stub (
- caldav_modify_object,
+ caldav_modify_objects,
(ECalBackendSync *backend,
EDataCal *cal,
GCancellable *cancellable,
- const gchar *calobj,
+ const GSList *calobjs,
CalObjModType mod,
- ECalComponent **old_component,
- ECalComponent **new_component,
+ GSList **old_components,
+ GSList **new_components,
GError **perror),
- do_modify_object,
+ do_modify_objects,
(cbdav,
- calobj,
+ calobjs,
mod,
- old_component,
- new_component,
+ old_components,
+ new_components,
perror))
caldav_busy_stub (
- caldav_remove_object,
+ caldav_remove_objects,
(ECalBackendSync *backend,
EDataCal *cal,
GCancellable *cancellable,
- const gchar *uid,
- const gchar *rid,
+ const GSList *ids,
CalObjModType mod,
- ECalComponent **old_component,
- ECalComponent **new_component,
+ GSList **old_components,
+ GSList **new_components,
GError **perror),
- do_remove_object,
+ do_remove_objects,
(cbdav,
- uid,
- rid,
+ ids,
mod,
- old_component,
- new_component,
+ old_components,
+ new_components,
perror))
caldav_busy_stub (
@@ -4862,9 +4884,9 @@ e_cal_backend_caldav_class_init (ECalBackendCalDAVClass *class)
sync_class->refresh_sync = caldav_refresh;
sync_class->remove_sync = caldav_remove;
- sync_class->create_object_sync = caldav_create_object;
- sync_class->modify_object_sync = caldav_modify_object;
- sync_class->remove_object_sync = caldav_remove_object;
+ sync_class->create_objects_sync = caldav_create_objects;
+ sync_class->modify_objects_sync = caldav_modify_objects;
+ sync_class->remove_objects_sync = caldav_remove_objects;
sync_class->receive_objects_sync = caldav_receive_objects;
sync_class->send_objects_sync = caldav_send_objects;
diff --git a/calendar/backends/contacts/e-cal-backend-contacts.c b/calendar/backends/contacts/e-cal-backend-contacts.c
index f595ece..d0e19d7 100644
--- a/calendar/backends/contacts/e-cal-backend-contacts.c
+++ b/calendar/backends/contacts/e-cal-backend-contacts.c
@@ -1582,13 +1582,13 @@ 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,
- ECalComponent **new_component,
- GError **perror)
+e_cal_backend_contacts_create_objects (ECalBackendSync *backend,
+ EDataCal *cal,
+ GCancellable *cancellable,
+ const GSList *calobjs,
+ GSList **uids,
+ GSList **new_components,
+ GError **perror)
{
g_propagate_error (perror, EDC_ERROR (PermissionDenied));
}
@@ -1612,7 +1612,7 @@ e_cal_backend_contacts_class_init (ECalBackendContactsClass *class)
sync_class->get_backend_property_sync = e_cal_backend_contacts_get_backend_property;
sync_class->open_sync = e_cal_backend_contacts_open;
sync_class->remove_sync = e_cal_backend_contacts_remove;
- sync_class->create_object_sync = e_cal_backend_contacts_create_object;
+ sync_class->create_objects_sync = e_cal_backend_contacts_create_objects;
sync_class->receive_objects_sync = e_cal_backend_contacts_receive_objects;
sync_class->send_objects_sync = e_cal_backend_contacts_send_objects;
sync_class->get_object_sync = e_cal_backend_contacts_get_object;
diff --git a/calendar/backends/file/e-cal-backend-file.c b/calendar/backends/file/e-cal-backend-file.c
index 79f4c8b..b63aea9 100644
--- a/calendar/backends/file/e-cal-backend-file.c
+++ b/calendar/backends/file/e-cal-backend-file.c
@@ -485,7 +485,10 @@ e_cal_backend_file_get_backend_property (ECalBackendSync *backend,
CAL_STATIC_CAPABILITY_NO_THISANDFUTURE ","
CAL_STATIC_CAPABILITY_DELEGATE_SUPPORTED ","
CAL_STATIC_CAPABILITY_REMOVE_ONLY_THIS ","
- CAL_STATIC_CAPABILITY_NO_THISANDPRIOR);
+ CAL_STATIC_CAPABILITY_NO_THISANDPRIOR ","
+ CAL_STATIC_CAPABILITY_BULK_ADDS ","
+ CAL_STATIC_CAPABILITY_BULK_MODIFIES ","
+ CAL_STATIC_CAPABILITY_BULK_REMOVES);
} else if (g_str_equal (prop_name, CAL_BACKEND_PROPERTY_CAL_EMAIL_ADDRESS) ||
g_str_equal (prop_name, CAL_BACKEND_PROPERTY_ALARM_EMAIL_ADDRESS)) {
/* A file backend has no particular email address associated
@@ -2242,96 +2245,125 @@ sanitize_component (ECalBackendFile *cbfile,
}
static void
-e_cal_backend_file_create_object (ECalBackendSync *backend,
- EDataCal *cal,
- GCancellable *cancellable,
- const gchar *in_calobj,
- gchar **uid,
- ECalComponent **new_component,
- GError **error)
+e_cal_backend_file_create_objects (ECalBackendSync *backend,
+ EDataCal *cal,
+ GCancellable *cancellable,
+ const GSList *in_calobjs,
+ GSList **uids,
+ GSList **new_components,
+ GError **error)
{
ECalBackendFile *cbfile;
ECalBackendFilePrivate *priv;
- icalcomponent *icalcomp;
- ECalComponent *comp;
- const gchar *comp_uid;
- struct icaltimetype current;
+ GSList *icalcomps = NULL;
+ const GSList *l;
cbfile = E_CAL_BACKEND_FILE (backend);
priv = cbfile->priv;
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_component != NULL, ObjectNotFound);
-
- /* Parse the icalendar text */
- icalcomp = icalparser_parse_string (in_calobj);
- if (!icalcomp) {
- g_propagate_error (error, EDC_ERROR (InvalidObject));
- return;
- }
+ e_return_data_cal_error_if_fail (in_calobjs != NULL, ObjectNotFound);
+ e_return_data_cal_error_if_fail (new_components != NULL, ObjectNotFound);
- /* Check kind with the parent */
- if (icalcomponent_isa (icalcomp) != e_cal_backend_get_kind (E_CAL_BACKEND (backend))) {
- icalcomponent_free (icalcomp);
- g_propagate_error (error, EDC_ERROR (InvalidObject));
- return;
- }
+ if (uids)
+ *uids = NULL;
g_static_rec_mutex_lock (&priv->idle_save_rmutex);
- /* Get the UID */
- comp_uid = icalcomponent_get_uid (icalcomp);
- if (!comp_uid) {
- gchar *new_uid;
+ /* First step, parse input strings and do uid verification: may fail */
+ for (l = in_calobjs; l; l = l->next) {
+ icalcomponent *icalcomp;
+ const gchar *comp_uid;
- new_uid = e_cal_component_gen_uid ();
- if (!new_uid) {
- icalcomponent_free (icalcomp);
+ /* Parse the icalendar text */
+ icalcomp = icalparser_parse_string ((gchar *) l->data);
+ if (!icalcomp) {
+ g_slist_free_full (icalcomps, (GDestroyNotify) icalcomponent_free);
+ g_static_rec_mutex_unlock (&priv->idle_save_rmutex);
+ g_propagate_error (error, EDC_ERROR (InvalidObject));
+ return;
+ }
+
+ /* Append icalcomponent to icalcomps */
+ icalcomps = g_slist_prepend (icalcomps, icalcomp);
+
+ /* Check kind with the parent */
+ if (icalcomponent_isa (icalcomp) != e_cal_backend_get_kind (E_CAL_BACKEND (backend))) {
+ g_slist_free_full (icalcomps, (GDestroyNotify) icalcomponent_free);
g_static_rec_mutex_unlock (&priv->idle_save_rmutex);
g_propagate_error (error, EDC_ERROR (InvalidObject));
return;
}
- icalcomponent_set_uid (icalcomp, new_uid);
+ /* Get the UID */
comp_uid = icalcomponent_get_uid (icalcomp);
+ if (!comp_uid) {
+ gchar *new_uid;
- g_free (new_uid);
- }
+ new_uid = e_cal_component_gen_uid ();
+ if (!new_uid) {
+ g_slist_free_full (icalcomps, (GDestroyNotify) icalcomponent_free);
+ g_static_rec_mutex_unlock (&priv->idle_save_rmutex);
+ g_propagate_error (error, EDC_ERROR (InvalidObject));
+ return;
+ }
- /* check the object is not in our cache */
- if (uid_in_use (cbfile, comp_uid)) {
- icalcomponent_free (icalcomp);
- g_static_rec_mutex_unlock (&priv->idle_save_rmutex);
- g_propagate_error (error, EDC_ERROR (ObjectIdAlreadyExists));
- return;
+ icalcomponent_set_uid (icalcomp, new_uid);
+ comp_uid = icalcomponent_get_uid (icalcomp);
+
+ g_free (new_uid);
+ }
+
+ /* check that the object is not in our cache */
+ if (uid_in_use (cbfile, comp_uid)) {
+ g_slist_free_full (icalcomps, (GDestroyNotify) icalcomponent_free);
+ g_static_rec_mutex_unlock (&priv->idle_save_rmutex);
+ g_propagate_error (error, EDC_ERROR (ObjectIdAlreadyExists));
+ return;
+ }
}
- /* Create the cal component */
- comp = e_cal_component_new ();
- e_cal_component_set_icalcomponent (comp, icalcomp);
+ icalcomps = g_slist_reverse (icalcomps);
+
+ /* Second step, add the objects */
+ for (l = icalcomps; l; l = l->next) {
+ ECalComponent *comp;
+ struct icaltimetype current;
+ icalcomponent *icalcomp = l->data;
+
+ /* Create the cal component */
+ comp = e_cal_component_new ();
+ e_cal_component_set_icalcomponent (comp, icalcomp);
+
+ /* Set the created and last modified times on the component */
+ current = icaltime_current_time_with_zone (icaltimezone_get_utc_timezone ());
+ e_cal_component_set_created (comp, ¤t);
+ e_cal_component_set_last_modified (comp, ¤t);
+
+ /* sanitize the component*/
+ sanitize_component (cbfile, comp);
+
+ /* Add the object */
+ add_component (cbfile, comp, TRUE);
- /* Set the created and last modified times on the component */
- current = icaltime_current_time_with_zone (icaltimezone_get_utc_timezone ());
- e_cal_component_set_created (comp, ¤t);
- e_cal_component_set_last_modified (comp, ¤t);
+ /* Keep the UID and the modified component to return them later */
+ if (uids)
+ *uids = g_slist_prepend (*uids, g_strdup (icalcomponent_get_uid (icalcomp)));
- /* sanitize the component*/
- sanitize_component (cbfile, comp);
+ *new_components = g_slist_prepend (*new_components, e_cal_component_clone (comp));
+ }
- /* Add the object */
- add_component (cbfile, comp, TRUE);
+ g_slist_free (icalcomps);
/* Save the file */
save (cbfile, TRUE);
- /* Return the UID and the modified component */
- if (uid)
- *uid = g_strdup (comp_uid);
+ g_static_rec_mutex_unlock (&priv->idle_save_rmutex);
- *new_component = e_cal_component_clone (comp);
+ if (uids)
+ *uids = g_slist_reverse (*uids);
- g_static_rec_mutex_unlock (&priv->idle_save_rmutex);
+ *new_components = g_slist_reverse (*new_components);
}
typedef struct {
@@ -2371,32 +2403,25 @@ remove_object_instance_cb (gpointer key,
}
static void
-e_cal_backend_file_modify_object (ECalBackendSync *backend,
- EDataCal *cal,
- GCancellable *cancellable,
- const gchar *calobj,
- CalObjModType mod,
- ECalComponent **old_component,
- ECalComponent **new_component,
- GError **error)
+e_cal_backend_file_modify_objects (ECalBackendSync *backend,
+ EDataCal *cal,
+ GCancellable *cancellable,
+ const GSList *calobjs,
+ CalObjModType mod,
+ GSList **old_components,
+ GSList **new_components,
+ GError **error)
{
- RemoveRecurrenceData rrdata;
ECalBackendFile *cbfile;
ECalBackendFilePrivate *priv;
- icalcomponent *icalcomp;
- const gchar *comp_uid;
- gchar *rid = NULL;
- gchar *real_rid;
- ECalComponent *comp, *recurrence;
- ECalBackendFileObject *obj_data;
- struct icaltimetype current;
- GList *detached = NULL;
+ GSList *icalcomps = NULL;
+ const GSList *l;
cbfile = E_CAL_BACKEND_FILE (backend);
priv = cbfile->priv;
e_return_data_cal_error_if_fail (priv->icalcomp != NULL, NoSuchCal);
- e_return_data_cal_error_if_fail (calobj != NULL, ObjectNotFound);
+ e_return_data_cal_error_if_fail (calobjs != NULL, ObjectNotFound);
switch (mod) {
case CALOBJ_MOD_THIS:
case CALOBJ_MOD_THISANDPRIOR:
@@ -2408,226 +2433,251 @@ e_cal_backend_file_modify_object (ECalBackendSync *backend,
return;
}
- /* Parse the icalendar text */
- icalcomp = icalparser_parse_string ((gchar *) calobj);
- if (!icalcomp) {
- g_propagate_error (error, EDC_ERROR (InvalidObject));
- return;
- }
-
- /* Check kind with the parent */
- if (icalcomponent_isa (icalcomp) != e_cal_backend_get_kind (E_CAL_BACKEND (backend))) {
- icalcomponent_free (icalcomp);
- g_propagate_error (error, EDC_ERROR (InvalidObject));
- return;
- }
+ if (old_components)
+ *old_components = NULL;
+ if (new_components)
+ *new_components = NULL;
g_static_rec_mutex_lock (&priv->idle_save_rmutex);
- /* Get the uid */
- comp_uid = icalcomponent_get_uid (icalcomp);
+ /* First step, parse input strings and do uid verification: may fail */
+ for (l = calobjs; l; l = l->next) {
+ const gchar *comp_uid;
+ icalcomponent *icalcomp;
- /* Get the object from our cache */
- if (!(obj_data = g_hash_table_lookup (priv->comp_uid_hash, comp_uid))) {
- icalcomponent_free (icalcomp);
- g_static_rec_mutex_unlock (&priv->idle_save_rmutex);
- g_propagate_error (error, EDC_ERROR (ObjectNotFound));
- return;
- }
+ /* Parse the icalendar text */
+ icalcomp = icalparser_parse_string (l->data);
+ if (!icalcomp) {
+ g_slist_free_full (icalcomps, (GDestroyNotify) icalcomponent_free);
+ g_static_rec_mutex_unlock (&priv->idle_save_rmutex);
+ g_propagate_error (error, EDC_ERROR (InvalidObject));
+ return;
+ }
- /* Create the cal component */
- comp = e_cal_component_new ();
- e_cal_component_set_icalcomponent (comp, icalcomp);
+ icalcomps = g_slist_prepend (icalcomps, icalcomp);
- /* Set the last modified time on the component */
- current = icaltime_current_time_with_zone (icaltimezone_get_utc_timezone ());
- e_cal_component_set_last_modified (comp, ¤t);
+ /* Check kind with the parent */
+ if (icalcomponent_isa (icalcomp) != e_cal_backend_get_kind (E_CAL_BACKEND (backend))) {
+ g_slist_free_full (icalcomps, (GDestroyNotify) icalcomponent_free);
+ g_static_rec_mutex_unlock (&priv->idle_save_rmutex);
+ g_propagate_error (error, EDC_ERROR (InvalidObject));
+ return;
+ }
- /* sanitize the component*/
- sanitize_component (cbfile, comp);
- rid = e_cal_component_get_recurid_as_string (comp);
+ /* Get the uid */
+ comp_uid = icalcomponent_get_uid (icalcomp);
- /* handle mod_type */
- switch (mod) {
- case CALOBJ_MOD_THIS :
- if (!rid || !*rid) {
- if (old_component && obj_data->full_object) {
- *old_component = e_cal_component_clone (obj_data->full_object);
- }
+ /* Get the object from our cache */
+ if (!g_hash_table_lookup (priv->comp_uid_hash, comp_uid)) {
+ g_slist_free_full (icalcomps, (GDestroyNotify) icalcomponent_free);
+ g_static_rec_mutex_unlock (&priv->idle_save_rmutex);
+ g_propagate_error (error, EDC_ERROR (ObjectNotFound));
+ return;
+ }
+ }
- /* replace only the full object */
- if (obj_data->full_object) {
- 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);
+ icalcomps = g_slist_reverse (icalcomps);
- g_object_unref (obj_data->full_object);
- }
+ /* Second step, update the objects */
+ for (l = icalcomps; l; l = l->next) {
+ struct icaltimetype current;
+ RemoveRecurrenceData rrdata;
+ GList *detached = NULL;
+ gchar *rid = NULL;
+ gchar *real_rid;
+ const gchar *comp_uid;
+ icalcomponent * icalcomp = l->data;
+ ECalComponent *comp, *recurrence;
+ ECalBackendFileObject *obj_data;
- /* add the new object */
- obj_data->full_object = comp;
+ comp_uid = icalcomponent_get_uid (icalcomp);
+ obj_data = g_hash_table_lookup (priv->comp_uid_hash, comp_uid);
- 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);
+ /* Create the cal component */
+ comp = e_cal_component_new ();
+ e_cal_component_set_icalcomponent (comp, icalcomp);
- save (cbfile, TRUE);
+ /* Set the last modified time on the component */
+ current = icaltime_current_time_with_zone (icaltimezone_get_utc_timezone ());
+ e_cal_component_set_last_modified (comp, ¤t);
- if (new_component) {
- *new_component = e_cal_component_clone (comp);
- }
+ /* sanitize the component*/
+ sanitize_component (cbfile, comp);
+ rid = e_cal_component_get_recurid_as_string (comp);
- g_static_rec_mutex_unlock (&priv->idle_save_rmutex);
- g_free (rid);
- return;
- }
+ /* handle mod_type */
+ switch (mod) {
+ case CALOBJ_MOD_THIS :
+ if (!rid || !*rid) {
+ if (old_components)
+ *old_components = g_slist_prepend (*old_components, obj_data->full_object ? e_cal_component_clone (obj_data->full_object) : NULL);
- if (g_hash_table_lookup_extended (obj_data->recurrences, rid, (gpointer *) &real_rid, (gpointer *) &recurrence)) {
- if (old_component) {
- *old_component = e_cal_component_clone (recurrence);
- }
+ /* replace only the full object */
+ if (obj_data->full_object) {
+ 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);
- /* 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);
- obj_data->recurrences_list = g_list_remove (obj_data->recurrences_list, recurrence);
- g_hash_table_remove (obj_data->recurrences, rid);
- }
+ g_object_unref (obj_data->full_object);
+ }
- /* add the detached instance */
- g_hash_table_insert (obj_data->recurrences,
- rid,
- 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);
- rid = NULL;
- break;
- case CALOBJ_MOD_THISANDPRIOR :
- case CALOBJ_MOD_THISANDFUTURE :
- if (!rid || !*rid) {
+ /* add the new object */
+ obj_data->full_object = comp;
- if (old_component && obj_data->full_object) {
- *old_component = e_cal_component_clone (obj_data->full_object);
+ 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);
+ break;
}
- remove_component (cbfile, comp_uid, obj_data);
+ if (g_hash_table_lookup_extended (obj_data->recurrences, rid, (gpointer *) &real_rid, (gpointer *) &recurrence)) {
+ if (*old_components)
+ *old_components = g_slist_prepend (*old_components, e_cal_component_clone (recurrence));
- /* Add the new object */
- add_component (cbfile, comp, TRUE);
- g_free (rid);
- rid = NULL;
+ /* 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);
+ obj_data->recurrences_list = g_list_remove (obj_data->recurrences_list, recurrence);
+ g_hash_table_remove (obj_data->recurrences, rid);
+ } else {
+ if (old_components)
+ *old_components = g_slist_prepend (*old_components, NULL);
+ }
+
+ /* add the detached instance */
+ g_hash_table_insert (obj_data->recurrences,
+ g_strdup (rid),
+ 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 :
+ case CALOBJ_MOD_THISANDFUTURE :
+ if (!rid || !*rid) {
+ if (old_components)
+ *old_components = g_slist_prepend (*old_components, obj_data->full_object ? e_cal_component_clone (obj_data->full_object) : NULL);
- /* remove the component from our data, temporarily */
- if (obj_data->full_object) {
- 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);
- }
+ remove_component (cbfile, comp_uid, obj_data);
- /* now deal with the detached recurrence */
- if (g_hash_table_lookup_extended (obj_data->recurrences, rid,
- (gpointer *) &real_rid, (gpointer *) &recurrence)) {
+ /* Add the new object */
+ add_component (cbfile, comp, TRUE);
+ break;
+ }
- if (old_component) {
- *old_component = e_cal_component_clone (recurrence);
+ /* remove the component from our data, temporarily */
+ if (obj_data->full_object) {
+ 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);
}
- /* 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);
- obj_data->recurrences_list = g_list_remove (obj_data->recurrences_list, recurrence);
- g_hash_table_remove (obj_data->recurrences, rid);
- } else {
+ /* now deal with the detached recurrence */
+ if (g_hash_table_lookup_extended (obj_data->recurrences, rid,
+ (gpointer *) &real_rid, (gpointer *) &recurrence)) {
+ if (old_components)
+ *old_components = g_slist_prepend (*old_components, e_cal_component_clone (recurrence));
- if (old_component && obj_data->full_object) {
- *old_component = e_cal_component_clone (obj_data->full_object);
+ /* 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);
+ obj_data->recurrences_list = g_list_remove (obj_data->recurrences_list, recurrence);
+ g_hash_table_remove (obj_data->recurrences, rid);
+ } else {
+ if (*old_components)
+ *old_components = g_slist_prepend (*old_components, obj_data->full_object ? e_cal_component_clone (obj_data->full_object) : NULL);
}
- }
- 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);
+ 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 */
- if (obj_data->full_object) {
- 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 modified object to the beginning of the list,
+ * so that it's always before any detached instance we
+ * might have */
+ if (obj_data->full_object) {
+ 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,
- rid,
- 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);
- rid = NULL;
- break;
- case CALOBJ_MOD_ALL :
- /* Remove the old version */
- if (old_component && obj_data->full_object) {
- *old_component = e_cal_component_clone (obj_data->full_object);
- }
+ /* add the new detached recurrence */
+ g_hash_table_insert (obj_data->recurrences,
+ g_strdup (rid),
+ 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 :
+ /* Remove the old version */
+ if (old_components)
+ *old_components = g_slist_prepend (*old_components, obj_data->full_object ? e_cal_component_clone (obj_data->full_object) : NULL);
- if (obj_data->recurrences_list) {
- /* has detached components, preserve them */
- GList *l;
+ if (obj_data->recurrences_list) {
+ /* has detached components, preserve them */
+ GList *ll;
- for (l = obj_data->recurrences_list; l; l = l->next) {
- detached = g_list_prepend (detached, g_object_ref (l->data));
+ for (ll = obj_data->recurrences_list; ll; ll = ll->next) {
+ detached = g_list_prepend (detached, g_object_ref (ll->data));
+ }
}
- }
- remove_component (cbfile, comp_uid, obj_data);
+ remove_component (cbfile, comp_uid, obj_data);
- /* Add the new object */
- add_component (cbfile, comp, TRUE);
+ /* Add the new object */
+ add_component (cbfile, comp, TRUE);
- if (detached) {
- /* it had some detached components, place them back */
- comp_uid = icalcomponent_get_uid (e_cal_component_get_icalcomponent (comp));
+ if (detached) {
+ /* it had some detached components, place them back */
+ comp_uid = icalcomponent_get_uid (e_cal_component_get_icalcomponent (comp));
- if ((obj_data = g_hash_table_lookup (priv->comp_uid_hash, comp_uid)) != NULL) {
- GList *l;
+ if ((obj_data = g_hash_table_lookup (priv->comp_uid_hash, comp_uid)) != NULL) {
+ GList *ll;
- for (l = detached; l; l = l->next) {
- ECalComponent *c = l->data;
+ for (ll = detached; ll; ll = ll->next) {
+ ECalComponent *c = ll->data;
- g_hash_table_insert (obj_data->recurrences, e_cal_component_get_recurid_as_string (c), c);
- icalcomponent_add_component (priv->icalcomp, e_cal_component_get_icalcomponent (c));
- priv->comp = g_list_append (priv->comp, c);
- obj_data->recurrences_list = g_list_append (obj_data->recurrences_list, c);
+ g_hash_table_insert (obj_data->recurrences, e_cal_component_get_recurid_as_string (c), c);
+ icalcomponent_add_component (priv->icalcomp, e_cal_component_get_icalcomponent (c));
+ priv->comp = g_list_append (priv->comp, c);
+ obj_data->recurrences_list = g_list_append (obj_data->recurrences_list, c);
+ }
}
+
+ g_list_free (detached);
}
+ break;
+ case CALOBJ_MOD_ONLY_THIS:
+ /* not reached, keep compiler happy */
+ break;
+ }
- g_list_free (detached);
+ g_free (rid);
+
+ if (new_components) {
+ *new_components = g_slist_prepend (*new_components, e_cal_component_clone (comp));
}
- break;
- case CALOBJ_MOD_ONLY_THIS:
- /* not reached, keep compiler happy */
- break;
}
- save (cbfile, TRUE);
- g_free (rid);
+ g_slist_free (icalcomps);
- if (new_component) {
- *new_component = e_cal_component_clone (comp);
- }
+ /* All the components were updated, now we save the file */
+ save (cbfile, TRUE);
g_static_rec_mutex_unlock (&priv->idle_save_rmutex);
+
+ if (old_components)
+ *old_components = g_slist_reverse (*old_components);
+
+ if (new_components)
+ *new_components = g_slist_reverse (*new_components);
}
/**
@@ -2824,28 +2874,26 @@ notify_comp_removed_cb (gpointer pecalcomp,
/* Remove_object handler for the file backend */
static void
-e_cal_backend_file_remove_object (ECalBackendSync *backend,
- EDataCal *cal,
- GCancellable *cancellable,
- const gchar *uid,
- const gchar *rid,
- CalObjModType mod,
- ECalComponent **old_component,
- ECalComponent **new_component,
- GError **error)
+e_cal_backend_file_remove_objects (ECalBackendSync *backend,
+ EDataCal *cal,
+ GCancellable *cancellable,
+ const GSList *ids,
+ CalObjModType mod,
+ GSList **old_components,
+ GSList **new_components,
+ GError **error)
{
ECalBackendFile *cbfile;
ECalBackendFilePrivate *priv;
- ECalBackendFileObject *obj_data;
- ECalComponent *comp;
- RemoveRecurrenceData rrdata;
- const gchar *recur_id = NULL;
+ const GSList *l;
cbfile = E_CAL_BACKEND_FILE (backend);
priv = cbfile->priv;
e_return_data_cal_error_if_fail (priv->icalcomp != NULL, NoSuchCal);
- e_return_data_cal_error_if_fail (uid != NULL, ObjectNotFound);
+ e_return_data_cal_error_if_fail (ids != NULL, ObjectNotFound);
+ e_return_data_cal_error_if_fail (old_components != NULL, ObjectNotFound);
+ e_return_data_cal_error_if_fail (new_components != NULL, ObjectNotFound);
switch (mod) {
case CALOBJ_MOD_THIS:
@@ -2859,78 +2907,115 @@ e_cal_backend_file_remove_object (ECalBackendSync *backend,
return;
}
- *old_component = *new_component = NULL;
+ *old_components = *new_components = NULL;
g_static_rec_mutex_lock (&priv->idle_save_rmutex);
- obj_data = g_hash_table_lookup (priv->comp_uid_hash, uid);
- if (!obj_data) {
- g_static_rec_mutex_unlock (&priv->idle_save_rmutex);
- g_propagate_error (error, EDC_ERROR (ObjectNotFound));
- return;
+ /* First step, validate the input */
+ for (l = ids; l; l = l->next) {
+ ECalComponentId *id = l->data;
+ /* Make the ID contains a uid */
+ if (!id || !id->uid) {
+ g_static_rec_mutex_unlock (&priv->idle_save_rmutex);
+ g_propagate_error (error, EDC_ERROR (ObjectNotFound));
+ return;
+ }
+ /* Check that it has a recurrence id if mod is CALOBJ_MOD_THISANDPRIOR
+ or CALOBJ_MOD_THISANDFUTURE */
+ if ((mod == CALOBJ_MOD_THISANDPRIOR || mod == CALOBJ_MOD_THISANDFUTURE) &&
+ (!id->rid || !*(id->rid))) {
+ g_static_rec_mutex_unlock (&priv->idle_save_rmutex);
+ g_propagate_error (error, EDC_ERROR (ObjectNotFound));
+ return;
+ }
+ /* Make sure the uid exists in the local hash table */
+ if (!g_hash_table_lookup (priv->comp_uid_hash, id->uid)) {
+ g_static_rec_mutex_unlock (&priv->idle_save_rmutex);
+ g_propagate_error (error, EDC_ERROR (ObjectNotFound));
+ return;
+ }
}
- if (rid && *rid)
- recur_id = rid;
+ /* Second step, remove objects from the calendar */
+ for (l = ids; l; l = l->next) {
+ const gchar *recur_id = NULL;
+ ECalComponent *comp;
+ RemoveRecurrenceData rrdata;
+ ECalBackendFileObject *obj_data;
+ ECalComponentId *id = l->data;
- switch (mod) {
- case CALOBJ_MOD_ALL :
- *old_component = clone_ecalcomp_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);
+ obj_data = g_hash_table_lookup (priv->comp_uid_hash, id->uid);
- *new_component = NULL;
- break;
- case CALOBJ_MOD_ONLY_THIS:
- case CALOBJ_MOD_THIS :
- remove_instance (cbfile, obj_data, uid, recur_id, mod,
- old_component, new_component, error);
- break;
- case CALOBJ_MOD_THISANDPRIOR :
- case CALOBJ_MOD_THISANDFUTURE :
- comp = obj_data->full_object;
+ if (id->rid && *(id->rid))
+ recur_id = id->rid;
- if (!recur_id || !*recur_id) {
- g_static_rec_mutex_unlock (&priv->idle_save_rmutex);
- g_propagate_error (error, EDC_ERROR (ObjectNotFound));
- return;
- }
+ switch (mod) {
+ case CALOBJ_MOD_ALL :
+ *old_components = g_slist_prepend (*old_components, clone_ecalcomp_from_fileobject (obj_data, recur_id));
+ *new_components = g_slist_prepend (*new_components, NULL);
- if (comp) {
- *old_component = e_cal_component_clone (comp);
+ if (obj_data->recurrences_list)
+ g_list_foreach (obj_data->recurrences_list, notify_comp_removed_cb, cbfile);
+ remove_component (cbfile, id->uid, obj_data);
+ break;
+ case CALOBJ_MOD_ONLY_THIS:
+ case CALOBJ_MOD_THIS: {
+ ECalComponent *old_component = NULL;
+ ECalComponent *new_component = NULL;
- /* remove the component from our data, temporarily */
- icalcomponent_remove_component (priv->icalcomp,
- e_cal_component_get_icalcomponent (comp));
- priv->comp = g_list_remove (priv->comp, comp);
+ obj_data = remove_instance (cbfile, obj_data, id->uid, recur_id, mod,
+ &old_component, &new_component, error);
- e_cal_util_remove_instances (e_cal_component_get_icalcomponent (comp),
- icaltime_from_string (recur_id), mod);
+ *old_components = g_slist_prepend (*old_components, old_component);
+ *new_components = g_slist_prepend (*new_components, new_component);
+ break;
}
+ case CALOBJ_MOD_THISANDPRIOR :
+ case CALOBJ_MOD_THISANDFUTURE :
+ comp = obj_data->full_object;
- /* now remove all detached instances */
- rrdata.cbfile = cbfile;
- rrdata.obj_data = obj_data;
- rrdata.rid = recur_id;
- rrdata.mod = mod;
- g_hash_table_foreach_remove (obj_data->recurrences, (GHRFunc) remove_object_instance_cb, &rrdata);
+ if (comp) {
+ *old_components = g_slist_prepend (*old_components, e_cal_component_clone (comp));
- /* add the modified object to the beginning of the list,
- * so that it's always before any detached instance we
- * might have */
- if (comp)
- priv->comp = g_list_prepend (priv->comp, comp);
+ /* remove the component from our data, temporarily */
+ icalcomponent_remove_component (priv->icalcomp,
+ e_cal_component_get_icalcomponent (comp));
+ priv->comp = g_list_remove (priv->comp, comp);
- if (obj_data->full_object) {
- *new_component = e_cal_component_clone (obj_data->full_object);
+ e_cal_util_remove_instances (e_cal_component_get_icalcomponent (comp),
+ icaltime_from_string (recur_id), mod);
+ } else {
+ *old_components = g_slist_prepend (*old_components, NULL);
+ }
+
+ /* now remove all detached instances */
+ rrdata.cbfile = cbfile;
+ rrdata.obj_data = obj_data;
+ rrdata.rid = recur_id;
+ 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 */
+ if (comp)
+ priv->comp = g_list_prepend (priv->comp, comp);
+
+ if (obj_data->full_object) {
+ *new_components = g_slist_prepend (*new_components, e_cal_component_clone (obj_data->full_object));
+ } else {
+ *new_components = g_slist_prepend (*new_components, NULL);
+ }
+ break;
}
- break;
}
save (cbfile, TRUE);
g_static_rec_mutex_unlock (&priv->idle_save_rmutex);
+
+ *old_components = g_slist_reverse (*old_components);
+ *new_components = g_slist_reverse (*new_components);
}
static gboolean
@@ -3443,9 +3528,9 @@ e_cal_backend_file_class_init (ECalBackendFileClass *class)
sync_class->get_backend_property_sync = e_cal_backend_file_get_backend_property;
sync_class->open_sync = e_cal_backend_file_open;
sync_class->remove_sync = e_cal_backend_file_remove;
- sync_class->create_object_sync = e_cal_backend_file_create_object;
- sync_class->modify_object_sync = e_cal_backend_file_modify_object;
- sync_class->remove_object_sync = e_cal_backend_file_remove_object;
+ sync_class->create_objects_sync = e_cal_backend_file_create_objects;
+ sync_class->modify_objects_sync = e_cal_backend_file_modify_objects;
+ sync_class->remove_objects_sync = e_cal_backend_file_remove_objects;
sync_class->receive_objects_sync = e_cal_backend_file_receive_objects;
sync_class->send_objects_sync = e_cal_backend_file_send_objects;
sync_class->get_object_sync = e_cal_backend_file_get_object;
diff --git a/calendar/backends/http/e-cal-backend-http.c b/calendar/backends/http/e-cal-backend-http.c
index d120ce4..66a7e15 100644
--- a/calendar/backends/http/e-cal-backend-http.c
+++ b/calendar/backends/http/e-cal-backend-http.c
@@ -1261,43 +1261,42 @@ 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,
- ECalComponent **new_component,
- GError **perror)
+e_cal_backend_http_create_objects (ECalBackendSync *backend,
+ EDataCal *cal,
+ GCancellable *cancellable,
+ const GSList *calobjs,
+ GSList **uids,
+ GSList **new_components,
+ 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,
- ECalComponent **old_component,
- ECalComponent **new_component,
- GError **perror)
+e_cal_backend_http_modify_objects (ECalBackendSync *backend,
+ EDataCal *cal,
+ GCancellable *cancellable,
+ const GSList *calobjs,
+ CalObjModType mod,
+ GSList **old_components,
+ GSList **new_components,
+ GError **perror)
{
g_propagate_error (perror, EDC_ERROR (PermissionDenied));
}
-/* Remove_object handler for the file backend */
+/* Remove_objects 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,
- ECalComponent **old_component,
- ECalComponent **new_component,
- GError **perror)
+e_cal_backend_http_remove_objects (ECalBackendSync *backend,
+ EDataCal *cal,
+ GCancellable *cancellable,
+ const GSList *ids,
+ CalObjModType mod,
+ GSList **old_components,
+ GSList **new_components,
+ GError **perror)
{
- *old_component = *new_component = NULL;
+ *old_components = *new_components = NULL;
g_propagate_error (perror, EDC_ERROR (PermissionDenied));
}
@@ -1389,9 +1388,9 @@ e_cal_backend_http_class_init (ECalBackendHttpClass *class)
sync_class->authenticate_user_sync = e_cal_backend_http_authenticate_user;
sync_class->refresh_sync = e_cal_backend_http_refresh;
sync_class->remove_sync = e_cal_backend_http_remove;
- sync_class->create_object_sync = e_cal_backend_http_create_object;
- sync_class->modify_object_sync = e_cal_backend_http_modify_object;
- sync_class->remove_object_sync = e_cal_backend_http_remove_object;
+ sync_class->create_objects_sync = e_cal_backend_http_create_objects;
+ sync_class->modify_objects_sync = e_cal_backend_http_modify_objects;
+ sync_class->remove_objects_sync = e_cal_backend_http_remove_objects;
sync_class->receive_objects_sync = e_cal_backend_http_receive_objects;
sync_class->send_objects_sync = e_cal_backend_http_send_objects;
sync_class->get_object_sync = e_cal_backend_http_get_object;
diff --git a/calendar/libecal/e-cal-client.c b/calendar/libecal/e-cal-client.c
index 7f37f4e..6685e07 100644
--- a/calendar/libecal/e-cal-client.c
+++ b/calendar/libecal/e-cal-client.c
@@ -562,6 +562,43 @@ convert_type (ECalClientSourceType type)
return AnyType;
}
+/*
+ * Converts a GSList of icalcomponents into a NULL-terminated array of
+ * valid UTF-8 strings, suitable for sending over DBus.
+ */
+static gchar **
+icalcomponent_slist_to_utf8_icomp_array (GSList *icalcomponents)
+{
+ gchar **array;
+ const GSList *l;
+ gint i = 0;
+
+ array = g_new0 (gchar *, g_slist_length (icalcomponents) + 1);
+ for (l = icalcomponents; l != NULL; l = l->next) {
+ gchar *comp_str = icalcomponent_as_ical_string_r ((icalcomponent *) l->data);
+ array[i++] = e_util_utf8_make_valid (comp_str);
+ g_free (comp_str);
+ }
+
+ return array;
+}
+
+/*
+ * Converts a GSList of icalcomponents into a GSList of strings.
+ */
+static GSList *
+icalcomponent_slist_to_string_slist (GSList *icalcomponents)
+{
+ GSList *strings = NULL;
+ const GSList *l;
+
+ for (l = icalcomponents; l != NULL; l = l->next) {
+ strings = g_slist_prepend (strings, icalcomponent_as_ical_string_r ((icalcomponent *) l->data));
+ }
+
+ return g_slist_reverse (strings);
+}
+
/**
* e_cal_client_new:
* @source: An #ESource pointer
@@ -2693,6 +2730,29 @@ complete_string_exchange (gboolean res,
}
static gboolean
+complete_strv_exchange (gboolean res,
+ gchar **out_strings,
+ GSList **result,
+ GError **error)
+{
+ g_return_val_if_fail (result != NULL, FALSE);
+
+ if (res && out_strings) {
+ *result = e_client_util_strv_to_slist ((const gchar * const*) out_strings);
+ } else {
+ *result = NULL;
+ res = FALSE;
+
+ if (error && !*error)
+ g_propagate_error (error, e_client_error_create (E_CLIENT_ERROR_INVALID_ARG, NULL));
+ }
+
+ g_strfreev (out_strings);
+
+ return res;
+}
+
+static gboolean
cal_client_get_default_object_from_cache_finish (EClient *client,
GAsyncResult *result,
gchar **prop_value,
@@ -3644,14 +3704,19 @@ e_cal_client_create_object (ECalClient *client,
gpointer user_data)
{
gchar *comp_str, *gdbus_comp = NULL;
+ const gchar *strv[2];
g_return_if_fail (icalcomp != NULL);
comp_str = icalcomponent_as_ical_string_r (icalcomp);
+ strv[0] = e_util_ensure_gdbus_string (comp_str, &gdbus_comp);
+ strv[1] = NULL;
- e_client_proxy_call_string (E_CLIENT (client), e_util_ensure_gdbus_string (comp_str, &gdbus_comp), cancellable, callback, user_data, e_cal_client_create_object,
- e_gdbus_cal_call_create_object,
- NULL, NULL, e_gdbus_cal_call_create_object_finish, NULL, NULL);
+ g_return_if_fail (strv[0] != NULL);
+
+ e_client_proxy_call_strv (E_CLIENT (client), strv, cancellable, callback, user_data, e_cal_client_create_object,
+ e_gdbus_cal_call_create_objects,
+ NULL, NULL, NULL, e_gdbus_cal_call_create_objects_finish, NULL);
g_free (comp_str);
g_free (gdbus_comp);
@@ -3679,11 +3744,17 @@ e_cal_client_create_object_finish (ECalClient *client,
GError **error)
{
gboolean res;
+ gchar **out_strings = NULL;
gchar *out_string = NULL;
g_return_val_if_fail (uid != NULL, FALSE);
- res = e_client_proxy_call_finish_string (E_CLIENT (client), result, &out_string, error, e_cal_client_create_object);
+ res = e_client_proxy_call_finish_strv (E_CLIENT (client), result, &out_strings, error, e_cal_client_create_object);
+
+ if (res && out_strings) {
+ out_string = g_strdup (out_strings[0]);
+ g_strfreev (out_strings);
+ }
return complete_string_exchange (res, out_string, uid, error);
}
@@ -3715,6 +3786,8 @@ e_cal_client_create_object_sync (ECalClient *client,
{
gboolean res;
gchar *comp_str, *gdbus_comp = NULL;
+ const gchar *strv[2];
+ gchar **out_strings = NULL;
gchar *out_string = NULL;
g_return_val_if_fail (client != NULL, FALSE);
@@ -3729,16 +3802,144 @@ e_cal_client_create_object_sync (ECalClient *client,
}
comp_str = icalcomponent_as_ical_string_r (icalcomp);
+ strv[0] = e_util_ensure_gdbus_string (comp_str, &gdbus_comp);
+ strv[1] = NULL;
+
+ g_return_val_if_fail (strv[0] != NULL, FALSE);
- res = e_client_proxy_call_sync_string__string (E_CLIENT (client), e_util_ensure_gdbus_string (comp_str, &gdbus_comp), &out_string, cancellable, error, e_gdbus_cal_call_create_object_sync);
+ res = e_client_proxy_call_sync_strv__strv (E_CLIENT (client), strv, &out_strings, cancellable, error, e_gdbus_cal_call_create_objects_sync);
g_free (comp_str);
g_free (gdbus_comp);
+ if (res && out_strings) {
+ out_string = g_strdup (out_strings[0]);
+ g_strfreev (out_strings);
+ }
+
return complete_string_exchange (res, out_string, uid, error);
}
/**
+ * e_cal_client_create_objects:
+ * @client: an #ECalClient
+ * @icalcomps: The components to create
+ * @cancellable: a #GCancellable; can be %NULL
+ * @callback: callback to call when a result is ready
+ * @user_data: user data for the @callback
+ *
+ * Requests the calendar backend to create the objects specified by the @icalcomps
+ * argument. Some backends would assign a specific UID to the newly created object,
+ * but this function does not modify the original @icalcomps if their UID changes.
+ * The call is finished by e_cal_client_create_objects_finish() from
+ * the @callback.
+ *
+ * Since: 3.6
+ **/
+void
+e_cal_client_create_objects (ECalClient *client,
+ GSList *icalcomps,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ gchar **array;
+
+ g_return_if_fail (client != NULL);
+ g_return_if_fail (E_IS_CAL_CLIENT (client));
+ g_return_if_fail (client->priv != NULL);
+ g_return_if_fail (icalcomps != NULL);
+
+ array = icalcomponent_slist_to_utf8_icomp_array (icalcomps);
+
+ e_client_proxy_call_strv (E_CLIENT (client), (const gchar * const *) array, cancellable, callback, user_data, e_cal_client_create_objects,
+ e_gdbus_cal_call_create_objects,
+ NULL, NULL, NULL, e_gdbus_cal_call_create_objects_finish, NULL);
+
+ g_strfreev (array);
+}
+
+/**
+ * e_cal_client_create_objects_finish:
+ * @client: an #ECalClient
+ * @result: a #GAsyncResult
+ * @uids: (out): Return value for the UIDs assigned to the new components by the calendar backend
+ * @error: (out): a #GError to set an error, if any
+ *
+ * Finishes previous call of e_cal_client_create_objects() and
+ * sets @uids to newly assigned UIDs for the created objects.
+ * This @uids should be freed with e_client_util_free_string_slist().
+ *
+ * Returns: %TRUE if successful, %FALSE otherwise.
+ *
+ * Since: 3.6
+ **/
+gboolean
+e_cal_client_create_objects_finish (ECalClient *client,
+ GAsyncResult *result,
+ GSList **uids,
+ GError **error)
+{
+ gboolean res;
+ gchar **out_strings = NULL;
+
+ g_return_val_if_fail (client != NULL, FALSE);
+ g_return_val_if_fail (E_IS_CAL_CLIENT (client), FALSE);
+ g_return_val_if_fail (client->priv != NULL, FALSE);
+ g_return_val_if_fail (uids != NULL, FALSE);
+
+ res = e_client_proxy_call_finish_strv (E_CLIENT (client), result, &out_strings, error, e_cal_client_create_objects);
+
+ return complete_strv_exchange (res, out_strings, uids, error);
+}
+
+/**
+ * e_cal_client_create_objects_sync:
+ * @client: an #ECalClient
+ * @icalcomps: The components to create
+ * @uids: (out): Return value for the UIDs assigned to the new components by the calendar backend
+ * @cancellable: a #GCancellable; can be %NULL
+ * @error: (out): a #GError to set an error, if any
+ *
+ * Requests the calendar backend to create the objects specified by the @icalcomps
+ * argument. Some backends would assign a specific UID to the newly created objects,
+ * in those cases these UIDs would be returned in the @uids argument. This function
+ * does not modify the original @icalcomps if their UID changes.
+ * Returned @uid should be freed with e_client_util_free_string_slist().
+ *
+ * Returns: %TRUE if successful, %FALSE otherwise.
+ *
+ * Since: 3.6
+ **/
+gboolean
+e_cal_client_create_objects_sync (ECalClient *client,
+ GSList *icalcomps,
+ GSList **uids,
+ GCancellable *cancellable,
+ GError **error)
+{
+ gboolean res;
+ gchar **array, **out_strings = NULL;
+
+ g_return_val_if_fail (client != NULL, FALSE);
+ g_return_val_if_fail (E_IS_CAL_CLIENT (client), FALSE);
+ g_return_val_if_fail (client->priv != NULL, FALSE);
+ g_return_val_if_fail (icalcomps != NULL, FALSE);
+ g_return_val_if_fail (uids != NULL, FALSE);
+
+ if (!client->priv->gdbus_cal) {
+ set_proxy_gone_error (error);
+ return FALSE;
+ }
+
+ array = icalcomponent_slist_to_utf8_icomp_array (icalcomps);
+
+ res = e_client_proxy_call_sync_strv__strv (E_CLIENT (client), (const gchar * const *) array, &out_strings, cancellable, error, e_gdbus_cal_call_create_objects_sync);
+
+ return complete_strv_exchange (res, out_strings, uids, error);
+}
+
+/**
* e_cal_client_modify_object:
* @client: an #ECalClient
* @icalcomp: Component to modify
@@ -3769,15 +3970,17 @@ e_cal_client_modify_object (ECalClient *client,
gpointer user_data)
{
gchar *comp_str, **strv;
+ GSList comp_strings = {0,};
g_return_if_fail (icalcomp != NULL);
comp_str = icalcomponent_as_ical_string_r (icalcomp);
- strv = e_gdbus_cal_encode_modify_object (comp_str, mod);
+ comp_strings.data = comp_str;
+ strv = e_gdbus_cal_encode_modify_objects (&comp_strings, mod);
e_client_proxy_call_strv (E_CLIENT (client), (const gchar * const *) strv, cancellable, callback, user_data, e_cal_client_modify_object,
- e_gdbus_cal_call_modify_object,
- e_gdbus_cal_call_modify_object_finish, NULL, NULL, NULL, NULL);
+ e_gdbus_cal_call_modify_objects,
+ e_gdbus_cal_call_modify_objects_finish, NULL, NULL, NULL, NULL);
g_strfreev (strv);
g_free (comp_str);
@@ -3832,6 +4035,7 @@ e_cal_client_modify_object_sync (ECalClient *client,
{
gboolean res;
gchar *comp_str, **strv;
+ GSList comp_strings = {0,};
g_return_val_if_fail (client != NULL, FALSE);
g_return_val_if_fail (E_IS_CAL_CLIENT (client), FALSE);
@@ -3844,9 +4048,10 @@ e_cal_client_modify_object_sync (ECalClient *client,
}
comp_str = icalcomponent_as_ical_string_r (icalcomp);
- strv = e_gdbus_cal_encode_modify_object (comp_str, mod);
+ comp_strings.data = comp_str;
+ strv = e_gdbus_cal_encode_modify_objects (&comp_strings, mod);
- res = e_client_proxy_call_sync_strv__void (E_CLIENT (client), (const gchar * const *) strv, cancellable, error, e_gdbus_cal_call_modify_object_sync);
+ res = e_client_proxy_call_sync_strv__void (E_CLIENT (client), (const gchar * const *) strv, cancellable, error, e_gdbus_cal_call_modify_objects_sync);
g_strfreev (strv);
g_free (comp_str);
@@ -3855,6 +4060,131 @@ e_cal_client_modify_object_sync (ECalClient *client,
}
/**
+ * e_cal_client_modify_objects:
+ * @client: an #ECalClient
+ * @comps: Components to modify
+ * @mod: Type of modification
+ * @cancellable: a #GCancellable; can be %NULL
+ * @callback: callback to call when a result is ready
+ * @user_data: user data for the @callback
+ *
+ * Requests the calendar backend to modify existing objects. If an object
+ * does not exist on the calendar, an error will be returned.
+ *
+ * For recurrent appointments, the @mod argument specifies what to modify,
+ * if all instances (CALOBJ_MOD_ALL), a single instance (CALOBJ_MOD_THIS),
+ * or a specific set of instances (CALOBJ_MOD_THISNADPRIOR and
+ * CALOBJ_MOD_THISANDFUTURE).
+ *
+ * The call is finished by e_cal_client_modify_objects_finish() from
+ * the @callback.
+ *
+ * Since: 3.6
+ **/
+void
+e_cal_client_modify_objects (ECalClient *client,
+ /* const */ GSList *comps,
+ CalObjModType mod,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GSList *comp_strings;
+ gchar **strv;
+
+ g_return_if_fail (client != NULL);
+ g_return_if_fail (E_IS_CAL_CLIENT (client));
+ g_return_if_fail (client->priv != NULL);
+ g_return_if_fail (comps != NULL);
+
+ comp_strings = icalcomponent_slist_to_string_slist(comps);
+ strv = e_gdbus_cal_encode_modify_objects (comp_strings, mod);
+
+ e_client_proxy_call_strv (E_CLIENT (client), (const gchar * const *) strv, cancellable, callback, user_data, e_cal_client_modify_objects,
+ e_gdbus_cal_call_modify_objects,
+ e_gdbus_cal_call_modify_objects_finish, NULL, NULL, NULL, NULL);
+
+ g_strfreev (strv);
+ e_client_util_free_string_slist (comp_strings);
+}
+
+/**
+ * e_cal_client_modify_objects_finish:
+ * @client: an #ECalClient
+ * @result: a #GAsyncResult
+ * @error: (out): a #GError to set an error, if any
+ *
+ * Finishes previous call of e_cal_client_modify_objects().
+ *
+ * Returns: %TRUE if successful, %FALSE otherwise.
+ *
+ * Since: 3.6
+ **/
+gboolean
+e_cal_client_modify_objects_finish (ECalClient *client,
+ GAsyncResult *result,
+ GError **error)
+{
+ g_return_val_if_fail (client != NULL, FALSE);
+ g_return_val_if_fail (E_IS_CAL_CLIENT (client), FALSE);
+ g_return_val_if_fail (client->priv != NULL, FALSE);
+
+ return e_client_proxy_call_finish_void (E_CLIENT (client), result, error, e_cal_client_modify_objects);
+}
+
+/**
+ * e_cal_client_modify_objects_sync:
+ * @client: an #ECalClient
+ * @comps: Components to modify
+ * @mod: Type of modification
+ * @cancellable: a #GCancellable; can be %NULL
+ * @error: (out): a #GError to set an error, if any
+ *
+ * Requests the calendar backend to modify existing objects. If an object
+ * does not exist on the calendar, an error will be returned.
+ *
+ * For recurrent appointments, the @mod argument specifies what to modify,
+ * if all instances (CALOBJ_MOD_ALL), a single instance (CALOBJ_MOD_THIS),
+ * or a specific set of instances (CALOBJ_MOD_THISNADPRIOR and
+ * CALOBJ_MOD_THISANDFUTURE).
+ *
+ * Returns: %TRUE if successful, %FALSE otherwise.
+ *
+ * Since: 3.6
+ **/
+gboolean
+e_cal_client_modify_objects_sync (ECalClient *client,
+ /* const */ GSList *comps,
+ CalObjModType mod,
+ GCancellable *cancellable,
+ GError **error)
+{
+ gboolean res;
+ gchar **strv;
+ GSList *comp_strings;
+
+ g_return_val_if_fail (client != NULL, FALSE);
+ g_return_val_if_fail (E_IS_CAL_CLIENT (client), FALSE);
+ g_return_val_if_fail (client->priv != NULL, FALSE);
+ g_return_val_if_fail (comps != NULL, FALSE);
+
+ if (!client->priv->gdbus_cal) {
+ set_proxy_gone_error (error);
+ return FALSE;
+ }
+
+ comp_strings = icalcomponent_slist_to_string_slist(comps);
+ strv = e_gdbus_cal_encode_modify_objects (comp_strings, mod);
+
+ res = e_client_proxy_call_sync_strv__void (E_CLIENT (client), (const gchar * const *) strv, cancellable, error, e_gdbus_cal_call_modify_objects_sync);
+
+ g_strfreev (strv);
+ e_client_util_free_string_slist (comp_strings);
+
+ return res;
+}
+
+/**
* e_cal_client_remove_object:
* @client: an #ECalClient
* @uid: UID of the object to remove
@@ -3885,14 +4215,19 @@ e_cal_client_remove_object (ECalClient *client,
gpointer user_data)
{
gchar **strv;
+ GSList ids = {0,};
+ ECalComponentId id;
g_return_if_fail (uid != NULL);
- strv = e_gdbus_cal_encode_remove_object (uid, rid, mod);
+ id.uid = (gchar *)uid;
+ id.rid = (gchar *)rid;
+ ids.data = &id;
+ strv = e_gdbus_cal_encode_remove_objects (&ids, mod);
e_client_proxy_call_strv (E_CLIENT (client), (const gchar * const *) strv, cancellable, callback, user_data, e_cal_client_remove_object,
- e_gdbus_cal_call_remove_object,
- e_gdbus_cal_call_remove_object_finish, NULL, NULL, NULL, NULL);
+ e_gdbus_cal_call_remove_objects,
+ e_gdbus_cal_call_remove_objects_finish, NULL, NULL, NULL, NULL);
g_strfreev (strv);
}
@@ -3946,6 +4281,8 @@ e_cal_client_remove_object_sync (ECalClient *client,
{
gboolean res;
gchar **strv;
+ GSList ids = {0,};
+ ECalComponentId id;
g_return_val_if_fail (client != NULL, FALSE);
g_return_val_if_fail (E_IS_CAL_CLIENT (client), FALSE);
@@ -3957,9 +4294,118 @@ e_cal_client_remove_object_sync (ECalClient *client,
return FALSE;
}
- strv = e_gdbus_cal_encode_remove_object (uid, rid, mod);
+ id.uid = (gchar *)uid;
+ id.rid = (gchar *)rid;
+ ids.data = &id;
+ strv = e_gdbus_cal_encode_remove_objects (&ids, mod);
+
+ res = e_client_proxy_call_sync_strv__void (E_CLIENT (client), (const gchar * const *) strv, cancellable, error, e_gdbus_cal_call_remove_objects_sync);
+
+ g_strfreev (strv);
+
+ return res;
+}
+
+/**
+ * e_cal_client_remove_objects:
+ * @client: an #ECalClient
+ * @ids: A list of #ECalComponentId objects identifying the objects to remove
+ * @mod: Type of the removal
+ * @cancellable: a #GCancellable; can be %NULL
+ * @callback: callback to call when a result is ready
+ * @user_data: user data for the @callback
+ *
+ * This function allows the removal of instances of recurrent
+ * appointments. #ECalComponentId objects can identify specific instances (if rid is not NULL).
+ * If what you want is to remove all instances, use a #NULL rid in the #ECalComponentId and CALOBJ_MOD_ALL
+ * for the @mod.
+ *
+ * The call is finished by e_cal_client_remove_objects_finish() from
+ * the @callback.
+ *
+ * Since: 3.6
+ **/
+void
+e_cal_client_remove_objects (ECalClient *client,
+ const GSList *ids,
+ CalObjModType mod,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ gchar **strv;
+
+ g_return_if_fail (ids != NULL);
+
+ strv = e_gdbus_cal_encode_remove_objects (ids, mod);
+
+ e_client_proxy_call_strv (E_CLIENT (client), (const gchar * const *) strv, cancellable, callback, user_data, e_cal_client_remove_objects,
+ e_gdbus_cal_call_remove_objects,
+ e_gdbus_cal_call_remove_objects_finish, NULL, NULL, NULL, NULL);
+
+ g_strfreev (strv);
+}
+
+/**
+ * e_cal_client_remove_objects_finish:
+ * @client: an #ECalClient
+ * @result: a #GAsyncResult
+ * @error: (out): a #GError to set an error, if any
+ *
+ * Finishes previous call of e_cal_client_remove_objects().
+ *
+ * Returns: %TRUE if successful, %FALSE otherwise.
+ *
+ * Since: 3.6
+ **/
+gboolean
+e_cal_client_remove_objects_finish (ECalClient *client,
+ GAsyncResult *result,
+ GError **error)
+{
+ return e_client_proxy_call_finish_void (E_CLIENT (client), result, error, e_cal_client_remove_objects);
+}
+
+/**
+ * e_cal_client_remove_objects_sync:
+ * @client: an #ECalClient
+ * @ids: A list of #ECalComponentId objects identifying the objects to remove
+ * @mod: Type of the removal
+ * @cancellable: a #GCancellable; can be %NULL
+ * @error: (out): a #GError to set an error, if any
+ *
+ * This function allows the removal of instances of recurrent
+ * appointments. #ECalComponentId objects can identify specific instances (if rid is not NULL).
+ * If what you want is to remove all instances, use a #NULL rid in the #ECalComponentId and CALOBJ_MOD_ALL
+ * for the @mod.
+ *
+ * Returns: %TRUE if successful, %FALSE otherwise.
+ *
+ * Since: 3.6
+ **/
+gboolean
+e_cal_client_remove_objects_sync (ECalClient *client,
+ const GSList *ids,
+ CalObjModType mod,
+ GCancellable *cancellable,
+ GError **error)
+{
+ gboolean res;
+ gchar **strv;
+
+ g_return_val_if_fail (client != NULL, FALSE);
+ g_return_val_if_fail (E_IS_CAL_CLIENT (client), FALSE);
+ g_return_val_if_fail (client->priv != NULL, FALSE);
+ g_return_val_if_fail (ids != NULL, FALSE);
+
+ if (!client->priv->gdbus_cal) {
+ set_proxy_gone_error (error);
+ return FALSE;
+ }
+
+ strv = e_gdbus_cal_encode_remove_objects (ids, mod);
- res = e_client_proxy_call_sync_strv__void (E_CLIENT (client), (const gchar * const *) strv, cancellable, error, e_gdbus_cal_call_remove_object_sync);
+ res = e_client_proxy_call_sync_strv__void (E_CLIENT (client), (const gchar * const *) strv, cancellable, error, e_gdbus_cal_call_remove_objects_sync);
g_strfreev (strv);
diff --git a/calendar/libecal/e-cal-client.h b/calendar/libecal/e-cal-client.h
index 3e77baf..1733511 100644
--- a/calendar/libecal/e-cal-client.h
+++ b/calendar/libecal/e-cal-client.h
@@ -206,14 +206,26 @@ void e_cal_client_create_object (ECalClient *client, /* const */ icalcomponen
gboolean e_cal_client_create_object_finish (ECalClient *client, GAsyncResult *result, gchar **uid, GError **error);
gboolean e_cal_client_create_object_sync (ECalClient *client, /* const */ icalcomponent *icalcomp, gchar **uid, GCancellable *cancellable, GError **error);
+void e_cal_client_create_objects (ECalClient *client, GSList *icalcomps, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data);
+gboolean e_cal_client_create_objects_finish (ECalClient *client, GAsyncResult *result, GSList **uids, GError **error);
+gboolean e_cal_client_create_objects_sync (ECalClient *client, GSList *icalcomps, GSList **uids, GCancellable *cancellable, GError **error);
+
void e_cal_client_modify_object (ECalClient *client, /* const */ icalcomponent *icalcomp, CalObjModType mod, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data);
gboolean e_cal_client_modify_object_finish (ECalClient *client, GAsyncResult *result, GError **error);
gboolean e_cal_client_modify_object_sync (ECalClient *client, /* const */ icalcomponent *icalcomp, CalObjModType mod, GCancellable *cancellable, GError **error);
+void e_cal_client_modify_objects (ECalClient *client, /* const */ GSList *icalcomps, CalObjModType mod, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data);
+gboolean e_cal_client_modify_objects_finish (ECalClient *client, GAsyncResult *result, GError **error);
+gboolean e_cal_client_modify_objects_sync (ECalClient *client, /* const */ GSList *icalcomps, CalObjModType mod, GCancellable *cancellable, GError **error);
+
void e_cal_client_remove_object (ECalClient *client, const gchar *uid, const gchar *rid, CalObjModType mod, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data);
gboolean e_cal_client_remove_object_finish (ECalClient *client, GAsyncResult *result, GError **error);
gboolean e_cal_client_remove_object_sync (ECalClient *client, const gchar *uid, const gchar *rid, CalObjModType mod, GCancellable *cancellable, GError **error);
+void e_cal_client_remove_objects (ECalClient *client, const GSList *ids, CalObjModType mod, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data);
+gboolean e_cal_client_remove_objects_finish (ECalClient *client, GAsyncResult *result, GError **error);
+gboolean e_cal_client_remove_objects_sync (ECalClient *client, const GSList *ids, CalObjModType mod, GCancellable *cancellable, GError **error);
+
void e_cal_client_receive_objects (ECalClient *client, /* const */ icalcomponent *icalcomp, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data);
gboolean e_cal_client_receive_objects_finish (ECalClient *client, GAsyncResult *result, GError **error);
gboolean e_cal_client_receive_objects_sync (ECalClient *client, /* const */ icalcomponent *icalcomp, GCancellable *cancellable, GError **error);
diff --git a/calendar/libecal/e-cal-util.h b/calendar/libecal/e-cal-util.h
index fe6a48d..966aeb5 100644
--- a/calendar/libecal/e-cal-util.h
+++ b/calendar/libecal/e-cal-util.h
@@ -113,6 +113,33 @@ gboolean e_cal_util_event_dates_match (icalcomponent *icalcomp1, icalcomponent *
#define CAL_STATIC_CAPABILITY_NO_TRANSPARENCY "no-transparency"
/**
+ * CAL_STATIC_CAPABILITY_BULK_ADDS:
+ *
+ * Flag indicating that the backend supports bulk additions.
+ *
+ * Since: 3.6
+ */
+#define CAL_STATIC_CAPABILITY_BULK_ADDS "bulk-adds"
+
+/**
+ * CAL_STATIC_CAPABILITY_BULK_MODIFIES:
+ *
+ * Flag indicating that the backend supports bulk modifications.
+ *
+ * Since: 3.6
+ */
+#define CAL_STATIC_CAPABILITY_BULK_MODIFIES "bulk-modifies"
+
+/**
+ * CAL_STATIC_CAPABILITY_BULK_REMOVES:
+ *
+ * Flag indicating that the backend supports bulk removals.
+ *
+ * Since: 3.6
+ */
+#define CAL_STATIC_CAPABILITY_BULK_REMOVES "bulk-removes"
+
+/**
* CAL_STATIC_CAPABILITY_REMOVE_ONLY_THIS:
*
* FIXME: Document me.
diff --git a/calendar/libecal/e-cal.c b/calendar/libecal/e-cal.c
index c2ab5c9..2a9bca1 100644
--- a/calendar/libecal/e-cal.c
+++ b/calendar/libecal/e-cal.c
@@ -3917,7 +3917,9 @@ e_cal_create_object (ECal *ecal,
GError **error)
{
ECalPrivate *priv;
- gchar *obj, *muid = NULL, *gdbus_obj = NULL;
+ gchar *obj, *gdbus_obj = NULL;
+ const gchar *strv[2];
+ gchar **muids = NULL;
e_return_error_if_fail (E_IS_CAL (ecal), E_CALENDAR_STATUS_INVALID_ARG);
e_return_error_if_fail (icalcomp != NULL, E_CALENDAR_STATUS_INVALID_ARG);
@@ -3930,8 +3932,10 @@ e_cal_create_object (ECal *ecal,
}
obj = icalcomponent_as_ical_string_r (icalcomp);
- if (!e_gdbus_cal_call_create_object_sync (priv->gdbus_cal, e_util_ensure_gdbus_string (obj, &gdbus_obj), &muid, NULL, error)) {
- g_free (muid);
+ strv[0] = e_util_ensure_gdbus_string (obj, &gdbus_obj);
+ strv[1] = NULL;
+
+ if (!e_gdbus_cal_call_create_objects_sync (priv->gdbus_cal, strv, &muids, NULL, error)) {
g_free (obj);
g_free (gdbus_obj);
@@ -3941,15 +3945,15 @@ e_cal_create_object (ECal *ecal,
g_free (obj);
g_free (gdbus_obj);
- if (!muid) {
+ if (!muids) {
E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_OTHER_ERROR, error);
} else {
- icalcomponent_set_uid (icalcomp, muid);
+ icalcomponent_set_uid (icalcomp, muids[0]);
if (uid)
- *uid = muid;
- else
- g_free (muid);
+ *uid = g_strdup (muids[0]);
+
+ g_strfreev (muids);
E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_OK, error);
}
@@ -3982,6 +3986,7 @@ e_cal_modify_object (ECal *ecal,
{
ECalPrivate *priv;
gchar *obj, **strv;
+ GSList objs = {0,};
e_return_error_if_fail (E_IS_CAL (ecal), E_CALENDAR_STATUS_INVALID_ARG);
e_return_error_if_fail (icalcomp, E_CALENDAR_STATUS_INVALID_ARG);
@@ -4003,8 +4008,9 @@ e_cal_modify_object (ECal *ecal,
}
obj = icalcomponent_as_ical_string_r (icalcomp);
- strv = e_gdbus_cal_encode_modify_object (obj, mod);
- if (!e_gdbus_cal_call_modify_object_sync (priv->gdbus_cal, (const gchar * const *) strv, NULL, error)) {
+ objs.data = obj;
+ strv = e_gdbus_cal_encode_modify_objects (&objs, mod);
+ if (!e_gdbus_cal_call_modify_objects_sync (priv->gdbus_cal, (const gchar * const *) strv, NULL, error)) {
g_free (obj);
g_strfreev (strv);
@@ -4073,6 +4079,8 @@ e_cal_remove_object_with_mod (ECal *ecal,
{
ECalPrivate *priv;
gchar **strv;
+ GSList ids = {0,};
+ ECalComponentId id;
e_return_error_if_fail (E_IS_CAL (ecal), E_CALENDAR_STATUS_INVALID_ARG);
e_return_error_if_fail (uid, E_CALENDAR_STATUS_INVALID_ARG);
@@ -4093,8 +4101,11 @@ e_cal_remove_object_with_mod (ECal *ecal,
E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
}
- strv = e_gdbus_cal_encode_remove_object (uid, rid, mod);
- if (!e_gdbus_cal_call_remove_object_sync (priv->gdbus_cal, (const gchar * const *) strv, NULL, error)) {
+ id.uid = (gchar *)uid;
+ id.rid = (gchar *)rid;
+ ids.data = &id;
+ strv = e_gdbus_cal_encode_remove_objects (&ids, mod);
+ if (!e_gdbus_cal_call_remove_objects_sync (priv->gdbus_cal, (const gchar * const *) strv, NULL, error)) {
g_strfreev (strv);
E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_DBUS_EXCEPTION, error);
diff --git a/calendar/libedata-cal/e-cal-backend-sync.c b/calendar/libedata-cal/e-cal-backend-sync.c
index 34ef6a2..f6226e5 100644
--- a/calendar/libedata-cal/e-cal-backend-sync.c
+++ b/calendar/libedata-cal/e-cal-backend-sync.c
@@ -11,6 +11,7 @@
#endif
#include "e-cal-backend-sync.h"
+#include "libedataserver/e-data-server-util.h"
#include <libical/icaltz-util.h>
#define E_CAL_BACKEND_SYNC_GET_PRIVATE(obj) \
@@ -307,96 +308,93 @@ e_cal_backend_sync_get_free_busy (ECalBackendSync *backend,
}
/**
- * e_cal_backend_sync_create_object:
+ * e_cal_backend_sync_create_objects:
* @backend: An ECalBackendSync object.
* @cal: An EDataCal object.
* @cancellable: a #GCancellable for the operation
- * @calobj: The object to be added.
- * @uid: Placeholder for server-generated UID.
- * @new_component: (out) (transfer full): Placeholder for returned #ECalComponent.
+ * @calobjs: The objects to be added.
+ * @uids: Placeholder for server-generated UIDs.
+ * @new_components: (out) (transfer full): Placeholder for returned #ECalComponent objects.
* @error: Out parameter for a #GError.
*
- * Calls the create_object_sync method on the given backend.
+ * Calls the create_objects_sync method on the given backend.
*/
void
-e_cal_backend_sync_create_object (ECalBackendSync *backend,
- EDataCal *cal,
- GCancellable *cancellable,
- const gchar *calobj,
- gchar **uid,
- ECalComponent **new_component,
- GError **error)
+e_cal_backend_sync_create_objects (ECalBackendSync *backend,
+ EDataCal *cal,
+ GCancellable *cancellable,
+ const GSList *calobjs,
+ GSList **uids,
+ GSList **new_components,
+ 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);
+ e_return_data_cal_error_if_fail (E_CAL_BACKEND_SYNC_GET_CLASS (backend)->create_objects_sync != NULL, UnsupportedMethod);
- LOCK_WRAPPER (create_object_sync, (backend, cal, cancellable, calobj, uid, new_component, error));
+ LOCK_WRAPPER (create_objects_sync, (backend, cal, cancellable, calobjs, uids, new_components, error));
}
/**
- * e_cal_backend_sync_modify_object:
+ * e_cal_backend_sync_modify_objects:
* @backend: An ECalBackendSync object.
* @cal: An EDataCal object.
* @cancellable: a #GCancellable for the operation
- * @calobj: Object to be modified.
+ * @calobjs: Objects to be modified.
* @mod: Type of modification to be done.
- * @old_component: (out) (transfer full): Placeholder for returning the old component as it was stored on the
+ * @old_components: (out) (transfer full): Placeholder for returning the old components as they were stored on the
* backend.
- * @new_component: (out) (transfer full): Placeholder for returning the new component as it has been stored
+ * @new_components: (out) (transfer full): Placeholder for returning the new components as they have been stored
* on the backend.
* @error: Out parameter for a #GError.
*
- * Calls the modify_object_sync method on the given backend.
+ * Calls the modify_objects_sync method on the given backend.
*/
void
-e_cal_backend_sync_modify_object (ECalBackendSync *backend,
- EDataCal *cal,
- GCancellable *cancellable,
- const gchar *calobj,
- CalObjModType mod,
- ECalComponent **old_component,
- ECalComponent **new_component,
- GError **error)
+e_cal_backend_sync_modify_objects (ECalBackendSync *backend,
+ EDataCal *cal,
+ GCancellable *cancellable,
+ const GSList *calobjs,
+ CalObjModType mod,
+ GSList **old_components,
+ GSList **new_components,
+ 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);
+ e_return_data_cal_error_if_fail (E_CAL_BACKEND_SYNC_GET_CLASS (backend)->modify_objects_sync != NULL, UnsupportedMethod);
- LOCK_WRAPPER (modify_object_sync, (backend, cal, cancellable, calobj, mod, old_component, new_component, error));
+ LOCK_WRAPPER (modify_objects_sync, (backend, cal, cancellable, calobjs, mod, old_components, new_components, error));
}
/**
- * e_cal_backend_sync_remove_object:
+ * e_cal_backend_sync_remove_objects:
* @backend: An ECalBackendSync object.
* @cal: An EDataCal object.
* @cancellable: a #GCancellable for the operation
- * @uid: UID of the object to remove.
- * @rid: Recurrence ID of the instance to remove, or NULL if removing the
- * whole object.
+ * @ids: List of #ECalComponentId objects identifying the objects to remove.
* @mod: Type of removal.
- * @old_component: (out) (transfer full): Placeholder for returning the old component as it was stored on the
+ * @old_components: (out) (transfer full): Placeholder for returning the old components as they were stored on the
* backend.
- * @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.
+ * @new_components: (out) (transfer full): Placeholder for returning the new components as they have been stored
+ * on the backend (when removing individual instances). If removing whole objects,
+ * they will be set to %NULL.
* @error: Out parameter for a #GError.
*
- * Calls the remove_object_sync method on the given backend.
+ * Calls the remove_objects_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,
- ECalComponent **old_component,
- ECalComponent **new_component,
- GError **error)
+e_cal_backend_sync_remove_objects (ECalBackendSync *backend,
+ EDataCal *cal,
+ GCancellable *cancellable,
+ const GSList *ids,
+ CalObjModType mod,
+ GSList **old_components,
+ GSList **new_components,
+ 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);
+ e_return_data_cal_error_if_fail (E_CAL_BACKEND_SYNC_GET_CLASS (backend)->remove_objects_sync != NULL, UnsupportedMethod);
- LOCK_WRAPPER (remove_object_sync, (backend, cal, cancellable, uid, rid, mod, old_component, new_component, error));
+ LOCK_WRAPPER (remove_objects_sync, (backend, cal, cancellable, ids, mod, old_components, new_components, error));
}
/**
@@ -728,80 +726,81 @@ cal_backend_get_free_busy (ECalBackend *backend,
g_slist_free (freebusyobjs);
}
+static GSList *
+ecalcomponent_slist_from_strings (const GSList *strings)
+{
+ GSList *ecalcomps = NULL;
+ const GSList *l;
+
+ for (l = strings; l; l = l->next) {
+ ECalComponent *component = e_cal_component_new_from_string (l->data);
+ ecalcomps = g_slist_prepend (ecalcomps, component);
+ }
+
+ return g_slist_reverse (ecalcomps);
+}
+
static void
-cal_backend_create_object (ECalBackend *backend,
- EDataCal *cal,
- guint32 opid,
- GCancellable *cancellable,
- const gchar *calobj)
+cal_backend_create_objects (ECalBackend *backend,
+ EDataCal *cal,
+ guint32 opid,
+ GCancellable *cancellable,
+ const GSList *calobjs)
{
GError *error = NULL;
- gchar *uid = NULL;
- ECalComponent *new_component = NULL;
+ GSList *uids = NULL;
+ GSList *new_components = NULL;
- e_cal_backend_sync_create_object (E_CAL_BACKEND_SYNC (backend), cal, cancellable, calobj, &uid, &new_component, &error);
+ e_cal_backend_sync_create_objects (E_CAL_BACKEND_SYNC (backend), cal, cancellable, calobjs, &uids, &new_components, &error);
- if (!new_component)
- new_component = e_cal_component_new_from_string (calobj);
+ if (!new_components)
+ new_components = ecalcomponent_slist_from_strings (calobjs);
- e_data_cal_respond_create_object (cal, opid, error, uid, new_component);
+ e_data_cal_respond_create_objects (cal, opid, error, uids, new_components);
- g_free (uid);
-
- if (new_component)
- g_object_unref (new_component);
+ g_slist_free_full (uids, g_free);
+ e_util_free_nullable_object_slist (new_components);
}
static void
-cal_backend_modify_object (ECalBackend *backend,
- EDataCal *cal,
- guint32 opid,
- GCancellable *cancellable,
- const gchar *calobj,
- CalObjModType mod)
+cal_backend_modify_objects (ECalBackend *backend,
+ EDataCal *cal,
+ guint32 opid,
+ GCancellable *cancellable,
+ const GSList *calobjs,
+ CalObjModType mod)
{
GError *error = NULL;
- ECalComponent *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);
+ GSList *old_components = NULL, *new_components = NULL;
- if (!old_component)
- old_component = e_cal_component_new_from_string (calobj);
+ e_cal_backend_sync_modify_objects (E_CAL_BACKEND_SYNC (backend), cal, cancellable, calobjs, mod, &old_components, &new_components, &error);
- e_data_cal_respond_modify_object (cal, opid, error, old_component, new_component);
+ if (!old_components)
+ old_components = ecalcomponent_slist_from_strings (calobjs);
- if (old_component)
- g_object_unref (old_component);
+ e_data_cal_respond_modify_objects (cal, opid, error, old_components, new_components);
- if (new_component)
- g_object_unref (new_component);
+ e_util_free_nullable_object_slist (old_components);
+ e_util_free_nullable_object_slist (new_components);
}
static void
-cal_backend_remove_object (ECalBackend *backend,
- EDataCal *cal,
- guint32 opid,
- GCancellable *cancellable,
- const gchar *uid,
- const gchar *rid,
- CalObjModType mod)
+cal_backend_remove_objects (ECalBackend *backend,
+ EDataCal *cal,
+ guint32 opid,
+ GCancellable *cancellable,
+ const GSList *ids,
+ CalObjModType mod)
{
GError *error = NULL;
- ECalComponent *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_component, &new_component, &error);
+ GSList *old_components = NULL, *new_components = NULL;
- e_data_cal_respond_remove_object (cal, opid, error, &compid, old_component, new_component);
+ e_cal_backend_sync_remove_objects (E_CAL_BACKEND_SYNC (backend), cal, cancellable, ids, mod, &old_components, &new_components, &error);
- if (old_component)
- g_object_unref (old_component);
+ e_data_cal_respond_remove_objects (cal, opid, error, ids, old_components, new_components);
- if (new_component)
- g_object_unref (new_component);
+ e_util_free_nullable_object_slist (old_components);
+ e_util_free_nullable_object_slist (new_components);
}
static void
@@ -1049,9 +1048,9 @@ e_cal_backend_sync_class_init (ECalBackendSyncClass *class)
backend_class->get_object = cal_backend_get_object;
backend_class->get_object_list = cal_backend_get_object_list;
backend_class->get_free_busy = cal_backend_get_free_busy;
- backend_class->create_object = cal_backend_create_object;
- backend_class->modify_object = cal_backend_modify_object;
- backend_class->remove_object = cal_backend_remove_object;
+ backend_class->create_objects = cal_backend_create_objects;
+ backend_class->modify_objects = cal_backend_modify_objects;
+ backend_class->remove_objects = cal_backend_remove_objects;
backend_class->receive_objects = cal_backend_receive_objects;
backend_class->send_objects = cal_backend_send_objects;
backend_class->get_attachment_uris = cal_backend_get_attachment_uris;
diff --git a/calendar/libedata-cal/e-cal-backend-sync.h b/calendar/libedata-cal/e-cal-backend-sync.h
index d3c2d13..6b7d180 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, ECalComponent **new_component, GError **error);
- void (* modify_object_sync) (ECalBackendSync *backend, EDataCal *cal, GCancellable *cancellable, const gchar *calobj, CalObjModType mod, ECalComponent **old_component, ECalComponent **new_component, GError **error);
- void (* remove_object_sync) (ECalBackendSync *backend, EDataCal *cal, GCancellable *cancellable, const gchar *uid, const gchar *rid, CalObjModType mod, ECalComponent **old_component, ECalComponent **new_component, GError **error);
+ void (* create_objects_sync) (ECalBackendSync *backend, EDataCal *cal, GCancellable *cancellable, const GSList *calobjs, GSList **uids, GSList **new_components, GError **error);
+ void (* modify_objects_sync) (ECalBackendSync *backend, EDataCal *cal, GCancellable *cancellable, const GSList *calobjs, CalObjModType mod, GSList **old_components, GSList **new_components, GError **error);
+ void (* remove_objects_sync) (ECalBackendSync *backend, EDataCal *cal, GCancellable *cancellable, const GSList *ids, CalObjModType mod, GSList **old_components, GSList **new_components, 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 **freebusyobjects, GError **error);
-void e_cal_backend_sync_create_object (ECalBackendSync *backend, EDataCal *cal, GCancellable *cancellable, const gchar *calobj, gchar **uid, ECalComponent **new_component, GError **error);
-void e_cal_backend_sync_modify_object (ECalBackendSync *backend, EDataCal *cal, GCancellable *cancellable, const gchar *calobj, CalObjModType mod, ECalComponent **old_component, ECalComponent **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, ECalComponent **old_component, ECalComponent **new_component, GError **error);
+void e_cal_backend_sync_create_objects (ECalBackendSync *backend, EDataCal *cal, GCancellable *cancellable, const GSList *calobjs, GSList **uids, GSList **new_components, GError **error);
+void e_cal_backend_sync_modify_objects (ECalBackendSync *backend, EDataCal *cal, GCancellable *cancellable, const GSList *calobjs, CalObjModType mod, GSList **old_components, GSList **new_components, GError **error);
+void e_cal_backend_sync_remove_objects (ECalBackendSync *backend, EDataCal *cal, GCancellable *cancellable, const GSList *ids, CalObjModType mod, GSList **old_components, GSList **new_components, 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 1894690..d956ae3 100644
--- a/calendar/libedata-cal/e-cal-backend.c
+++ b/calendar/libedata-cal/e-cal-backend.c
@@ -1014,105 +1014,103 @@ e_cal_backend_get_free_busy (ECalBackend *backend,
}
/**
- * e_cal_backend_create_object:
+ * e_cal_backend_create_objects:
* @backend: an #ECalBackend
* @cal: an #EDataCal
* @opid: the ID to use for this operation
* @cancellable: a #GCancellable for the operation
- * @calobj: The object to create.
+ * @calobjs: The objects to create (list of gchar *).
*
* Calls the create_object method on the given backend.
- * This might be finished with e_data_cal_respond_create_object().
+ * This might be finished with e_data_cal_respond_create_objects().
**/
void
-e_cal_backend_create_object (ECalBackend *backend,
- EDataCal *cal,
- guint32 opid,
- GCancellable *cancellable,
- const gchar *calobj)
+e_cal_backend_create_objects (ECalBackend *backend,
+ EDataCal *cal,
+ guint32 opid,
+ GCancellable *cancellable,
+ const GSList *calobjs)
{
g_return_if_fail (backend != NULL);
g_return_if_fail (E_IS_CAL_BACKEND (backend));
- g_return_if_fail (calobj != NULL);
+ g_return_if_fail (calobjs != NULL);
if (e_cal_backend_is_opening (backend))
- e_data_cal_respond_create_object (cal, opid, EDC_OPENING_ERROR, NULL, NULL);
- else if (!E_CAL_BACKEND_GET_CLASS (backend)->create_object)
- e_data_cal_respond_create_object (cal, opid, EDC_ERROR (UnsupportedMethod), NULL, NULL);
+ e_data_cal_respond_create_objects (cal, opid, EDC_OPENING_ERROR, NULL, NULL);
+ else if (!E_CAL_BACKEND_GET_CLASS (backend)->create_objects)
+ e_data_cal_respond_create_objects (cal, opid, EDC_ERROR (UnsupportedMethod), NULL, NULL);
else if (!e_cal_backend_is_opened (backend))
- e_data_cal_respond_create_object (cal, opid, EDC_NOT_OPENED_ERROR, NULL, NULL);
+ e_data_cal_respond_create_objects (cal, opid, EDC_NOT_OPENED_ERROR, NULL, NULL);
else
- (* E_CAL_BACKEND_GET_CLASS (backend)->create_object) (backend, cal, opid, cancellable, calobj);
+ (* E_CAL_BACKEND_GET_CLASS (backend)->create_objects) (backend, cal, opid, cancellable, calobjs);
}
/**
- * e_cal_backend_modify_object:
+ * e_cal_backend_modify_objects:
* @backend: an #ECalBackend
* @cal: an #EDataCal
* @opid: the ID to use for this operation
* @cancellable: a #GCancellable for the operation
- * @calobj: Object to be modified.
+ * @calobjs: Objects to be modified (list of gchar *).
* @mod: Type of modification.
*
- * Calls the modify_object method on the given backend.
- * This might be finished with e_data_cal_respond_modify_object().
+ * Calls the modify_objects method on the given backend.
+ * This might be finished with e_data_cal_respond_modify_objects().
**/
void
-e_cal_backend_modify_object (ECalBackend *backend,
- EDataCal *cal,
- guint32 opid,
- GCancellable *cancellable,
- const gchar *calobj,
- CalObjModType mod)
+e_cal_backend_modify_objects (ECalBackend *backend,
+ EDataCal *cal,
+ guint32 opid,
+ GCancellable *cancellable,
+ const GSList *calobjs,
+ CalObjModType mod)
{
g_return_if_fail (backend != NULL);
g_return_if_fail (E_IS_CAL_BACKEND (backend));
- g_return_if_fail (calobj != NULL);
+ g_return_if_fail (calobjs != NULL);
if (e_cal_backend_is_opening (backend))
- e_data_cal_respond_modify_object (cal, opid, EDC_OPENING_ERROR, NULL, NULL);
- else if (!E_CAL_BACKEND_GET_CLASS (backend)->modify_object)
- e_data_cal_respond_modify_object (cal, opid, EDC_ERROR (UnsupportedMethod), NULL, NULL);
+ e_data_cal_respond_modify_objects (cal, opid, EDC_OPENING_ERROR, NULL, NULL);
+ else if (!E_CAL_BACKEND_GET_CLASS (backend)->modify_objects)
+ e_data_cal_respond_modify_objects (cal, opid, EDC_ERROR (UnsupportedMethod), NULL, NULL);
else if (!e_cal_backend_is_opened (backend))
- e_data_cal_respond_modify_object (cal, opid, EDC_NOT_OPENED_ERROR, NULL, NULL);
+ e_data_cal_respond_modify_objects (cal, opid, EDC_NOT_OPENED_ERROR, NULL, NULL);
else
- (* E_CAL_BACKEND_GET_CLASS (backend)->modify_object) (backend, cal, opid, cancellable, calobj, mod);
+ (* E_CAL_BACKEND_GET_CLASS (backend)->modify_objects) (backend, cal, opid, cancellable, calobjs, mod);
}
/**
- * e_cal_backend_remove_object:
+ * e_cal_backend_remove_objects:
* @backend: an #ECalBackend
* @cal: an #EDataCal
* @opid: the ID to use for this operation
* @cancellable: a #GCancellable for the operation
- * @uid: Unique identifier of the object to remove.
- * @rid: A recurrence ID.
+ * @ids: List of #ECalComponentId objects identifying the objects to remove
* @mod: Type of removal.
*
- * Removes an object in a calendar backend. The backend will notify all of its
+ * Removes objects in a calendar backend. The backend will notify all of its
* clients about the change.
- * This might be finished with e_data_cal_respond_remove_object().
+ * This might be finished with e_data_cal_respond_remove_objects().
**/
void
-e_cal_backend_remove_object (ECalBackend *backend,
- EDataCal *cal,
- guint32 opid,
- GCancellable *cancellable,
- const gchar *uid,
- const gchar *rid,
- CalObjModType mod)
+e_cal_backend_remove_objects (ECalBackend *backend,
+ EDataCal *cal,
+ guint32 opid,
+ GCancellable *cancellable,
+ const GSList *ids,
+ CalObjModType mod)
{
g_return_if_fail (backend != NULL);
g_return_if_fail (E_IS_CAL_BACKEND (backend));
- g_return_if_fail (uid != NULL);
- g_return_if_fail (E_CAL_BACKEND_GET_CLASS (backend)->remove_object != NULL);
+ g_return_if_fail (ids != NULL);
+ g_return_if_fail (E_CAL_BACKEND_GET_CLASS (backend)->remove_objects != NULL);
if (e_cal_backend_is_opening (backend))
- e_data_cal_respond_remove_object (cal, opid, EDC_OPENING_ERROR, NULL, NULL, NULL);
+ e_data_cal_respond_remove_objects (cal, opid, EDC_OPENING_ERROR, NULL, NULL, NULL);
else if (!e_cal_backend_is_opened (backend))
- e_data_cal_respond_remove_object (cal, opid, EDC_NOT_OPENED_ERROR, NULL, NULL, NULL);
+ e_data_cal_respond_remove_objects (cal, opid, EDC_NOT_OPENED_ERROR, NULL, NULL, NULL);
else
- (* E_CAL_BACKEND_GET_CLASS (backend)->remove_object) (backend, cal, opid, cancellable, uid, rid, mod);
+ (* E_CAL_BACKEND_GET_CLASS (backend)->remove_objects) (backend, cal, opid, cancellable, ids, mod);
}
/**
diff --git a/calendar/libedata-cal/e-cal-backend.h b/calendar/libedata-cal/e-cal-backend.h
index 13cf488..20e99d0 100644
--- a/calendar/libedata-cal/e-cal-backend.h
+++ b/calendar/libedata-cal/e-cal-backend.h
@@ -160,9 +160,9 @@ struct _ECalBackendClass {
void (* get_object) (ECalBackend *backend, EDataCal *cal, guint32 opid, GCancellable *cancellable, const gchar *uid, const gchar *rid);
void (* get_object_list) (ECalBackend *backend, EDataCal *cal, guint32 opid, GCancellable *cancellable, const gchar *sexp);
void (* get_free_busy) (ECalBackend *backend, EDataCal *cal, guint32 opid, GCancellable *cancellable, const GSList *users, time_t start, time_t end);
- void (* create_object) (ECalBackend *backend, EDataCal *cal, guint32 opid, GCancellable *cancellable, const gchar *calobj);
- void (* modify_object) (ECalBackend *backend, EDataCal *cal, guint32 opid, GCancellable *cancellable, const gchar *calobj, CalObjModType mod);
- void (* remove_object) (ECalBackend *backend, EDataCal *cal, guint32 opid, GCancellable *cancellable, const gchar *uid, const gchar *rid, CalObjModType mod);
+ void (* create_objects) (ECalBackend *backend, EDataCal *cal, guint32 opid, GCancellable *cancellable, const GSList *calobjs);
+ void (* modify_objects) (ECalBackend *backend, EDataCal *cal, guint32 opid, GCancellable *cancellable, const GSList *calobjs, CalObjModType mod);
+ void (* remove_objects) (ECalBackend *backend, EDataCal *cal, guint32 opid, GCancellable *cancellable, const GSList *ids, CalObjModType mod);
void (* receive_objects) (ECalBackend *backend, EDataCal *cal, guint32 opid, GCancellable *cancellable, const gchar *calobj);
void (* send_objects) (ECalBackend *backend, EDataCal *cal, guint32 opid, GCancellable *cancellable, const gchar *calobj);
void (* get_attachment_uris) (ECalBackend *backend, EDataCal *cal, guint32 opid, GCancellable *cancellable, const gchar *uid, const gchar *rid);
@@ -212,9 +212,9 @@ void e_cal_backend_refresh (ECalBackend *backend, EDataCal *cal, guint32 opid
void e_cal_backend_get_object (ECalBackend *backend, EDataCal *cal, guint32 opid, GCancellable *cancellable, const gchar *uid, const gchar *rid);
void e_cal_backend_get_object_list (ECalBackend *backend, EDataCal *cal, guint32 opid, GCancellable *cancellable, const gchar *sexp);
void e_cal_backend_get_free_busy (ECalBackend *backend, EDataCal *cal, guint32 opid, GCancellable *cancellable, const GSList *users, time_t start, time_t end);
-void e_cal_backend_create_object (ECalBackend *backend, EDataCal *cal, guint32 opid, GCancellable *cancellable, const gchar *calobj);
-void e_cal_backend_modify_object (ECalBackend *backend, EDataCal *cal, guint32 opid, GCancellable *cancellable, const gchar *calobj, CalObjModType mod);
-void e_cal_backend_remove_object (ECalBackend *backend, EDataCal *cal, guint32 opid, GCancellable *cancellable, const gchar *uid, const gchar *rid, CalObjModType mod);
+void e_cal_backend_create_objects (ECalBackend *backend, EDataCal *cal, guint32 opid, GCancellable *cancellable, const GSList *calobjs);
+void e_cal_backend_modify_objects (ECalBackend *backend, EDataCal *cal, guint32 opid, GCancellable *cancellable, const GSList *calobjs, CalObjModType mod);
+void e_cal_backend_remove_objects (ECalBackend *backend, EDataCal *cal, guint32 opid, GCancellable *cancellable, const GSList *ids, CalObjModType mod);
void e_cal_backend_receive_objects (ECalBackend *backend, EDataCal *cal, guint32 opid, GCancellable *cancellable, const gchar *calobj);
void e_cal_backend_send_objects (ECalBackend *backend, EDataCal *cal, guint32 opid, GCancellable *cancellable, const gchar *calobj);
void e_cal_backend_get_attachment_uris (ECalBackend *backend, EDataCal *cal, guint32 opid, GCancellable *cancellable, const gchar *uid, const gchar *rid);
diff --git a/calendar/libedata-cal/e-data-cal.c b/calendar/libedata-cal/e-data-cal.c
index df1f682..680baf4 100644
--- a/calendar/libedata-cal/e-data-cal.c
+++ b/calendar/libedata-cal/e-data-cal.c
@@ -71,9 +71,9 @@ typedef enum {
OP_GET_OBJECT,
OP_GET_OBJECT_LIST,
OP_GET_FREE_BUSY,
- OP_CREATE_OBJECT,
- OP_MODIFY_OBJECT,
- OP_REMOVE_OBJECT,
+ OP_CREATE_OBJECTS,
+ OP_MODIFY_OBJECTS,
+ OP_REMOVE_OBJECTS,
OP_RECEIVE_OBJECTS,
OP_SEND_OBJECTS,
OP_GET_ATTACHMENT_URIS,
@@ -117,21 +117,21 @@ typedef struct {
time_t start, end;
GSList *users;
} fb;
- /* OP_CREATE_OBJECT */
+ /* OP_CREATE_OBJECTS */
+ GSList *calobjs;
/* OP_RECEIVE_OBJECTS */
/* OP_SEND_OBJECTS */
struct _co {
gchar *calobj;
} co;
- /* OP_MODIFY_OBJECT */
+ /* OP_MODIFY_OBJECTS */
struct _mo {
- gchar *calobj;
+ GSList *calobjs;
EDataCalObjModType mod;
} mo;
- /* OP_REMOVE_OBJECT */
+ /* OP_REMOVE_OBJECTS */
struct _ro {
- gchar *uid;
- gchar *rid;
+ GSList *ids;
EDataCalObjModType mod;
} ro;
/* OP_GET_TIMEZONE */
@@ -214,21 +214,19 @@ operation_thread (gpointer data,
break;
case OP_GET_FREE_BUSY:
e_cal_backend_get_free_busy (backend, op->cal, op->id, op->cancellable, op->d.fb.users, op->d.fb.start, op->d.fb.end);
- g_slist_foreach (op->d.fb.users, (GFunc) g_free, NULL);
- g_slist_free (op->d.fb.users);
+ g_slist_free_full (op->d.fb.users, g_free);
break;
- case OP_CREATE_OBJECT:
- e_cal_backend_create_object (backend, op->cal, op->id, op->cancellable, op->d.co.calobj);
- g_free (op->d.co.calobj);
+ case OP_CREATE_OBJECTS:
+ e_cal_backend_create_objects (backend, op->cal, op->id, op->cancellable, op->d.calobjs);
+ g_slist_free_full (op->d.calobjs, g_free);
break;
- case OP_MODIFY_OBJECT:
- e_cal_backend_modify_object (backend, op->cal, op->id, op->cancellable, op->d.mo.calobj, op->d.mo.mod);
- g_free (op->d.mo.calobj);
+ case OP_MODIFY_OBJECTS:
+ e_cal_backend_modify_objects (backend, op->cal, op->id, op->cancellable, op->d.mo.calobjs, op->d.mo.mod);
+ g_slist_free_full (op->d.mo.calobjs, g_free);
break;
- case OP_REMOVE_OBJECT:
- e_cal_backend_remove_object (backend, op->cal, op->id, op->cancellable, op->d.ro.uid, op->d.ro.rid && *op->d.ro.rid ? op->d.ro.rid : NULL, op->d.ro.mod);
- g_free (op->d.ro.uid);
- g_free (op->d.ro.rid);
+ case OP_REMOVE_OBJECTS:
+ e_cal_backend_remove_objects (backend, op->cal, op->id, op->cancellable, op->d.ro.ids, op->d.ro.mod);
+ g_slist_free_full (op->d.ro.ids, (GDestroyNotify)e_cal_component_free_id);
break;
case OP_RECEIVE_OBJECTS:
e_cal_backend_receive_objects (backend, op->cal, op->id, op->cancellable, op->d.co.calobj);
@@ -679,55 +677,55 @@ impl_Cal_get_free_busy (EGdbusCal *object,
}
static gboolean
-impl_Cal_create_object (EGdbusCal *object,
- GDBusMethodInvocation *invocation,
- const gchar *in_calobj,
- EDataCal *cal)
+impl_Cal_create_objects (EGdbusCal *object,
+ GDBusMethodInvocation *invocation,
+ const gchar * const *in_calobjs,
+ EDataCal *cal)
{
OperationData *op;
- op = op_new (OP_CREATE_OBJECT, cal);
- op->d.co.calobj = g_strdup (in_calobj);
+ op = op_new (OP_CREATE_OBJECTS, cal);
+ op->d.calobjs = e_util_strv_to_slist (in_calobjs);
- e_gdbus_cal_complete_create_object (cal->priv->gdbus_object, invocation, op->id);
+ e_gdbus_cal_complete_create_objects (cal->priv->gdbus_object, invocation, op->id);
e_operation_pool_push (ops_pool, op);
return TRUE;
}
static gboolean
-impl_Cal_modify_object (EGdbusCal *object,
- GDBusMethodInvocation *invocation,
- const gchar * const *in_calobj_mod,
- EDataCal *cal)
+impl_Cal_modify_objects (EGdbusCal *object,
+ GDBusMethodInvocation *invocation,
+ const gchar * const *in_mod_calobjs,
+ EDataCal *cal)
{
OperationData *op;
guint mod;
- op = op_new (OP_MODIFY_OBJECT, cal);
- g_return_val_if_fail (e_gdbus_cal_decode_modify_object (in_calobj_mod, &op->d.mo.calobj, &mod), FALSE);
+ op = op_new (OP_MODIFY_OBJECTS, cal);
+ g_return_val_if_fail (e_gdbus_cal_decode_modify_objects (in_mod_calobjs, &op->d.mo.calobjs, &mod), FALSE);
op->d.mo.mod = mod;
- e_gdbus_cal_complete_modify_object (cal->priv->gdbus_object, invocation, op->id);
+ e_gdbus_cal_complete_modify_objects (cal->priv->gdbus_object, invocation, op->id);
e_operation_pool_push (ops_pool, op);
return TRUE;
}
static gboolean
-impl_Cal_remove_object (EGdbusCal *object,
- GDBusMethodInvocation *invocation,
- const gchar * const *in_uid_rid_mod,
- EDataCal *cal)
+impl_Cal_remove_objects (EGdbusCal *object,
+ GDBusMethodInvocation *invocation,
+ const gchar * const *in_mod_ids,
+ EDataCal *cal)
{
OperationData *op;
guint mod = 0;
- op = op_new (OP_REMOVE_OBJECT, cal);
- g_return_val_if_fail (e_gdbus_cal_decode_remove_object (in_uid_rid_mod, &op->d.ro.uid, &op->d.ro.rid, &mod), FALSE);
+ op = op_new (OP_REMOVE_OBJECTS, cal);
+ g_return_val_if_fail (e_gdbus_cal_decode_remove_objects (in_mod_ids, &op->d.ro.ids, &mod), FALSE);
op->d.ro.mod = mod;
- e_gdbus_cal_complete_remove_object (cal->priv->gdbus_object, invocation, op->id);
+ e_gdbus_cal_complete_remove_objects (cal->priv->gdbus_object, invocation, op->id);
e_operation_pool_push (ops_pool, op);
return TRUE;
@@ -1163,102 +1161,125 @@ e_data_cal_respond_get_free_busy (EDataCal *cal,
}
/**
- * e_data_cal_respond_create_object:
+ * e_data_cal_respond_create_objects:
* @cal: A calendar client interface.
* @error: Operation error, if any, automatically freed if passed it.
- * @uid: UID of the object created.
- * @new_component: The newly created #ECalComponent.
+ * @uids: UIDs of the objects created.
+ * @new_components: The newly created #ECalComponent objects.
*
- * Notifies listeners of the completion of the create_object method call.
+ * Notifies listeners of the completion of the create_objects method call.
*
- * Since: 3.2
+ * Since: 3.6
*/
void
-e_data_cal_respond_create_object (EDataCal *cal,
- guint32 opid,
- GError *error,
- const gchar *uid,
- /* const */ ECalComponent *new_component)
+e_data_cal_respond_create_objects (EDataCal *cal,
+ guint32 opid,
+ GError *error,
+ const GSList *uids,
+ /* const */ GSList *new_components)
{
- gchar *gdbus_uid = NULL;
+ gchar **array = NULL;
+ const GSList *l;
+ gint i = 0;
op_complete (cal, opid);
+ array = g_new0 (gchar *, g_slist_length ((GSList *) uids) + 1);
+ for (l = uids; l != NULL; l = l->next) {
+ array[i++] = e_util_utf8_make_valid (l->data);
+ }
+
/* Translators: This is prefix to a detailed error message */
g_prefix_error (&error, "%s", _("Cannot create calendar object: "));
- e_gdbus_cal_emit_create_object_done (cal->priv->gdbus_object, opid, error, e_util_ensure_gdbus_string (uid, &gdbus_uid));
+ e_gdbus_cal_emit_create_objects_done (cal->priv->gdbus_object, opid, error, (const gchar * const *)array);
- g_free (gdbus_uid);
+ g_strfreev (array);
if (error)
g_error_free (error);
- else
- e_cal_backend_notify_component_created (cal->priv->backend, new_component);
+ else {
+ for (l = new_components; l; l = l->next) {
+ e_cal_backend_notify_component_created (cal->priv->backend, l->data);
+ }
+ }
}
/**
- * e_data_cal_respond_modify_object:
+ * e_data_cal_respond_modify_objects:
* @cal: A calendar client interface.
* @error: Operation error, if any, automatically freed if passed it.
- * @old_component: The old #ECalComponent.
- * @new_component: The new #ECalComponent.
+ * @old_components: The old #ECalComponents.
+ * @new_components: The new #ECalComponents.
*
- * Notifies listeners of the completion of the modify_object method call.
+ * Notifies listeners of the completion of the modify_objects method call.
*
- * Since: 3.2
+ * Since: 3.6
*/
void
-e_data_cal_respond_modify_object (EDataCal *cal,
- guint32 opid,
- GError *error,
- /* const */ ECalComponent *old_component,
- /* const */ ECalComponent *new_component)
+e_data_cal_respond_modify_objects (EDataCal *cal,
+ guint32 opid,
+ GError *error,
+ /* const */ GSList *old_components,
+ /* const */ GSList *new_components)
{
op_complete (cal, opid);
/* Translators: This is prefix to a detailed error message */
g_prefix_error (&error, "%s", _("Cannot modify calendar object: "));
- e_gdbus_cal_emit_modify_object_done (cal->priv->gdbus_object, opid, error);
+ e_gdbus_cal_emit_modify_objects_done (cal->priv->gdbus_object, opid, error);
if (error)
g_error_free (error);
- else
- e_cal_backend_notify_component_modified (cal->priv->backend, old_component, new_component);
+ else {
+ const GSList *lold = old_components, *lnew = new_components;
+ while (lold && lnew) {
+ e_cal_backend_notify_component_modified (cal->priv->backend, lold->data, lnew->data);
+ lold = lold->next;
+ lnew = lnew->next;
+ }
+ }
}
/**
- * e_data_cal_respond_remove_object:
+ * e_data_cal_respond_remove_objects:
* @cal: A calendar client interface.
* @error: Operation error, if any, automatically freed if passed it.
- * @id: ID of the removed object.
- * @old_component: The old #ECalComponent.
- * @new_component: The new #ECalComponent. This will not be NULL only
- * when removing instances of a recurring appointment.
+ * @ids: IDs of the removed objects.
+ * @old_components: The old #ECalComponents.
+ * @new_components: The new #ECalComponents. They will not be NULL only
+ * when removing instances of recurring appointments.
*
- * Notifies listeners of the completion of the remove_object method call.
+ * Notifies listeners of the completion of the remove_objects method call.
*
- * Since: 3.2
+ * Since: 3.6
*/
void
-e_data_cal_respond_remove_object (EDataCal *cal,
+e_data_cal_respond_remove_objects (EDataCal *cal,
guint32 opid,
GError *error,
- const ECalComponentId *id,
- /* const */ ECalComponent *old_component,
- /* const */ ECalComponent *new_component)
+ const GSList *ids,
+ /* const */ GSList *old_components,
+ /* const */ GSList *new_components)
{
op_complete (cal, opid);
/* Translators: This is prefix to a detailed error message */
g_prefix_error (&error, "%s", _("Cannot remove calendar object: "));
- e_gdbus_cal_emit_remove_object_done (cal->priv->gdbus_object, opid, error);
+ e_gdbus_cal_emit_remove_objects_done (cal->priv->gdbus_object, opid, error);
if (error)
g_error_free (error);
- else
- e_cal_backend_notify_component_removed (cal->priv->backend, id, old_component, new_component);
+ else {
+ const GSList *lid = ids, *lold = old_components, *lnew = new_components;
+ while (lid && lold && lnew) {
+ e_cal_backend_notify_component_removed (cal->priv->backend, lid->data, lold->data, lnew->data);
+ lid = lid->next;
+ lold = lold->next;
+ lnew = lnew->next;
+ }
+ }
}
/**
@@ -1768,14 +1789,14 @@ e_data_cal_init (EDataCal *ecal)
gdbus_object, "handle-get-free-busy",
G_CALLBACK (impl_Cal_get_free_busy), ecal);
g_signal_connect (
- gdbus_object, "handle-create-object",
- G_CALLBACK (impl_Cal_create_object), ecal);
+ gdbus_object, "handle-create-objects",
+ G_CALLBACK (impl_Cal_create_objects), ecal);
g_signal_connect (
- gdbus_object, "handle-modify-object",
- G_CALLBACK (impl_Cal_modify_object), ecal);
+ gdbus_object, "handle-modify-objects",
+ G_CALLBACK (impl_Cal_modify_objects), ecal);
g_signal_connect (
- gdbus_object, "handle-remove-object",
- G_CALLBACK (impl_Cal_remove_object), ecal);
+ gdbus_object, "handle-remove-objects",
+ G_CALLBACK (impl_Cal_remove_objects), ecal);
g_signal_connect (
gdbus_object, "handle-receive-objects",
G_CALLBACK (impl_Cal_receive_objects), ecal);
diff --git a/calendar/libedata-cal/e-data-cal.h b/calendar/libedata-cal/e-data-cal.h
index f9c5ecd..15daa43 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 */ ECalComponent *new_component);
-void e_data_cal_respond_modify_object (EDataCal *cal, guint32 opid, GError *error, /* const */ ECalComponent *old_component, /* const */ ECalComponent *new_component);
-void e_data_cal_respond_remove_object (EDataCal *cal, guint32 opid, GError *error, const ECalComponentId *id, /* const */ ECalComponent *old_component, /* const */ ECalComponent *new_component);
+void e_data_cal_respond_create_objects (EDataCal *cal, guint32 opid, GError *error, const GSList *uids, /*const */ GSList *new_components);
+void e_data_cal_respond_modify_objects (EDataCal *cal, guint32 opid, GError *error, /* const */ GSList *old_components, /* const */ GSList *new_components);
+void e_data_cal_respond_remove_objects (EDataCal *cal, guint32 opid, GError *error, const GSList *ids, /* const */ GSList *old_components, /* const */ GSList *new_components);
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 *attachment_uris);
diff --git a/calendar/libegdbus/e-gdbus-cal.c b/calendar/libegdbus/e-gdbus-cal.c
index 8c9212a..c8edbd8 100644
--- a/calendar/libegdbus/e-gdbus-cal.c
+++ b/calendar/libegdbus/e-gdbus-cal.c
@@ -25,6 +25,8 @@
#include <libedataserver/e-data-server-util.h>
#include <libedataserver/e-gdbus-marshallers.h>
+/* We only need the ECalComponentId structure from the following header */
+#include <libecal/e-cal-component.h>
#include "e-gdbus-cal.h"
@@ -63,12 +65,12 @@ enum
__GET_OBJECT_LIST_DONE_SIGNAL,
__GET_FREE_BUSY_METHOD,
__GET_FREE_BUSY_DONE_SIGNAL,
- __CREATE_OBJECT_METHOD,
- __CREATE_OBJECT_DONE_SIGNAL,
- __MODIFY_OBJECT_METHOD,
- __MODIFY_OBJECT_DONE_SIGNAL,
- __REMOVE_OBJECT_METHOD,
- __REMOVE_OBJECT_DONE_SIGNAL,
+ __CREATE_OBJECTS_METHOD,
+ __CREATE_OBJECTS_DONE_SIGNAL,
+ __MODIFY_OBJECTS_METHOD,
+ __MODIFY_OBJECTS_DONE_SIGNAL,
+ __REMOVE_OBJECTS_METHOD,
+ __REMOVE_OBJECTS_DONE_SIGNAL,
__RECEIVE_OBJECTS_METHOD,
__RECEIVE_OBJECTS_DONE_SIGNAL,
__SEND_OBJECTS_METHOD,
@@ -163,12 +165,12 @@ E_DECLARE_GDBUS_METHOD_DONE_EMISSION_HOOK_ASYNC_STRV (GDBUS_CAL_INTERFACE_NAME,
get_object_list)
E_DECLARE_GDBUS_METHOD_DONE_EMISSION_HOOK_ASYNC_VOID (GDBUS_CAL_INTERFACE_NAME,
get_free_busy)
-E_DECLARE_GDBUS_METHOD_DONE_EMISSION_HOOK_ASYNC_STRING (GDBUS_CAL_INTERFACE_NAME,
- create_object)
+E_DECLARE_GDBUS_METHOD_DONE_EMISSION_HOOK_ASYNC_STRV (GDBUS_CAL_INTERFACE_NAME,
+ create_objects)
E_DECLARE_GDBUS_METHOD_DONE_EMISSION_HOOK_ASYNC_VOID (GDBUS_CAL_INTERFACE_NAME,
- modify_object)
+ modify_objects)
E_DECLARE_GDBUS_METHOD_DONE_EMISSION_HOOK_ASYNC_VOID (GDBUS_CAL_INTERFACE_NAME,
- remove_object)
+ remove_objects)
E_DECLARE_GDBUS_METHOD_DONE_EMISSION_HOOK_ASYNC_VOID (GDBUS_CAL_INTERFACE_NAME,
receive_objects)
E_DECLARE_GDBUS_METHOD_DONE_EMISSION_HOOK_ASYNC_STRV (GDBUS_CAL_INTERFACE_NAME,
@@ -211,9 +213,9 @@ e_gdbus_cal_default_init (EGdbusCalIface *iface)
E_INIT_GDBUS_METHOD_ASYNC_STRV__STRING (EGdbusCalIface, "get_object", get_object, __GET_OBJECT_METHOD, __GET_OBJECT_DONE_SIGNAL)
E_INIT_GDBUS_METHOD_ASYNC_STRING__STRV (EGdbusCalIface, "get_object_list", get_object_list, __GET_OBJECT_LIST_METHOD, __GET_OBJECT_LIST_DONE_SIGNAL)
E_INIT_GDBUS_METHOD_ASYNC_STRV__VOID (EGdbusCalIface, "get_free_busy", get_free_busy, __GET_FREE_BUSY_METHOD, __GET_FREE_BUSY_DONE_SIGNAL)
- E_INIT_GDBUS_METHOD_ASYNC_STRING__STRING(EGdbusCalIface, "create_object", create_object, __CREATE_OBJECT_METHOD, __CREATE_OBJECT_DONE_SIGNAL)
- E_INIT_GDBUS_METHOD_ASYNC_STRV__VOID (EGdbusCalIface, "modify_object", modify_object, __MODIFY_OBJECT_METHOD, __MODIFY_OBJECT_DONE_SIGNAL)
- E_INIT_GDBUS_METHOD_ASYNC_STRV__VOID (EGdbusCalIface, "remove_object", remove_object, __REMOVE_OBJECT_METHOD, __REMOVE_OBJECT_DONE_SIGNAL)
+ E_INIT_GDBUS_METHOD_ASYNC_STRV__STRV (EGdbusCalIface, "create_objects", create_objects, __CREATE_OBJECTS_METHOD, __CREATE_OBJECTS_DONE_SIGNAL)
+ E_INIT_GDBUS_METHOD_ASYNC_STRV__VOID (EGdbusCalIface, "modify_objects", modify_objects, __MODIFY_OBJECTS_METHOD, __MODIFY_OBJECTS_DONE_SIGNAL)
+ E_INIT_GDBUS_METHOD_ASYNC_STRV__VOID (EGdbusCalIface, "remove_objects", remove_objects, __REMOVE_OBJECTS_METHOD, __REMOVE_OBJECTS_DONE_SIGNAL)
E_INIT_GDBUS_METHOD_ASYNC_STRING__VOID (EGdbusCalIface, "receive_objects", receive_objects, __RECEIVE_OBJECTS_METHOD, __RECEIVE_OBJECTS_DONE_SIGNAL)
E_INIT_GDBUS_METHOD_ASYNC_STRING__STRV (EGdbusCalIface, "send_objects", send_objects, __SEND_OBJECTS_METHOD, __SEND_OBJECTS_DONE_SIGNAL)
E_INIT_GDBUS_METHOD_ASYNC_STRV__STRV (EGdbusCalIface, "get_attachment_uris", get_attachment_uris, __GET_ATTACHMENT_URIS_METHOD, __GET_ATTACHMENT_URIS_DONE_SIGNAL)
@@ -547,170 +549,199 @@ e_gdbus_cal_call_get_free_busy_sync (GDBusProxy *proxy,
}
void
-e_gdbus_cal_call_create_object (GDBusProxy *proxy,
- const gchar *in_calobj,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
+e_gdbus_cal_call_create_objects (GDBusProxy *proxy,
+ const gchar * const *in_calobjs,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
{
- e_gdbus_proxy_call_string ("create_object", e_gdbus_cal_call_create_object, E_GDBUS_ASYNC_OP_KEEPER (proxy), in_calobj, cancellable, callback, user_data);
+ e_gdbus_proxy_call_strv ("create_objects", e_gdbus_cal_call_create_objects, E_GDBUS_ASYNC_OP_KEEPER (proxy), in_calobjs, cancellable, callback, user_data);
}
gboolean
-e_gdbus_cal_call_create_object_finish (GDBusProxy *proxy,
- GAsyncResult *result,
- gchar **out_uid,
- GError **error)
+e_gdbus_cal_call_create_objects_finish (GDBusProxy *proxy,
+ GAsyncResult *result,
+ gchar ***out_uids,
+ GError **error)
{
- return e_gdbus_proxy_finish_call_string (E_GDBUS_ASYNC_OP_KEEPER (proxy), result, out_uid, error, e_gdbus_cal_call_create_object);
+ return e_gdbus_proxy_finish_call_strv (E_GDBUS_ASYNC_OP_KEEPER (proxy), result, out_uids, error, e_gdbus_cal_call_create_objects);
}
gboolean
-e_gdbus_cal_call_create_object_sync (GDBusProxy *proxy,
- const gchar *in_calobj,
- gchar **out_uid,
- GCancellable *cancellable,
- GError **error)
+e_gdbus_cal_call_create_objects_sync (GDBusProxy *proxy,
+ const gchar * const *in_calobjs,
+ gchar ***out_uids,
+ GCancellable *cancellable,
+ GError **error)
{
- return e_gdbus_proxy_call_sync_string__string (proxy, in_calobj, out_uid, cancellable, error,
- e_gdbus_cal_call_create_object,
- e_gdbus_cal_call_create_object_finish);
+ return e_gdbus_proxy_call_sync_strv__strv (proxy, in_calobjs, out_uids, cancellable, error,
+ e_gdbus_cal_call_create_objects,
+ e_gdbus_cal_call_create_objects_finish);
}
/* free returned pointer with g_strfreev() */
gchar **
-e_gdbus_cal_encode_modify_object (const gchar *in_calobj,
- guint in_mod)
+e_gdbus_cal_encode_modify_objects (const GSList *in_calobjs,
+ guint in_mod)
{
gchar **strv;
+ const GSList *l;
+ gint i = 0;
- g_return_val_if_fail (in_calobj != NULL, NULL);
+ g_return_val_if_fail (in_calobjs != NULL, NULL);
- strv = g_new0 (gchar *, 3);
- strv[0] = e_util_utf8_make_valid (in_calobj);
- strv[1] = g_strdup_printf ("%u", (guint32) in_mod);
- strv[2] = NULL;
+ strv = g_new0 (gchar *, g_slist_length ((GSList *)in_calobjs) + 2);
+ strv[i++] = g_strdup_printf ("%u", (guint32) in_mod);
+
+ for (l = in_calobjs; l; l = l->next) {
+ strv[i++] = e_util_utf8_make_valid ((gchar *) l->data);
+ }
+
+ strv[i] = NULL;
return strv;
}
-/* free out_calobj with g_free() */
+/* free calobjs with g_slist_free_full(calobjs, g_free) */
gboolean
-e_gdbus_cal_decode_modify_object (const gchar * const *in_strv,
- gchar **out_calobj,
- guint *out_mod)
+e_gdbus_cal_decode_modify_objects (const gchar * const *in_strv,
+ GSList **calobjs,
+ guint *out_mod)
{
+ gint ii;
+
g_return_val_if_fail (in_strv != NULL, FALSE);
g_return_val_if_fail (in_strv[0] != NULL, FALSE);
g_return_val_if_fail (in_strv[1] != NULL, FALSE);
- g_return_val_if_fail (in_strv[2] == NULL, FALSE);
- g_return_val_if_fail (out_calobj != NULL, FALSE);
+ g_return_val_if_fail (calobjs != NULL, FALSE);
g_return_val_if_fail (out_mod != NULL, FALSE);
- *out_calobj = g_strdup (in_strv[0]);
- *out_mod = atoi (in_strv[1]);
+ *out_mod = atoi (in_strv[0]);
+ *calobjs = NULL;
+
+ for (ii = 1; in_strv[ii]; ii++) {
+ *calobjs = g_slist_prepend (*calobjs, g_strdup (in_strv[ii]));
+ }
+
+ *calobjs = g_slist_reverse (*calobjs);
return TRUE;
}
void
-e_gdbus_cal_call_modify_object (GDBusProxy *proxy,
- const gchar * const *in_calobj_mod,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
+e_gdbus_cal_call_modify_objects (GDBusProxy *proxy,
+ const gchar * const *in_mod_calobjs,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
{
- e_gdbus_proxy_call_strv ("modify_object", e_gdbus_cal_call_modify_object, E_GDBUS_ASYNC_OP_KEEPER (proxy), in_calobj_mod, cancellable, callback, user_data);
+ e_gdbus_proxy_call_strv ("modify_objects", e_gdbus_cal_call_modify_objects, E_GDBUS_ASYNC_OP_KEEPER (proxy), in_mod_calobjs, cancellable, callback, user_data);
}
gboolean
-e_gdbus_cal_call_modify_object_finish (GDBusProxy *proxy,
- GAsyncResult *result,
- GError **error)
+e_gdbus_cal_call_modify_objects_finish (GDBusProxy *proxy,
+ GAsyncResult *result,
+ GError **error)
{
- return e_gdbus_proxy_finish_call_void (E_GDBUS_ASYNC_OP_KEEPER (proxy), result, error, e_gdbus_cal_call_modify_object);
+ return e_gdbus_proxy_finish_call_void (E_GDBUS_ASYNC_OP_KEEPER (proxy), result, error, e_gdbus_cal_call_modify_objects);
}
gboolean
-e_gdbus_cal_call_modify_object_sync (GDBusProxy *proxy,
- const gchar * const *in_calobj_mod,
- GCancellable *cancellable,
- GError **error)
+e_gdbus_cal_call_modify_objects_sync (GDBusProxy *proxy,
+ const gchar * const *in_mod_calobjs,
+ GCancellable *cancellable,
+ GError **error)
{
- return e_gdbus_proxy_call_sync_strv__void (proxy, in_calobj_mod, cancellable, error,
- e_gdbus_cal_call_modify_object,
- e_gdbus_cal_call_modify_object_finish);
+ return e_gdbus_proxy_call_sync_strv__void (proxy, in_mod_calobjs, cancellable, error,
+ e_gdbus_cal_call_modify_objects,
+ e_gdbus_cal_call_modify_objects_finish);
}
/* free returned pointer with g_strfreev() */
gchar **
-e_gdbus_cal_encode_remove_object (const gchar *in_uid,
- const gchar *in_rid,
- guint in_mod)
+e_gdbus_cal_encode_remove_objects (const GSList *in_ids,
+ guint in_mod)
{
gchar **strv;
+ const GSList *l;
+ gint i = 0;
- g_return_val_if_fail (in_uid != NULL, NULL);
+ g_return_val_if_fail (in_ids != NULL, NULL);
- strv = g_new0 (gchar *, 4);
- strv[0] = e_util_utf8_make_valid (in_uid);
- strv[1] = e_util_utf8_make_valid (in_rid ? in_rid : "");
- strv[2] = g_strdup_printf ("%u", (guint32) in_mod);
- strv[3] = NULL;
+ strv = g_new0 (gchar *, 2 + 2 * g_slist_length ((GSList *)in_ids));
+ strv[i++] = g_strdup_printf ("%u", (guint32) in_mod);
+
+ for (l = in_ids; l; l = l->next) {
+ ECalComponentId *id = l->data;
+
+ strv[i++] = e_util_utf8_make_valid (id->uid);
+ strv[i++] = e_util_utf8_make_valid (id->rid ? id->rid : "");
+ }
+
+ strv[i] = NULL;
return strv;
}
-/* free out_uid and out_rid with g_free() */
+/* free ids g_slist_free_full(ids, g_free) */
gboolean
-e_gdbus_cal_decode_remove_object (const gchar * const *in_strv,
- gchar **out_uid,
- gchar **out_rid,
- guint *out_mod)
+e_gdbus_cal_decode_remove_objects (const gchar * const *in_strv,
+ GSList **out_ids,
+ guint *out_mod)
{
+ gint ii;
+
g_return_val_if_fail (in_strv != NULL, FALSE);
g_return_val_if_fail (in_strv[0] != NULL, FALSE);
g_return_val_if_fail (in_strv[1] != NULL, FALSE);
g_return_val_if_fail (in_strv[2] != NULL, FALSE);
- g_return_val_if_fail (in_strv[3] == NULL, FALSE);
- g_return_val_if_fail (out_uid != NULL, FALSE);
- g_return_val_if_fail (out_rid != NULL, FALSE);
+ g_return_val_if_fail (out_ids != NULL, FALSE);
g_return_val_if_fail (out_mod != NULL, FALSE);
- *out_uid = g_strdup (in_strv[0]);
- *out_rid = g_strdup (in_strv[1]);
- *out_mod = atoi (in_strv[2]);
+ *out_mod = atoi (in_strv[0]);
+
+ *out_ids = NULL;
+
+ for (ii = 1; in_strv[ii] && in_strv[ii + 1]; ii += 2) {
+ ECalComponentId *id = g_new (ECalComponentId, 1);
+ id->uid = g_strdup (in_strv[ii]);
+ id->rid = *in_strv[ii + 1] ? g_strdup (in_strv[ii + 1]) : NULL;
+
+ *out_ids = g_slist_prepend (*out_ids, id);
+ }
+
+ *out_ids = g_slist_reverse (*out_ids);
return TRUE;
}
void
-e_gdbus_cal_call_remove_object (GDBusProxy *proxy,
- const gchar * const *in_uid_rid_mod,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
+e_gdbus_cal_call_remove_objects (GDBusProxy *proxy,
+ const gchar * const *in_mod_ids,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
{
- e_gdbus_proxy_call_strv ("remove_object", e_gdbus_cal_call_remove_object, E_GDBUS_ASYNC_OP_KEEPER (proxy), in_uid_rid_mod, cancellable, callback, user_data);
+ e_gdbus_proxy_call_strv ("remove_objects", e_gdbus_cal_call_remove_objects, E_GDBUS_ASYNC_OP_KEEPER (proxy), in_mod_ids, cancellable, callback, user_data);
}
gboolean
-e_gdbus_cal_call_remove_object_finish (GDBusProxy *proxy,
- GAsyncResult *result,
- GError **error)
+e_gdbus_cal_call_remove_objects_finish (GDBusProxy *proxy,
+ GAsyncResult *result,
+ GError **error)
{
- return e_gdbus_proxy_finish_call_void (E_GDBUS_ASYNC_OP_KEEPER (proxy), result, error, e_gdbus_cal_call_remove_object);
+ return e_gdbus_proxy_finish_call_void (E_GDBUS_ASYNC_OP_KEEPER (proxy), result, error, e_gdbus_cal_call_remove_objects);
}
gboolean
-e_gdbus_cal_call_remove_object_sync (GDBusProxy *proxy,
- const gchar * const *in_uid_rid_mod,
- GCancellable *cancellable,
- GError **error)
+e_gdbus_cal_call_remove_objects_sync (GDBusProxy *proxy,
+ const gchar * const *in_mod_ids,
+ GCancellable *cancellable,
+ GError **error)
{
- return e_gdbus_proxy_call_sync_strv__void (proxy, in_uid_rid_mod, cancellable, error,
- e_gdbus_cal_call_remove_object,
- e_gdbus_cal_call_remove_object_finish);
+ return e_gdbus_proxy_call_sync_strv__void (proxy, in_mod_ids, cancellable, error,
+ e_gdbus_cal_call_remove_objects,
+ e_gdbus_cal_call_remove_objects_finish);
}
void
@@ -1163,13 +1194,13 @@ DECLARE_EMIT_DONE_SIGNAL_1 (get_object_list,
const gchar * const *)
DECLARE_EMIT_DONE_SIGNAL_0 (get_free_busy,
__GET_FREE_BUSY_DONE_SIGNAL)
-DECLARE_EMIT_DONE_SIGNAL_1 (create_object,
- __CREATE_OBJECT_DONE_SIGNAL,
- const gchar *)
-DECLARE_EMIT_DONE_SIGNAL_0 (modify_object,
- __MODIFY_OBJECT_DONE_SIGNAL)
-DECLARE_EMIT_DONE_SIGNAL_0 (remove_object,
- __REMOVE_OBJECT_DONE_SIGNAL)
+DECLARE_EMIT_DONE_SIGNAL_1 (create_objects,
+ __CREATE_OBJECTS_DONE_SIGNAL,
+ const gchar * const *)
+DECLARE_EMIT_DONE_SIGNAL_0 (modify_objects,
+ __MODIFY_OBJECTS_DONE_SIGNAL)
+DECLARE_EMIT_DONE_SIGNAL_0 (remove_objects,
+ __REMOVE_OBJECTS_DONE_SIGNAL)
DECLARE_EMIT_DONE_SIGNAL_0 (receive_objects,
__RECEIVE_OBJECTS_DONE_SIGNAL)
DECLARE_EMIT_DONE_SIGNAL_1 (send_objects,
@@ -1259,9 +1290,9 @@ E_DECLARE_GDBUS_ASYNC_METHOD_1 (cal, set_backend_property, propnamevalue, "as"
E_DECLARE_GDBUS_ASYNC_METHOD_1_WITH_RETURN (cal, get_object, uid_rid, "as", object, "s")
E_DECLARE_GDBUS_ASYNC_METHOD_1_WITH_RETURN (cal, get_object_list, sexp, "s", objects, "as")
E_DECLARE_GDBUS_ASYNC_METHOD_1 (cal, get_free_busy, start_stop_users, "as")
-E_DECLARE_GDBUS_ASYNC_METHOD_1_WITH_RETURN (cal, create_object, object, "s", uid, "s")
-E_DECLARE_GDBUS_ASYNC_METHOD_1 (cal, modify_object, object_mod, "as")
-E_DECLARE_GDBUS_ASYNC_METHOD_1 (cal, remove_object, uid_rid_mod, "as")
+E_DECLARE_GDBUS_ASYNC_METHOD_1_WITH_RETURN (cal, create_objects, objects, "as", uids, "as")
+E_DECLARE_GDBUS_ASYNC_METHOD_1 (cal, modify_objects, object_mod, "as")
+E_DECLARE_GDBUS_ASYNC_METHOD_1 (cal, remove_objects, mod_ids, "as")
E_DECLARE_GDBUS_ASYNC_METHOD_1 (cal, receive_objects, object, "s")
E_DECLARE_GDBUS_ASYNC_METHOD_1_WITH_RETURN (cal, send_objects, object, "s", object_users, "as")
E_DECLARE_GDBUS_ASYNC_METHOD_1_WITH_RETURN (cal, get_attachment_uris, uid_rid, "as", attachments, "as")
@@ -1287,9 +1318,9 @@ static const GDBusMethodInfo * const e_gdbus_cal_method_info_pointers[] =
&E_DECLARED_GDBUS_METHOD_INFO_NAME (cal, get_object),
&E_DECLARED_GDBUS_METHOD_INFO_NAME (cal, get_object_list),
&E_DECLARED_GDBUS_METHOD_INFO_NAME (cal, get_free_busy),
- &E_DECLARED_GDBUS_METHOD_INFO_NAME (cal, create_object),
- &E_DECLARED_GDBUS_METHOD_INFO_NAME (cal, modify_object),
- &E_DECLARED_GDBUS_METHOD_INFO_NAME (cal, remove_object),
+ &E_DECLARED_GDBUS_METHOD_INFO_NAME (cal, create_objects),
+ &E_DECLARED_GDBUS_METHOD_INFO_NAME (cal, modify_objects),
+ &E_DECLARED_GDBUS_METHOD_INFO_NAME (cal, remove_objects),
&E_DECLARED_GDBUS_METHOD_INFO_NAME (cal, receive_objects),
&E_DECLARED_GDBUS_METHOD_INFO_NAME (cal, send_objects),
&E_DECLARED_GDBUS_METHOD_INFO_NAME (cal, get_attachment_uris),
@@ -1322,9 +1353,9 @@ static const GDBusSignalInfo * const e_gdbus_cal_signal_info_pointers[] =
&E_DECLARED_GDBUS_SIGNAL_INFO_NAME (cal, get_object_done),
&E_DECLARED_GDBUS_SIGNAL_INFO_NAME (cal, get_object_list_done),
&E_DECLARED_GDBUS_SIGNAL_INFO_NAME (cal, get_free_busy_done),
- &E_DECLARED_GDBUS_SIGNAL_INFO_NAME (cal, create_object_done),
- &E_DECLARED_GDBUS_SIGNAL_INFO_NAME (cal, modify_object_done),
- &E_DECLARED_GDBUS_SIGNAL_INFO_NAME (cal, remove_object_done),
+ &E_DECLARED_GDBUS_SIGNAL_INFO_NAME (cal, create_objects_done),
+ &E_DECLARED_GDBUS_SIGNAL_INFO_NAME (cal, modify_objects_done),
+ &E_DECLARED_GDBUS_SIGNAL_INFO_NAME (cal, remove_objects_done),
&E_DECLARED_GDBUS_SIGNAL_INFO_NAME (cal, receive_objects_done),
&E_DECLARED_GDBUS_SIGNAL_INFO_NAME (cal, send_objects_done),
&E_DECLARED_GDBUS_SIGNAL_INFO_NAME (cal, get_attachment_uris_done),
@@ -1561,9 +1592,9 @@ e_gdbus_cal_proxy_init (EGdbusCalProxy *proxy)
E_GDBUS_CONNECT_METHOD_DONE_SIGNAL_STRING (get_object);
E_GDBUS_CONNECT_METHOD_DONE_SIGNAL_STRV (get_object_list);
E_GDBUS_CONNECT_METHOD_DONE_SIGNAL_VOID (get_free_busy);
- E_GDBUS_CONNECT_METHOD_DONE_SIGNAL_STRING (create_object);
- E_GDBUS_CONNECT_METHOD_DONE_SIGNAL_VOID (modify_object);
- E_GDBUS_CONNECT_METHOD_DONE_SIGNAL_VOID (remove_object);
+ E_GDBUS_CONNECT_METHOD_DONE_SIGNAL_STRV (create_objects);
+ E_GDBUS_CONNECT_METHOD_DONE_SIGNAL_VOID (modify_objects);
+ E_GDBUS_CONNECT_METHOD_DONE_SIGNAL_VOID (remove_objects);
E_GDBUS_CONNECT_METHOD_DONE_SIGNAL_VOID (receive_objects);
E_GDBUS_CONNECT_METHOD_DONE_SIGNAL_STRV (send_objects);
E_GDBUS_CONNECT_METHOD_DONE_SIGNAL_STRV (get_attachment_uris);
diff --git a/calendar/libegdbus/e-gdbus-cal.h b/calendar/libegdbus/e-gdbus-cal.h
index 695d13b..7220f64 100644
--- a/calendar/libegdbus/e-gdbus-cal.h
+++ b/calendar/libegdbus/e-gdbus-cal.h
@@ -136,14 +136,14 @@ struct _EGdbusCalIface
gboolean (*handle_get_free_busy) (EGdbusCal *object, GDBusMethodInvocation *invocation, const gchar * const *in_start_end_userlist);
void (*get_free_busy_done) (EGdbusCal *object, guint arg_opid, const GError *arg_error);
- gboolean (*handle_create_object) (EGdbusCal *object, GDBusMethodInvocation *invocation, const gchar *in_calobj);
- void (*create_object_done) (EGdbusCal *object, guint arg_opid, const GError *arg_error, gchar **out_uid);
+ gboolean (*handle_create_objects) (EGdbusCal *object, GDBusMethodInvocation *invocation, const gchar *const *in_calobjs);
+ void (*create_objects_done) (EGdbusCal *object, guint arg_opid, const GError *arg_error, gchar ***out_uids);
- gboolean (*handle_modify_object) (EGdbusCal *object, GDBusMethodInvocation *invocation, const gchar * const *in_calobj_mod);
- void (*modify_object_done) (EGdbusCal *object, guint arg_opid, const GError *arg_error);
+ gboolean (*handle_modify_objects) (EGdbusCal *object, GDBusMethodInvocation *invocation, const gchar * const *in_mod_calobjs);
+ void (*modify_objects_done) (EGdbusCal *object, guint arg_opid, const GError *arg_error);
- gboolean (*handle_remove_object) (EGdbusCal *object, GDBusMethodInvocation *invocation, const gchar * const *in_uid_rid_mod);
- void (*remove_object_done) (EGdbusCal *object, guint arg_opid, const GError *arg_error);
+ gboolean (*handle_remove_objects) (EGdbusCal *object, GDBusMethodInvocation *invocation, const gchar * const *in_mod_ids);
+ void (*remove_objects_done) (EGdbusCal *object, guint arg_opid, const GError *arg_error);
gboolean (*handle_receive_objects) (EGdbusCal *object, GDBusMethodInvocation *invocation, const gchar *in_calobj);
void (*receive_objects_done) (EGdbusCal *object, guint arg_opid, const GError *arg_error);
@@ -211,21 +211,21 @@ void e_gdbus_cal_call_get_free_busy (GDBusProxy *proxy, const gchar * const *
gboolean e_gdbus_cal_call_get_free_busy_finish (GDBusProxy *proxy, GAsyncResult *result, GError **error);
gboolean e_gdbus_cal_call_get_free_busy_sync (GDBusProxy *proxy, const gchar * const *in_start_end_userlist, GCancellable *cancellable, GError **error);
-void e_gdbus_cal_call_create_object (GDBusProxy *proxy, const gchar *in_calobj, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data);
-gboolean e_gdbus_cal_call_create_object_finish (GDBusProxy *proxy, GAsyncResult *result, gchar **out_uid, GError **error);
-gboolean e_gdbus_cal_call_create_object_sync (GDBusProxy *proxy, const gchar *in_calobj, gchar **out_uid, GCancellable *cancellable, GError **error);
+void e_gdbus_cal_call_create_objects (GDBusProxy *proxy, const gchar * const *in_calobjs, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data);
+gboolean e_gdbus_cal_call_create_objects_finish (GDBusProxy *proxy, GAsyncResult *result, gchar ***out_uids, GError **error);
+gboolean e_gdbus_cal_call_create_objects_sync (GDBusProxy *proxy, const gchar * const *in_calobjs, gchar ***out_uids, GCancellable *cancellable, GError **error);
-gchar ** e_gdbus_cal_encode_modify_object (const gchar *in_calobj, guint in_mod);
-gboolean e_gdbus_cal_decode_modify_object (const gchar * const *in_strv, gchar **out_calobj, guint *out_mod);
-void e_gdbus_cal_call_modify_object (GDBusProxy *proxy, const gchar * const *in_calobj_mod, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data);
-gboolean e_gdbus_cal_call_modify_object_finish (GDBusProxy *proxy, GAsyncResult *result, GError **error);
-gboolean e_gdbus_cal_call_modify_object_sync (GDBusProxy *proxy, const gchar * const *in_calobj_mod, GCancellable *cancellable, GError **error);
+gchar ** e_gdbus_cal_encode_modify_objects (const GSList *in_calobjs, guint in_mod);
+gboolean e_gdbus_cal_decode_modify_objects (const gchar * const *in_strv, GSList **out_calobjs, guint *out_mod);
+void e_gdbus_cal_call_modify_objects (GDBusProxy *proxy, const gchar * const *in_mod_calobjs, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data);
+gboolean e_gdbus_cal_call_modify_objects_finish (GDBusProxy *proxy, GAsyncResult *result, GError **error);
+gboolean e_gdbus_cal_call_modify_objects_sync (GDBusProxy *proxy, const gchar * const *in_mod_calobjs, GCancellable *cancellable, GError **error);
-gchar ** e_gdbus_cal_encode_remove_object (const gchar *in_uid, const gchar *in_rid, guint in_mod);
-gboolean e_gdbus_cal_decode_remove_object (const gchar * const *in_strv, gchar **out_uid, gchar **out_rid, guint *out_mod);
-void e_gdbus_cal_call_remove_object (GDBusProxy *proxy, const gchar * const *in_uid_rid_mod, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data);
-gboolean e_gdbus_cal_call_remove_object_finish (GDBusProxy *proxy, GAsyncResult *result, GError **error);
-gboolean e_gdbus_cal_call_remove_object_sync (GDBusProxy *proxy, const gchar * const *in_uid_rid_mod, GCancellable *cancellable, GError **error);
+gchar ** e_gdbus_cal_encode_remove_objects (const GSList *in_ids, guint in_mod);
+gboolean e_gdbus_cal_decode_remove_objects (const gchar * const *in_strv, GSList **out_ids, guint *out_mod);
+void e_gdbus_cal_call_remove_objects (GDBusProxy *proxy, const gchar * const *in_mod_ids, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data);
+gboolean e_gdbus_cal_call_remove_objects_finish (GDBusProxy *proxy, GAsyncResult *result, GError **error);
+gboolean e_gdbus_cal_call_remove_objects_sync (GDBusProxy *proxy, const gchar * const *in_mod_ids, GCancellable *cancellable, GError **error);
void e_gdbus_cal_call_receive_objects (GDBusProxy *proxy, const gchar *in_calobj, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data);
gboolean e_gdbus_cal_call_receive_objects_finish (GDBusProxy *proxy, GAsyncResult *result, GError **error);
@@ -286,9 +286,9 @@ gboolean e_gdbus_cal_call_close_sync (GDBusProxy *proxy, GCancellable *cancell
#define e_gdbus_cal_complete_get_object e_gdbus_complete_async_method
#define e_gdbus_cal_complete_get_object_list e_gdbus_complete_async_method
#define e_gdbus_cal_complete_get_free_busy e_gdbus_complete_async_method
-#define e_gdbus_cal_complete_create_object e_gdbus_complete_async_method
-#define e_gdbus_cal_complete_modify_object e_gdbus_complete_async_method
-#define e_gdbus_cal_complete_remove_object e_gdbus_complete_async_method
+#define e_gdbus_cal_complete_create_objects e_gdbus_complete_async_method
+#define e_gdbus_cal_complete_modify_objects e_gdbus_complete_async_method
+#define e_gdbus_cal_complete_remove_objects e_gdbus_complete_async_method
#define e_gdbus_cal_complete_receive_objects e_gdbus_complete_async_method
#define e_gdbus_cal_complete_send_objects e_gdbus_complete_async_method
#define e_gdbus_cal_complete_get_attachment_uris e_gdbus_complete_async_method
@@ -310,9 +310,9 @@ void e_gdbus_cal_emit_get_object_done (EGdbusCal *object, guint arg_opid, cons
void e_gdbus_cal_emit_get_object_list_done (EGdbusCal *object, guint arg_opid, const GError *arg_error, const gchar * const *out_objects);
void e_gdbus_cal_emit_get_free_busy_done (EGdbusCal *object, guint arg_opid, const GError *arg_error);
void e_gdbus_cal_emit_get_free_busy_data (EGdbusCal *object, guint arg_opid, const GError *arg_error, const gchar * const *out_freebusy);
-void e_gdbus_cal_emit_create_object_done (EGdbusCal *object, guint arg_opid, const GError *arg_error, const gchar *out_uid);
-void e_gdbus_cal_emit_modify_object_done (EGdbusCal *object, guint arg_opid, const GError *arg_error);
-void e_gdbus_cal_emit_remove_object_done (EGdbusCal *object, guint arg_opid, const GError *arg_error);
+void e_gdbus_cal_emit_create_objects_done (EGdbusCal *object, guint arg_opid, const GError *arg_error, const gchar * const *out_uids);
+void e_gdbus_cal_emit_modify_objects_done (EGdbusCal *object, guint arg_opid, const GError *arg_error);
+void e_gdbus_cal_emit_remove_objects_done (EGdbusCal *object, guint arg_opid, const GError *arg_error);
void e_gdbus_cal_emit_receive_objects_done (EGdbusCal *object, guint arg_opid, const GError *arg_error);
void e_gdbus_cal_emit_send_objects_done (EGdbusCal *object, guint arg_opid, const GError *arg_error, const gchar * const *out_calobj_users);
void e_gdbus_cal_emit_get_attachment_uris_done (EGdbusCal *object, guint arg_opid, const GError *arg_error, const gchar * const *out_attachments);
diff --git a/configure.ac b/configure.ac
index d9a9e33..ad9bac2 100644
--- a/configure.ac
+++ b/configure.ac
@@ -61,7 +61,7 @@ dnl ******************************
dnl D-Bus versioning
dnl ******************************
ADDRESS_BOOK_DBUS_SERVICE_NAME="org.gnome.evolution.dataserver.AddressBook3"
-CALENDAR_DBUS_SERVICE_NAME="org.gnome.evolution.dataserver.Calendar1"
+CALENDAR_DBUS_SERVICE_NAME="org.gnome.evolution.dataserver.Calendar2"
AC_DEFINE_UNQUOTED(
ADDRESS_BOOK_DBUS_SERVICE_NAME,
@@ -87,11 +87,11 @@ LIBEDATASERVERUI_CURRENT=1
LIBEDATASERVERUI_REVISION=0
LIBEDATASERVERUI_AGE=0
-LIBECAL_CURRENT=13
+LIBECAL_CURRENT=14
LIBECAL_REVISION=2
LIBECAL_AGE=2
-LIBEDATACAL_CURRENT=15
+LIBEDATACAL_CURRENT=16
LIBEDATACAL_REVISION=0
LIBEDATACAL_AGE=0
diff --git a/libedataserver/e-data-server-util.c b/libedataserver/e-data-server-util.c
index c7211a2..a608fbd 100644
--- a/libedataserver/e-data-server-util.c
+++ b/libedataserver/e-data-server-util.c
@@ -947,6 +947,26 @@ e_util_free_object_slist (GSList *objects)
}
/**
+ * e_util_free_nullable_object_slist:
+ * @objects: a #GSList of nullable #GObject-s
+ *
+ * Calls g_object_unref() on each member of @objects if non-NULL and then frees
+ * also @objects itself.
+ *
+ * Since: 3.6
+ **/
+void
+e_util_free_nullable_object_slist (GSList *objects)
+{
+ const GSList *l;
+ for (l = objects; l; l = l->next) {
+ if (l->data)
+ g_object_unref (l->data);
+ }
+ g_slist_free (objects);
+}
+
+/**
* e_binding_transform_enum_value_to_nick:
* @binding: a #GBinding
* @source_value: a #GValue whose type is derived from #G_TYPE_ENUM
diff --git a/libedataserver/e-data-server-util.h b/libedataserver/e-data-server-util.h
index 8450c63..b68c460 100644
--- a/libedataserver/e-data-server-util.h
+++ b/libedataserver/e-data-server-util.h
@@ -69,6 +69,7 @@ GSList * e_util_copy_string_slist (GSList *copy_to, const GSList *strings);
GSList * e_util_copy_object_slist (GSList *copy_to, const GSList *objects);
void e_util_free_string_slist (GSList *strings);
void e_util_free_object_slist (GSList *objects);
+void e_util_free_nullable_object_slist (GSList *objects);
/* Useful GBinding transform functions */
gboolean e_binding_transform_enum_value_to_nick
diff --git a/tests/libecal/client/Makefile.am b/tests/libecal/client/Makefile.am
index 68037ca..af2b893 100644
--- a/tests/libecal/client/Makefile.am
+++ b/tests/libecal/client/Makefile.am
@@ -31,6 +31,7 @@ TESTS = \
test-client-get-revision \
test-client-send-objects \
test-client-receive-objects \
+ test-client-bulk-methods \
test-client-get-attachment-uris \
test-client-get-view \
test-client-revision-view \
@@ -77,6 +78,8 @@ test_client_open_LDADD=$(TEST_LIBS)
test_client_open_CPPFLAGS=$(TEST_CPPFLAGS)
test_client_receive_objects_LDADD=$(TEST_LIBS)
test_client_receive_objects_CPPFLAGS=$(TEST_CPPFLAGS)
+test_client_bulk_methods_LDADD=$(TEST_LIBS)
+test_client_bulk_methods_CPPFLAGS=$(TEST_CPPFLAGS)
test_client_refresh_LDADD=$(TEST_LIBS)
test_client_refresh_CPPFLAGS=$(TEST_CPPFLAGS)
test_client_remove_object_LDADD=$(TEST_LIBS)
diff --git a/tests/libecal/client/test-client-bulk-methods.c b/tests/libecal/client/test-client-bulk-methods.c
new file mode 100644
index 0000000..c4d9069
--- /dev/null
+++ b/tests/libecal/client/test-client-bulk-methods.c
@@ -0,0 +1,253 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+#include <stdlib.h>
+#include <libecal/e-cal-client.h>
+#include <libical/ical.h>
+
+#include "client-test-utils.h"
+
+#define NB_COMPONENTS 5
+
+static gboolean
+test_icalcomps (icalcomponent *icalcomp1,
+ icalcomponent *icalcomp2)
+{
+ struct icaltimetype t1, t2;
+
+ if (!icalcomp2) {
+ g_printerr ("Failure: get object returned NULL\n");
+ return FALSE;
+ }
+
+ if (g_strcmp0 (icalcomponent_get_uid (icalcomp1), icalcomponent_get_uid (icalcomp2)) != 0) {
+ g_printerr ("Failure: uid doesn't match, expected '%s', got '%s'\n", icalcomponent_get_uid (icalcomp1), icalcomponent_get_uid (icalcomp2));
+ return FALSE;
+ }
+
+ if (g_strcmp0 (icalcomponent_get_summary (icalcomp1), icalcomponent_get_summary (icalcomp2)) != 0) {
+ g_printerr ("Failure: summary doesn't match, expected '%s', got '%s'\n", icalcomponent_get_summary (icalcomp1), icalcomponent_get_summary (icalcomp2));
+ return FALSE;
+ }
+
+ t1 = icalcomponent_get_dtstart (icalcomp1);
+ t2 = icalcomponent_get_dtstart (icalcomp2);
+
+ if (icaltime_compare (t1, t2) != 0) {
+ g_printerr ("Failure: dtend doesn't match, expected '%s', got '%s'\n", icaltime_as_ical_string (t1), icaltime_as_ical_string (t2));
+ return FALSE;
+ }
+
+ t1 = icalcomponent_get_dtend (icalcomp1);
+ t2 = icalcomponent_get_dtend (icalcomp2);
+
+ if (icaltime_compare (t1, t2) != 0) {
+ g_printerr ("Failure: dtend doesn't match, expected '%s', got '%s'\n", icaltime_as_ical_string (t1), icaltime_as_ical_string (t2));
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static gboolean
+check_removed (ECalClient *cal_client,
+ const GSList *uids)
+{
+ g_return_val_if_fail (cal_client != NULL, FALSE);
+ g_return_val_if_fail (uids != NULL, FALSE);
+
+ while (uids) {
+ GError *error = NULL;
+ icalcomponent *icalcomp = NULL;
+
+ if (!e_cal_client_get_object_sync(cal_client, uids->data, NULL, &icalcomp, NULL, &error) &&
+ g_error_matches (error, E_CAL_CLIENT_ERROR, E_CAL_CLIENT_ERROR_OBJECT_NOT_FOUND)) {
+ g_clear_error (&error);
+ } else {
+ report_error ("check objects removed sync", &error);
+ icalcomponent_free (icalcomp);
+ return FALSE;
+ }
+
+ uids = uids->next;
+ }
+
+ return TRUE;
+}
+
+static GSList *
+uid_slist_to_ecalcomponentid_slist(GSList *uids)
+{
+ GSList *ids = NULL;
+ const GSList *l;
+
+ for (l = uids; l; l = l->next) {
+ ECalComponentId *id = g_new0 (ECalComponentId, 1);
+ id->uid = g_strdup (l->data);
+ ids = g_slist_append (ids, id);
+ }
+
+ return ids;
+}
+
+static gboolean
+check_icalcomps_exist (ECalClient *cal_client,
+ GSList *icalcomps)
+{
+ const GSList *l;
+
+ for (l = icalcomps; l; l = l->next) {
+ GError *error = NULL;
+ icalcomponent *icalcomp = l->data;
+ icalcomponent *icalcomp2 = NULL;
+ const char *uid = icalcomponent_get_uid(icalcomp);
+
+ if (!e_cal_client_get_object_sync(cal_client, uid, NULL, &icalcomp2, NULL, &error)) {
+ report_error ("get object sync", &error);
+ return FALSE;
+ }
+
+ g_return_val_if_fail (icalcomp2 != NULL, FALSE);
+
+ if (!test_icalcomps (icalcomp, icalcomp2)) {
+ icalcomponent_free (icalcomp2);
+ return FALSE;
+ }
+
+ icalcomponent_free (icalcomp2);
+ }
+
+ return TRUE;
+}
+
+static gboolean
+test_bulk_methods(GSList *icalcomps)
+{
+ ECalClient *cal_client;
+ GError *error = NULL;
+ GSList *uids = NULL, *ids = NULL;
+ const GSList *lcomp, *luid;
+ gint i = 0;
+
+ g_return_val_if_fail (icalcomps != NULL, FALSE);
+
+ cal_client = new_temp_client (E_CAL_CLIENT_SOURCE_TYPE_EVENTS, NULL);
+ g_return_val_if_fail (cal_client != NULL, FALSE);
+
+ if (!e_client_open_sync (E_CLIENT (cal_client), FALSE, NULL, &error)) {
+ report_error ("client open sync", &error);
+ g_object_unref (cal_client);
+ return FALSE;
+ }
+
+ /* Create all the objects in bulk */
+ if (!e_cal_client_create_objects_sync (cal_client, icalcomps, &uids, NULL, &error)) {
+ report_error ("create objects sync", &error);
+ g_object_unref (cal_client);
+ return FALSE;
+ }
+
+ g_return_val_if_fail (uids != NULL, FALSE);
+ g_return_val_if_fail (g_slist_length (uids) == NB_COMPONENTS, FALSE);
+
+ /* Update icalcomponents uids */
+ luid = uids;
+ lcomp = icalcomps;
+ while (luid && lcomp) {
+ icalcomponent_set_uid (lcomp->data, luid->data);
+ luid = luid->next;
+ lcomp = lcomp->next;
+ }
+
+ /* Retrieve all the objects and check that they are the same */
+ if (!check_icalcomps_exist (cal_client, icalcomps)) {
+ g_object_unref (cal_client);
+ g_slist_free_full (uids, g_free);
+ return FALSE;
+ }
+
+ /* Modify the objects */
+ for (lcomp = icalcomps; lcomp; lcomp = lcomp->next) {
+ gchar *summary;
+ icalcomponent *icalcomp = lcomp->data;
+
+ summary = g_strdup_printf ("Edited test summary %d", i);
+ icalcomponent_set_summary(icalcomp, summary);
+
+ g_free (summary);
+ ++i;
+ }
+
+ /* Save the modified objects in bulk */
+ if (!e_cal_client_modify_objects_sync(cal_client, icalcomps, CALOBJ_MOD_ALL, NULL, &error)) {
+ report_error ("modify objects sync", &error);
+ g_object_unref (cal_client);
+ g_slist_free_full (uids, g_free);
+ return FALSE;
+ }
+
+ /* Retrieve all the objects and check that they have been modified */
+ if (!check_icalcomps_exist (cal_client, icalcomps)) {
+ g_object_unref (cal_client);
+ g_slist_free_full (uids, g_free);
+ return FALSE;
+ }
+
+ /* Remove all the objects in bulk */
+ ids = uid_slist_to_ecalcomponentid_slist (uids);
+
+ if (!e_cal_client_remove_objects_sync(cal_client, ids, CALOBJ_MOD_ALL, NULL, &error)) {
+ report_error ("remove objects sync", &error);
+ g_object_unref (cal_client);
+ g_slist_free_full (ids, (GDestroyNotify) e_cal_component_free_id);
+ g_slist_free_full (uids, g_free);
+ return FALSE;
+ }
+ g_slist_free_full (ids, (GDestroyNotify) e_cal_component_free_id);
+
+ /* Check that the objects don't exist anymore */
+ if (!check_removed(cal_client, uids)) {
+ g_object_unref (cal_client);
+ g_slist_free_full (uids, g_free);
+ return FALSE;
+ }
+
+ g_slist_free_full (uids, g_free);
+ g_object_unref (cal_client);
+ return TRUE;
+}
+
+gint
+main (gint argc,
+ gchar **argv)
+{
+ GSList *icalcomps = NULL;
+ struct icaltimetype now;
+ gint i;
+ gboolean res;
+
+ main_initialize ();
+
+ now = icaltime_current_time_with_zone (icaltimezone_get_utc_timezone ());
+
+ /* Build up new components */
+ for (i = 0; i < NB_COMPONENTS; ++i) {
+ icalcomponent *icalcomp;
+ gchar *summary;
+
+ icalcomp = icalcomponent_new (ICAL_VEVENT_COMPONENT);
+ summary = g_strdup_printf ("Test summary %d", i);
+ icalcomponent_set_summary (icalcomp, summary);
+ icalcomponent_set_dtstart (icalcomp, now);
+ icalcomponent_set_dtend (icalcomp, icaltime_from_timet (icaltime_as_timet (now) + 60 * 60 * 60, 0));
+
+ icalcomps = g_slist_append (icalcomps, icalcomp);
+ g_free (summary);
+ }
+
+ /* Test synchronous bulk methods */
+ res = test_bulk_methods (icalcomps);
+
+ g_slist_free_full (icalcomps, (GDestroyNotify)icalcomponent_free);
+
+ return (res != TRUE);
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]