1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /* Evolution calendar - generic backend class
4 * Copyright (C) 2000 Ximian, Inc.
5 * Copyright (C) 2000 Ximian, Inc.
7 * Authors: Federico Mena-Quintero <federico@ximian.com>
8 * JP Rosevear <jpr@ximian.com>
9 * Rodrigo Moya <rodrigo@ximian.com>
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of version 2 of the GNU Lesser General Public
13 * License as published by the Free Software Foundation.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License for more details.
20 * You should have received a copy of the GNU Lesser General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
26 #include <libxml/parser.h>
27 #include <libxml/parserInternals.h>
28 #include <libxml/xmlmemory.h>
30 #include "e-cal-backend.h"
34 /* Private part of the CalBackend structure */
35 struct _ECalBackendPrivate {
36 /* The source for this backend */
39 /* URI, from source. This is cached, since we return const. */
42 /* The kind of components for this backend */
43 icalcomponent_kind kind;
45 /* List of Cal objects */
46 GMutex *clients_mutex;
49 GMutex *queries_mutex;
52 /* ECalBackend to pass notifications on to */
53 ECalBackend *notification_proxy;
71 static guint e_cal_backend_signals[LAST_SIGNAL];
73 static void e_cal_backend_class_init (ECalBackendClass *class);
74 static void e_cal_backend_init (ECalBackend *backend);
75 static void e_cal_backend_finalize (GObject *object);
77 #define CLASS(backend) (E_CAL_BACKEND_CLASS (G_OBJECT_GET_CLASS (backend)))
79 static GObjectClass *parent_class;
84 * e_cal_backend_get_type:
86 * Registers the #ECalBackend class if necessary, and returns the type ID
89 * Return value: The type ID of the #ECalBackend class.
92 e_cal_backend_get_type (void)
94 static GType e_cal_backend_type = 0;
96 if (!e_cal_backend_type) {
97 static GTypeInfo info = {
98 sizeof (ECalBackendClass),
100 (GBaseFinalizeFunc) NULL,
101 (GClassInitFunc) e_cal_backend_class_init,
103 sizeof (ECalBackend),
105 (GInstanceInitFunc) e_cal_backend_init,
107 e_cal_backend_type = g_type_register_static (G_TYPE_OBJECT, "ECalBackend", &info, 0);
110 return e_cal_backend_type;
114 e_cal_backend_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
116 ECalBackend *backend;
117 ECalBackendPrivate *priv;
119 backend = E_CAL_BACKEND (object);
120 priv = backend->priv;
122 switch (property_id) {
127 new_source = g_value_get_object (value);
129 g_object_ref (new_source);
132 g_object_unref (priv->source);
134 priv->source = new_source;
139 priv->uri = e_source_get_uri (priv->source);
146 priv->uri = g_value_dup_string (value);
150 priv->kind = g_value_get_ulong (value);
153 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
159 e_cal_backend_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
161 ECalBackend *backend;
162 ECalBackendPrivate *priv;
164 backend = E_CAL_BACKEND (object);
165 priv = backend->priv;
167 switch (property_id) {
169 g_value_set_object (value, e_cal_backend_get_source (backend));
172 g_value_set_string (value, e_cal_backend_get_uri (backend));
175 g_value_set_ulong (value, e_cal_backend_get_kind (backend));
178 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
183 /* Class initialization function for the calendar backend */
185 e_cal_backend_class_init (ECalBackendClass *class)
187 GObjectClass *object_class;
189 parent_class = (GObjectClass *) g_type_class_peek_parent (class);
191 object_class = (GObjectClass *) class;
193 object_class->set_property = e_cal_backend_set_property;
194 object_class->get_property = e_cal_backend_get_property;
195 object_class->finalize = e_cal_backend_finalize;
197 g_object_class_install_property (object_class, PROP_SOURCE,
198 g_param_spec_object ("source", NULL, NULL, E_TYPE_SOURCE,
199 G_PARAM_READABLE | G_PARAM_WRITABLE
200 | G_PARAM_CONSTRUCT_ONLY));
202 g_object_class_install_property (object_class, PROP_URI,
203 g_param_spec_string ("uri", NULL, NULL, "",
204 G_PARAM_READABLE | G_PARAM_WRITABLE
205 | G_PARAM_CONSTRUCT_ONLY));
207 g_object_class_install_property (object_class, PROP_KIND,
208 g_param_spec_ulong ("kind", NULL, NULL,
209 ICAL_NO_COMPONENT, ICAL_XLICMIMEPART_COMPONENT,
211 G_PARAM_READABLE | G_PARAM_WRITABLE
212 | G_PARAM_CONSTRUCT_ONLY));
213 e_cal_backend_signals[LAST_CLIENT_GONE] =
214 g_signal_new ("last_client_gone",
215 G_TYPE_FROM_CLASS (class),
217 G_STRUCT_OFFSET (ECalBackendClass, last_client_gone),
219 g_cclosure_marshal_VOID__VOID,
221 e_cal_backend_signals[OPENED] =
222 g_signal_new ("opened",
223 G_TYPE_FROM_CLASS (class),
225 G_STRUCT_OFFSET (ECalBackendClass, opened),
227 g_cclosure_marshal_VOID__ENUM,
230 e_cal_backend_signals[REMOVED] =
231 g_signal_new ("removed",
232 G_TYPE_FROM_CLASS (class),
234 G_STRUCT_OFFSET (ECalBackendClass, removed),
236 g_cclosure_marshal_VOID__ENUM,
240 class->last_client_gone = NULL;
241 class->opened = NULL;
242 class->obj_updated = NULL;
244 class->get_cal_address = NULL;
245 class->get_alarm_email_address = NULL;
246 class->get_static_capabilities = NULL;
248 class->is_loaded = NULL;
249 class->is_read_only = NULL;
250 class->start_query = NULL;
251 class->get_mode = NULL;
252 class->set_mode = NULL;
253 class->get_object = NULL;
254 class->get_default_object = NULL;
255 class->get_object_list = NULL;
256 class->get_free_busy = NULL;
257 class->get_changes = NULL;
258 class->discard_alarm = NULL;
259 class->create_object = NULL;
260 class->modify_object = NULL;
261 class->remove_object = NULL;
262 class->receive_objects = NULL;
263 class->send_objects = NULL;
264 class->get_timezone = NULL;
265 class->add_timezone = NULL;
266 class->set_default_timezone = NULL;
269 /* Object initialization func for the calendar backend */
271 e_cal_backend_init (ECalBackend *backend)
273 ECalBackendPrivate *priv;
275 priv = g_new0 (ECalBackendPrivate, 1);
276 backend->priv = priv;
278 priv->clients = NULL;
279 priv->clients_mutex = g_mutex_new ();
281 /* FIXME bonobo_object_ref/unref? */
282 priv->queries = e_list_new((EListCopyFunc) g_object_ref, (EListFreeFunc) g_object_unref, NULL);
283 priv->queries_mutex = g_mutex_new ();
287 e_cal_backend_finalize (GObject *object)
289 ECalBackend *backend = (ECalBackend *)object;
290 ECalBackendPrivate *priv;
292 priv = backend->priv;
294 g_assert (priv->clients == NULL);
296 g_object_unref (priv->queries);
298 g_mutex_free (priv->clients_mutex);
299 g_mutex_free (priv->queries_mutex);
302 g_object_unref (priv->source);
305 G_OBJECT_CLASS (parent_class)->finalize (object);
311 * e_cal_backend_get_source:
312 * @backend: An #ECalBackend object.
314 * Gets the #ESource associated with the given backend.
316 * Return value: The #ESource for the backend.
319 e_cal_backend_get_source (ECalBackend *backend)
321 ECalBackendPrivate *priv;
323 g_return_val_if_fail (backend != NULL, NULL);
324 g_return_val_if_fail (E_IS_CAL_BACKEND (backend), NULL);
326 priv = backend->priv;
332 * e_cal_backend_get_uri:
333 * @backend: A calendar backend.
335 * Queries the URI of a calendar backend, which must already have an open
338 * Return value: The URI where the calendar is stored.
341 e_cal_backend_get_uri (ECalBackend *backend)
343 ECalBackendPrivate *priv;
345 g_return_val_if_fail (backend != NULL, NULL);
346 g_return_val_if_fail (E_IS_CAL_BACKEND (backend), NULL);
348 priv = backend->priv;
354 * e_cal_backend_get_kind:
355 * @backend: An #ECalBackend object.
357 * Gets the kind of components the given backend stores.
359 * Return value: The kind of components for this backend.
362 e_cal_backend_get_kind (ECalBackend *backend)
364 ECalBackendPrivate *priv;
366 g_return_val_if_fail (backend != NULL, ICAL_NO_COMPONENT);
367 g_return_val_if_fail (E_IS_CAL_BACKEND (backend), ICAL_NO_COMPONENT);
369 priv = backend->priv;
375 cal_destroy_cb (gpointer data, GObject *where_cal_was)
377 ECalBackend *backend = E_CAL_BACKEND (data);
379 e_cal_backend_remove_client (backend, (EDataCal *) where_cal_was);
383 listener_died_cb (gpointer cnx, gpointer data)
385 EDataCal *cal = E_DATA_CAL (data);
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;
502 * e_cal_backend_get_cal_address:
503 * @backend: A calendar backend.
505 * Queries the cal address associated with a calendar backend, which
506 * must already have an open calendar.
509 e_cal_backend_get_cal_address (ECalBackend *backend, EDataCal *cal)
511 g_return_if_fail (backend != NULL);
512 g_return_if_fail (E_IS_CAL_BACKEND (backend));
514 g_assert (CLASS (backend)->get_cal_address != NULL);
515 (* CLASS (backend)->get_cal_address) (backend, cal);
519 e_cal_backend_notify_readonly (ECalBackend *backend, gboolean read_only)
521 ECalBackendPrivate *priv;
524 priv = backend->priv;
526 if (priv->notification_proxy) {
527 e_cal_backend_notify_readonly (priv->notification_proxy, read_only);
530 for (l = priv->clients; l; l = l->next)
531 e_data_cal_notify_read_only (l->data, GNOME_Evolution_Calendar_Success, read_only);
535 e_cal_backend_notify_cal_address (ECalBackend *backend, char *address)
537 ECalBackendPrivate *priv;
540 priv = backend->priv;
542 for (l = priv->clients; l; l = l->next)
543 e_data_cal_notify_cal_address (l->data, GNOME_Evolution_Calendar_Success, address);
547 * e_cal_backend_get_alarm_email_address:
548 * @backend: An #ECalBackend object.
549 * @cal: An #EDataCal object.
551 * Calls the get_alarm_email_address method on the given backend.
554 e_cal_backend_get_alarm_email_address (ECalBackend *backend, EDataCal *cal)
556 g_return_if_fail (backend != NULL);
557 g_return_if_fail (E_IS_CAL_BACKEND (backend));
559 g_assert (CLASS (backend)->get_alarm_email_address != NULL);
560 (* CLASS (backend)->get_alarm_email_address) (backend, cal);
564 *e_cal_backend_get_alarm_email_address:
565 * @backend: An #ECalBackend object.
566 * @cal: An #EDataCal object.
568 * Calls the get_ldap_attribute method of the given backend.
571 e_cal_backend_get_ldap_attribute (ECalBackend *backend, EDataCal *cal)
573 g_return_if_fail (backend != NULL);
574 g_return_if_fail (E_IS_CAL_BACKEND (backend));
576 g_assert (CLASS (backend)->get_ldap_attribute != NULL);
577 (* CLASS (backend)->get_ldap_attribute) (backend, cal);
581 * e_cal_backend_get_alarm_email_address:
582 * @backend: An #ECalBackend object.
583 * @cal: An #EDataCal object.
585 * Calls the get_static_capabilities method on the given backend.
588 e_cal_backend_get_static_capabilities (ECalBackend *backend, EDataCal *cal)
590 g_return_if_fail (backend != NULL);
591 g_return_if_fail (E_IS_CAL_BACKEND (backend));
593 g_assert (CLASS (backend)->get_static_capabilities != NULL);
594 (* CLASS (backend)->get_static_capabilities) (backend, cal);
598 * e_cal_backend_open:
599 * @backend: A calendar backend.
600 * @cal: An #EDataCal object.
601 * @only_if_exists: Whether the calendar should be opened only if it already
602 * exists. If FALSE, a new calendar will be created when the specified @uri
604 * @username: User name to use for authentication (if needed).
605 * @password: Password for @username.
607 * Opens a calendar backend with data from a calendar stored at the specified
611 e_cal_backend_open (ECalBackend *backend, EDataCal *cal, gboolean only_if_exists,
612 const char *username, const char *password)
614 g_return_if_fail (backend != NULL);
615 g_return_if_fail (E_IS_CAL_BACKEND (backend));
617 g_assert (CLASS (backend)->open != NULL);
618 (* CLASS (backend)->open) (backend, cal, only_if_exists, username, password);
622 * e_cal_backend_remove:
623 * @backend: A calendar backend.
624 * @cal: An #EDataCal object.
626 * Removes the calendar being accessed by the given backend.
629 e_cal_backend_remove (ECalBackend *backend, EDataCal *cal)
631 g_return_if_fail (backend != NULL);
632 g_return_if_fail (E_IS_CAL_BACKEND (backend));
634 g_assert (CLASS (backend)->remove != NULL);
635 (* CLASS (backend)->remove) (backend, cal);
639 * e_cal_backend_is_loaded:
640 * @backend: A calendar backend.
642 * Queries whether a calendar backend has been loaded yet.
644 * Return value: TRUE if the backend has been loaded with data, FALSE
648 e_cal_backend_is_loaded (ECalBackend *backend)
652 g_return_val_if_fail (backend != NULL, FALSE);
653 g_return_val_if_fail (E_IS_CAL_BACKEND (backend), FALSE);
655 g_assert (CLASS (backend)->is_loaded != NULL);
656 result = (* CLASS (backend)->is_loaded) (backend);
662 * e_cal_backend_is_read_only
663 * @backend: A calendar backend.
664 * @cal: An #EDataCal object.
666 * Queries whether a calendar backend is read only or not.
670 e_cal_backend_is_read_only (ECalBackend *backend, EDataCal *cal)
672 g_return_if_fail (backend != NULL);
673 g_return_if_fail (E_IS_CAL_BACKEND (backend));
675 g_assert (CLASS (backend)->is_read_only != NULL);
676 (* CLASS (backend)->is_read_only) (backend, cal);
680 * e_cal_backend_start_query:
681 * @backend: A calendar backend.
682 * @query: The query to be started.
684 * Starts a new live query on the given backend.
687 e_cal_backend_start_query (ECalBackend *backend, EDataCalView *query)
689 g_return_if_fail (backend != NULL);
690 g_return_if_fail (E_IS_CAL_BACKEND (backend));
692 g_assert (CLASS (backend)->start_query != NULL);
693 (* CLASS (backend)->start_query) (backend, query);
697 * e_cal_backend_get_mode:
698 * @backend: A calendar backend.
700 * Queries whether a calendar backend is connected remotely.
702 * Return value: The current mode the calendar is in
705 e_cal_backend_get_mode (ECalBackend *backend)
709 g_return_val_if_fail (backend != NULL, FALSE);
710 g_return_val_if_fail (E_IS_CAL_BACKEND (backend), FALSE);
712 g_assert (CLASS (backend)->get_mode != NULL);
713 result = (* CLASS (backend)->get_mode) (backend);
720 * e_cal_backend_set_mode:
721 * @backend: A calendar backend
722 * @mode: Mode to change to
724 * Sets the mode of the calendar
727 e_cal_backend_set_mode (ECalBackend *backend, CalMode mode)
729 g_return_if_fail (backend != NULL);
730 g_return_if_fail (E_IS_CAL_BACKEND (backend));
732 g_assert (CLASS (backend)->set_mode != NULL);
733 (* CLASS (backend)->set_mode) (backend, mode);
737 * e_cal_backend_get_default_object:
738 * @backend: A calendar backend.
739 * @cal: An #EDataCal object.
741 * Calls the get_default_object method on the given backend.
744 e_cal_backend_get_default_object (ECalBackend *backend, EDataCal *cal)
746 g_return_if_fail (backend != NULL);
747 g_return_if_fail (E_IS_CAL_BACKEND (backend));
749 g_assert (CLASS (backend)->get_default_object != NULL);
750 (* CLASS (backend)->get_default_object) (backend, cal);
754 * e_cal_backend_get_object:
755 * @backend: A calendar backend.
756 * @cal: An #EDataCal object.
757 * @uid: Unique identifier for a calendar object.
758 * @rid: ID for the object's recurrence to get.
760 * Queries a calendar backend for a calendar object based on its unique
761 * identifier and its recurrence ID (if a recurrent appointment).
764 e_cal_backend_get_object (ECalBackend *backend, EDataCal *cal, const char *uid, const char *rid)
766 g_return_if_fail (backend != NULL);
767 g_return_if_fail (E_IS_CAL_BACKEND (backend));
768 g_return_if_fail (uid != NULL);
770 g_assert (CLASS (backend)->get_object != NULL);
771 (* CLASS (backend)->get_object) (backend, cal, uid, rid);
775 * e_cal_backend_get_object_list:
776 * @backend: A calendar backend.
777 * @cal: An #EDataCal object.
778 * @sexp: Expression to search for.
780 * Calls the get_object_list method on the given backend.
783 e_cal_backend_get_object_list (ECalBackend *backend, EDataCal *cal, const char *sexp)
785 g_return_if_fail (backend != NULL);
786 g_return_if_fail (E_IS_CAL_BACKEND (backend));
788 g_assert (CLASS (backend)->get_object_list != NULL);
789 (* CLASS (backend)->get_object_list) (backend, cal, sexp);
793 * e_cal_backend_get_attachment_list:
794 * @backend: A calendar backend.
795 * @cal: An #EDataCal object.
796 * @uid: Unique identifier for a calendar object.
797 * @rid: ID for the object's recurrence to get.
799 * Queries a calendar backend for attachments present in a calendar object based
800 * on its unique identifier and its recurrence ID (if a recurrent appointment).
803 e_cal_backend_get_attachment_list (ECalBackend *backend, EDataCal *cal, const char *uid, const char *rid)
805 g_return_if_fail (backend != NULL);
806 g_return_if_fail (E_IS_CAL_BACKEND (backend));
807 g_return_if_fail (uid != NULL);
809 g_assert (CLASS (backend)->get_object != NULL);
810 (* CLASS (backend)->get_attachment_list) (backend, cal, uid, rid);
814 * e_cal_backend_get_free_busy:
815 * @backend: A calendar backend.
816 * @cal: An #EDataCal object.
817 * @users: List of users to get free/busy information for.
818 * @start: Start time for query.
819 * @end: End time for query.
821 * Gets a free/busy object for the given time interval
824 e_cal_backend_get_free_busy (ECalBackend *backend, EDataCal *cal, GList *users, time_t start, time_t end)
826 g_return_if_fail (backend != NULL);
827 g_return_if_fail (E_IS_CAL_BACKEND (backend));
828 g_return_if_fail (start != -1 && end != -1);
829 g_return_if_fail (start <= end);
831 g_assert (CLASS (backend)->get_free_busy != NULL);
832 (* CLASS (backend)->get_free_busy) (backend, cal, users, start, end);
836 * e_cal_backend_get_changes:
837 * @backend: A calendar backend.
838 * @cal: An #EDataCal object.
839 * @change_id: A unique uid for the callers change list
841 * Builds a sequence of objects and the type of change that occurred on them since
842 * the last time the give change_id was seen
845 e_cal_backend_get_changes (ECalBackend *backend, EDataCal *cal, const char *change_id)
847 g_return_if_fail (backend != NULL);
848 g_return_if_fail (E_IS_CAL_BACKEND (backend));
849 g_return_if_fail (change_id != NULL);
851 g_assert (CLASS (backend)->get_changes != NULL);
852 (* CLASS (backend)->get_changes) (backend, cal, change_id);
856 * e_cal_backend_discard_alarm
857 * @backend: A calendar backend.
858 * @cal: An #EDataCal object.
859 * @uid: UID of the component to discard the alarm from.
862 * Discards an alarm from the given component. This allows the specific backend
863 * to do whatever is needed to really discard the alarm.
866 e_cal_backend_discard_alarm (ECalBackend *backend, EDataCal *cal, const char *uid, const char *auid)
868 g_return_if_fail (backend != NULL);
869 g_return_if_fail (E_IS_CAL_BACKEND (backend));
870 g_return_if_fail (uid != NULL);
871 g_return_if_fail (auid != NULL);
873 g_assert (CLASS (backend)->discard_alarm != NULL);
874 (* CLASS (backend)->discard_alarm) (backend, cal, uid, auid);
878 * e_cal_backend_create_object:
879 * @backend: A calendar backend.
880 * @cal: An #EDataCal object.
881 * @calobj: The object to create.
883 * Calls the create_object method on the given backend.
886 e_cal_backend_create_object (ECalBackend *backend, EDataCal *cal, const char *calobj)
888 g_return_if_fail (backend != NULL);
889 g_return_if_fail (E_IS_CAL_BACKEND (backend));
890 g_return_if_fail (calobj != NULL);
892 if (CLASS (backend)->create_object)
893 (* CLASS (backend)->create_object) (backend, cal, calobj);
895 e_data_cal_notify_object_created (cal, GNOME_Evolution_Calendar_PermissionDenied, NULL, NULL);
899 * e_cal_backend_modify_object:
900 * @backend: A calendar backend.
901 * @cal: An #EDataCal object.
902 * @calobj: Object to be modified.
903 * @mod: Type of modification.
905 * Calls the modify_object method on the given backend.
908 e_cal_backend_modify_object (ECalBackend *backend, EDataCal *cal, const char *calobj, CalObjModType mod)
910 g_return_if_fail (backend != NULL);
911 g_return_if_fail (E_IS_CAL_BACKEND (backend));
912 g_return_if_fail (calobj != NULL);
914 if (CLASS (backend)->modify_object)
915 (* CLASS (backend)->modify_object) (backend, cal, calobj, mod);
917 e_data_cal_notify_object_removed (cal, GNOME_Evolution_Calendar_PermissionDenied, NULL, NULL, NULL);
921 * e_cal_backend_remove_object:
922 * @backend: A calendar backend.
923 * @cal: An #EDataCal object.
924 * @uid: Unique identifier of the object to remove.
925 * @rid: A recurrence ID.
926 * @mod: Type of removal.
928 * Removes an object in a calendar backend. The backend will notify all of its
929 * clients about the change.
932 e_cal_backend_remove_object (ECalBackend *backend, EDataCal *cal, const char *uid, const char *rid, CalObjModType mod)
934 g_return_if_fail (backend != NULL);
935 g_return_if_fail (E_IS_CAL_BACKEND (backend));
936 g_return_if_fail (uid != NULL);
938 g_assert (CLASS (backend)->remove_object != NULL);
939 (* CLASS (backend)->remove_object) (backend, cal, uid, rid, mod);
943 * e_cal_backend_receive_objects:
944 * @backend: A calendar backend.
945 * @cal: An #EDataCal object.
946 * @calobj: iCalendar object.
948 * Calls the receive_objects method on the given backend.
951 e_cal_backend_receive_objects (ECalBackend *backend, EDataCal *cal, const char *calobj)
953 g_return_if_fail (backend != NULL);
954 g_return_if_fail (E_IS_CAL_BACKEND (backend));
955 g_return_if_fail (calobj != NULL);
957 g_assert (CLASS (backend)->receive_objects != NULL);
958 (* CLASS (backend)->receive_objects) (backend, cal, calobj);
962 * e_cal_backend_send_objects:
963 * @backend: A calendar backend.
964 * @cal: An #EDataCal object.
965 * @calobj: iCalendar object to be sent.
967 * Calls the send_objects method on the given backend.
970 e_cal_backend_send_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)->send_objects != NULL);
977 (* CLASS (backend)->send_objects) (backend, cal, calobj);
981 * e_cal_backend_get_timezone:
982 * @backend: A calendar backend.
983 * @cal: An #EDataCal object.
984 * @tzid: Unique identifier of a VTIMEZONE object. Note that this must not be
987 * Returns the icaltimezone* corresponding to the TZID, or NULL if the TZID
991 e_cal_backend_get_timezone (ECalBackend *backend, EDataCal *cal, const char *tzid)
993 g_return_if_fail (backend != NULL);
994 g_return_if_fail (E_IS_CAL_BACKEND (backend));
995 g_return_if_fail (tzid != NULL);
997 g_assert (CLASS (backend)->get_timezone != NULL);
998 (* CLASS (backend)->get_timezone) (backend, cal, tzid);
1002 * e_cal_backend_set_default_zone:
1003 * @backend: A calendar backend.
1004 * @cal: An #EDataCal object.
1005 * @tzobj: The timezone object, in a string.
1007 * Sets the default timezone for the calendar, which is used to resolve
1008 * DATE and floating DATE-TIME values.
1011 e_cal_backend_set_default_zone (ECalBackend *backend, EDataCal *cal, const char *tzobj)
1013 g_return_if_fail (backend != NULL);
1014 g_return_if_fail (E_IS_CAL_BACKEND (backend));
1015 g_return_if_fail (tzobj != NULL);
1017 (* CLASS (backend)->set_default_zone) (backend, cal, tzobj);
1021 * @deprecated This virual function should not be used in the backends, use
1022 * e_cal_backend_set_zone instead. This function restricts the default timezone
1023 * to be libical builtin timezone.
1025 * e_cal_backend_set_default_timezone:
1026 * @backend: A calendar backend.
1027 * @cal: An #EDataCal object.
1028 * @tzid: The TZID identifying the timezone.
1030 * Sets the default timezone for the calendar, which is used to resolve
1031 * DATE and floating DATE-TIME values.
1035 e_cal_backend_set_default_timezone (ECalBackend *backend, EDataCal *cal, const char *tzid)
1037 g_return_if_fail (backend != NULL);
1038 g_return_if_fail (E_IS_CAL_BACKEND (backend));
1039 g_return_if_fail (tzid != NULL);
1041 (* CLASS (backend)->set_default_timezone) (backend, cal, tzid);
1045 * e_cal_backend_add_timezone
1046 * @backend: A calendar backend.
1047 * @cal: An #EDataCal object.
1048 * @tzobj: The timezone object, in a string.
1050 * Add a timezone object to the given backend.
1053 e_cal_backend_add_timezone (ECalBackend *backend, EDataCal *cal, const char *tzobj)
1055 g_return_if_fail (E_IS_CAL_BACKEND (backend));
1056 g_return_if_fail (tzobj != NULL);
1057 g_return_if_fail (CLASS (backend)->add_timezone != NULL);
1059 (* CLASS (backend)->add_timezone) (backend, cal, tzobj);
1063 * e_cal_backend_internal_get_default_timezone:
1064 * @backend: A calendar backend.
1066 * Calls the internal_get_default_timezone method on the given backend.
1069 e_cal_backend_internal_get_default_timezone (ECalBackend *backend)
1071 g_return_val_if_fail (E_IS_CAL_BACKEND (backend), NULL);
1072 g_return_val_if_fail (CLASS (backend)->internal_get_default_timezone != NULL, NULL);
1074 return (* CLASS (backend)->internal_get_default_timezone) (backend);
1078 * e_cal_backend_internal_get_timezone:
1079 * @backend: A calendar backend.
1080 * @tzid: ID of the timezone to get.
1082 * Calls the internal_get_timezone method on the given backend.
1085 e_cal_backend_internal_get_timezone (ECalBackend *backend, const char *tzid)
1087 g_return_val_if_fail (E_IS_CAL_BACKEND (backend), NULL);
1088 g_return_val_if_fail (tzid != NULL, NULL);
1089 g_return_val_if_fail (CLASS (backend)->internal_get_timezone != NULL, NULL);
1091 return (* CLASS (backend)->internal_get_timezone) (backend, tzid);
1095 * e_cal_backend_set_notification_proxy:
1096 * @backend: A calendar backend.
1097 * @proxy: The calendar backend to act as notification proxy.
1099 * Sets the backend that will act as notification proxy for the given backend.
1102 e_cal_backend_set_notification_proxy (ECalBackend *backend, ECalBackend *proxy)
1104 ECalBackendPrivate *priv;
1106 g_return_if_fail (E_IS_CAL_BACKEND (backend));
1108 priv = backend->priv;
1110 priv->notification_proxy = proxy;
1114 * e_cal_backend_notify_object_created:
1115 * @backend: A calendar backend.
1116 * @calobj: iCalendar representation of new object
1118 * Notifies each of the backend's listeners about a new object.
1120 * #e_data_cal_notify_object_created() calls this for you. You only need to
1121 * call e_cal_backend_notify_object_created() yourself to report objects
1122 * created by non-EDS clients.
1125 e_cal_backend_notify_object_created (ECalBackend *backend, const char *calobj)
1127 ECalBackendPrivate *priv;
1130 EDataCalView *query;
1132 priv = backend->priv;
1134 if (priv->notification_proxy) {
1135 e_cal_backend_notify_object_created (priv->notification_proxy, calobj);
1139 queries = e_cal_backend_get_queries (backend);
1140 iter = e_list_get_iterator (queries);
1142 while (e_iterator_is_valid (iter)) {
1143 query = QUERY (e_iterator_get (iter));
1145 bonobo_object_ref (query);
1146 if (e_data_cal_view_object_matches (query, calobj))
1147 e_data_cal_view_notify_objects_added_1 (query, calobj);
1148 bonobo_object_unref (query);
1150 e_iterator_next (iter);
1152 g_object_unref (iter);
1156 match_query_and_notify (EDataCalView *query, const char *old_object, const char *object)
1158 gboolean old_match = FALSE, new_match = FALSE;
1161 old_match = e_data_cal_view_object_matches (query, old_object);
1163 new_match = e_data_cal_view_object_matches (query, object);
1164 if (old_match && new_match)
1165 e_data_cal_view_notify_objects_modified_1 (query, object);
1167 e_data_cal_view_notify_objects_added_1 (query, object);
1168 else if (old_match) {
1169 ECalComponent *comp = NULL;
1171 comp = e_cal_component_new_from_string (old_object);
1173 ECalComponentId *id = e_cal_component_get_id (comp);
1175 e_data_cal_view_notify_objects_removed_1 (query, id);
1177 e_cal_component_free_id (id);
1178 g_object_unref (comp);
1184 * e_cal_backend_notify_view_progress:
1185 * @backend: A calendar backend.
1186 * @message: the UID of the removed object
1187 * @percent: percentage of the objects loaded in the view
1189 * Notifies each of the backend's listeners about the view_progress in downloading the items.
1192 e_cal_backend_notify_view_progress (ECalBackend *backend, const char *message, int percent)
1194 ECalBackendPrivate *priv;
1197 EDataCalView *query;
1199 priv = backend->priv;
1201 if (priv->notification_proxy) {
1202 e_cal_backend_notify_view_progress (priv->notification_proxy, message, percent);
1206 queries = e_cal_backend_get_queries (backend);
1207 iter = e_list_get_iterator (queries);
1209 while (e_iterator_is_valid (iter)) {
1210 query = QUERY (e_iterator_get (iter));
1212 bonobo_object_ref (query);
1214 e_data_cal_view_notify_progress (query, message, percent);
1216 bonobo_object_unref (query);
1218 e_iterator_next (iter);
1220 g_object_unref (iter);
1224 * e_cal_backend_notify_view_done:
1225 * @backend: A calendar backend.
1226 * @status: returns the status once the view is fully populated.
1228 * Notifies each of the backend's listeners about the view_done in downloading the items.
1231 e_cal_backend_notify_view_done (ECalBackend *backend, GNOME_Evolution_Calendar_CallStatus status)
1233 ECalBackendPrivate *priv;
1236 EDataCalView *query;
1238 priv = backend->priv;
1240 if (priv->notification_proxy) {
1241 e_cal_backend_notify_view_done (priv->notification_proxy, status);
1245 queries = e_cal_backend_get_queries (backend);
1246 iter = e_list_get_iterator (queries);
1248 while (e_iterator_is_valid (iter)) {
1249 query = QUERY (e_iterator_get (iter));
1251 bonobo_object_ref (query);
1253 e_data_cal_view_notify_done (query, status);
1255 bonobo_object_unref (query);
1257 e_iterator_next (iter);
1259 g_object_unref (iter);
1263 * e_cal_backend_notify_object_modified:
1264 * @backend: A calendar backend.
1265 * @old_object: iCalendar representation of the original form of the object
1266 * @object: iCalendar representation of the new form of the object
1268 * Notifies each of the backend's listeners about a modified object.
1270 * #e_data_cal_notify_object_modified() calls this for you. You only need to
1271 * call e_cal_backend_notify_object_modified() yourself to report objects
1272 * modified by non-EDS clients.
1275 e_cal_backend_notify_object_modified (ECalBackend *backend,
1276 const char *old_object, const char *object)
1278 ECalBackendPrivate *priv;
1281 EDataCalView *query;
1283 priv = backend->priv;
1285 if (priv->notification_proxy) {
1286 e_cal_backend_notify_object_modified (priv->notification_proxy, old_object, object);
1290 queries = e_cal_backend_get_queries (backend);
1291 iter = e_list_get_iterator (queries);
1293 while (e_iterator_is_valid (iter)) {
1294 query = QUERY (e_iterator_get (iter));
1296 bonobo_object_ref (query);
1297 match_query_and_notify (query, old_object, object);
1298 bonobo_object_unref (query);
1300 e_iterator_next (iter);
1302 g_object_unref (iter);
1306 * e_cal_backend_notify_object_removed:
1307 * @backend: A calendar backend.
1308 * @id: the Id of the removed object
1309 * @old_object: iCalendar representation of the removed object
1310 * @new_object: iCalendar representation of the object after the removal. This
1311 * only applies to recurrent appointments that had an instance removed. In that
1312 * case, this function notifies a modification instead of a removal.
1314 * Notifies each of the backend's listeners about a removed object.
1316 * e_data_cal_notify_object_removed() calls this for you. You only need to
1317 * call e_cal_backend_notify_object_removed() yourself to report objects
1318 * removed by non-EDS clients.
1321 e_cal_backend_notify_object_removed (ECalBackend *backend, const ECalComponentId *id,
1322 const char *old_object, const char *object)
1324 ECalBackendPrivate *priv;
1327 EDataCalView *query;
1329 priv = backend->priv;
1331 if (priv->notification_proxy) {
1332 e_cal_backend_notify_object_removed (priv->notification_proxy, id, old_object, object);
1336 queries = e_cal_backend_get_queries (backend);
1337 iter = e_list_get_iterator (queries);
1339 while (e_iterator_is_valid (iter)) {
1340 query = QUERY (e_iterator_get (iter));
1342 bonobo_object_ref (query);
1344 if (object == NULL) {
1345 /* if object == NULL, it means the object has been completely
1346 removed from the backend */
1347 if (e_data_cal_view_object_matches (query, old_object))
1348 e_data_cal_view_notify_objects_removed_1 (query, id);
1350 match_query_and_notify (query, old_object, object);
1352 bonobo_object_unref (query);
1354 e_iterator_next (iter);
1356 g_object_unref (iter);
1360 * e_cal_backend_notify_mode:
1361 * @backend: A calendar backend.
1362 * @status: Status of the mode set
1363 * @mode: the current mode
1365 * Notifies each of the backend's listeners about the results of a
1369 e_cal_backend_notify_mode (ECalBackend *backend,
1370 GNOME_Evolution_Calendar_CalListener_SetModeStatus status,
1371 GNOME_Evolution_Calendar_CalMode mode)
1373 ECalBackendPrivate *priv = backend->priv;
1376 if (priv->notification_proxy) {
1377 e_cal_backend_notify_mode (priv->notification_proxy, status, mode);
1381 for (l = priv->clients; l; l = l->next)
1382 e_data_cal_notify_mode (l->data, status, mode);
1386 * e_cal_backend_notify_auth_required:
1387 * @backend: A calendar backend.
1389 * Notifies each of the backend's listeners that authentication is required to
1390 * open the calendar.
1393 e_cal_backend_notify_auth_required (ECalBackend *backend)
1395 ECalBackendPrivate *priv = backend->priv;
1398 for (l = priv->clients; l; l = l->next)
1399 e_data_cal_notify_auth_required (l->data);
1403 * e_cal_backend_notify_error:
1404 * @backend: A calendar backend.
1405 * @message: Error message
1407 * Notifies each of the backend's listeners about an error
1410 e_cal_backend_notify_error (ECalBackend *backend, const char *message)
1412 ECalBackendPrivate *priv = backend->priv;
1415 if (priv->notification_proxy) {
1416 e_cal_backend_notify_error (priv->notification_proxy, message);
1420 for (l = priv->clients; l; l = l->next)
1421 e_data_cal_notify_error (l->data, message);