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_authenticate_user:
93 * @backend: an #ECalBackendSync
94 * @cancellable: a #GCancellable for the operation
95 * @credentials: an #ECredentials to authenticate with
96 * @error: #GError to set, when something fails
98 * Authenticates @backend with given @credentials.
103 e_cal_backend_sync_authenticate_user (ECalBackendSync *backend,
104 GCancellable *cancellable,
105 ECredentials *credentials,
108 e_return_data_cal_error_if_fail (E_IS_CAL_BACKEND_SYNC (backend), InvalidArg);
109 e_return_data_cal_error_if_fail (credentials, InvalidArg);
111 LOCK_WRAPPER (authenticate_user_sync, (backend, cancellable, credentials, error));
115 * e_cal_backend_sync_remove:
116 * @backend: An ECalBackendSync object.
117 * @cal: An EDataCal object.
118 * @cancellable: a #GCancellable for the operation
119 * @error: Out parameter for a #GError.
121 * Calls the remove_sync method on the given backend.
124 e_cal_backend_sync_remove (ECalBackendSync *backend,
126 GCancellable *cancellable,
129 e_return_data_cal_error_if_fail (backend && E_IS_CAL_BACKEND_SYNC (backend), InvalidArg);
131 LOCK_WRAPPER (remove_sync, (backend, cal, cancellable, error));
135 * e_cal_backend_sync_refresh:
136 * @backend: An ECalBackendSync object.
137 * @cal: An EDataCal object.
138 * @cancellable: a #GCancellable for the operation
139 * @error: Out parameter for a #GError.
141 * Calls the refresh_sync method on the given backend.
146 e_cal_backend_sync_refresh (ECalBackendSync *backend,
148 GCancellable *cancellable,
151 e_return_data_cal_error_if_fail (backend && E_IS_CAL_BACKEND_SYNC (backend), InvalidArg);
152 e_return_data_cal_error_if_fail (E_CAL_BACKEND_SYNC_GET_CLASS (backend)->refresh_sync != NULL, UnsupportedMethod);
154 LOCK_WRAPPER (refresh_sync, (backend, cal, cancellable, error));
158 * e_cal_backend_sync_get_backend_property:
159 * @backend: An ECalBackendSync object.
160 * @cal: An EDataCal object.
161 * @cancellable: a #GCancellable for the operation
162 * @prop_name: Property name whose value to retrieve.
163 * @prop_value: Return value of the @prop_name.
164 * @error: Out parameter for a #GError.
166 * Calls the get_backend_property_sync method on the given backend.
168 * Returns whether processed this property. Returning FALSE means to pass
169 * the call to the ECalBackend parent class, thus neither @error should be
175 e_cal_backend_sync_get_backend_property (ECalBackendSync *backend,
177 GCancellable *cancellable,
178 const gchar *prop_name,
182 gboolean res = FALSE;
184 e_return_data_cal_error_val_if_fail (backend && E_IS_CAL_BACKEND_SYNC (backend), InvalidArg);
185 e_return_data_cal_error_val_if_fail (prop_name, InvalidArg);
186 e_return_data_cal_error_val_if_fail (prop_value, InvalidArg);
188 LOCK_WRAPPER_RET_VAL (get_backend_property_sync, (backend, cal, cancellable, prop_name, prop_value, error));
194 * e_cal_backend_sync_set_backend_property:
195 * @backend: An ECalBackendSync object.
196 * @cal: An EDataCal object.
197 * @cancellable: a #GCancellable for the operation
198 * @prop_name: Property name to set.
199 * @prop_value: New value of the @prop_name.
200 * @error: Out parameter for a #GError.
202 * Calls the set_backend_property_sync method on the given backend.
204 * Returns whether processed this property. Returning FALSE means to pass
205 * the call to the ECalBackend parent class, thus neither @error should be
211 e_cal_backend_sync_set_backend_property (ECalBackendSync *backend,
213 GCancellable *cancellable,
214 const gchar *prop_name,
215 const gchar *prop_value,
218 gboolean res = FALSE;
220 e_return_data_cal_error_val_if_fail (backend && E_IS_CAL_BACKEND_SYNC (backend), InvalidArg);
221 e_return_data_cal_error_val_if_fail (prop_name, InvalidArg);
222 e_return_data_cal_error_val_if_fail (prop_value, InvalidArg);
224 LOCK_WRAPPER_RET_VAL (set_backend_property_sync, (backend, cal, cancellable, prop_name, prop_value, error));
230 * e_cal_backend_sync_get_object:
231 * @backend: An ECalBackendSync object.
232 * @cal: An EDataCal object.
233 * @cancellable: a #GCancellable for the operation
234 * @uid: UID of the object to get.
235 * @rid: Recurrence ID of the specific instance to get, or NULL if getting the
237 * @calobj: Placeholder for returned object.
238 * @error: Out parameter for a #GError.
240 * Calls the get_object_sync method on the given backend.
243 e_cal_backend_sync_get_object (ECalBackendSync *backend,
245 GCancellable *cancellable,
251 e_return_data_cal_error_if_fail (backend && E_IS_CAL_BACKEND_SYNC (backend), InvalidArg);
252 e_return_data_cal_error_if_fail (calobj, InvalidArg);
254 LOCK_WRAPPER (get_object_sync, (backend, cal, cancellable, uid, rid, calobj, error));
258 * e_cal_backend_sync_get_object_list:
259 * @backend: An ECalBackendSync object.
260 * @cal: An EDataCal object.
261 * @cancellable: a #GCancellable for the operation
262 * @sexp: Search query.
263 * @calobjs: Placeholder for list of returned objects.
264 * @error: Out parameter for a #GError.
266 * Calls the get_object_list_sync method on the given backend.
269 e_cal_backend_sync_get_object_list (ECalBackendSync *backend,
271 GCancellable *cancellable,
276 e_return_data_cal_error_if_fail (backend && E_IS_CAL_BACKEND_SYNC (backend), InvalidArg);
277 e_return_data_cal_error_if_fail (calobjs, InvalidArg);
279 LOCK_WRAPPER (get_object_list_sync, (backend, cal, cancellable, sexp, calobjs, error));
283 * e_cal_backend_sync_get_free_busy:
284 * @backend: An ECalBackendSync object.
285 * @cal: An EDataCal object.
286 * @cancellable: a #GCancellable for the operation
287 * @users: List of users to get F/B info from.
288 * @start: Time range start.
289 * @end: Time range end.
290 * @freebusyobjects: Placeholder for F/B information.
291 * @error: Out parameter for a #GError.
293 * Calls the get_free_busy_sync method on the given backend.
296 e_cal_backend_sync_get_free_busy (ECalBackendSync *backend,
298 GCancellable *cancellable,
302 GSList **freebusyobjects,
305 e_return_data_cal_error_if_fail (E_IS_CAL_BACKEND_SYNC (backend), InvalidArg);
307 LOCK_WRAPPER (get_free_busy_sync, (backend, cal, cancellable, users, start, end, freebusyobjects, error));
311 * e_cal_backend_sync_create_objects:
312 * @backend: An ECalBackendSync object.
313 * @cal: An EDataCal object.
314 * @cancellable: a #GCancellable for the operation
315 * @calobjs: The objects to be added.
316 * @uids: Placeholder for server-generated UIDs.
317 * @new_components: (out) (transfer full): Placeholder for returned #ECalComponent objects.
318 * @error: Out parameter for a #GError.
320 * Calls the create_objects_sync method on the given backend.
323 e_cal_backend_sync_create_objects (ECalBackendSync *backend,
325 GCancellable *cancellable,
326 const GSList *calobjs,
328 GSList **new_components,
331 e_return_data_cal_error_if_fail (backend && E_IS_CAL_BACKEND_SYNC (backend), InvalidArg);
332 e_return_data_cal_error_if_fail (E_CAL_BACKEND_SYNC_GET_CLASS (backend)->create_objects_sync != NULL, UnsupportedMethod);
334 LOCK_WRAPPER (create_objects_sync, (backend, cal, cancellable, calobjs, uids, new_components, error));
338 * e_cal_backend_sync_modify_objects:
339 * @backend: An ECalBackendSync object.
340 * @cal: An EDataCal object.
341 * @cancellable: a #GCancellable for the operation
342 * @calobjs: Objects to be modified.
343 * @mod: Type of modification to be done.
344 * @old_components: (out) (transfer full): Placeholder for returning the old components as they were stored on the
346 * @new_components: (out) (transfer full): Placeholder for returning the new components as they have been stored
348 * @error: Out parameter for a #GError.
350 * Calls the modify_objects_sync method on the given backend.
353 e_cal_backend_sync_modify_objects (ECalBackendSync *backend,
355 GCancellable *cancellable,
356 const GSList *calobjs,
358 GSList **old_components,
359 GSList **new_components,
362 e_return_data_cal_error_if_fail (backend && E_IS_CAL_BACKEND_SYNC (backend), InvalidArg);
363 e_return_data_cal_error_if_fail (E_CAL_BACKEND_SYNC_GET_CLASS (backend)->modify_objects_sync != NULL, UnsupportedMethod);
365 LOCK_WRAPPER (modify_objects_sync, (backend, cal, cancellable, calobjs, mod, old_components, new_components, error));
369 * e_cal_backend_sync_remove_objects:
370 * @backend: An ECalBackendSync object.
371 * @cal: An EDataCal object.
372 * @cancellable: a #GCancellable for the operation
373 * @ids: List of #ECalComponentId objects identifying the objects to remove.
374 * @mod: Type of removal.
375 * @old_components: (out) (transfer full): Placeholder for returning the old components as they were stored on the
377 * @new_components: (out) (transfer full): Placeholder for returning the new components as they have been stored
378 * on the backend (when removing individual instances). If removing whole objects,
379 * they will be set to %NULL.
380 * @error: Out parameter for a #GError.
382 * Calls the remove_objects_sync method on the given backend.
385 e_cal_backend_sync_remove_objects (ECalBackendSync *backend,
387 GCancellable *cancellable,
390 GSList **old_components,
391 GSList **new_components,
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)->remove_objects_sync != NULL, UnsupportedMethod);
397 LOCK_WRAPPER (remove_objects_sync, (backend, cal, cancellable, ids, mod, old_components, new_components, error));
401 * e_cal_backend_sync_receive_objects:
402 * @backend: An ECalBackendSync object.
403 * @cal: An EDataCal object.
404 * @cancellable: a #GCancellable for the operation
405 * @calobj: iCalendar object to receive.
406 * @error: Out parameter for a #GError.
408 * Calls the receive_objects_sync method on the given backend.
411 e_cal_backend_sync_receive_objects (ECalBackendSync *backend,
413 GCancellable *cancellable,
417 e_return_data_cal_error_if_fail (backend && E_IS_CAL_BACKEND_SYNC (backend), InvalidArg);
418 e_return_data_cal_error_if_fail (E_CAL_BACKEND_SYNC_GET_CLASS (backend)->receive_objects_sync != NULL, UnsupportedMethod);
420 LOCK_WRAPPER (receive_objects_sync, (backend, cal, cancellable, calobj, error));
424 * e_cal_backend_sync_send_objects:
425 * @backend: An ECalBackendSync object.
426 * @cal: An EDataCal object.
427 * @cancellable: a #GCancellable for the operation
428 * @calobj: The iCalendar object to send.
429 * @users: List of users to send notifications to.
430 * @modified_calobj: Placeholder for the iCalendar object after being modified.
431 * @error: Out parameter for a #GError.
433 * Calls the send_objects_sync method on the given backend.
436 e_cal_backend_sync_send_objects (ECalBackendSync *backend,
438 GCancellable *cancellable,
441 gchar **modified_calobj,
444 e_return_data_cal_error_if_fail (backend && E_IS_CAL_BACKEND_SYNC (backend), InvalidArg);
445 e_return_data_cal_error_if_fail (E_CAL_BACKEND_SYNC_GET_CLASS (backend)->send_objects_sync != NULL, UnsupportedMethod);
447 LOCK_WRAPPER (send_objects_sync, (backend, cal, cancellable, calobj, users, modified_calobj, error));
451 * e_cal_backend_sync_get_attachment_uris:
452 * @backend: An ECalBackendSync object.
453 * @cal: An EDataCal object.
454 * @cancellable: a #GCancellable for the operation
455 * @uid: Unique id of the calendar object.
456 * @rid: Recurrence id of the calendar object.
457 * @attachments: Placeholder for list of returned attachment uris.
458 * @error: Out parameter for a #GError.
460 * Calls the get_attachment_uris_sync method on the given backend.
465 e_cal_backend_sync_get_attachment_uris (ECalBackendSync *backend,
467 GCancellable *cancellable,
470 GSList **attachments,
473 e_return_data_cal_error_if_fail (backend && E_IS_CAL_BACKEND_SYNC (backend), InvalidArg);
474 e_return_data_cal_error_if_fail (attachments, InvalidArg);
476 LOCK_WRAPPER (get_attachment_uris_sync, (backend, cal, cancellable, uid, rid, attachments, error));
480 * e_cal_backend_sync_discard_alarm:
481 * @backend: An ECalBackendSync object.
482 * @cal: An EDataCal object.
483 * @cancellable: a #GCancellable for the operation
484 * @uid: Unique id of the calendar object.
485 * @rid: Recurrence id of the calendar object.
486 * @auid: Alarm ID to remove.
487 * @error: Out parameter for a #GError.
489 * Calls the discard_alarm_sync method on the given backend.
492 e_cal_backend_sync_discard_alarm (ECalBackendSync *backend,
494 GCancellable *cancellable,
500 e_return_data_cal_error_if_fail (backend && E_IS_CAL_BACKEND_SYNC (backend), InvalidArg);
501 e_return_data_cal_error_if_fail (uid, InvalidArg);
502 e_return_data_cal_error_if_fail (auid, InvalidArg);
504 LOCK_WRAPPER (discard_alarm_sync, (backend, cal, cancellable, uid, rid, auid, error));
508 * e_cal_backend_sync_get_timezone:
509 * @backend: An ECalBackendSync object.
510 * @cal: An EDataCal object.
511 * @cancellable: a #GCancellable for the operation
512 * @tzid: ID of the timezone to retrieve.
513 * @tzobject: Placeholder for the returned timezone.
514 * @error: Out parameter for a #GError.
516 * Calls the get_timezone_sync method on the given backend.
517 * This method is not mandatory on the backend, because here
518 * is used internal_get_timezone call to fetch timezone from
519 * it and that is transformed to a string. In other words,
520 * any object deriving from ECalBackendSync can implement only
521 * internal_get_timezone and can skip implementation of
522 * get_timezone_sync completely.
525 e_cal_backend_sync_get_timezone (ECalBackendSync *backend,
527 GCancellable *cancellable,
532 e_return_data_cal_error_if_fail (E_IS_CAL_BACKEND_SYNC (backend), InvalidArg);
534 if (E_CAL_BACKEND_SYNC_GET_CLASS (backend)->get_timezone_sync) {
535 LOCK_WRAPPER (get_timezone_sync, (backend, cal, cancellable, tzid, tzobject, error));
538 if (tzobject && !*tzobject) {
539 icaltimezone *zone = NULL;
541 if (backend->priv->mutex_lock)
542 g_mutex_lock (backend->priv->sync_mutex);
543 zone = e_cal_backend_internal_get_timezone (E_CAL_BACKEND (backend), tzid);
544 if (backend->priv->mutex_lock)
545 g_mutex_unlock (backend->priv->sync_mutex);
548 g_propagate_error (error, e_data_cal_create_error (ObjectNotFound, NULL));
550 icalcomponent *icalcomp;
552 icalcomp = icaltimezone_get_component (zone);
555 g_propagate_error (error, e_data_cal_create_error (InvalidObject, NULL));
557 *tzobject = icalcomponent_as_ical_string_r (icalcomp);
564 * e_cal_backend_sync_add_timezone:
565 * @backend: An ECalBackendSync object.
566 * @cal: An EDataCal object.
567 * @cancellable: a #GCancellable for the operation
568 * @tzobject: VTIMEZONE object to be added.
569 * @error: Out parameter for a #GError.
571 * Calls the add_timezone_sync method on the given backend.
574 e_cal_backend_sync_add_timezone (ECalBackendSync *backend,
576 GCancellable *cancellable,
577 const gchar *tzobject,
580 e_return_data_cal_error_if_fail (E_IS_CAL_BACKEND_SYNC (backend), InvalidArg);
582 LOCK_WRAPPER (add_timezone_sync, (backend, cal, cancellable, tzobject, error));
586 cal_backend_open (ECalBackend *backend,
589 GCancellable *cancellable,
590 gboolean only_if_exists)
592 GError *error = NULL;
594 e_cal_backend_sync_open (E_CAL_BACKEND_SYNC (backend), cal, cancellable, only_if_exists, &error);
596 e_data_cal_respond_open (cal, opid, error);
600 cal_backend_authenticate_user (ECalBackend *backend,
601 GCancellable *cancellable,
602 ECredentials *credentials)
604 GError *error = NULL;
606 e_cal_backend_sync_authenticate_user (E_CAL_BACKEND_SYNC (backend), cancellable, credentials, &error);
608 e_cal_backend_notify_opened (backend, error);
612 cal_backend_remove (ECalBackend *backend,
615 GCancellable *cancellable)
617 GError *error = NULL;
619 e_cal_backend_sync_remove (E_CAL_BACKEND_SYNC (backend), cal, cancellable, &error);
621 e_data_cal_respond_remove (cal, opid, error);
625 cal_backend_refresh (ECalBackend *backend,
628 GCancellable *cancellable)
630 GError *error = NULL;
632 e_cal_backend_sync_refresh (E_CAL_BACKEND_SYNC (backend), cal, cancellable, &error);
634 e_data_cal_respond_refresh (cal, opid, error);
638 cal_backend_get_backend_property (ECalBackend *backend,
641 GCancellable *cancellable,
642 const gchar *prop_name)
644 GError *error = NULL;
645 gchar *prop_value = NULL;
647 if (e_cal_backend_sync_get_backend_property (E_CAL_BACKEND_SYNC (backend), cal, cancellable, prop_name, &prop_value, &error))
648 e_data_cal_respond_get_backend_property (cal, opid, error, prop_value);
650 (* E_CAL_BACKEND_CLASS (e_cal_backend_sync_parent_class)->get_backend_property) (backend, cal, opid, cancellable, prop_name);
656 cal_backend_set_backend_property (ECalBackend *backend,
659 GCancellable *cancellable,
660 const gchar *prop_name,
661 const gchar *prop_value)
663 GError *error = NULL;
665 if (e_cal_backend_sync_set_backend_property (E_CAL_BACKEND_SYNC (backend), cal, cancellable, prop_name, prop_value, &error))
666 e_data_cal_respond_set_backend_property (cal, opid, error);
668 (* E_CAL_BACKEND_CLASS (e_cal_backend_sync_parent_class)->set_backend_property) (backend, cal, opid, cancellable, prop_name, prop_value);
672 cal_backend_get_object (ECalBackend *backend,
675 GCancellable *cancellable,
679 GError *error = NULL;
680 gchar *calobj = NULL;
682 e_cal_backend_sync_get_object (E_CAL_BACKEND_SYNC (backend), cal, cancellable, uid, rid, &calobj, &error);
684 e_data_cal_respond_get_object (cal, opid, error, calobj);
690 cal_backend_get_object_list (ECalBackend *backend,
693 GCancellable *cancellable,
696 GError *error = NULL;
697 GSList *calobjs = NULL;
699 e_cal_backend_sync_get_object_list (E_CAL_BACKEND_SYNC (backend), cal, cancellable, sexp, &calobjs, &error);
701 e_data_cal_respond_get_object_list (cal, opid, error, calobjs);
703 g_slist_foreach (calobjs, (GFunc) g_free, NULL);
704 g_slist_free (calobjs);
708 cal_backend_get_free_busy (ECalBackend *backend,
711 GCancellable *cancellable,
716 GError *error = NULL;
717 GSList *freebusyobjs = NULL;
719 e_cal_backend_sync_get_free_busy (E_CAL_BACKEND_SYNC (backend), cal, cancellable, users, start, end, &freebusyobjs, &error);
722 e_data_cal_report_free_busy_data (cal, freebusyobjs);
723 e_data_cal_respond_get_free_busy (cal, opid, error);
725 g_slist_foreach (freebusyobjs, (GFunc) g_free, NULL);
726 g_slist_free (freebusyobjs);
730 ecalcomponent_slist_from_strings (const GSList *strings)
732 GSList *ecalcomps = NULL;
735 for (l = strings; l; l = l->next) {
736 ECalComponent *component = e_cal_component_new_from_string (l->data);
737 ecalcomps = g_slist_prepend (ecalcomps, component);
740 return g_slist_reverse (ecalcomps);
744 cal_backend_create_objects (ECalBackend *backend,
747 GCancellable *cancellable,
748 const GSList *calobjs)
750 GError *error = NULL;
752 GSList *new_components = NULL;
754 e_cal_backend_sync_create_objects (E_CAL_BACKEND_SYNC (backend), cal, cancellable, calobjs, &uids, &new_components, &error);
757 new_components = ecalcomponent_slist_from_strings (calobjs);
759 e_data_cal_respond_create_objects (cal, opid, error, uids, new_components);
761 g_slist_free_full (uids, g_free);
762 e_util_free_nullable_object_slist (new_components);
766 cal_backend_modify_objects (ECalBackend *backend,
769 GCancellable *cancellable,
770 const GSList *calobjs,
773 GError *error = NULL;
774 GSList *old_components = NULL, *new_components = NULL;
776 e_cal_backend_sync_modify_objects (E_CAL_BACKEND_SYNC (backend), cal, cancellable, calobjs, mod, &old_components, &new_components, &error);
779 old_components = ecalcomponent_slist_from_strings (calobjs);
781 e_data_cal_respond_modify_objects (cal, opid, error, old_components, new_components);
783 e_util_free_nullable_object_slist (old_components);
784 e_util_free_nullable_object_slist (new_components);
788 cal_backend_remove_objects (ECalBackend *backend,
791 GCancellable *cancellable,
795 GError *error = NULL;
796 GSList *old_components = NULL, *new_components = NULL;
798 e_cal_backend_sync_remove_objects (E_CAL_BACKEND_SYNC (backend), cal, cancellable, ids, mod, &old_components, &new_components, &error);
800 e_data_cal_respond_remove_objects (cal, opid, error, ids, old_components, new_components);
802 e_util_free_nullable_object_slist (old_components);
803 e_util_free_nullable_object_slist (new_components);
807 cal_backend_receive_objects (ECalBackend *backend,
810 GCancellable *cancellable,
813 GError *error = NULL;
815 e_cal_backend_sync_receive_objects (E_CAL_BACKEND_SYNC (backend), cal, cancellable, calobj, &error);
817 e_data_cal_respond_receive_objects (cal, opid, error);
821 cal_backend_send_objects (ECalBackend *backend,
824 GCancellable *cancellable,
827 GError *error = NULL;
828 GSList *users = NULL;
829 gchar *modified_calobj = NULL;
831 e_cal_backend_sync_send_objects (E_CAL_BACKEND_SYNC (backend), cal, cancellable, calobj, &users, &modified_calobj, &error);
833 e_data_cal_respond_send_objects (cal, opid, error, users, modified_calobj ? modified_calobj : calobj);
835 g_slist_foreach (users, (GFunc) g_free, NULL);
836 g_slist_free (users);
837 g_free (modified_calobj);
841 cal_backend_get_attachment_uris (ECalBackend *backend,
844 GCancellable *cancellable,
848 GError *error = NULL;
849 GSList *attachments = NULL;
851 e_cal_backend_sync_get_attachment_uris (E_CAL_BACKEND_SYNC (backend), cal, cancellable, uid, rid, &attachments, &error);
853 e_data_cal_respond_get_attachment_uris (cal, opid, error, attachments);
855 g_slist_foreach (attachments, (GFunc) g_free, NULL);
856 g_slist_free (attachments);
860 cal_backend_discard_alarm (ECalBackend *backend,
863 GCancellable *cancellable,
868 GError *error = NULL;
870 e_cal_backend_sync_discard_alarm (E_CAL_BACKEND_SYNC (backend), cal, cancellable, uid, rid, auid, &error);
872 e_data_cal_respond_discard_alarm (cal, opid, error);
876 cal_backend_get_timezone (ECalBackend *backend,
879 GCancellable *cancellable,
882 GError *error = NULL;
883 gchar *object = NULL;
885 e_cal_backend_sync_get_timezone (E_CAL_BACKEND_SYNC (backend), cal, cancellable, tzid, &object, &error);
887 if (!object && tzid) {
888 /* fallback if tzid contains only the location of timezone */
891 for (i = 0; tzid[i]; i++) {
897 icalcomponent *icalcomp = NULL, *free_comp = NULL;
899 icaltimezone *zone = icaltimezone_get_builtin_timezone (tzid);
901 /* Try fetching the timezone from zone directory. There are some timezones like MST, US/Pacific etc. which do not appear in
902 zone.tab, so they will not be available in the libical builtin timezone */
903 icalcomp = free_comp = icaltzutil_fetch_timezone (tzid);
907 icalcomp = icaltimezone_get_component (zone);
910 icalcomponent *clone = icalcomponent_new_clone (icalcomp);
913 prop = icalcomponent_get_first_property (clone, ICAL_TZID_PROPERTY);
915 /* change tzid to our, because the component has the buildin tzid */
916 icalproperty_set_tzid (prop, tzid);
918 object = icalcomponent_as_ical_string_r (clone);
919 g_clear_error (&error);
921 icalcomponent_free (clone);
925 icalcomponent_free (free_comp);
928 /* also cache this timezone to backend */
930 e_cal_backend_sync_add_timezone (E_CAL_BACKEND_SYNC (backend), cal, cancellable, object, NULL);
933 e_data_cal_respond_get_timezone (cal, opid, error, object);
939 cal_backend_add_timezone (ECalBackend *backend,
942 GCancellable *cancellable,
943 const gchar *tzobject)
945 GError *error = NULL;
947 e_cal_backend_sync_add_timezone (E_CAL_BACKEND_SYNC (backend), cal, cancellable, tzobject, &error);
949 e_data_cal_respond_add_timezone (cal, opid, error);
952 /* The default implementation is looking for timezone in the ical's builtin timezones,
953 * and if that fails, then it tries to extract the location from the tzid and get the
954 * timezone based on it. If even that fails, then it's returning UTC timezone.
955 * That means, that any object deriving from ECalBackendSync is supposed to implement
956 * this function for checking for a timezone in its own timezone cache, and if that
957 * fails, then call parent's object internal_get_timezone, and that's all.
959 static icaltimezone *
960 cal_backend_internal_get_timezone (ECalBackend *backend,
963 icaltimezone *zone = NULL;
968 zone = icaltimezone_get_builtin_timezone_from_tzid (tzid);
971 const gchar *s, *slash1 = NULL, *slash2 = NULL;
973 /* get builtin by a location, if any */
974 for (s = tzid; *s; s++) {
982 zone = icaltimezone_get_builtin_timezone (slash1 + 1);
984 zone = icaltimezone_get_builtin_timezone (tzid);
988 zone = icaltimezone_get_utc_timezone ();
994 cal_backend_sync_get_backend_property (ECalBackendSync *backend,
996 GCancellable *cancellable,
997 const gchar *prop_name,
1001 /* to indicate to pass to the ECalBackend parent class */
1006 cal_backend_sync_set_backend_property (ECalBackendSync *backend,
1008 GCancellable *cancellable,
1009 const gchar *prop_name,
1010 const gchar *prop_value,
1013 /* to indicate to pass to the ECalBackend parent class */
1018 e_cal_backend_sync_finalize (GObject *object)
1020 ECalBackendSyncPrivate *priv;
1022 priv = E_CAL_BACKEND_SYNC_GET_PRIVATE (object);
1024 g_mutex_free (priv->sync_mutex);
1026 /* Chain up to parent's finalize() method. */
1027 G_OBJECT_CLASS (e_cal_backend_sync_parent_class)->finalize (object);
1031 e_cal_backend_sync_class_init (ECalBackendSyncClass *class)
1033 GObjectClass *object_class;
1034 ECalBackendClass *backend_class;
1036 g_type_class_add_private (class, sizeof (ECalBackendSyncPrivate));
1038 object_class = G_OBJECT_CLASS (class);
1039 object_class->finalize = e_cal_backend_sync_finalize;
1041 backend_class = E_CAL_BACKEND_CLASS (class);
1042 backend_class->open = cal_backend_open;
1043 backend_class->authenticate_user = cal_backend_authenticate_user;
1044 backend_class->remove = cal_backend_remove;
1045 backend_class->refresh = cal_backend_refresh;
1046 backend_class->get_backend_property = cal_backend_get_backend_property;
1047 backend_class->set_backend_property = cal_backend_set_backend_property;
1048 backend_class->get_object = cal_backend_get_object;
1049 backend_class->get_object_list = cal_backend_get_object_list;
1050 backend_class->get_free_busy = cal_backend_get_free_busy;
1051 backend_class->create_objects = cal_backend_create_objects;
1052 backend_class->modify_objects = cal_backend_modify_objects;
1053 backend_class->remove_objects = cal_backend_remove_objects;
1054 backend_class->receive_objects = cal_backend_receive_objects;
1055 backend_class->send_objects = cal_backend_send_objects;
1056 backend_class->get_attachment_uris = cal_backend_get_attachment_uris;
1057 backend_class->discard_alarm = cal_backend_discard_alarm;
1058 backend_class->get_timezone = cal_backend_get_timezone;
1059 backend_class->add_timezone = cal_backend_add_timezone;
1060 backend_class->internal_get_timezone = cal_backend_internal_get_timezone;
1062 class->get_backend_property_sync = cal_backend_sync_get_backend_property;
1063 class->set_backend_property_sync = cal_backend_sync_set_backend_property;
1067 e_cal_backend_sync_init (ECalBackendSync *backend)
1069 backend->priv = E_CAL_BACKEND_SYNC_GET_PRIVATE (backend);
1070 backend->priv->sync_mutex = g_mutex_new ();