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);
303 G_OBJECT_CLASS (parent_class)->finalize (object);
309 * e_cal_backend_get_source:
310 * @backend: An #ECalBackend object.
312 * Gets the #ESource associated with the given backend.
314 * Return value: The #ESource for the backend.
317 e_cal_backend_get_source (ECalBackend *backend)
319 ECalBackendPrivate *priv;
321 g_return_val_if_fail (backend != NULL, NULL);
322 g_return_val_if_fail (E_IS_CAL_BACKEND (backend), NULL);
324 priv = backend->priv;
330 * e_cal_backend_get_uri:
331 * @backend: A calendar backend.
333 * Queries the URI of a calendar backend, which must already have an open
336 * Return value: The URI where the calendar is stored.
339 e_cal_backend_get_uri (ECalBackend *backend)
341 ECalBackendPrivate *priv;
343 g_return_val_if_fail (backend != NULL, NULL);
344 g_return_val_if_fail (E_IS_CAL_BACKEND (backend), NULL);
346 priv = backend->priv;
352 * e_cal_backend_get_kind:
353 * @backend: An #ECalBackend object.
355 * Gets the kind of components the given backend stores.
357 * Return value: The kind of components for this backend.
360 e_cal_backend_get_kind (ECalBackend *backend)
362 ECalBackendPrivate *priv;
364 g_return_val_if_fail (backend != NULL, ICAL_NO_COMPONENT);
365 g_return_val_if_fail (E_IS_CAL_BACKEND (backend), ICAL_NO_COMPONENT);
367 priv = backend->priv;
373 cal_destroy_cb (gpointer data, GObject *where_cal_was)
375 ECalBackend *backend = E_CAL_BACKEND (data);
377 e_cal_backend_remove_client (backend, (EDataCal *) where_cal_was);
381 listener_died_cb (gpointer cnx, gpointer data)
383 EDataCal *cal = E_DATA_CAL (data);
385 e_cal_backend_remove_client (e_data_cal_get_backend (cal), cal);
389 last_client_gone (ECalBackend *backend)
391 g_signal_emit (backend, e_cal_backend_signals[LAST_CLIENT_GONE], 0);
395 * e_cal_backend_add_client:
396 * @backend: An ECalBackend object.
397 * @cal: An EDataCal object.
399 * Adds a new client to the given backend. For any event, the backend will
400 * notify all clients added via this function.
403 e_cal_backend_add_client (ECalBackend *backend, EDataCal *cal)
405 ECalBackendPrivate *priv;
407 g_return_if_fail (backend != NULL);
408 g_return_if_fail (E_IS_CAL_BACKEND (backend));
409 g_return_if_fail (cal != NULL);
410 g_return_if_fail (E_IS_DATA_CAL (cal));
412 priv = backend->priv;
414 bonobo_object_set_immortal (BONOBO_OBJECT (cal), TRUE);
416 g_object_weak_ref (G_OBJECT (cal), cal_destroy_cb, backend);
418 ORBit_small_listen_for_broken (e_data_cal_get_listener (cal), G_CALLBACK (listener_died_cb), cal);
420 g_mutex_lock (priv->clients_mutex);
421 priv->clients = g_list_append (priv->clients, cal);
422 g_mutex_unlock (priv->clients_mutex);
426 * e_cal_backend_remove_client:
427 * @backend: An #ECalBackend object.
428 * @cal: An #EDataCal object.
430 * Removes a client from the list of connected clients to the given backend.
433 e_cal_backend_remove_client (ECalBackend *backend, EDataCal *cal)
435 ECalBackendPrivate *priv;
437 /* XXX this needs a bit more thinking wrt the mutex - we
438 should be holding it when we check to see if clients is
440 g_return_if_fail (backend != NULL);
441 g_return_if_fail (E_IS_CAL_BACKEND (backend));
442 g_return_if_fail (cal != NULL);
443 g_return_if_fail (E_IS_DATA_CAL (cal));
445 priv = backend->priv;
448 g_mutex_lock (priv->clients_mutex);
449 priv->clients = g_list_remove (priv->clients, cal);
450 g_mutex_unlock (priv->clients_mutex);
452 /* When all clients go away, notify the parent factory about it so that
453 * it may decide whether to kill the backend or not.
456 last_client_gone (backend);
460 * e_cal_backend_add_query:
461 * @backend: An #ECalBackend object.
462 * @query: An #EDataCalView object.
464 * Adds a query to the list of live queries being run by the given backend.
465 * Doing so means that any listener on the query will get notified of any
466 * change that affect the live query.
469 e_cal_backend_add_query (ECalBackend *backend, EDataCalView *query)
471 g_return_if_fail (backend != NULL);
472 g_return_if_fail (E_IS_CAL_BACKEND (backend));
474 g_mutex_lock (backend->priv->queries_mutex);
476 e_list_append (backend->priv->queries, query);
478 g_mutex_unlock (backend->priv->queries_mutex);
482 * e_cal_backend_get_queries:
483 * @backend: An #ECalBackend object.
485 * Gets the list of live queries being run on the given backend.
487 * Return value: The list of live queries.
490 e_cal_backend_get_queries (ECalBackend *backend)
492 g_return_val_if_fail (backend != NULL, NULL);
493 g_return_val_if_fail (E_IS_CAL_BACKEND (backend), NULL);
495 return backend->priv->queries;
500 * e_cal_backend_get_cal_address:
501 * @backend: A calendar backend.
503 * Queries the cal address associated with a calendar backend, which
504 * must already have an open calendar.
507 e_cal_backend_get_cal_address (ECalBackend *backend, EDataCal *cal)
509 g_return_if_fail (backend != NULL);
510 g_return_if_fail (E_IS_CAL_BACKEND (backend));
512 g_assert (CLASS (backend)->get_cal_address != NULL);
513 (* CLASS (backend)->get_cal_address) (backend, cal);
517 e_cal_backend_notify_readonly (ECalBackend *backend, gboolean read_only)
519 ECalBackendPrivate *priv;
522 priv = backend->priv;
524 if (priv->notification_proxy) {
525 e_cal_backend_notify_readonly (priv->notification_proxy, read_only);
528 for (l = priv->clients; l; l = l->next)
529 e_data_cal_notify_read_only (l->data, GNOME_Evolution_Calendar_Success, read_only);
533 e_cal_backend_notify_cal_address (ECalBackend *backend, char *address)
535 ECalBackendPrivate *priv;
538 priv = backend->priv;
540 for (l = priv->clients; l; l = l->next)
541 e_data_cal_notify_cal_address (l->data, GNOME_Evolution_Calendar_Success, address);
545 * e_cal_backend_get_alarm_email_address:
546 * @backend: An #ECalBackend object.
547 * @cal: An #EDataCal object.
549 * Calls the get_alarm_email_address method on the given backend.
552 e_cal_backend_get_alarm_email_address (ECalBackend *backend, EDataCal *cal)
554 g_return_if_fail (backend != NULL);
555 g_return_if_fail (E_IS_CAL_BACKEND (backend));
557 g_assert (CLASS (backend)->get_alarm_email_address != NULL);
558 (* CLASS (backend)->get_alarm_email_address) (backend, cal);
562 *e_cal_backend_get_alarm_email_address:
563 * @backend: An #ECalBackend object.
564 * @cal: An #EDataCal object.
566 * Calls the get_ldap_attribute method of the given backend.
569 e_cal_backend_get_ldap_attribute (ECalBackend *backend, EDataCal *cal)
571 g_return_if_fail (backend != NULL);
572 g_return_if_fail (E_IS_CAL_BACKEND (backend));
574 g_assert (CLASS (backend)->get_ldap_attribute != NULL);
575 (* CLASS (backend)->get_ldap_attribute) (backend, cal);
579 * e_cal_backend_get_alarm_email_address:
580 * @backend: An #ECalBackend object.
581 * @cal: An #EDataCal object.
583 * Calls the get_static_capabilities method on the given backend.
586 e_cal_backend_get_static_capabilities (ECalBackend *backend, EDataCal *cal)
588 g_return_if_fail (backend != NULL);
589 g_return_if_fail (E_IS_CAL_BACKEND (backend));
591 g_assert (CLASS (backend)->get_static_capabilities != NULL);
592 (* CLASS (backend)->get_static_capabilities) (backend, cal);
596 * e_cal_backend_open:
597 * @backend: A calendar backend.
598 * @cal: An #EDataCal object.
599 * @only_if_exists: Whether the calendar should be opened only if it already
600 * exists. If FALSE, a new calendar will be created when the specified @uri
602 * @username: User name to use for authentication (if needed).
603 * @password: Password for @username.
605 * Opens a calendar backend with data from a calendar stored at the specified
609 e_cal_backend_open (ECalBackend *backend, EDataCal *cal, gboolean only_if_exists,
610 const char *username, const char *password)
612 g_return_if_fail (backend != NULL);
613 g_return_if_fail (E_IS_CAL_BACKEND (backend));
615 g_assert (CLASS (backend)->open != NULL);
616 (* CLASS (backend)->open) (backend, cal, only_if_exists, username, password);
620 * e_cal_backend_remove:
621 * @backend: A calendar backend.
622 * @cal: An #EDataCal object.
624 * Removes the calendar being accessed by the given backend.
627 e_cal_backend_remove (ECalBackend *backend, EDataCal *cal)
629 g_return_if_fail (backend != NULL);
630 g_return_if_fail (E_IS_CAL_BACKEND (backend));
632 g_assert (CLASS (backend)->remove != NULL);
633 (* CLASS (backend)->remove) (backend, cal);
637 * e_cal_backend_is_loaded:
638 * @backend: A calendar backend.
640 * Queries whether a calendar backend has been loaded yet.
642 * Return value: TRUE if the backend has been loaded with data, FALSE
646 e_cal_backend_is_loaded (ECalBackend *backend)
650 g_return_val_if_fail (backend != NULL, FALSE);
651 g_return_val_if_fail (E_IS_CAL_BACKEND (backend), FALSE);
653 g_assert (CLASS (backend)->is_loaded != NULL);
654 result = (* CLASS (backend)->is_loaded) (backend);
660 * e_cal_backend_is_read_only
661 * @backend: A calendar backend.
662 * @cal: An #EDataCal object.
664 * Queries whether a calendar backend is read only or not.
668 e_cal_backend_is_read_only (ECalBackend *backend, EDataCal *cal)
670 g_return_if_fail (backend != NULL);
671 g_return_if_fail (E_IS_CAL_BACKEND (backend));
673 g_assert (CLASS (backend)->is_read_only != NULL);
674 (* CLASS (backend)->is_read_only) (backend, cal);
678 * e_cal_backend_start_query:
679 * @backend: A calendar backend.
680 * @query: The query to be started.
682 * Starts a new live query on the given backend.
685 e_cal_backend_start_query (ECalBackend *backend, EDataCalView *query)
687 g_return_if_fail (backend != NULL);
688 g_return_if_fail (E_IS_CAL_BACKEND (backend));
690 g_assert (CLASS (backend)->start_query != NULL);
691 (* CLASS (backend)->start_query) (backend, query);
695 * e_cal_backend_get_mode:
696 * @backend: A calendar backend.
698 * Queries whether a calendar backend is connected remotely.
700 * Return value: The current mode the calendar is in
703 e_cal_backend_get_mode (ECalBackend *backend)
707 g_return_val_if_fail (backend != NULL, FALSE);
708 g_return_val_if_fail (E_IS_CAL_BACKEND (backend), FALSE);
710 g_assert (CLASS (backend)->get_mode != NULL);
711 result = (* CLASS (backend)->get_mode) (backend);
718 * e_cal_backend_set_mode:
719 * @backend: A calendar backend
720 * @mode: Mode to change to
722 * Sets the mode of the calendar
725 e_cal_backend_set_mode (ECalBackend *backend, CalMode mode)
727 g_return_if_fail (backend != NULL);
728 g_return_if_fail (E_IS_CAL_BACKEND (backend));
730 g_assert (CLASS (backend)->set_mode != NULL);
731 (* CLASS (backend)->set_mode) (backend, mode);
735 * e_cal_backend_get_default_object:
736 * @backend: A calendar backend.
737 * @cal: An #EDataCal object.
739 * Calls the get_default_object method on the given backend.
742 e_cal_backend_get_default_object (ECalBackend *backend, EDataCal *cal)
744 g_return_if_fail (backend != NULL);
745 g_return_if_fail (E_IS_CAL_BACKEND (backend));
747 g_assert (CLASS (backend)->get_default_object != NULL);
748 (* CLASS (backend)->get_default_object) (backend, cal);
752 * e_cal_backend_get_object:
753 * @backend: A calendar backend.
754 * @cal: An #EDataCal object.
755 * @uid: Unique identifier for a calendar object.
756 * @rid: ID for the object's recurrence to get.
758 * Queries a calendar backend for a calendar object based on its unique
759 * identifier and its recurrence ID (if a recurrent appointment).
762 e_cal_backend_get_object (ECalBackend *backend, EDataCal *cal, const char *uid, const char *rid)
764 g_return_if_fail (backend != NULL);
765 g_return_if_fail (E_IS_CAL_BACKEND (backend));
766 g_return_if_fail (uid != NULL);
768 g_assert (CLASS (backend)->get_object != NULL);
769 (* CLASS (backend)->get_object) (backend, cal, uid, rid);
773 * e_cal_backend_get_object_list:
774 * @backend: A calendar backend.
775 * @cal: An #EDataCal object.
776 * @sexp: Expression to search for.
778 * Calls the get_object_list method on the given backend.
781 e_cal_backend_get_object_list (ECalBackend *backend, EDataCal *cal, const char *sexp)
783 g_return_if_fail (backend != NULL);
784 g_return_if_fail (E_IS_CAL_BACKEND (backend));
786 g_assert (CLASS (backend)->get_object_list != NULL);
787 (* CLASS (backend)->get_object_list) (backend, cal, sexp);
791 * e_cal_backend_get_attachment_list:
792 * @backend: A calendar backend.
793 * @cal: An #EDataCal object.
794 * @uid: Unique identifier for a calendar object.
795 * @rid: ID for the object's recurrence to get.
797 * Queries a calendar backend for attachments present in a calendar object based
798 * on its unique identifier and its recurrence ID (if a recurrent appointment).
801 e_cal_backend_get_attachment_list (ECalBackend *backend, EDataCal *cal, const char *uid, const char *rid)
803 g_return_if_fail (backend != NULL);
804 g_return_if_fail (E_IS_CAL_BACKEND (backend));
805 g_return_if_fail (uid != NULL);
807 g_assert (CLASS (backend)->get_object != NULL);
808 (* CLASS (backend)->get_attachment_list) (backend, cal, uid, rid);
812 * e_cal_backend_get_free_busy:
813 * @backend: A calendar backend.
814 * @cal: An #EDataCal object.
815 * @users: List of users to get free/busy information for.
816 * @start: Start time for query.
817 * @end: End time for query.
819 * Gets a free/busy object for the given time interval
822 e_cal_backend_get_free_busy (ECalBackend *backend, EDataCal *cal, GList *users, time_t start, time_t end)
824 g_return_if_fail (backend != NULL);
825 g_return_if_fail (E_IS_CAL_BACKEND (backend));
826 g_return_if_fail (start != -1 && end != -1);
827 g_return_if_fail (start <= end);
829 g_assert (CLASS (backend)->get_free_busy != NULL);
830 (* CLASS (backend)->get_free_busy) (backend, cal, users, start, end);
834 * e_cal_backend_get_changes:
835 * @backend: A calendar backend.
836 * @cal: An #EDataCal object.
837 * @change_id: A unique uid for the callers change list
839 * Builds a sequence of objects and the type of change that occurred on them since
840 * the last time the give change_id was seen
843 e_cal_backend_get_changes (ECalBackend *backend, EDataCal *cal, const char *change_id)
845 g_return_if_fail (backend != NULL);
846 g_return_if_fail (E_IS_CAL_BACKEND (backend));
847 g_return_if_fail (change_id != NULL);
849 g_assert (CLASS (backend)->get_changes != NULL);
850 (* CLASS (backend)->get_changes) (backend, cal, change_id);
854 * e_cal_backend_discard_alarm
855 * @backend: A calendar backend.
856 * @cal: An #EDataCal object.
857 * @uid: UID of the component to discard the alarm from.
860 * Discards an alarm from the given component. This allows the specific backend
861 * to do whatever is needed to really discard the alarm.
864 e_cal_backend_discard_alarm (ECalBackend *backend, EDataCal *cal, const char *uid, const char *auid)
866 g_return_if_fail (backend != NULL);
867 g_return_if_fail (E_IS_CAL_BACKEND (backend));
868 g_return_if_fail (uid != NULL);
869 g_return_if_fail (auid != NULL);
871 g_assert (CLASS (backend)->discard_alarm != NULL);
872 (* CLASS (backend)->discard_alarm) (backend, cal, uid, auid);
876 * e_cal_backend_create_object:
877 * @backend: A calendar backend.
878 * @cal: An #EDataCal object.
879 * @calobj: The object to create.
881 * Calls the create_object method on the given backend.
884 e_cal_backend_create_object (ECalBackend *backend, EDataCal *cal, const char *calobj)
886 g_return_if_fail (backend != NULL);
887 g_return_if_fail (E_IS_CAL_BACKEND (backend));
888 g_return_if_fail (calobj != NULL);
890 if (CLASS (backend)->create_object)
891 (* CLASS (backend)->create_object) (backend, cal, calobj);
893 e_data_cal_notify_object_created (cal, GNOME_Evolution_Calendar_PermissionDenied, NULL, NULL);
897 * e_cal_backend_modify_object:
898 * @backend: A calendar backend.
899 * @cal: An #EDataCal object.
900 * @calobj: Object to be modified.
901 * @mod: Type of modification.
903 * Calls the modify_object method on the given backend.
906 e_cal_backend_modify_object (ECalBackend *backend, EDataCal *cal, const char *calobj, CalObjModType mod)
908 g_return_if_fail (backend != NULL);
909 g_return_if_fail (E_IS_CAL_BACKEND (backend));
910 g_return_if_fail (calobj != NULL);
912 if (CLASS (backend)->modify_object)
913 (* CLASS (backend)->modify_object) (backend, cal, calobj, mod);
915 e_data_cal_notify_object_removed (cal, GNOME_Evolution_Calendar_PermissionDenied, NULL, NULL, NULL);
919 * e_cal_backend_remove_object:
920 * @backend: A calendar backend.
921 * @cal: An #EDataCal object.
922 * @uid: Unique identifier of the object to remove.
923 * @rid: A recurrence ID.
924 * @mod: Type of removal.
926 * Removes an object in a calendar backend. The backend will notify all of its
927 * clients about the change.
930 e_cal_backend_remove_object (ECalBackend *backend, EDataCal *cal, const char *uid, const char *rid, CalObjModType mod)
932 g_return_if_fail (backend != NULL);
933 g_return_if_fail (E_IS_CAL_BACKEND (backend));
934 g_return_if_fail (uid != NULL);
936 g_assert (CLASS (backend)->remove_object != NULL);
937 (* CLASS (backend)->remove_object) (backend, cal, uid, rid, mod);
941 * e_cal_backend_receive_objects:
942 * @backend: A calendar backend.
943 * @cal: An #EDataCal object.
944 * @calobj: iCalendar object.
946 * Calls the receive_objects method on the given backend.
949 e_cal_backend_receive_objects (ECalBackend *backend, EDataCal *cal, const char *calobj)
951 g_return_if_fail (backend != NULL);
952 g_return_if_fail (E_IS_CAL_BACKEND (backend));
953 g_return_if_fail (calobj != NULL);
955 g_assert (CLASS (backend)->receive_objects != NULL);
956 (* CLASS (backend)->receive_objects) (backend, cal, calobj);
960 * e_cal_backend_send_objects:
961 * @backend: A calendar backend.
962 * @cal: An #EDataCal object.
963 * @calobj: iCalendar object to be sent.
965 * Calls the send_objects method on the given backend.
968 e_cal_backend_send_objects (ECalBackend *backend, EDataCal *cal, const char *calobj)
970 g_return_if_fail (backend != NULL);
971 g_return_if_fail (E_IS_CAL_BACKEND (backend));
972 g_return_if_fail (calobj != NULL);
974 g_assert (CLASS (backend)->send_objects != NULL);
975 (* CLASS (backend)->send_objects) (backend, cal, calobj);
979 * e_cal_backend_get_timezone:
980 * @backend: A calendar backend.
981 * @cal: An #EDataCal object.
982 * @tzid: Unique identifier of a VTIMEZONE object. Note that this must not be
985 * Returns the icaltimezone* corresponding to the TZID, or NULL if the TZID
989 e_cal_backend_get_timezone (ECalBackend *backend, EDataCal *cal, const char *tzid)
991 g_return_if_fail (backend != NULL);
992 g_return_if_fail (E_IS_CAL_BACKEND (backend));
993 g_return_if_fail (tzid != NULL);
995 g_assert (CLASS (backend)->get_timezone != NULL);
996 (* CLASS (backend)->get_timezone) (backend, cal, tzid);
1000 * e_cal_backend_set_default_zone:
1001 * @backend: A calendar backend.
1002 * @cal: An #EDataCal object.
1003 * @tzobj: The timezone object, in a string.
1005 * Sets the default timezone for the calendar, which is used to resolve
1006 * DATE and floating DATE-TIME values.
1009 e_cal_backend_set_default_zone (ECalBackend *backend, EDataCal *cal, const char *tzobj)
1011 g_return_if_fail (backend != NULL);
1012 g_return_if_fail (E_IS_CAL_BACKEND (backend));
1013 g_return_if_fail (tzobj != NULL);
1015 (* CLASS (backend)->set_default_zone) (backend, cal, tzobj);
1019 * @deprecated This virual function should not be used in the backends, use
1020 * e_cal_backend_set_zone instead. This function restricts the default timezone
1021 * to be libical builtin timezone.
1023 * e_cal_backend_set_default_timezone:
1024 * @backend: A calendar backend.
1025 * @cal: An #EDataCal object.
1026 * @tzid: The TZID identifying the timezone.
1028 * Sets the default timezone for the calendar, which is used to resolve
1029 * DATE and floating DATE-TIME values.
1033 e_cal_backend_set_default_timezone (ECalBackend *backend, EDataCal *cal, const char *tzid)
1035 g_return_if_fail (backend != NULL);
1036 g_return_if_fail (E_IS_CAL_BACKEND (backend));
1037 g_return_if_fail (tzid != NULL);
1039 (* CLASS (backend)->set_default_timezone) (backend, cal, tzid);
1043 * e_cal_backend_add_timezone
1044 * @backend: A calendar backend.
1045 * @cal: An #EDataCal object.
1046 * @tzobj: The timezone object, in a string.
1048 * Add a timezone object to the given backend.
1051 e_cal_backend_add_timezone (ECalBackend *backend, EDataCal *cal, const char *tzobj)
1053 g_return_if_fail (E_IS_CAL_BACKEND (backend));
1054 g_return_if_fail (tzobj != NULL);
1055 g_return_if_fail (CLASS (backend)->add_timezone != NULL);
1057 (* CLASS (backend)->add_timezone) (backend, cal, tzobj);
1061 * e_cal_backend_internal_get_default_timezone:
1062 * @backend: A calendar backend.
1064 * Calls the internal_get_default_timezone method on the given backend.
1067 e_cal_backend_internal_get_default_timezone (ECalBackend *backend)
1069 g_return_val_if_fail (E_IS_CAL_BACKEND (backend), NULL);
1070 g_return_val_if_fail (CLASS (backend)->internal_get_default_timezone != NULL, NULL);
1072 return (* CLASS (backend)->internal_get_default_timezone) (backend);
1076 * e_cal_backend_internal_get_timezone:
1077 * @backend: A calendar backend.
1078 * @tzid: ID of the timezone to get.
1080 * Calls the internal_get_timezone method on the given backend.
1083 e_cal_backend_internal_get_timezone (ECalBackend *backend, const char *tzid)
1085 g_return_val_if_fail (E_IS_CAL_BACKEND (backend), NULL);
1086 g_return_val_if_fail (tzid != NULL, NULL);
1087 g_return_val_if_fail (CLASS (backend)->internal_get_timezone != NULL, NULL);
1089 return (* CLASS (backend)->internal_get_timezone) (backend, tzid);
1093 * e_cal_backend_set_notification_proxy:
1094 * @backend: A calendar backend.
1095 * @proxy: The calendar backend to act as notification proxy.
1097 * Sets the backend that will act as notification proxy for the given backend.
1100 e_cal_backend_set_notification_proxy (ECalBackend *backend, ECalBackend *proxy)
1102 ECalBackendPrivate *priv;
1104 g_return_if_fail (E_IS_CAL_BACKEND (backend));
1106 priv = backend->priv;
1108 priv->notification_proxy = proxy;
1112 * e_cal_backend_notify_object_created:
1113 * @backend: A calendar backend.
1114 * @calobj: iCalendar representation of new object
1116 * Notifies each of the backend's listeners about a new object.
1118 * #e_data_cal_notify_object_created() calls this for you. You only need to
1119 * call e_cal_backend_notify_object_created() yourself to report objects
1120 * created by non-EDS clients.
1123 e_cal_backend_notify_object_created (ECalBackend *backend, const char *calobj)
1125 ECalBackendPrivate *priv;
1128 EDataCalView *query;
1130 priv = backend->priv;
1132 if (priv->notification_proxy) {
1133 e_cal_backend_notify_object_created (priv->notification_proxy, calobj);
1137 queries = e_cal_backend_get_queries (backend);
1138 iter = e_list_get_iterator (queries);
1140 while (e_iterator_is_valid (iter)) {
1141 query = QUERY (e_iterator_get (iter));
1143 bonobo_object_ref (query);
1144 if (e_data_cal_view_object_matches (query, calobj))
1145 e_data_cal_view_notify_objects_added_1 (query, calobj);
1146 bonobo_object_unref (query);
1148 e_iterator_next (iter);
1150 g_object_unref (iter);
1154 match_query_and_notify (EDataCalView *query, const char *old_object, const char *object)
1156 gboolean old_match = FALSE, new_match = FALSE;
1159 old_match = e_data_cal_view_object_matches (query, old_object);
1161 new_match = e_data_cal_view_object_matches (query, object);
1162 if (old_match && new_match)
1163 e_data_cal_view_notify_objects_modified_1 (query, object);
1165 e_data_cal_view_notify_objects_added_1 (query, object);
1166 else if (old_match) {
1167 ECalComponent *comp = NULL;
1169 comp = e_cal_component_new_from_string (old_object);
1171 ECalComponentId *id = e_cal_component_get_id (comp);
1173 e_data_cal_view_notify_objects_removed_1 (query, id);
1175 e_cal_component_free_id (id);
1176 g_object_unref (comp);
1182 * e_cal_backend_notify_view_progress:
1183 * @backend: A calendar backend.
1184 * @message: the UID of the removed object
1185 * @percent: percentage of the objects loaded in the view
1187 * Notifies each of the backend's listeners about the view_progress in downloading the items.
1190 e_cal_backend_notify_view_progress (ECalBackend *backend, const char *message, int percent)
1192 ECalBackendPrivate *priv;
1195 EDataCalView *query;
1197 priv = backend->priv;
1199 if (priv->notification_proxy) {
1200 e_cal_backend_notify_view_progress (priv->notification_proxy, message, percent);
1204 queries = e_cal_backend_get_queries (backend);
1205 iter = e_list_get_iterator (queries);
1207 while (e_iterator_is_valid (iter)) {
1208 query = QUERY (e_iterator_get (iter));
1210 bonobo_object_ref (query);
1212 e_data_cal_view_notify_progress (query, message, percent);
1214 bonobo_object_unref (query);
1216 e_iterator_next (iter);
1218 g_object_unref (iter);
1222 * e_cal_backend_notify_view_done:
1223 * @backend: A calendar backend.
1224 * @status: returns the status once the view is fully populated.
1226 * Notifies each of the backend's listeners about the view_done in downloading the items.
1229 e_cal_backend_notify_view_done (ECalBackend *backend, GNOME_Evolution_Calendar_CallStatus status)
1231 ECalBackendPrivate *priv;
1234 EDataCalView *query;
1236 priv = backend->priv;
1238 if (priv->notification_proxy) {
1239 e_cal_backend_notify_view_done (priv->notification_proxy, status);
1243 queries = e_cal_backend_get_queries (backend);
1244 iter = e_list_get_iterator (queries);
1246 while (e_iterator_is_valid (iter)) {
1247 query = QUERY (e_iterator_get (iter));
1249 bonobo_object_ref (query);
1251 e_data_cal_view_notify_done (query, status);
1253 bonobo_object_unref (query);
1255 e_iterator_next (iter);
1257 g_object_unref (iter);
1261 * e_cal_backend_notify_object_modified:
1262 * @backend: A calendar backend.
1263 * @old_object: iCalendar representation of the original form of the object
1264 * @object: iCalendar representation of the new form of the object
1266 * Notifies each of the backend's listeners about a modified object.
1268 * #e_data_cal_notify_object_modified() calls this for you. You only need to
1269 * call e_cal_backend_notify_object_modified() yourself to report objects
1270 * modified by non-EDS clients.
1273 e_cal_backend_notify_object_modified (ECalBackend *backend,
1274 const char *old_object, const char *object)
1276 ECalBackendPrivate *priv;
1279 EDataCalView *query;
1281 priv = backend->priv;
1283 if (priv->notification_proxy) {
1284 e_cal_backend_notify_object_modified (priv->notification_proxy, old_object, object);
1288 queries = e_cal_backend_get_queries (backend);
1289 iter = e_list_get_iterator (queries);
1291 while (e_iterator_is_valid (iter)) {
1292 query = QUERY (e_iterator_get (iter));
1294 bonobo_object_ref (query);
1295 match_query_and_notify (query, old_object, object);
1296 bonobo_object_unref (query);
1298 e_iterator_next (iter);
1300 g_object_unref (iter);
1304 * e_cal_backend_notify_object_removed:
1305 * @backend: A calendar backend.
1306 * @id: the Id of the removed object
1307 * @old_object: iCalendar representation of the removed object
1308 * @new_object: iCalendar representation of the object after the removal. This
1309 * only applies to recurrent appointments that had an instance removed. In that
1310 * case, this function notifies a modification instead of a removal.
1312 * Notifies each of the backend's listeners about a removed object.
1314 * e_data_cal_notify_object_removed() calls this for you. You only need to
1315 * call e_cal_backend_notify_object_removed() yourself to report objects
1316 * removed by non-EDS clients.
1319 e_cal_backend_notify_object_removed (ECalBackend *backend, const ECalComponentId *id,
1320 const char *old_object, const char *object)
1322 ECalBackendPrivate *priv;
1325 EDataCalView *query;
1327 priv = backend->priv;
1329 if (priv->notification_proxy) {
1330 e_cal_backend_notify_object_removed (priv->notification_proxy, id, old_object, object);
1334 queries = e_cal_backend_get_queries (backend);
1335 iter = e_list_get_iterator (queries);
1337 while (e_iterator_is_valid (iter)) {
1338 query = QUERY (e_iterator_get (iter));
1340 bonobo_object_ref (query);
1342 if (object == NULL) {
1343 /* if object == NULL, it means the object has been completely
1344 removed from the backend */
1345 if (e_data_cal_view_object_matches (query, old_object))
1346 e_data_cal_view_notify_objects_removed_1 (query, id);
1348 match_query_and_notify (query, old_object, object);
1350 bonobo_object_unref (query);
1352 e_iterator_next (iter);
1354 g_object_unref (iter);
1358 * e_cal_backend_notify_mode:
1359 * @backend: A calendar backend.
1360 * @status: Status of the mode set
1361 * @mode: the current mode
1363 * Notifies each of the backend's listeners about the results of a
1367 e_cal_backend_notify_mode (ECalBackend *backend,
1368 GNOME_Evolution_Calendar_CalListener_SetModeStatus status,
1369 GNOME_Evolution_Calendar_CalMode mode)
1371 ECalBackendPrivate *priv = backend->priv;
1374 if (priv->notification_proxy) {
1375 e_cal_backend_notify_mode (priv->notification_proxy, status, mode);
1379 for (l = priv->clients; l; l = l->next)
1380 e_data_cal_notify_mode (l->data, status, mode);
1384 * e_cal_backend_notify_auth_required:
1385 * @backend: A calendar backend.
1387 * Notifies each of the backend's listeners that authentication is required to
1388 * open the calendar.
1391 e_cal_backend_notify_auth_required (ECalBackend *backend)
1393 ECalBackendPrivate *priv = backend->priv;
1396 for (l = priv->clients; l; l = l->next)
1397 e_data_cal_notify_auth_required (l->data);
1401 * e_cal_backend_notify_error:
1402 * @backend: A calendar backend.
1403 * @message: Error message
1405 * Notifies each of the backend's listeners about an error
1408 e_cal_backend_notify_error (ECalBackend *backend, const char *message)
1410 ECalBackendPrivate *priv = backend->priv;
1413 if (priv->notification_proxy) {
1414 e_cal_backend_notify_error (priv->notification_proxy, message);
1418 for (l = priv->clients; l; l = l->next)
1419 e_data_cal_notify_error (l->data, message);