1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /* Evolution calendar - generic backend class
4 * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
6 * Authors: Federico Mena-Quintero <federico@ximian.com>
7 * JP Rosevear <jpr@ximian.com>
8 * Rodrigo Moya <rodrigo@ximian.com>
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of version 2 of the GNU Lesser General Public
12 * License as published by the Free Software Foundation.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
25 #include <libxml/parser.h>
26 #include <libxml/parserInternals.h>
27 #include <libxml/xmlmemory.h>
29 #include "e-cal-backend.h"
33 /* Private part of the CalBackend structure */
34 struct _ECalBackendPrivate {
35 /* The source for this backend */
38 /* URI, from source. This is cached, since we return const. */
41 /* The kind of components for this backend */
42 icalcomponent_kind kind;
44 /* List of Cal objects */
45 GMutex *clients_mutex;
48 GMutex *queries_mutex;
51 /* ECalBackend to pass notifications on to */
52 ECalBackend *notification_proxy;
70 static guint e_cal_backend_signals[LAST_SIGNAL];
72 static void e_cal_backend_class_init (ECalBackendClass *class);
73 static void e_cal_backend_init (ECalBackend *backend);
74 static void e_cal_backend_finalize (GObject *object);
76 #define CLASS(backend) (E_CAL_BACKEND_CLASS (G_OBJECT_GET_CLASS (backend)))
78 static GObjectClass *parent_class;
83 * e_cal_backend_get_type:
85 * Registers the #ECalBackend class if necessary, and returns the type ID
88 * Return value: The type ID of the #ECalBackend class.
91 e_cal_backend_get_type (void)
93 static GType e_cal_backend_type = 0;
95 if (!e_cal_backend_type) {
96 static GTypeInfo info = {
97 sizeof (ECalBackendClass),
99 (GBaseFinalizeFunc) NULL,
100 (GClassInitFunc) e_cal_backend_class_init,
102 sizeof (ECalBackend),
104 (GInstanceInitFunc) e_cal_backend_init,
106 e_cal_backend_type = g_type_register_static (G_TYPE_OBJECT, "ECalBackend", &info, 0);
109 return e_cal_backend_type;
113 e_cal_backend_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
115 ECalBackend *backend;
116 ECalBackendPrivate *priv;
118 backend = E_CAL_BACKEND (object);
119 priv = backend->priv;
121 switch (property_id) {
126 new_source = g_value_get_object (value);
128 g_object_ref (new_source);
131 g_object_unref (priv->source);
133 priv->source = new_source;
138 priv->uri = e_source_get_uri (priv->source);
145 priv->uri = g_value_dup_string (value);
149 priv->kind = g_value_get_ulong (value);
152 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
158 e_cal_backend_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
160 ECalBackend *backend;
161 ECalBackendPrivate *priv;
163 backend = E_CAL_BACKEND (object);
164 priv = backend->priv;
166 switch (property_id) {
168 g_value_set_object (value, e_cal_backend_get_source (backend));
171 g_value_set_string (value, e_cal_backend_get_uri (backend));
174 g_value_set_ulong (value, e_cal_backend_get_kind (backend));
177 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
182 /* Class initialization function for the calendar backend */
184 e_cal_backend_class_init (ECalBackendClass *class)
186 GObjectClass *object_class;
188 parent_class = (GObjectClass *) g_type_class_peek_parent (class);
190 object_class = (GObjectClass *) class;
192 object_class->set_property = e_cal_backend_set_property;
193 object_class->get_property = e_cal_backend_get_property;
194 object_class->finalize = e_cal_backend_finalize;
196 g_object_class_install_property (object_class, PROP_SOURCE,
197 g_param_spec_object ("source", NULL, NULL, E_TYPE_SOURCE,
198 G_PARAM_READABLE | G_PARAM_WRITABLE
199 | G_PARAM_CONSTRUCT_ONLY));
201 g_object_class_install_property (object_class, PROP_URI,
202 g_param_spec_string ("uri", NULL, NULL, "",
203 G_PARAM_READABLE | G_PARAM_WRITABLE
204 | G_PARAM_CONSTRUCT_ONLY));
206 g_object_class_install_property (object_class, PROP_KIND,
207 g_param_spec_ulong ("kind", NULL, NULL,
208 ICAL_NO_COMPONENT, ICAL_XLICMIMEPART_COMPONENT,
210 G_PARAM_READABLE | G_PARAM_WRITABLE
211 | G_PARAM_CONSTRUCT_ONLY));
212 e_cal_backend_signals[LAST_CLIENT_GONE] =
213 g_signal_new ("last_client_gone",
214 G_TYPE_FROM_CLASS (class),
216 G_STRUCT_OFFSET (ECalBackendClass, last_client_gone),
218 g_cclosure_marshal_VOID__VOID,
220 e_cal_backend_signals[OPENED] =
221 g_signal_new ("opened",
222 G_TYPE_FROM_CLASS (class),
224 G_STRUCT_OFFSET (ECalBackendClass, opened),
226 g_cclosure_marshal_VOID__ENUM,
229 e_cal_backend_signals[REMOVED] =
230 g_signal_new ("removed",
231 G_TYPE_FROM_CLASS (class),
233 G_STRUCT_OFFSET (ECalBackendClass, removed),
235 g_cclosure_marshal_VOID__ENUM,
239 class->last_client_gone = NULL;
240 class->opened = NULL;
241 class->obj_updated = NULL;
243 class->get_cal_address = NULL;
244 class->get_alarm_email_address = NULL;
245 class->get_static_capabilities = NULL;
247 class->is_loaded = NULL;
248 class->is_read_only = NULL;
249 class->start_query = NULL;
250 class->get_mode = NULL;
251 class->set_mode = NULL;
252 class->get_object = NULL;
253 class->get_default_object = NULL;
254 class->get_object_list = NULL;
255 class->get_free_busy = NULL;
256 class->get_changes = NULL;
257 class->discard_alarm = NULL;
258 class->create_object = NULL;
259 class->modify_object = NULL;
260 class->remove_object = NULL;
261 class->receive_objects = NULL;
262 class->send_objects = NULL;
263 class->get_timezone = NULL;
264 class->add_timezone = NULL;
265 class->set_default_timezone = NULL;
268 /* Object initialization func for the calendar backend */
270 e_cal_backend_init (ECalBackend *backend)
272 ECalBackendPrivate *priv;
274 priv = g_new0 (ECalBackendPrivate, 1);
275 backend->priv = priv;
277 priv->clients = NULL;
278 priv->clients_mutex = g_mutex_new ();
280 /* FIXME bonobo_object_ref/unref? */
281 priv->queries = e_list_new ((EListCopyFunc) bonobo_object_ref, (EListFreeFunc) bonobo_object_unref, NULL);
282 priv->queries_mutex = g_mutex_new ();
286 e_cal_backend_finalize (GObject *object)
288 ECalBackend *backend = (ECalBackend *)object;
289 ECalBackendPrivate *priv;
291 priv = backend->priv;
293 g_assert (priv->clients == NULL);
295 g_object_unref (priv->queries);
297 g_mutex_free (priv->clients_mutex);
298 g_mutex_free (priv->queries_mutex);
301 g_object_unref (priv->source);
304 G_OBJECT_CLASS (parent_class)->finalize (object);
310 * e_cal_backend_get_source:
311 * @backend: An #ECalBackend object.
313 * Gets the #ESource associated with the given backend.
315 * Return value: The #ESource for the backend.
318 e_cal_backend_get_source (ECalBackend *backend)
320 ECalBackendPrivate *priv;
322 g_return_val_if_fail (backend != NULL, NULL);
323 g_return_val_if_fail (E_IS_CAL_BACKEND (backend), NULL);
325 priv = backend->priv;
331 * e_cal_backend_get_uri:
332 * @backend: A calendar backend.
334 * Queries the URI of a calendar backend, which must already have an open
337 * Return value: The URI where the calendar is stored.
340 e_cal_backend_get_uri (ECalBackend *backend)
342 ECalBackendPrivate *priv;
344 g_return_val_if_fail (backend != NULL, NULL);
345 g_return_val_if_fail (E_IS_CAL_BACKEND (backend), NULL);
347 priv = backend->priv;
353 * e_cal_backend_get_kind:
354 * @backend: An #ECalBackend object.
356 * Gets the kind of components the given backend stores.
358 * Return value: The kind of components for this backend.
361 e_cal_backend_get_kind (ECalBackend *backend)
363 ECalBackendPrivate *priv;
365 g_return_val_if_fail (backend != NULL, ICAL_NO_COMPONENT);
366 g_return_val_if_fail (E_IS_CAL_BACKEND (backend), ICAL_NO_COMPONENT);
368 priv = backend->priv;
374 cal_destroy_cb (gpointer data, GObject *where_cal_was)
376 ECalBackend *backend = E_CAL_BACKEND (data);
378 e_cal_backend_remove_client (backend, (EDataCal *) where_cal_was);
382 listener_died_cb (gpointer cnx, gpointer data)
384 EDataCal *cal = E_DATA_CAL (data);
386 if (ORBit_small_get_connection_status (e_data_cal_get_listener(cal)) == ORBIT_CONNECTION_DISCONNECTED)
387 e_cal_backend_remove_client (e_data_cal_get_backend (cal), cal);
391 last_client_gone (ECalBackend *backend)
393 g_signal_emit (backend, e_cal_backend_signals[LAST_CLIENT_GONE], 0);
397 * e_cal_backend_add_client:
398 * @backend: An ECalBackend object.
399 * @cal: An EDataCal object.
401 * Adds a new client to the given backend. For any event, the backend will
402 * notify all clients added via this function.
405 e_cal_backend_add_client (ECalBackend *backend, EDataCal *cal)
407 ECalBackendPrivate *priv;
409 g_return_if_fail (backend != NULL);
410 g_return_if_fail (E_IS_CAL_BACKEND (backend));
411 g_return_if_fail (cal != NULL);
412 g_return_if_fail (E_IS_DATA_CAL (cal));
414 priv = backend->priv;
416 bonobo_object_set_immortal (BONOBO_OBJECT (cal), TRUE);
418 g_object_weak_ref (G_OBJECT (cal), cal_destroy_cb, backend);
420 ORBit_small_listen_for_broken (e_data_cal_get_listener (cal), G_CALLBACK (listener_died_cb), cal);
422 g_mutex_lock (priv->clients_mutex);
423 priv->clients = g_list_append (priv->clients, cal);
424 g_mutex_unlock (priv->clients_mutex);
428 * e_cal_backend_remove_client:
429 * @backend: An #ECalBackend object.
430 * @cal: An #EDataCal object.
432 * Removes a client from the list of connected clients to the given backend.
435 e_cal_backend_remove_client (ECalBackend *backend, EDataCal *cal)
437 ECalBackendPrivate *priv;
439 /* XXX this needs a bit more thinking wrt the mutex - we
440 should be holding it when we check to see if clients is
442 g_return_if_fail (backend != NULL);
443 g_return_if_fail (E_IS_CAL_BACKEND (backend));
444 g_return_if_fail (cal != NULL);
445 g_return_if_fail (E_IS_DATA_CAL (cal));
447 priv = backend->priv;
450 g_mutex_lock (priv->clients_mutex);
451 priv->clients = g_list_remove (priv->clients, cal);
452 g_mutex_unlock (priv->clients_mutex);
454 /* When all clients go away, notify the parent factory about it so that
455 * it may decide whether to kill the backend or not.
458 last_client_gone (backend);
462 * e_cal_backend_add_query:
463 * @backend: An #ECalBackend object.
464 * @query: An #EDataCalView object.
466 * Adds a query to the list of live queries being run by the given backend.
467 * Doing so means that any listener on the query will get notified of any
468 * change that affect the live query.
471 e_cal_backend_add_query (ECalBackend *backend, EDataCalView *query)
473 g_return_if_fail (backend != NULL);
474 g_return_if_fail (E_IS_CAL_BACKEND (backend));
476 g_mutex_lock (backend->priv->queries_mutex);
478 e_list_append (backend->priv->queries, query);
480 g_mutex_unlock (backend->priv->queries_mutex);
484 * e_cal_backend_get_queries:
485 * @backend: An #ECalBackend object.
487 * Gets the list of live queries being run on the given backend.
489 * Return value: The list of live queries.
492 e_cal_backend_get_queries (ECalBackend *backend)
494 g_return_val_if_fail (backend != NULL, NULL);
495 g_return_val_if_fail (E_IS_CAL_BACKEND (backend), NULL);
497 return backend->priv->queries;
501 * e_cal_backend_remove_query
502 * @backend: An #ECalBackend object.
503 * @query: An #EDataCalView object, previously added with @ref e_cal_backend_add_query.
505 * Removes query from the list of live queries for the backend.
508 e_cal_backend_remove_query (ECalBackend *backend, EDataCalView *query)
510 g_return_if_fail (backend != NULL);
511 g_return_if_fail (E_IS_CAL_BACKEND (backend));
513 g_mutex_lock (backend->priv->queries_mutex);
515 e_list_remove (backend->priv->queries, query);
517 g_mutex_unlock (backend->priv->queries_mutex);
521 * e_cal_backend_get_cal_address:
522 * @backend: A calendar backend.
524 * Queries the cal address associated with a calendar backend, which
525 * must already have an open calendar.
528 e_cal_backend_get_cal_address (ECalBackend *backend, EDataCal *cal)
530 g_return_if_fail (backend != NULL);
531 g_return_if_fail (E_IS_CAL_BACKEND (backend));
533 g_assert (CLASS (backend)->get_cal_address != NULL);
534 (* CLASS (backend)->get_cal_address) (backend, cal);
538 e_cal_backend_notify_readonly (ECalBackend *backend, gboolean read_only)
540 ECalBackendPrivate *priv;
543 priv = backend->priv;
545 if (priv->notification_proxy) {
546 e_cal_backend_notify_readonly (priv->notification_proxy, read_only);
549 for (l = priv->clients; l; l = l->next)
550 e_data_cal_notify_read_only (l->data, GNOME_Evolution_Calendar_Success, read_only);
554 e_cal_backend_notify_cal_address (ECalBackend *backend, char *address)
556 ECalBackendPrivate *priv;
559 priv = backend->priv;
561 for (l = priv->clients; l; l = l->next)
562 e_data_cal_notify_cal_address (l->data, GNOME_Evolution_Calendar_Success, address);
566 * e_cal_backend_get_alarm_email_address:
567 * @backend: An #ECalBackend object.
568 * @cal: An #EDataCal object.
570 * Calls the get_alarm_email_address method on the given backend.
573 e_cal_backend_get_alarm_email_address (ECalBackend *backend, EDataCal *cal)
575 g_return_if_fail (backend != NULL);
576 g_return_if_fail (E_IS_CAL_BACKEND (backend));
578 g_assert (CLASS (backend)->get_alarm_email_address != NULL);
579 (* CLASS (backend)->get_alarm_email_address) (backend, cal);
583 *e_cal_backend_get_alarm_email_address:
584 * @backend: An #ECalBackend object.
585 * @cal: An #EDataCal object.
587 * Calls the get_ldap_attribute method of the given backend.
590 e_cal_backend_get_ldap_attribute (ECalBackend *backend, EDataCal *cal)
592 g_return_if_fail (backend != NULL);
593 g_return_if_fail (E_IS_CAL_BACKEND (backend));
595 g_assert (CLASS (backend)->get_ldap_attribute != NULL);
596 (* CLASS (backend)->get_ldap_attribute) (backend, cal);
600 * e_cal_backend_get_alarm_email_address:
601 * @backend: An #ECalBackend object.
602 * @cal: An #EDataCal object.
604 * Calls the get_static_capabilities method on the given backend.
607 e_cal_backend_get_static_capabilities (ECalBackend *backend, EDataCal *cal)
609 g_return_if_fail (backend != NULL);
610 g_return_if_fail (E_IS_CAL_BACKEND (backend));
612 g_assert (CLASS (backend)->get_static_capabilities != NULL);
613 (* CLASS (backend)->get_static_capabilities) (backend, cal);
617 * e_cal_backend_open:
618 * @backend: A calendar backend.
619 * @cal: An #EDataCal object.
620 * @only_if_exists: Whether the calendar should be opened only if it already
621 * exists. If FALSE, a new calendar will be created when the specified @uri
623 * @username: User name to use for authentication (if needed).
624 * @password: Password for @username.
626 * Opens a calendar backend with data from a calendar stored at the specified
630 e_cal_backend_open (ECalBackend *backend, EDataCal *cal, gboolean only_if_exists,
631 const char *username, const char *password)
633 g_return_if_fail (backend != NULL);
634 g_return_if_fail (E_IS_CAL_BACKEND (backend));
636 g_assert (CLASS (backend)->open != NULL);
637 (* CLASS (backend)->open) (backend, cal, only_if_exists, username, password);
641 * e_cal_backend_remove:
642 * @backend: A calendar backend.
643 * @cal: An #EDataCal object.
645 * Removes the calendar being accessed by the given backend.
648 e_cal_backend_remove (ECalBackend *backend, EDataCal *cal)
650 g_return_if_fail (backend != NULL);
651 g_return_if_fail (E_IS_CAL_BACKEND (backend));
653 g_assert (CLASS (backend)->remove != NULL);
654 (* CLASS (backend)->remove) (backend, cal);
658 * e_cal_backend_is_loaded:
659 * @backend: A calendar backend.
661 * Queries whether a calendar backend has been loaded yet.
663 * Return value: TRUE if the backend has been loaded with data, FALSE
667 e_cal_backend_is_loaded (ECalBackend *backend)
671 g_return_val_if_fail (backend != NULL, FALSE);
672 g_return_val_if_fail (E_IS_CAL_BACKEND (backend), FALSE);
674 g_assert (CLASS (backend)->is_loaded != NULL);
675 result = (* CLASS (backend)->is_loaded) (backend);
681 * e_cal_backend_is_read_only
682 * @backend: A calendar backend.
683 * @cal: An #EDataCal object.
685 * Queries whether a calendar backend is read only or not.
689 e_cal_backend_is_read_only (ECalBackend *backend, EDataCal *cal)
691 g_return_if_fail (backend != NULL);
692 g_return_if_fail (E_IS_CAL_BACKEND (backend));
694 g_assert (CLASS (backend)->is_read_only != NULL);
695 (* CLASS (backend)->is_read_only) (backend, cal);
699 * e_cal_backend_start_query:
700 * @backend: A calendar backend.
701 * @query: The query to be started.
703 * Starts a new live query on the given backend.
706 e_cal_backend_start_query (ECalBackend *backend, EDataCalView *query)
708 g_return_if_fail (backend != NULL);
709 g_return_if_fail (E_IS_CAL_BACKEND (backend));
711 g_assert (CLASS (backend)->start_query != NULL);
712 (* CLASS (backend)->start_query) (backend, query);
716 * e_cal_backend_get_mode:
717 * @backend: A calendar backend.
719 * Queries whether a calendar backend is connected remotely.
721 * Return value: The current mode the calendar is in
724 e_cal_backend_get_mode (ECalBackend *backend)
728 g_return_val_if_fail (backend != NULL, FALSE);
729 g_return_val_if_fail (E_IS_CAL_BACKEND (backend), FALSE);
731 g_assert (CLASS (backend)->get_mode != NULL);
732 result = (* CLASS (backend)->get_mode) (backend);
739 * e_cal_backend_set_mode:
740 * @backend: A calendar backend
741 * @mode: Mode to change to
743 * Sets the mode of the calendar
746 e_cal_backend_set_mode (ECalBackend *backend, CalMode mode)
748 g_return_if_fail (backend != NULL);
749 g_return_if_fail (E_IS_CAL_BACKEND (backend));
751 g_assert (CLASS (backend)->set_mode != NULL);
752 (* CLASS (backend)->set_mode) (backend, mode);
756 * e_cal_backend_get_default_object:
757 * @backend: A calendar backend.
758 * @cal: An #EDataCal object.
760 * Calls the get_default_object method on the given backend.
763 e_cal_backend_get_default_object (ECalBackend *backend, EDataCal *cal)
765 g_return_if_fail (backend != NULL);
766 g_return_if_fail (E_IS_CAL_BACKEND (backend));
768 g_assert (CLASS (backend)->get_default_object != NULL);
769 (* CLASS (backend)->get_default_object) (backend, cal);
773 * e_cal_backend_get_object:
774 * @backend: A calendar backend.
775 * @cal: An #EDataCal object.
776 * @uid: Unique identifier for a calendar object.
777 * @rid: ID for the object's recurrence to get.
779 * Queries a calendar backend for a calendar object based on its unique
780 * identifier and its recurrence ID (if a recurrent appointment).
783 e_cal_backend_get_object (ECalBackend *backend, EDataCal *cal, const char *uid, const char *rid)
785 g_return_if_fail (backend != NULL);
786 g_return_if_fail (E_IS_CAL_BACKEND (backend));
787 g_return_if_fail (uid != NULL);
789 g_assert (CLASS (backend)->get_object != NULL);
790 (* CLASS (backend)->get_object) (backend, cal, uid, rid);
794 * e_cal_backend_get_object_list:
795 * @backend: A calendar backend.
796 * @cal: An #EDataCal object.
797 * @sexp: Expression to search for.
799 * Calls the get_object_list method on the given backend.
802 e_cal_backend_get_object_list (ECalBackend *backend, EDataCal *cal, const char *sexp)
804 g_return_if_fail (backend != NULL);
805 g_return_if_fail (E_IS_CAL_BACKEND (backend));
807 g_assert (CLASS (backend)->get_object_list != NULL);
808 (* CLASS (backend)->get_object_list) (backend, cal, sexp);
812 * e_cal_backend_get_attachment_list:
813 * @backend: A calendar backend.
814 * @cal: An #EDataCal object.
815 * @uid: Unique identifier for a calendar object.
816 * @rid: ID for the object's recurrence to get.
818 * Queries a calendar backend for attachments present in a calendar object based
819 * on its unique identifier and its recurrence ID (if a recurrent appointment).
822 e_cal_backend_get_attachment_list (ECalBackend *backend, EDataCal *cal, const char *uid, const char *rid)
824 g_return_if_fail (backend != NULL);
825 g_return_if_fail (E_IS_CAL_BACKEND (backend));
826 g_return_if_fail (uid != NULL);
828 g_assert (CLASS (backend)->get_object != NULL);
829 (* CLASS (backend)->get_attachment_list) (backend, cal, uid, rid);
833 * e_cal_backend_get_free_busy:
834 * @backend: A calendar backend.
835 * @cal: An #EDataCal object.
836 * @users: List of users to get free/busy information for.
837 * @start: Start time for query.
838 * @end: End time for query.
840 * Gets a free/busy object for the given time interval
843 e_cal_backend_get_free_busy (ECalBackend *backend, EDataCal *cal, GList *users, time_t start, time_t end)
845 g_return_if_fail (backend != NULL);
846 g_return_if_fail (E_IS_CAL_BACKEND (backend));
847 g_return_if_fail (start != -1 && end != -1);
848 g_return_if_fail (start <= end);
850 g_assert (CLASS (backend)->get_free_busy != NULL);
851 (* CLASS (backend)->get_free_busy) (backend, cal, users, start, end);
855 * e_cal_backend_get_changes:
856 * @backend: A calendar backend.
857 * @cal: An #EDataCal object.
858 * @change_id: A unique uid for the callers change list
860 * Builds a sequence of objects and the type of change that occurred on them since
861 * the last time the give change_id was seen
864 e_cal_backend_get_changes (ECalBackend *backend, EDataCal *cal, const char *change_id)
866 g_return_if_fail (backend != NULL);
867 g_return_if_fail (E_IS_CAL_BACKEND (backend));
868 g_return_if_fail (change_id != NULL);
870 g_assert (CLASS (backend)->get_changes != NULL);
871 (* CLASS (backend)->get_changes) (backend, cal, change_id);
875 * e_cal_backend_discard_alarm
876 * @backend: A calendar backend.
877 * @cal: An #EDataCal object.
878 * @uid: UID of the component to discard the alarm from.
881 * Discards an alarm from the given component. This allows the specific backend
882 * to do whatever is needed to really discard the alarm.
885 e_cal_backend_discard_alarm (ECalBackend *backend, EDataCal *cal, const char *uid, const char *auid)
887 g_return_if_fail (backend != NULL);
888 g_return_if_fail (E_IS_CAL_BACKEND (backend));
889 g_return_if_fail (uid != NULL);
890 g_return_if_fail (auid != NULL);
892 g_assert (CLASS (backend)->discard_alarm != NULL);
893 (* CLASS (backend)->discard_alarm) (backend, cal, uid, auid);
897 * e_cal_backend_create_object:
898 * @backend: A calendar backend.
899 * @cal: An #EDataCal object.
900 * @calobj: The object to create.
902 * Calls the create_object method on the given backend.
905 e_cal_backend_create_object (ECalBackend *backend, EDataCal *cal, const char *calobj)
907 g_return_if_fail (backend != NULL);
908 g_return_if_fail (E_IS_CAL_BACKEND (backend));
909 g_return_if_fail (calobj != NULL);
911 if (CLASS (backend)->create_object)
912 (* CLASS (backend)->create_object) (backend, cal, calobj);
914 e_data_cal_notify_object_created (cal, GNOME_Evolution_Calendar_PermissionDenied, NULL, NULL);
918 * e_cal_backend_modify_object:
919 * @backend: A calendar backend.
920 * @cal: An #EDataCal object.
921 * @calobj: Object to be modified.
922 * @mod: Type of modification.
924 * Calls the modify_object method on the given backend.
927 e_cal_backend_modify_object (ECalBackend *backend, EDataCal *cal, const char *calobj, CalObjModType mod)
929 g_return_if_fail (backend != NULL);
930 g_return_if_fail (E_IS_CAL_BACKEND (backend));
931 g_return_if_fail (calobj != NULL);
933 if (CLASS (backend)->modify_object)
934 (* CLASS (backend)->modify_object) (backend, cal, calobj, mod);
936 e_data_cal_notify_object_removed (cal, GNOME_Evolution_Calendar_PermissionDenied, NULL, NULL, NULL);
940 * e_cal_backend_remove_object:
941 * @backend: A calendar backend.
942 * @cal: An #EDataCal object.
943 * @uid: Unique identifier of the object to remove.
944 * @rid: A recurrence ID.
945 * @mod: Type of removal.
947 * Removes an object in a calendar backend. The backend will notify all of its
948 * clients about the change.
951 e_cal_backend_remove_object (ECalBackend *backend, EDataCal *cal, const char *uid, const char *rid, CalObjModType mod)
953 g_return_if_fail (backend != NULL);
954 g_return_if_fail (E_IS_CAL_BACKEND (backend));
955 g_return_if_fail (uid != NULL);
957 g_assert (CLASS (backend)->remove_object != NULL);
958 (* CLASS (backend)->remove_object) (backend, cal, uid, rid, mod);
962 * e_cal_backend_receive_objects:
963 * @backend: A calendar backend.
964 * @cal: An #EDataCal object.
965 * @calobj: iCalendar object.
967 * Calls the receive_objects method on the given backend.
970 e_cal_backend_receive_objects (ECalBackend *backend, EDataCal *cal, const char *calobj)
972 g_return_if_fail (backend != NULL);
973 g_return_if_fail (E_IS_CAL_BACKEND (backend));
974 g_return_if_fail (calobj != NULL);
976 g_assert (CLASS (backend)->receive_objects != NULL);
977 (* CLASS (backend)->receive_objects) (backend, cal, calobj);
981 * e_cal_backend_send_objects:
982 * @backend: A calendar backend.
983 * @cal: An #EDataCal object.
984 * @calobj: iCalendar object to be sent.
986 * Calls the send_objects method on the given backend.
989 e_cal_backend_send_objects (ECalBackend *backend, EDataCal *cal, const char *calobj)
991 g_return_if_fail (backend != NULL);
992 g_return_if_fail (E_IS_CAL_BACKEND (backend));
993 g_return_if_fail (calobj != NULL);
995 g_assert (CLASS (backend)->send_objects != NULL);
996 (* CLASS (backend)->send_objects) (backend, cal, calobj);
1000 * e_cal_backend_get_timezone:
1001 * @backend: A calendar backend.
1002 * @cal: An #EDataCal object.
1003 * @tzid: Unique identifier of a VTIMEZONE object. Note that this must not be
1006 * Returns the icaltimezone* corresponding to the TZID, or NULL if the TZID
1010 e_cal_backend_get_timezone (ECalBackend *backend, EDataCal *cal, const char *tzid)
1012 g_return_if_fail (backend != NULL);
1013 g_return_if_fail (E_IS_CAL_BACKEND (backend));
1014 g_return_if_fail (tzid != NULL);
1016 g_assert (CLASS (backend)->get_timezone != NULL);
1017 (* CLASS (backend)->get_timezone) (backend, cal, tzid);
1021 * e_cal_backend_set_default_zone:
1022 * @backend: A calendar backend.
1023 * @cal: An #EDataCal object.
1024 * @tzobj: The timezone object, in a string.
1026 * Sets the default timezone for the calendar, which is used to resolve
1027 * DATE and floating DATE-TIME values.
1030 e_cal_backend_set_default_zone (ECalBackend *backend, EDataCal *cal, const char *tzobj)
1032 g_return_if_fail (backend != NULL);
1033 g_return_if_fail (E_IS_CAL_BACKEND (backend));
1034 g_return_if_fail (tzobj != NULL);
1036 (* CLASS (backend)->set_default_zone) (backend, cal, tzobj);
1040 * @deprecated This virual function should not be used in the backends, use
1041 * e_cal_backend_set_zone instead. This function restricts the default timezone
1042 * to be libical builtin timezone.
1044 * e_cal_backend_set_default_timezone:
1045 * @backend: A calendar backend.
1046 * @cal: An #EDataCal object.
1047 * @tzid: The TZID identifying the timezone.
1049 * Sets the default timezone for the calendar, which is used to resolve
1050 * DATE and floating DATE-TIME values.
1054 e_cal_backend_set_default_timezone (ECalBackend *backend, EDataCal *cal, const char *tzid)
1056 g_return_if_fail (backend != NULL);
1057 g_return_if_fail (E_IS_CAL_BACKEND (backend));
1058 g_return_if_fail (tzid != NULL);
1060 (* CLASS (backend)->set_default_timezone) (backend, cal, tzid);
1064 * e_cal_backend_add_timezone
1065 * @backend: A calendar backend.
1066 * @cal: An #EDataCal object.
1067 * @tzobj: The timezone object, in a string.
1069 * Add a timezone object to the given backend.
1072 e_cal_backend_add_timezone (ECalBackend *backend, EDataCal *cal, const char *tzobj)
1074 g_return_if_fail (E_IS_CAL_BACKEND (backend));
1075 g_return_if_fail (tzobj != NULL);
1076 g_return_if_fail (CLASS (backend)->add_timezone != NULL);
1078 (* CLASS (backend)->add_timezone) (backend, cal, tzobj);
1082 * e_cal_backend_internal_get_default_timezone:
1083 * @backend: A calendar backend.
1085 * Calls the internal_get_default_timezone method on the given backend.
1088 e_cal_backend_internal_get_default_timezone (ECalBackend *backend)
1090 g_return_val_if_fail (E_IS_CAL_BACKEND (backend), NULL);
1091 g_return_val_if_fail (CLASS (backend)->internal_get_default_timezone != NULL, NULL);
1093 return (* CLASS (backend)->internal_get_default_timezone) (backend);
1097 * e_cal_backend_internal_get_timezone:
1098 * @backend: A calendar backend.
1099 * @tzid: ID of the timezone to get.
1101 * Calls the internal_get_timezone method on the given backend.
1104 e_cal_backend_internal_get_timezone (ECalBackend *backend, const char *tzid)
1106 g_return_val_if_fail (E_IS_CAL_BACKEND (backend), NULL);
1107 g_return_val_if_fail (tzid != NULL, NULL);
1108 g_return_val_if_fail (CLASS (backend)->internal_get_timezone != NULL, NULL);
1110 return (* CLASS (backend)->internal_get_timezone) (backend, tzid);
1114 * e_cal_backend_set_notification_proxy:
1115 * @backend: A calendar backend.
1116 * @proxy: The calendar backend to act as notification proxy.
1118 * Sets the backend that will act as notification proxy for the given backend.
1121 e_cal_backend_set_notification_proxy (ECalBackend *backend, ECalBackend *proxy)
1123 ECalBackendPrivate *priv;
1125 g_return_if_fail (E_IS_CAL_BACKEND (backend));
1127 priv = backend->priv;
1129 priv->notification_proxy = proxy;
1133 * e_cal_backend_notify_object_created:
1134 * @backend: A calendar backend.
1135 * @calobj: iCalendar representation of new object
1137 * Notifies each of the backend's listeners about a new object.
1139 * #e_data_cal_notify_object_created() calls this for you. You only need to
1140 * call e_cal_backend_notify_object_created() yourself to report objects
1141 * created by non-EDS clients.
1144 e_cal_backend_notify_object_created (ECalBackend *backend, const char *calobj)
1146 ECalBackendPrivate *priv;
1149 EDataCalView *query;
1151 priv = backend->priv;
1153 if (priv->notification_proxy) {
1154 e_cal_backend_notify_object_created (priv->notification_proxy, calobj);
1158 queries = e_cal_backend_get_queries (backend);
1159 iter = e_list_get_iterator (queries);
1161 while (e_iterator_is_valid (iter)) {
1162 query = QUERY (e_iterator_get (iter));
1164 bonobo_object_ref (query);
1165 if (e_data_cal_view_object_matches (query, calobj))
1166 e_data_cal_view_notify_objects_added_1 (query, calobj);
1167 bonobo_object_unref (query);
1169 e_iterator_next (iter);
1171 g_object_unref (iter);
1175 match_query_and_notify (EDataCalView *query, const char *old_object, const char *object)
1177 gboolean old_match = FALSE, new_match = FALSE;
1180 old_match = e_data_cal_view_object_matches (query, old_object);
1182 new_match = e_data_cal_view_object_matches (query, object);
1183 if (old_match && new_match)
1184 e_data_cal_view_notify_objects_modified_1 (query, object);
1186 e_data_cal_view_notify_objects_added_1 (query, object);
1187 else if (old_match) {
1188 ECalComponent *comp = NULL;
1190 comp = e_cal_component_new_from_string (old_object);
1192 ECalComponentId *id = e_cal_component_get_id (comp);
1194 e_data_cal_view_notify_objects_removed_1 (query, id);
1196 e_cal_component_free_id (id);
1197 g_object_unref (comp);
1203 * e_cal_backend_notify_view_progress:
1204 * @backend: A calendar backend.
1205 * @message: the UID of the removed object
1206 * @percent: percentage of the objects loaded in the view
1208 * Notifies each of the backend's listeners about the view_progress in downloading the items.
1211 e_cal_backend_notify_view_progress (ECalBackend *backend, const char *message, int percent)
1213 ECalBackendPrivate *priv;
1216 EDataCalView *query;
1218 priv = backend->priv;
1220 if (priv->notification_proxy) {
1221 e_cal_backend_notify_view_progress (priv->notification_proxy, message, percent);
1225 queries = e_cal_backend_get_queries (backend);
1226 iter = e_list_get_iterator (queries);
1228 while (e_iterator_is_valid (iter)) {
1229 query = QUERY (e_iterator_get (iter));
1231 bonobo_object_ref (query);
1233 e_data_cal_view_notify_progress (query, message, percent);
1235 bonobo_object_unref (query);
1237 e_iterator_next (iter);
1239 g_object_unref (iter);
1243 * e_cal_backend_notify_view_done:
1244 * @backend: A calendar backend.
1245 * @status: returns the status once the view is fully populated.
1247 * Notifies each of the backend's listeners about the view_done in downloading the items.
1250 e_cal_backend_notify_view_done (ECalBackend *backend, GNOME_Evolution_Calendar_CallStatus status)
1252 ECalBackendPrivate *priv;
1255 EDataCalView *query;
1257 priv = backend->priv;
1259 if (priv->notification_proxy) {
1260 e_cal_backend_notify_view_done (priv->notification_proxy, status);
1264 queries = e_cal_backend_get_queries (backend);
1265 iter = e_list_get_iterator (queries);
1267 while (e_iterator_is_valid (iter)) {
1268 query = QUERY (e_iterator_get (iter));
1270 bonobo_object_ref (query);
1272 e_data_cal_view_notify_done (query, status);
1274 bonobo_object_unref (query);
1276 e_iterator_next (iter);
1278 g_object_unref (iter);
1282 * e_cal_backend_notify_object_modified:
1283 * @backend: A calendar backend.
1284 * @old_object: iCalendar representation of the original form of the object
1285 * @object: iCalendar representation of the new form of the object
1287 * Notifies each of the backend's listeners about a modified object.
1289 * #e_data_cal_notify_object_modified() calls this for you. You only need to
1290 * call e_cal_backend_notify_object_modified() yourself to report objects
1291 * modified by non-EDS clients.
1294 e_cal_backend_notify_object_modified (ECalBackend *backend,
1295 const char *old_object, const char *object)
1297 ECalBackendPrivate *priv;
1300 EDataCalView *query;
1302 priv = backend->priv;
1304 if (priv->notification_proxy) {
1305 e_cal_backend_notify_object_modified (priv->notification_proxy, old_object, object);
1309 queries = e_cal_backend_get_queries (backend);
1310 iter = e_list_get_iterator (queries);
1312 while (e_iterator_is_valid (iter)) {
1313 query = QUERY (e_iterator_get (iter));
1315 bonobo_object_ref (query);
1316 match_query_and_notify (query, old_object, object);
1317 bonobo_object_unref (query);
1319 e_iterator_next (iter);
1321 g_object_unref (iter);
1325 * e_cal_backend_notify_object_removed:
1326 * @backend: A calendar backend.
1327 * @id: the Id of the removed object
1328 * @old_object: iCalendar representation of the removed object
1329 * @new_object: iCalendar representation of the object after the removal. This
1330 * only applies to recurrent appointments that had an instance removed. In that
1331 * case, this function notifies a modification instead of a removal.
1333 * Notifies each of the backend's listeners about a removed object.
1335 * e_data_cal_notify_object_removed() calls this for you. You only need to
1336 * call e_cal_backend_notify_object_removed() yourself to report objects
1337 * removed by non-EDS clients.
1340 e_cal_backend_notify_object_removed (ECalBackend *backend, const ECalComponentId *id,
1341 const char *old_object, const char *object)
1343 ECalBackendPrivate *priv;
1346 EDataCalView *query;
1348 priv = backend->priv;
1350 if (priv->notification_proxy) {
1351 e_cal_backend_notify_object_removed (priv->notification_proxy, id, old_object, object);
1355 queries = e_cal_backend_get_queries (backend);
1356 iter = e_list_get_iterator (queries);
1358 while (e_iterator_is_valid (iter)) {
1359 query = QUERY (e_iterator_get (iter));
1361 bonobo_object_ref (query);
1363 if (object == NULL) {
1364 /* if object == NULL, it means the object has been completely
1365 removed from the backend */
1366 if (e_data_cal_view_object_matches (query, old_object))
1367 e_data_cal_view_notify_objects_removed_1 (query, id);
1369 match_query_and_notify (query, old_object, object);
1371 bonobo_object_unref (query);
1373 e_iterator_next (iter);
1375 g_object_unref (iter);
1379 * e_cal_backend_notify_mode:
1380 * @backend: A calendar backend.
1381 * @status: Status of the mode set
1382 * @mode: the current mode
1384 * Notifies each of the backend's listeners about the results of a
1388 e_cal_backend_notify_mode (ECalBackend *backend,
1389 GNOME_Evolution_Calendar_CalListener_SetModeStatus status,
1390 GNOME_Evolution_Calendar_CalMode mode)
1392 ECalBackendPrivate *priv = backend->priv;
1395 if (priv->notification_proxy) {
1396 e_cal_backend_notify_mode (priv->notification_proxy, status, mode);
1400 for (l = priv->clients; l; l = l->next)
1401 e_data_cal_notify_mode (l->data, status, mode);
1405 * e_cal_backend_notify_auth_required:
1406 * @backend: A calendar backend.
1408 * Notifies each of the backend's listeners that authentication is required to
1409 * open the calendar.
1412 e_cal_backend_notify_auth_required (ECalBackend *backend)
1414 ECalBackendPrivate *priv = backend->priv;
1417 for (l = priv->clients; l; l = l->next)
1418 e_data_cal_notify_auth_required (l->data);
1422 * e_cal_backend_notify_error:
1423 * @backend: A calendar backend.
1424 * @message: Error message
1426 * Notifies each of the backend's listeners about an error
1429 e_cal_backend_notify_error (ECalBackend *backend, const char *message)
1431 ECalBackendPrivate *priv = backend->priv;
1434 if (priv->notification_proxy) {
1435 e_cal_backend_notify_error (priv->notification_proxy, message);
1439 for (l = priv->clients; l; l = l->next)
1440 e_data_cal_notify_error (l->data, message);