1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
4 * Chris Toshok (toshok@ximian.com)
6 * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
13 #include "e-cal-backend-sync.h"
14 #include "libedataserver/e-data-server-util.h"
15 #include <libical/icaltz-util.h>
17 #define E_CAL_BACKEND_SYNC_GET_PRIVATE(obj) \
18 (G_TYPE_INSTANCE_GET_PRIVATE \
19 ((obj), E_TYPE_CAL_BACKEND_SYNC, ECalBackendSyncPrivate))
21 G_DEFINE_TYPE (ECalBackendSync, e_cal_backend_sync, E_TYPE_CAL_BACKEND)
23 struct _ECalBackendSyncPrivate {
29 #define LOCK_WRAPPER(func, args) G_STMT_START { \
30 gboolean locked = backend->priv->mutex_lock; \
31 e_return_data_cal_error_if_fail (E_CAL_BACKEND_SYNC_GET_CLASS (backend)->func, NotSupported); \
33 g_mutex_lock (backend->priv->sync_mutex); \
34 (* E_CAL_BACKEND_SYNC_GET_CLASS (backend)->func) args; \
36 g_mutex_unlock (backend->priv->sync_mutex); \
39 #define LOCK_WRAPPER_RET_VAL(func, args) G_STMT_START { \
40 gboolean locked = backend->priv->mutex_lock; \
41 e_return_data_cal_error_val_if_fail (E_CAL_BACKEND_SYNC_GET_CLASS (backend)->func, NotSupported); \
43 g_mutex_lock (backend->priv->sync_mutex); \
44 res = (* E_CAL_BACKEND_SYNC_GET_CLASS (backend)->func) args; \
46 g_mutex_unlock (backend->priv->sync_mutex); \
50 * e_cal_backend_sync_set_lock:
51 * @backend: An ECalBackendSync object.
54 * Sets the lock mode on the ECalBackendSync object. If TRUE, the backend
55 * will create a locking mutex for every operation, so that only one can
56 * happen at a time. If FALSE, no lock would be done and many operations
57 * can happen at the same time.
60 e_cal_backend_sync_set_lock (ECalBackendSync *backend,
63 g_return_if_fail (backend && E_IS_CAL_BACKEND_SYNC (backend));
65 backend->priv->mutex_lock = lock;
69 * e_cal_backend_sync_open:
70 * @backend: An ECalBackendSync object.
71 * @cal: An EDataCal object.
72 * @cancellable: a #GCancellable for the operation
73 * @only_if_exists: Whether to open the calendar if and only if it already exists
74 * or just create it when it does not exist.
75 * @error: Out parameter for a #GError.
77 * Calls the open_sync method on the given backend.
80 e_cal_backend_sync_open (ECalBackendSync *backend,
82 GCancellable *cancellable,
83 gboolean only_if_exists,
86 e_return_data_cal_error_if_fail (backend && E_IS_CAL_BACKEND_SYNC (backend), InvalidArg);
88 LOCK_WRAPPER (open_sync, (backend, cal, cancellable, only_if_exists, error));
92 * e_cal_backend_sync_remove:
93 * @backend: An ECalBackendSync object.
94 * @cal: An EDataCal object.
95 * @cancellable: a #GCancellable for the operation
96 * @error: Out parameter for a #GError.
98 * Calls the remove_sync method on the given backend.
101 e_cal_backend_sync_remove (ECalBackendSync *backend,
103 GCancellable *cancellable,
106 e_return_data_cal_error_if_fail (backend && E_IS_CAL_BACKEND_SYNC (backend), InvalidArg);
108 LOCK_WRAPPER (remove_sync, (backend, cal, cancellable, error));
112 * e_cal_backend_sync_refresh:
113 * @backend: An ECalBackendSync object.
114 * @cal: An EDataCal object.
115 * @cancellable: a #GCancellable for the operation
116 * @error: Out parameter for a #GError.
118 * Calls the refresh_sync method on the given backend.
123 e_cal_backend_sync_refresh (ECalBackendSync *backend,
125 GCancellable *cancellable,
128 e_return_data_cal_error_if_fail (backend && E_IS_CAL_BACKEND_SYNC (backend), InvalidArg);
129 e_return_data_cal_error_if_fail (E_CAL_BACKEND_SYNC_GET_CLASS (backend)->refresh_sync != NULL, UnsupportedMethod);
131 LOCK_WRAPPER (refresh_sync, (backend, cal, cancellable, error));
135 * e_cal_backend_sync_get_backend_property:
136 * @backend: An ECalBackendSync object.
137 * @cal: An EDataCal object.
138 * @cancellable: a #GCancellable for the operation
139 * @prop_name: Property name whose value to retrieve.
140 * @prop_value: Return value of the @prop_name.
141 * @error: Out parameter for a #GError.
143 * Calls the get_backend_property_sync method on the given backend.
145 * Returns whether processed this property. Returning FALSE means to pass
146 * the call to the ECalBackend parent class, thus neither @error should be
152 e_cal_backend_sync_get_backend_property (ECalBackendSync *backend,
154 GCancellable *cancellable,
155 const gchar *prop_name,
159 gboolean res = FALSE;
161 e_return_data_cal_error_val_if_fail (backend && E_IS_CAL_BACKEND_SYNC (backend), InvalidArg);
162 e_return_data_cal_error_val_if_fail (prop_name, InvalidArg);
163 e_return_data_cal_error_val_if_fail (prop_value, InvalidArg);
165 LOCK_WRAPPER_RET_VAL (get_backend_property_sync, (backend, cal, cancellable, prop_name, prop_value, error));
171 * e_cal_backend_sync_set_backend_property:
172 * @backend: An ECalBackendSync object.
173 * @cal: An EDataCal object.
174 * @cancellable: a #GCancellable for the operation
175 * @prop_name: Property name to set.
176 * @prop_value: New value of the @prop_name.
177 * @error: Out parameter for a #GError.
179 * Calls the set_backend_property_sync method on the given backend.
181 * Returns whether processed this property. Returning FALSE means to pass
182 * the call to the ECalBackend parent class, thus neither @error should be
188 e_cal_backend_sync_set_backend_property (ECalBackendSync *backend,
190 GCancellable *cancellable,
191 const gchar *prop_name,
192 const gchar *prop_value,
195 gboolean res = FALSE;
197 e_return_data_cal_error_val_if_fail (backend && E_IS_CAL_BACKEND_SYNC (backend), InvalidArg);
198 e_return_data_cal_error_val_if_fail (prop_name, InvalidArg);
199 e_return_data_cal_error_val_if_fail (prop_value, InvalidArg);
201 LOCK_WRAPPER_RET_VAL (set_backend_property_sync, (backend, cal, cancellable, prop_name, prop_value, error));
207 * e_cal_backend_sync_get_object:
208 * @backend: An ECalBackendSync object.
209 * @cal: An EDataCal object.
210 * @cancellable: a #GCancellable for the operation
211 * @uid: UID of the object to get.
212 * @rid: Recurrence ID of the specific instance to get, or NULL if getting the
214 * @calobj: Placeholder for returned object.
215 * @error: Out parameter for a #GError.
217 * Calls the get_object_sync method on the given backend.
220 e_cal_backend_sync_get_object (ECalBackendSync *backend,
222 GCancellable *cancellable,
228 e_return_data_cal_error_if_fail (backend && E_IS_CAL_BACKEND_SYNC (backend), InvalidArg);
229 e_return_data_cal_error_if_fail (calobj, InvalidArg);
231 LOCK_WRAPPER (get_object_sync, (backend, cal, cancellable, uid, rid, calobj, error));
235 * e_cal_backend_sync_get_object_list:
236 * @backend: An ECalBackendSync object.
237 * @cal: An EDataCal object.
238 * @cancellable: a #GCancellable for the operation
239 * @sexp: Search query.
240 * @calobjs: Placeholder for list of returned objects.
241 * @error: Out parameter for a #GError.
243 * Calls the get_object_list_sync method on the given backend.
246 e_cal_backend_sync_get_object_list (ECalBackendSync *backend,
248 GCancellable *cancellable,
253 e_return_data_cal_error_if_fail (backend && E_IS_CAL_BACKEND_SYNC (backend), InvalidArg);
254 e_return_data_cal_error_if_fail (calobjs, InvalidArg);
256 LOCK_WRAPPER (get_object_list_sync, (backend, cal, cancellable, sexp, calobjs, error));
260 * e_cal_backend_sync_get_free_busy:
261 * @backend: An ECalBackendSync object.
262 * @cal: An EDataCal object.
263 * @cancellable: a #GCancellable for the operation
264 * @users: List of users to get F/B info from.
265 * @start: Time range start.
266 * @end: Time range end.
267 * @freebusyobjects: Placeholder for F/B information.
268 * @error: Out parameter for a #GError.
270 * Calls the get_free_busy_sync method on the given backend.
273 e_cal_backend_sync_get_free_busy (ECalBackendSync *backend,
275 GCancellable *cancellable,
279 GSList **freebusyobjects,
282 e_return_data_cal_error_if_fail (E_IS_CAL_BACKEND_SYNC (backend), InvalidArg);
284 LOCK_WRAPPER (get_free_busy_sync, (backend, cal, cancellable, users, start, end, freebusyobjects, error));
288 * e_cal_backend_sync_create_objects:
289 * @backend: An ECalBackendSync object.
290 * @cal: An EDataCal object.
291 * @cancellable: a #GCancellable for the operation
292 * @calobjs: The objects to be added.
293 * @uids: Placeholder for server-generated UIDs.
294 * @new_components: (out) (transfer full): Placeholder for returned #ECalComponent objects.
295 * @error: Out parameter for a #GError.
297 * Calls the create_objects_sync method on the given backend.
300 e_cal_backend_sync_create_objects (ECalBackendSync *backend,
302 GCancellable *cancellable,
303 const GSList *calobjs,
305 GSList **new_components,
308 e_return_data_cal_error_if_fail (backend && E_IS_CAL_BACKEND_SYNC (backend), InvalidArg);
309 e_return_data_cal_error_if_fail (E_CAL_BACKEND_SYNC_GET_CLASS (backend)->create_objects_sync != NULL, UnsupportedMethod);
311 LOCK_WRAPPER (create_objects_sync, (backend, cal, cancellable, calobjs, uids, new_components, error));
315 * e_cal_backend_sync_modify_objects:
316 * @backend: An ECalBackendSync object.
317 * @cal: An EDataCal object.
318 * @cancellable: a #GCancellable for the operation
319 * @calobjs: Objects to be modified.
320 * @mod: Type of modification to be done.
321 * @old_components: (out) (transfer full): Placeholder for returning the old components as they were stored on the
323 * @new_components: (out) (transfer full): Placeholder for returning the new components as they have been stored
325 * @error: Out parameter for a #GError.
327 * Calls the modify_objects_sync method on the given backend.
330 e_cal_backend_sync_modify_objects (ECalBackendSync *backend,
332 GCancellable *cancellable,
333 const GSList *calobjs,
335 GSList **old_components,
336 GSList **new_components,
339 e_return_data_cal_error_if_fail (backend && E_IS_CAL_BACKEND_SYNC (backend), InvalidArg);
340 e_return_data_cal_error_if_fail (E_CAL_BACKEND_SYNC_GET_CLASS (backend)->modify_objects_sync != NULL, UnsupportedMethod);
342 LOCK_WRAPPER (modify_objects_sync, (backend, cal, cancellable, calobjs, mod, old_components, new_components, error));
346 * e_cal_backend_sync_remove_objects:
347 * @backend: An ECalBackendSync object.
348 * @cal: An EDataCal object.
349 * @cancellable: a #GCancellable for the operation
350 * @ids: List of #ECalComponentId objects identifying the objects to remove.
351 * @mod: Type of removal.
352 * @old_components: (out) (transfer full): Placeholder for returning the old components as they were stored on the
354 * @new_components: (out) (transfer full): Placeholder for returning the new components as they have been stored
355 * on the backend (when removing individual instances). If removing whole objects,
356 * they will be set to %NULL.
357 * @error: Out parameter for a #GError.
359 * Calls the remove_objects_sync method on the given backend.
362 e_cal_backend_sync_remove_objects (ECalBackendSync *backend,
364 GCancellable *cancellable,
367 GSList **old_components,
368 GSList **new_components,
371 e_return_data_cal_error_if_fail (backend && E_IS_CAL_BACKEND_SYNC (backend), InvalidArg);
372 e_return_data_cal_error_if_fail (E_CAL_BACKEND_SYNC_GET_CLASS (backend)->remove_objects_sync != NULL, UnsupportedMethod);
374 LOCK_WRAPPER (remove_objects_sync, (backend, cal, cancellable, ids, mod, old_components, new_components, error));
378 * e_cal_backend_sync_receive_objects:
379 * @backend: An ECalBackendSync object.
380 * @cal: An EDataCal object.
381 * @cancellable: a #GCancellable for the operation
382 * @calobj: iCalendar object to receive.
383 * @error: Out parameter for a #GError.
385 * Calls the receive_objects_sync method on the given backend.
388 e_cal_backend_sync_receive_objects (ECalBackendSync *backend,
390 GCancellable *cancellable,
394 e_return_data_cal_error_if_fail (backend && E_IS_CAL_BACKEND_SYNC (backend), InvalidArg);
395 e_return_data_cal_error_if_fail (E_CAL_BACKEND_SYNC_GET_CLASS (backend)->receive_objects_sync != NULL, UnsupportedMethod);
397 LOCK_WRAPPER (receive_objects_sync, (backend, cal, cancellable, calobj, error));
401 * e_cal_backend_sync_send_objects:
402 * @backend: An ECalBackendSync object.
403 * @cal: An EDataCal object.
404 * @cancellable: a #GCancellable for the operation
405 * @calobj: The iCalendar object to send.
406 * @users: List of users to send notifications to.
407 * @modified_calobj: Placeholder for the iCalendar object after being modified.
408 * @error: Out parameter for a #GError.
410 * Calls the send_objects_sync method on the given backend.
413 e_cal_backend_sync_send_objects (ECalBackendSync *backend,
415 GCancellable *cancellable,
418 gchar **modified_calobj,
421 e_return_data_cal_error_if_fail (backend && E_IS_CAL_BACKEND_SYNC (backend), InvalidArg);
422 e_return_data_cal_error_if_fail (E_CAL_BACKEND_SYNC_GET_CLASS (backend)->send_objects_sync != NULL, UnsupportedMethod);
424 LOCK_WRAPPER (send_objects_sync, (backend, cal, cancellable, calobj, users, modified_calobj, error));
428 * e_cal_backend_sync_get_attachment_uris:
429 * @backend: An ECalBackendSync object.
430 * @cal: An EDataCal object.
431 * @cancellable: a #GCancellable for the operation
432 * @uid: Unique id of the calendar object.
433 * @rid: Recurrence id of the calendar object.
434 * @attachments: Placeholder for list of returned attachment uris.
435 * @error: Out parameter for a #GError.
437 * Calls the get_attachment_uris_sync method on the given backend.
442 e_cal_backend_sync_get_attachment_uris (ECalBackendSync *backend,
444 GCancellable *cancellable,
447 GSList **attachments,
450 e_return_data_cal_error_if_fail (backend && E_IS_CAL_BACKEND_SYNC (backend), InvalidArg);
451 e_return_data_cal_error_if_fail (attachments, InvalidArg);
453 LOCK_WRAPPER (get_attachment_uris_sync, (backend, cal, cancellable, uid, rid, attachments, error));
457 * e_cal_backend_sync_discard_alarm:
458 * @backend: An ECalBackendSync object.
459 * @cal: An EDataCal object.
460 * @cancellable: a #GCancellable for the operation
461 * @uid: Unique id of the calendar object.
462 * @rid: Recurrence id of the calendar object.
463 * @auid: Alarm ID to remove.
464 * @error: Out parameter for a #GError.
466 * Calls the discard_alarm_sync method on the given backend.
469 e_cal_backend_sync_discard_alarm (ECalBackendSync *backend,
471 GCancellable *cancellable,
477 e_return_data_cal_error_if_fail (backend && E_IS_CAL_BACKEND_SYNC (backend), InvalidArg);
478 e_return_data_cal_error_if_fail (uid, InvalidArg);
479 e_return_data_cal_error_if_fail (auid, InvalidArg);
481 LOCK_WRAPPER (discard_alarm_sync, (backend, cal, cancellable, uid, rid, auid, error));
485 * e_cal_backend_sync_get_timezone:
486 * @backend: An ECalBackendSync object.
487 * @cal: An EDataCal object.
488 * @cancellable: a #GCancellable for the operation
489 * @tzid: ID of the timezone to retrieve.
490 * @tzobject: Placeholder for the returned timezone.
491 * @error: Out parameter for a #GError.
493 * Calls the get_timezone_sync method on the given backend.
494 * This method is not mandatory on the backend, because here
495 * is used internal_get_timezone call to fetch timezone from
496 * it and that is transformed to a string. In other words,
497 * any object deriving from ECalBackendSync can implement only
498 * internal_get_timezone and can skip implementation of
499 * get_timezone_sync completely.
502 e_cal_backend_sync_get_timezone (ECalBackendSync *backend,
504 GCancellable *cancellable,
509 e_return_data_cal_error_if_fail (E_IS_CAL_BACKEND_SYNC (backend), InvalidArg);
511 if (E_CAL_BACKEND_SYNC_GET_CLASS (backend)->get_timezone_sync) {
512 LOCK_WRAPPER (get_timezone_sync, (backend, cal, cancellable, tzid, tzobject, error));
515 if (tzobject && !*tzobject) {
516 icaltimezone *zone = NULL;
518 if (backend->priv->mutex_lock)
519 g_mutex_lock (backend->priv->sync_mutex);
520 zone = e_cal_backend_internal_get_timezone (E_CAL_BACKEND (backend), tzid);
521 if (backend->priv->mutex_lock)
522 g_mutex_unlock (backend->priv->sync_mutex);
525 g_propagate_error (error, e_data_cal_create_error (ObjectNotFound, NULL));
527 icalcomponent *icalcomp;
529 icalcomp = icaltimezone_get_component (zone);
532 g_propagate_error (error, e_data_cal_create_error (InvalidObject, NULL));
534 *tzobject = icalcomponent_as_ical_string_r (icalcomp);
541 * e_cal_backend_sync_add_timezone:
542 * @backend: An ECalBackendSync object.
543 * @cal: An EDataCal object.
544 * @cancellable: a #GCancellable for the operation
545 * @tzobject: VTIMEZONE object to be added.
546 * @error: Out parameter for a #GError.
548 * Calls the add_timezone_sync method on the given backend.
551 e_cal_backend_sync_add_timezone (ECalBackendSync *backend,
553 GCancellable *cancellable,
554 const gchar *tzobject,
557 e_return_data_cal_error_if_fail (E_IS_CAL_BACKEND_SYNC (backend), InvalidArg);
559 LOCK_WRAPPER (add_timezone_sync, (backend, cal, cancellable, tzobject, error));
563 cal_backend_open (ECalBackend *backend,
566 GCancellable *cancellable,
567 gboolean only_if_exists)
569 GError *error = NULL;
571 e_cal_backend_sync_open (E_CAL_BACKEND_SYNC (backend), cal, cancellable, only_if_exists, &error);
573 e_data_cal_respond_open (cal, opid, error);
577 cal_backend_remove (ECalBackend *backend,
580 GCancellable *cancellable)
582 GError *error = NULL;
584 e_cal_backend_sync_remove (E_CAL_BACKEND_SYNC (backend), cal, cancellable, &error);
586 e_data_cal_respond_remove (cal, opid, error);
590 cal_backend_refresh (ECalBackend *backend,
593 GCancellable *cancellable)
595 GError *error = NULL;
597 e_cal_backend_sync_refresh (E_CAL_BACKEND_SYNC (backend), cal, cancellable, &error);
599 e_data_cal_respond_refresh (cal, opid, error);
603 cal_backend_get_backend_property (ECalBackend *backend,
606 GCancellable *cancellable,
607 const gchar *prop_name)
609 GError *error = NULL;
610 gchar *prop_value = NULL;
612 if (e_cal_backend_sync_get_backend_property (E_CAL_BACKEND_SYNC (backend), cal, cancellable, prop_name, &prop_value, &error))
613 e_data_cal_respond_get_backend_property (cal, opid, error, prop_value);
615 (* E_CAL_BACKEND_CLASS (e_cal_backend_sync_parent_class)->get_backend_property) (backend, cal, opid, cancellable, prop_name);
621 cal_backend_set_backend_property (ECalBackend *backend,
624 GCancellable *cancellable,
625 const gchar *prop_name,
626 const gchar *prop_value)
628 GError *error = NULL;
630 if (e_cal_backend_sync_set_backend_property (E_CAL_BACKEND_SYNC (backend), cal, cancellable, prop_name, prop_value, &error))
631 e_data_cal_respond_set_backend_property (cal, opid, error);
633 (* E_CAL_BACKEND_CLASS (e_cal_backend_sync_parent_class)->set_backend_property) (backend, cal, opid, cancellable, prop_name, prop_value);
637 cal_backend_get_object (ECalBackend *backend,
640 GCancellable *cancellable,
644 GError *error = NULL;
645 gchar *calobj = NULL;
647 e_cal_backend_sync_get_object (E_CAL_BACKEND_SYNC (backend), cal, cancellable, uid, rid, &calobj, &error);
649 e_data_cal_respond_get_object (cal, opid, error, calobj);
655 cal_backend_get_object_list (ECalBackend *backend,
658 GCancellable *cancellable,
661 GError *error = NULL;
662 GSList *calobjs = NULL;
664 e_cal_backend_sync_get_object_list (E_CAL_BACKEND_SYNC (backend), cal, cancellable, sexp, &calobjs, &error);
666 e_data_cal_respond_get_object_list (cal, opid, error, calobjs);
668 g_slist_foreach (calobjs, (GFunc) g_free, NULL);
669 g_slist_free (calobjs);
673 cal_backend_get_free_busy (ECalBackend *backend,
676 GCancellable *cancellable,
681 GError *error = NULL;
682 GSList *freebusyobjs = NULL;
684 e_cal_backend_sync_get_free_busy (E_CAL_BACKEND_SYNC (backend), cal, cancellable, users, start, end, &freebusyobjs, &error);
687 e_data_cal_report_free_busy_data (cal, freebusyobjs);
688 e_data_cal_respond_get_free_busy (cal, opid, error);
690 g_slist_foreach (freebusyobjs, (GFunc) g_free, NULL);
691 g_slist_free (freebusyobjs);
695 ecalcomponent_slist_from_strings (const GSList *strings)
697 GSList *ecalcomps = NULL;
700 for (l = strings; l; l = l->next) {
701 ECalComponent *component = e_cal_component_new_from_string (l->data);
702 ecalcomps = g_slist_prepend (ecalcomps, component);
705 return g_slist_reverse (ecalcomps);
709 cal_backend_create_objects (ECalBackend *backend,
712 GCancellable *cancellable,
713 const GSList *calobjs)
715 GError *error = NULL;
717 GSList *new_components = NULL;
719 e_cal_backend_sync_create_objects (E_CAL_BACKEND_SYNC (backend), cal, cancellable, calobjs, &uids, &new_components, &error);
722 new_components = ecalcomponent_slist_from_strings (calobjs);
724 e_data_cal_respond_create_objects (cal, opid, error, uids, new_components);
726 g_slist_free_full (uids, g_free);
727 e_util_free_nullable_object_slist (new_components);
731 cal_backend_modify_objects (ECalBackend *backend,
734 GCancellable *cancellable,
735 const GSList *calobjs,
738 GError *error = NULL;
739 GSList *old_components = NULL, *new_components = NULL;
741 e_cal_backend_sync_modify_objects (E_CAL_BACKEND_SYNC (backend), cal, cancellable, calobjs, mod, &old_components, &new_components, &error);
744 old_components = ecalcomponent_slist_from_strings (calobjs);
746 e_data_cal_respond_modify_objects (cal, opid, error, old_components, new_components);
748 e_util_free_nullable_object_slist (old_components);
749 e_util_free_nullable_object_slist (new_components);
753 cal_backend_remove_objects (ECalBackend *backend,
756 GCancellable *cancellable,
760 GError *error = NULL;
761 GSList *old_components = NULL, *new_components = NULL;
763 e_cal_backend_sync_remove_objects (E_CAL_BACKEND_SYNC (backend), cal, cancellable, ids, mod, &old_components, &new_components, &error);
765 e_data_cal_respond_remove_objects (cal, opid, error, ids, old_components, new_components);
767 e_util_free_nullable_object_slist (old_components);
768 e_util_free_nullable_object_slist (new_components);
772 cal_backend_receive_objects (ECalBackend *backend,
775 GCancellable *cancellable,
778 GError *error = NULL;
780 e_cal_backend_sync_receive_objects (E_CAL_BACKEND_SYNC (backend), cal, cancellable, calobj, &error);
782 e_data_cal_respond_receive_objects (cal, opid, error);
786 cal_backend_send_objects (ECalBackend *backend,
789 GCancellable *cancellable,
792 GError *error = NULL;
793 GSList *users = NULL;
794 gchar *modified_calobj = NULL;
796 e_cal_backend_sync_send_objects (E_CAL_BACKEND_SYNC (backend), cal, cancellable, calobj, &users, &modified_calobj, &error);
798 e_data_cal_respond_send_objects (cal, opid, error, users, modified_calobj ? modified_calobj : calobj);
800 g_slist_foreach (users, (GFunc) g_free, NULL);
801 g_slist_free (users);
802 g_free (modified_calobj);
806 cal_backend_get_attachment_uris (ECalBackend *backend,
809 GCancellable *cancellable,
813 GError *error = NULL;
814 GSList *attachments = NULL;
816 e_cal_backend_sync_get_attachment_uris (E_CAL_BACKEND_SYNC (backend), cal, cancellable, uid, rid, &attachments, &error);
818 e_data_cal_respond_get_attachment_uris (cal, opid, error, attachments);
820 g_slist_foreach (attachments, (GFunc) g_free, NULL);
821 g_slist_free (attachments);
825 cal_backend_discard_alarm (ECalBackend *backend,
828 GCancellable *cancellable,
833 GError *error = NULL;
835 e_cal_backend_sync_discard_alarm (E_CAL_BACKEND_SYNC (backend), cal, cancellable, uid, rid, auid, &error);
837 e_data_cal_respond_discard_alarm (cal, opid, error);
841 cal_backend_get_timezone (ECalBackend *backend,
844 GCancellable *cancellable,
847 GError *error = NULL;
848 gchar *object = NULL;
850 e_cal_backend_sync_get_timezone (E_CAL_BACKEND_SYNC (backend), cal, cancellable, tzid, &object, &error);
852 if (!object && tzid) {
853 /* fallback if tzid contains only the location of timezone */
856 for (i = 0; tzid[i]; i++) {
862 icalcomponent *icalcomp = NULL, *free_comp = NULL;
864 icaltimezone *zone = icaltimezone_get_builtin_timezone (tzid);
866 /* Try fetching the timezone from zone directory. There are some timezones like MST, US/Pacific etc. which do not appear in
867 zone.tab, so they will not be available in the libical builtin timezone */
868 icalcomp = free_comp = icaltzutil_fetch_timezone (tzid);
872 icalcomp = icaltimezone_get_component (zone);
875 icalcomponent *clone = icalcomponent_new_clone (icalcomp);
878 prop = icalcomponent_get_first_property (clone, ICAL_TZID_PROPERTY);
880 /* change tzid to our, because the component has the buildin tzid */
881 icalproperty_set_tzid (prop, tzid);
883 object = icalcomponent_as_ical_string_r (clone);
884 g_clear_error (&error);
886 icalcomponent_free (clone);
890 icalcomponent_free (free_comp);
893 /* also cache this timezone to backend */
895 e_cal_backend_sync_add_timezone (E_CAL_BACKEND_SYNC (backend), cal, cancellable, object, NULL);
898 e_data_cal_respond_get_timezone (cal, opid, error, object);
904 cal_backend_add_timezone (ECalBackend *backend,
907 GCancellable *cancellable,
908 const gchar *tzobject)
910 GError *error = NULL;
912 e_cal_backend_sync_add_timezone (E_CAL_BACKEND_SYNC (backend), cal, cancellable, tzobject, &error);
914 e_data_cal_respond_add_timezone (cal, opid, error);
917 /* The default implementation is looking for timezone in the ical's builtin timezones,
918 * and if that fails, then it tries to extract the location from the tzid and get the
919 * timezone based on it. If even that fails, then it's returning UTC timezone.
920 * That means, that any object deriving from ECalBackendSync is supposed to implement
921 * this function for checking for a timezone in its own timezone cache, and if that
922 * fails, then call parent's object internal_get_timezone, and that's all.
924 static icaltimezone *
925 cal_backend_internal_get_timezone (ECalBackend *backend,
928 icaltimezone *zone = NULL;
933 zone = icaltimezone_get_builtin_timezone_from_tzid (tzid);
936 const gchar *s, *slash1 = NULL, *slash2 = NULL;
938 /* get builtin by a location, if any */
939 for (s = tzid; *s; s++) {
947 zone = icaltimezone_get_builtin_timezone (slash1 + 1);
949 zone = icaltimezone_get_builtin_timezone (tzid);
953 zone = icaltimezone_get_utc_timezone ();
959 cal_backend_sync_get_backend_property (ECalBackendSync *backend,
961 GCancellable *cancellable,
962 const gchar *prop_name,
966 /* to indicate to pass to the ECalBackend parent class */
971 cal_backend_sync_set_backend_property (ECalBackendSync *backend,
973 GCancellable *cancellable,
974 const gchar *prop_name,
975 const gchar *prop_value,
978 /* to indicate to pass to the ECalBackend parent class */
983 e_cal_backend_sync_finalize (GObject *object)
985 ECalBackendSyncPrivate *priv;
987 priv = E_CAL_BACKEND_SYNC_GET_PRIVATE (object);
989 g_mutex_free (priv->sync_mutex);
991 /* Chain up to parent's finalize() method. */
992 G_OBJECT_CLASS (e_cal_backend_sync_parent_class)->finalize (object);
996 e_cal_backend_sync_class_init (ECalBackendSyncClass *class)
998 GObjectClass *object_class;
999 ECalBackendClass *backend_class;
1001 g_type_class_add_private (class, sizeof (ECalBackendSyncPrivate));
1003 object_class = G_OBJECT_CLASS (class);
1004 object_class->finalize = e_cal_backend_sync_finalize;
1006 backend_class = E_CAL_BACKEND_CLASS (class);
1007 backend_class->open = cal_backend_open;
1008 backend_class->remove = cal_backend_remove;
1009 backend_class->refresh = cal_backend_refresh;
1010 backend_class->get_backend_property = cal_backend_get_backend_property;
1011 backend_class->set_backend_property = cal_backend_set_backend_property;
1012 backend_class->get_object = cal_backend_get_object;
1013 backend_class->get_object_list = cal_backend_get_object_list;
1014 backend_class->get_free_busy = cal_backend_get_free_busy;
1015 backend_class->create_objects = cal_backend_create_objects;
1016 backend_class->modify_objects = cal_backend_modify_objects;
1017 backend_class->remove_objects = cal_backend_remove_objects;
1018 backend_class->receive_objects = cal_backend_receive_objects;
1019 backend_class->send_objects = cal_backend_send_objects;
1020 backend_class->get_attachment_uris = cal_backend_get_attachment_uris;
1021 backend_class->discard_alarm = cal_backend_discard_alarm;
1022 backend_class->get_timezone = cal_backend_get_timezone;
1023 backend_class->add_timezone = cal_backend_add_timezone;
1024 backend_class->internal_get_timezone = cal_backend_internal_get_timezone;
1026 class->get_backend_property_sync = cal_backend_sync_get_backend_property;
1027 class->set_backend_property_sync = cal_backend_sync_set_backend_property;
1031 e_cal_backend_sync_init (ECalBackendSync *backend)
1033 backend->priv = E_CAL_BACKEND_SYNC_GET_PRIVATE (backend);
1034 backend->priv->sync_mutex = g_mutex_new ();