diff options
author | Federico Mena Quintero <federico@helixcode.com> | 2000-05-09 00:58:27 +0800 |
---|---|---|
committer | Federico Mena Quintero <federico@src.gnome.org> | 2000-05-09 00:58:27 +0800 |
commit | 8160d7388e27c6f97e3ed96bc5d61fbf20ff2d16 (patch) | |
tree | ff1ff2df49f02deccc5424fdf6004f1b90e05553 /calendar/pcs/cal-backend.c | |
parent | c2dde9ab64a79b483804cddbd9622827b4b2baf2 (diff) | |
download | gsoc2013-evolution-8160d7388e27c6f97e3ed96bc5d61fbf20ff2d16.tar.gz gsoc2013-evolution-8160d7388e27c6f97e3ed96bc5d61fbf20ff2d16.tar.zst gsoc2013-evolution-8160d7388e27c6f97e3ed96bc5d61fbf20ff2d16.zip |
CalBackendClass now is just an interface for calendar backends; this is an
2000-05-08 Federico Mena Quintero <federico@helixcode.com>
* pcs/cal-backend.h (CalBackendClass): CalBackendClass now is just
an interface for calendar backends; this is an abstract class.
Put in the vtable for the backend methods.
* pcs/cal-backend.c (cal_backend_new): Removed function, since
CalBackend is not just an abstract class.
Removed implementation-specific functions and made public
functions call the virtual methods instead.
* pcs/cal-backend-imc.[ch]: New files with the CalBackendIMC
implementation; this implements a backend for iCalendar and
vCalendar files. Moved the implementation-specific stuff from
cal-backend.[ch] to here.
* pcs/cal-backend-imc.c (CalendarFormat): Moved enumeration to
here. Added a CAL_UNKNOWN value for when the backend is not
loaded yet.
(cal_backend_imc_init): Initialize priv->format as CAL_UNKNOWN.
(save_to_vcal): Use the same VCProdIdProp value as in
cal-util/calobj.c. Use "1.0" as the VCVersionProp as per the
vCalendar spec.
(ensure_uid): Return nothing, since the result value need not be
used anymore.
(add_object): Since we mark the calendar as dirty anyways, we do
not need to check the result value of ensure_uid() anymore.
(remove_object): Asssert that we know how to handle the object's
type. We do this in add_object() anyways.
* pcs/Makefile.am (libpcs_a_SOURCES): Added cal-backend-imc.[ch].
* gui/gnome-cal.c: Replaced debugging printf()s with g_message()
so that we can see the line number where they occur.
* gui/gnome-cal.c (gnome_calendar_load_cb): Sort of handle the
LOAD_METHOD_NOT_SUPPORTED result code, and added a default for the
switch.
* cal-client/cal-listener.h (CalListenerLoadStatus): Removed
enumeration; it is stupid to translate all values for the
CalClient when it is going to translate them again.
(CalListenerClass::cal_loaded): This signal now passes the
LoadStatus directly from the CORBA side.
* cal-client/cal-listener.c (Listener_cal_loaded): Do not
translate the status value.
* cal-client/cal-client.h (CalClientLoadStatus): Added the
CAL_CLIENT_LOAD_METHOD_NOT_SUPPORTED error code.
* cal-client/cal-client.c (cal_loaded_cb): Translate the CORBA
version of the LoadStatus result code.
* pcs/cal-factory.c (CalFactoryPrivate): New methods field for the
hash table from method strings to the GtkTypes for backend class
types.
(cal_factory_init): Create the priv->methods hash table.
(cal_factory_destroy): Free the priv->methods hash table.
(cal_factory_register_method): New function to register a backend
class for a particular URI method.
(launch_backend_for_uri): New function to launch a backend for a
particular URI's method.
(load_backend): Use launch_backend_for_uri(). Move the error
notification code from load_fn() to here.
(create_backend): Use launch_backend_for_uri(). Move the error
notification code form create_fn() to here; it is #ifdefed out
since currently cal_backend_create() does not have any error
reporting capabilities.
* idl/evolution-calendar.idl (Listener::LoadStatus): Added a
PROTOCOL_NOT_SUPPORTED error code.
* pcs/cal-factory.c (cal_factory_load cal_factory_create): Removed
functions, since they were supposed to be internal only.
(CalFactory_load): Call queue_load_create_job() directly.
(CalFactory_create): Likewise.
svn path=/trunk/; revision=2921
Diffstat (limited to 'calendar/pcs/cal-backend.c')
-rw-r--r-- | calendar/pcs/cal-backend.c | 933 |
1 files changed, 38 insertions, 895 deletions
diff --git a/calendar/pcs/cal-backend.c b/calendar/pcs/cal-backend.c index 3aed2a41fa..27cc3e53ce 100644 --- a/calendar/pcs/cal-backend.c +++ b/calendar/pcs/cal-backend.c @@ -1,5 +1,5 @@ /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* Evolution calendar backend +/* Evolution calendar - generic backend class * * Copyright (C) 2000 Helix Code, Inc. * @@ -25,39 +25,6 @@ #include <cal-util/calobj.h> #include "cal-backend.h" #include "libversit/vcc.h" -#include "icalendar.h" - - - - -/* Private part of the CalBackend structure */ -typedef struct { - /* URI where the calendar data is stored */ - GnomeVFSURI *uri; - - /* format of this calendar (ical or vcal) */ - CalendarFormat format; - - /* List of Cal objects with their listeners */ - GList *clients; - - /* All the iCalObject structures in the calendar, hashed by UID. The - * hash key *is* icalobj->uid; it is not copied, so don't free it when - * you remove an object from the hash table. - */ - GHashTable *object_hash; - - /* All events, TODOs, and journals in the calendar */ - GList *events; - GList *todos; - GList *journals; - - /* Whether a calendar has been loaded */ - guint loaded : 1; - - /* Do we need to sync to permanent storage? */ - gboolean dirty : 1; -} CalBackendPrivate; @@ -68,13 +35,13 @@ enum { }; static void cal_backend_class_init (CalBackendClass *class); -static void cal_backend_init (CalBackend *backend); -static void cal_backend_destroy (GtkObject *object); static GtkObjectClass *parent_class; static guint cal_backend_signals[LAST_SIGNAL]; +#define CLASS(backend) (CAL_BACKEND_CLASS (GTK_OBJECT (backend)->klass)) + /** @@ -97,7 +64,7 @@ cal_backend_get_type (void) sizeof (CalBackend), sizeof (CalBackendClass), (GtkClassInitFunc) cal_backend_class_init, - (GtkObjectInitFunc) cal_backend_init, + (GtkObjectInitFunc) NULL, NULL, /* reserved_1 */ NULL, /* reserved_2 */ (GtkClassInitFunc) NULL @@ -129,391 +96,11 @@ cal_backend_class_init (CalBackendClass *class) GTK_TYPE_NONE, 0); gtk_object_class_add_signals (object_class, cal_backend_signals, LAST_SIGNAL); - - object_class->destroy = cal_backend_destroy; -} - -/* Object initialization function for the calendar backend */ -static void -cal_backend_init (CalBackend *backend) -{ - CalBackendPrivate *priv; - - priv = g_new0 (CalBackendPrivate, 1); - backend->priv = priv; - - /* FIXME can be CAL_VCAL or CAL_ICAL */ - priv->format = CAL_VCAL; -} - -static void -save_to_vcal (CalBackend *backend, char *fname) -{ - FILE *fp; - CalBackendPrivate *priv = backend->priv; - VObject *vcal; - GList *l; - - if (g_file_exists (fname)){ - char *backup_name = g_strconcat (fname, "~", NULL); - - if (g_file_exists (backup_name)){ - unlink (backup_name); - } - rename (fname, backup_name); - g_free (backup_name); - } - - vcal = newVObject (VCCalProp); - addPropValue (vcal, VCProdIdProp, - "-//GNOME//NONSGML GnomeCalendar//EN"); - addPropValue (vcal, VCVersionProp, VERSION); - - for (l = priv->events; l; l = l->next) { - iCalObject *ical = l->data; - VObject *vobject = ical_object_to_vobject (ical); - addVObjectProp (vcal, vobject); - } - for (l = priv->todos; l; l = l->next) { - iCalObject *ical = l->data; - VObject *vobject = ical_object_to_vobject (ical); - addVObjectProp (vcal, vobject); - } - for (l = priv->journals; l; l = l->next) { - iCalObject *ical = l->data; - VObject *vobject = ical_object_to_vobject (ical); - addVObjectProp (vcal, vobject); - } - - fp = fopen(fname,"w"); - if (fp) { - writeVObject(fp, vcal); - fclose(fp); - } - cleanVObject (vcal); - cleanStrTbl (); -} - -/* Saves a calendar */ -static void -save (CalBackend *backend) -{ - char *str_uri; - CalBackendPrivate *priv = backend->priv; - - str_uri = gnome_vfs_uri_to_string (priv->uri, - (GNOME_VFS_URI_HIDE_USER_NAME - | GNOME_VFS_URI_HIDE_PASSWORD - | GNOME_VFS_URI_HIDE_HOST_NAME - | GNOME_VFS_URI_HIDE_HOST_PORT - | GNOME_VFS_URI_HIDE_TOPLEVEL_METHOD)); - - if (! priv->dirty){ - return; - } - - switch (priv->format) { - case CAL_VCAL: - save_to_vcal (backend, str_uri); - break; - case CAL_ICAL: - /*icalendar_calendar_save (backend, str_uri);*/ - /* FIX ME */ - break; - default: - /* FIX ME log */ - break; - } - - printf ("cal-backend: '%s' saved\n", str_uri); - - g_free (str_uri); -} - - -/* g_hash_table_foreach() callback to destroy an iCalObject */ -static void -free_ical_object (gpointer key, gpointer value, gpointer data) -{ - iCalObject *ico; - - ico = value; - ical_object_destroy (ico); -} - -/* Destroys a backend's data */ -static void -destroy (CalBackend *backend) -{ - CalBackendPrivate *priv; - - priv = backend->priv; - - if (priv->uri) { - gnome_vfs_uri_unref (priv->uri); - priv->uri = NULL; - } - - g_assert (priv->clients == NULL); - - if (priv->object_hash) { - g_hash_table_foreach (priv->object_hash, free_ical_object, NULL); - g_hash_table_destroy (priv->object_hash); - priv->object_hash = NULL; - } - - g_list_free (priv->events); - g_list_free (priv->todos); - g_list_free (priv->journals); - - priv->events = NULL; - priv->todos = NULL; - priv->journals = NULL; - - priv->loaded = FALSE; -} - -/* Destroy handler for the calendar backend */ -static void -cal_backend_destroy (GtkObject *object) -{ - CalBackend *backend; - CalBackendPrivate *priv; - - g_return_if_fail (object != NULL); - g_return_if_fail (IS_CAL_BACKEND (object)); - - backend = CAL_BACKEND (object); - priv = backend->priv; - - /* - if (priv->loaded) - save (backend); - */ - - destroy (backend); - - g_free (priv); - - if (GTK_OBJECT_CLASS (parent_class)->destroy) - (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); -} - - - -/* iCalObject manipulation functions */ - -/* Looks up an object by its UID in the backend's object hash table */ -static iCalObject * -lookup_object (CalBackend *backend, const char *uid) -{ - CalBackendPrivate *priv; - iCalObject *ico; - - priv = backend->priv; - ico = g_hash_table_lookup (priv->object_hash, uid); - - return ico; -} - -/* Ensures that an iCalObject has a unique identifier. If it doesn't have one, - * it will create one for it. Returns whether an UID was created or not. - */ -static gboolean -ensure_uid (iCalObject *ico) -{ - char *buf; - gulong str_time; - static guint seqno = 0; - - if (ico->uid){ - return FALSE; - } - - str_time = (gulong) time (NULL); - - /* Is this good enough? */ - - buf = g_strdup_printf ("Evolution-Tlacuache-%d-%ld-%u", - (int) getpid(), str_time, seqno++); - ico->uid = buf; - return TRUE; -} - -/* Adds an object to the calendar backend. Does *not* perform notification to - * calendar clients. - */ -static void -add_object (CalBackend *backend, iCalObject *ico) -{ - CalBackendPrivate *priv; - - g_assert (ico != NULL); - priv = backend->priv; - -#if 0 - /* FIXME: gnomecal old code */ - ico->new = 0; -#endif - - if (ensure_uid (ico)) - /* FIXME: mark the calendar as dirty so that we can re-save it - * with the object's new UID. - */ - ; - - g_hash_table_insert (priv->object_hash, ico->uid, ico); - - priv->dirty = TRUE; - - switch (ico->type) { - case ICAL_EVENT: - priv->events = g_list_prepend (priv->events, ico); -#if 0 - /* FIXME: gnomecal old code */ - ical_object_try_alarms (ico); -# ifdef DEBUGGING_MAIL_ALARM - ico->malarm.trigger = 0; - calendar_notify (0, ico); -# endif -#endif - break; - - case ICAL_TODO: - priv->todos = g_list_prepend (priv->todos, ico); - break; - - case ICAL_JOURNAL: - priv->journals = g_list_prepend (priv->journals, ico); - break; - - default: - g_assert_not_reached (); - } - -#if 0 - /* FIXME: gnomecal old code */ - ico->last_mod = time (NULL); -#endif -} - -/* Removes an object from the backend's hash and lists. Does not perform - * notification on the clients. - */ -static void -remove_object (CalBackend *backend, iCalObject *ico) -{ - CalBackendPrivate *priv; - GList **list, *l; - - priv = backend->priv; - - g_assert (ico->uid != NULL); - g_hash_table_remove (priv->object_hash, ico->uid); - - priv->dirty = TRUE; - - switch (ico->type) { - case ICAL_EVENT: - list = &priv->events; - break; - - case ICAL_TODO: - list = &priv->todos; - break; - - case ICAL_JOURNAL: - list = &priv->journals; - break; - - default: - list = NULL; - } - - if (!list){ - return; - } - - l = g_list_find (*list, ico); - g_assert (l != NULL); - - *list = g_list_remove_link (*list, l); - g_list_free_1 (l); - - ical_object_destroy (ico); -} - -/* Load a calendar from a VObject */ -static void -load_from_vobject (CalBackend *backend, VObject *vobject) -{ - CalBackendPrivate *priv; - VObjectIterator i; - - priv = backend->priv; - - g_assert (!priv->loaded); - g_assert (priv->object_hash == NULL); - priv->object_hash = g_hash_table_new (g_str_hash, g_str_equal); - - initPropIterator (&i, vobject); - - while (moreIteration (&i)) { - VObject *this; - iCalObject *ical; - const char *object_name; - - this = nextVObject (&i); - object_name = vObjectName (this); -#if 0 - /* FIXME? What is this used for in gnomecal? */ - if (strcmp (object_name, VCDCreatedProp) == 0) { - cal->created = time_from_isodate (str_val (this)); - continue; - } -#endif - if (strcmp (object_name, VCLocationProp) == 0) - continue; /* FIXME: imlement */ - - if (strcmp (object_name, VCProdIdProp) == 0) - continue; /* FIXME: implement */ - - if (strcmp (object_name, VCVersionProp) == 0) - continue; /* FIXME: implement */ - - if (strcmp (object_name, VCTimeZoneProp) == 0) - continue; /* FIXME: implement */ - - ical = ical_object_create_from_vobject (this, object_name); - - /* FIXME: some broken files may have duplicated UIDs. This is - * Bad(tm). Deal with it by creating new UIDs for them and - * spitting some messages to the console. - */ - - if (ical) - add_object (backend, ical); - } } /** - * cal_backend_new: - * @void: - * - * Creates a new empty calendar backend. A calendar must then be loaded or - * created before the backend can be used. - * - * Return value: A newly-created calendar backend. - **/ -CalBackend * -cal_backend_new (void) -{ - return CAL_BACKEND (gtk_type_new (CAL_BACKEND_TYPE)); -} - -/** * cal_backend_get_uri: * @backend: A calendar backend. * @@ -525,54 +112,11 @@ cal_backend_new (void) GnomeVFSURI * cal_backend_get_uri (CalBackend *backend) { - CalBackendPrivate *priv; - g_return_val_if_fail (backend != NULL, NULL); g_return_val_if_fail (IS_CAL_BACKEND (backend), NULL); - priv = backend->priv; - g_return_val_if_fail (priv->loaded, NULL); - g_assert (priv->uri != NULL); - - return priv->uri; -} - -/* Callback used when a Cal is destroyed */ -static void -cal_destroy_cb (GtkObject *object, gpointer data) -{ - Cal *cal; - Cal *lcal; - CalBackend *backend; - CalBackendPrivate *priv; - GList *l; - - cal = CAL (object); - - backend = CAL_BACKEND (data); - priv = backend->priv; - - /* Find the cal in the list of clients */ - - for (l = priv->clients; l; l = l->next) { - lcal = CAL (l->data); - - if (lcal == cal) - break; - } - - g_assert (l != NULL); - - /* Disconnect */ - - priv->clients = g_list_remove_link (priv->clients, l); - g_list_free_1 (l); - - /* When all clients go away, notify the parent factory about it so that - * it may decide whether to kill the backend or not. - */ - if (!priv->clients) - gtk_signal_emit (GTK_OBJECT (backend), cal_backend_signals[LAST_CLIENT_GONE]); + g_assert (CLASS (backend)->get_uri != NULL); + return (* CLASS (backend)->get_uri) (backend); } /** @@ -586,143 +130,13 @@ cal_destroy_cb (GtkObject *object, gpointer data) void cal_backend_add_cal (CalBackend *backend, Cal *cal) { - CalBackendPrivate *priv; - g_return_if_fail (backend != NULL); g_return_if_fail (IS_CAL_BACKEND (backend)); - priv = backend->priv; - g_return_if_fail (priv->loaded); - - g_return_if_fail (cal != NULL); - g_return_if_fail (IS_CAL (cal)); - - /* We do not keep a reference to the Cal since the calendar user agent - * owns it. - */ - - gtk_signal_connect (GTK_OBJECT (cal), "destroy", - GTK_SIGNAL_FUNC (cal_destroy_cb), - backend); - - priv->clients = g_list_prepend (priv->clients, cal); -} - - -static icalcomponent* -icalendar_parse_file (char* fname) -{ - FILE* fp; - icalcomponent* comp = NULL; - gchar* str; - struct stat st; - int n; - - fp = fopen (fname, "r"); - if (!fp) { - g_warning ("Cannot open open calendar file."); - return NULL; - } - - stat (fname, &st); - - str = g_malloc (st.st_size + 2); - - n = fread ((gchar*) str, 1, st.st_size, fp); - if (n != st.st_size) { - g_warning ("Read error."); - } - str[n] = '\0'; - - fclose (fp); - - comp = icalparser_parse_string (str); - g_free (str); - - return comp; -} - - -static void -icalendar_calendar_load (CalBackend * cal, char* fname) -{ - CalBackendPrivate *priv; - icalcomponent *comp; - icalcomponent *subcomp; - iCalObject *ical; - - g_assert (cal); - - priv = cal->priv; - - g_assert (!priv->loaded); - g_assert (priv->object_hash == NULL); - - priv->object_hash = g_hash_table_new (g_str_hash, g_str_equal); - - comp = icalendar_parse_file (fname); - subcomp = icalcomponent_get_first_component (comp, - ICAL_ANY_COMPONENT); - while (subcomp) { - ical = ical_object_create_from_icalcomponent (subcomp); - if (ical->type != ICAL_EVENT && - ical->type != ICAL_TODO && - ical->type != ICAL_JOURNAL) { - g_warning ("Skipping unsupported iCalendar component."); - } else - add_object (cal, ical); - subcomp = icalcomponent_get_next_component (comp, - ICAL_ANY_COMPONENT); - } + g_assert (CLASS (backend)->add_cal != NULL); + return (* CLASS (backend)->add_cal) (backend, cal); } - -/* -ics is to be used to designate a file containing (an arbitrary set of) -calendaring and scheduling information. - -ifb is to be used to designate a file containing free or busy time -information. - -anything else is assumed to be a vcal file. -*/ - -static CalendarFormat -cal_get_type_from_filename (char *str_uri) -{ - int len; - - if (str_uri == NULL) - return CAL_VCAL; - - len = strlen (str_uri); - if (len < 4) - return CAL_VCAL; - - if (str_uri[ len-4 ] == '.' && str_uri[ len-3 ] == 'i' && - str_uri[ len-2 ] == 'c' && str_uri[ len-1 ] == 's') - return CAL_ICAL; - - if (str_uri[ len-4 ] == '.' && str_uri[ len-3 ] == 'i' && - str_uri[ len-2 ] == 'f' && str_uri[ len-1 ] == 'b') - return CAL_ICAL; - - if (str_uri[ len-4 ] == '.' && str_uri[ len-3 ] == 'i' && - str_uri[ len-2 ] == 'c' && str_uri[ len-1 ] == 's') - return CAL_ICAL; - - if (len < 5) - return CAL_VCAL; - - if (str_uri[ len-5 ] == '.' && str_uri[ len-4 ] == 'i' && - str_uri[ len-3 ] == 'c' && str_uri[ len-2 ] == 'a' && - str_uri[ len-1 ] == 'l') - return CAL_ICAL; - - return CAL_VCAL; -} - - /** * cal_backend_load: * @backend: A calendar backend. @@ -736,66 +150,12 @@ cal_get_type_from_filename (char *str_uri) CalBackendLoadStatus cal_backend_load (CalBackend *backend, GnomeVFSURI *uri) { - CalBackendPrivate *priv; - VObject *vobject; - char *str_uri; - g_return_val_if_fail (backend != NULL, CAL_BACKEND_LOAD_ERROR); - g_return_val_if_fail (IS_CAL_BACKEND (backend),CAL_BACKEND_LOAD_ERROR); - - priv = backend->priv; - g_return_val_if_fail (!priv->loaded, CAL_BACKEND_LOAD_ERROR); - + g_return_val_if_fail (IS_CAL_BACKEND (backend), CAL_BACKEND_LOAD_ERROR); g_return_val_if_fail (uri != NULL, CAL_BACKEND_LOAD_ERROR); - /* FIXME: this looks rather bad; maybe we should check for local files - * and fail if they are remote. - */ - - str_uri = gnome_vfs_uri_to_string (uri, - (GNOME_VFS_URI_HIDE_USER_NAME - | GNOME_VFS_URI_HIDE_PASSWORD - | GNOME_VFS_URI_HIDE_HOST_NAME - | GNOME_VFS_URI_HIDE_HOST_PORT - | GNOME_VFS_URI_HIDE_TOPLEVEL_METHOD)); - - - /* look at the extension on the filename and decide - if this is a ical or vcal file */ - - priv->format = cal_get_type_from_filename (str_uri); - - /* load */ - - switch (priv->format) { - case CAL_VCAL: - vobject = Parse_MIME_FromFileName (str_uri); - - if (!vobject){ - g_free (str_uri); - return CAL_BACKEND_LOAD_ERROR; - } - - load_from_vobject (backend, vobject); - cleanVObject (vobject); - cleanStrTbl (); - break; - case CAL_ICAL: - icalendar_calendar_load (backend, str_uri); - break; - default: - g_free (str_uri); - return CAL_BACKEND_LOAD_ERROR; - } - - g_free (str_uri); - - gnome_vfs_uri_ref (uri); - - priv->uri = uri; - priv->loaded = TRUE; - - return CAL_BACKEND_LOAD_SUCCESS; + g_assert (CLASS (backend)->load != NULL); + return (* CLASS (backend)->load) (backend, uri); } /** @@ -808,31 +168,12 @@ cal_backend_load (CalBackend *backend, GnomeVFSURI *uri) void cal_backend_create (CalBackend *backend, GnomeVFSURI *uri) { - CalBackendPrivate *priv; - g_return_if_fail (backend != NULL); g_return_if_fail (IS_CAL_BACKEND (backend)); - - priv = backend->priv; - g_return_if_fail (!priv->loaded); - g_return_if_fail (uri != NULL); - /* Create the new calendar information */ - - g_assert (priv->object_hash == NULL); - priv->object_hash = g_hash_table_new (g_str_hash, g_str_equal); - - priv->dirty = TRUE; - - /* Done */ - - gnome_vfs_uri_ref (uri); - - priv->uri = uri; - priv->loaded = TRUE; - - save (backend); + g_assert (CLASS (backend)->create != NULL); + (* CLASS (backend)->create) (backend, uri); } /** @@ -850,66 +191,12 @@ cal_backend_create (CalBackend *backend, GnomeVFSURI *uri) char * cal_backend_get_object (CalBackend *backend, const char *uid) { - CalBackendPrivate *priv; - iCalObject *ico; - char *buf; - g_return_val_if_fail (backend != NULL, NULL); g_return_val_if_fail (IS_CAL_BACKEND (backend), NULL); - - priv = backend->priv; - g_return_val_if_fail (priv->loaded, NULL); - g_return_val_if_fail (uid != NULL, NULL); - g_assert (priv->object_hash != NULL); - - ico = lookup_object (backend, uid); - - if (!ico){ - return NULL; - } - - buf = ical_object_to_string (ico); - - return buf; -} - -struct get_uids_closure { - CalObjType type; - GList *uid_list; -}; - -/* Builds a list of UIDs for objects that match the sought type. Called from - * g_hash_table_foreach(). - */ -static void -build_uids_list (gpointer key, gpointer value, gpointer data) -{ - iCalObject *ico; - struct get_uids_closure *c; - gboolean store; - - ico = value; - c = data; - - store = FALSE; - - /* - if (c->type & CALOBJ_TYPE_ANY) - store = TRUE; - else */ - if (ico->type == ICAL_EVENT) - store = (c->type & CALOBJ_TYPE_EVENT) ? TRUE : FALSE; - else if (ico->type == ICAL_TODO) - store = (c->type & CALOBJ_TYPE_TODO) ? TRUE : FALSE; - else if (ico->type == ICAL_JOURNAL) - store = (c->type & CALOBJ_TYPE_JOURNAL) ? TRUE : FALSE; - else - store = (c->type & CALOBJ_TYPE_OTHER) ? TRUE : FALSE; - - if (store) - c->uid_list = g_list_prepend (c->uid_list, g_strdup (ico->uid)); + g_assert (CLASS (backend)->get_object != NULL); + return (* CLASS (backend)->get_object) (backend, uid); } /** @@ -925,68 +212,11 @@ build_uids_list (gpointer key, gpointer value, gpointer data) GList * cal_backend_get_uids (CalBackend *backend, CalObjType type) { - CalBackendPrivate *priv; - struct get_uids_closure c; - g_return_val_if_fail (backend != NULL, NULL); g_return_val_if_fail (IS_CAL_BACKEND (backend), NULL); - priv = backend->priv; - g_return_val_if_fail (priv->loaded, NULL); - - /* We go through the hash table instead of the lists of particular - * object types so that we can pick up CALOBJ_TYPE_OTHER objects. - */ - - c.type = type; - c.uid_list = NULL; - g_hash_table_foreach (priv->object_hash, build_uids_list, &c); - - return c.uid_list; -} - -struct build_event_list_closure { - CalBackend *backend; - GList *event_list; -}; - -/* Builds a sorted list of event object instances. Used as a callback from - * ical_object_generate_events(). - */ -static int -build_event_list (iCalObject *ico, time_t start, time_t end, void *data) -{ - CalObjInstance *icoi; - struct build_event_list_closure *c; - - c = data; - - icoi = g_new (CalObjInstance, 1); - - g_assert (ico->uid != NULL); - icoi->uid = g_strdup (ico->uid); - icoi->start = start; - icoi->end = end; - - c->event_list = g_list_prepend (c->event_list, icoi); - - return TRUE; -} - -/* Compares two CalObjInstance structures by their start times. Called from - * g_list_sort(). - */ -static gint -compare_instance_func (gconstpointer a, gconstpointer b) -{ - const CalObjInstance *ca, *cb; - time_t diff; - - ca = a; - cb = b; - - diff = ca->start - cb->start; - return (diff < 0) ? -1 : (diff > 0) ? 1 : 0; + g_assert (CLASS (backend)->get_uids != NULL); + return (* CLASS (backend)->get_uids) (backend, type); } /** @@ -1005,67 +235,13 @@ compare_instance_func (gconstpointer a, gconstpointer b) GList * cal_backend_get_events_in_range (CalBackend *backend, time_t start, time_t end) { - CalBackendPrivate *priv; - struct build_event_list_closure c; - GList *l; - g_return_val_if_fail (backend != NULL, NULL); g_return_val_if_fail (IS_CAL_BACKEND (backend), NULL); - - priv = backend->priv; - g_return_val_if_fail (priv->loaded, NULL); - g_return_val_if_fail (start != -1 && end != -1, NULL); g_return_val_if_fail (start <= end, NULL); - c.backend = backend; - c.event_list = NULL; - - for (l = priv->events; l; l = l->next) { - iCalObject *ico; - - ico = l->data; - ical_object_generate_events (ico, start, end, - build_event_list, &c); - } - - c.event_list = g_list_sort (c.event_list, compare_instance_func); - - return c.event_list; -} - -/* Notifies a backend's clients that an object was updated */ -static void -notify_update (CalBackend *backend, const char *uid) -{ - CalBackendPrivate *priv; - GList *l; - - priv = backend->priv; - - for (l = priv->clients; l; l = l->next) { - Cal *cal; - - cal = CAL (l->data); - cal_notify_update (cal, uid); - } -} - -/* Notifies a backend's clients that an object was removed */ -static void -notify_remove (CalBackend *backend, const char *uid) -{ - CalBackendPrivate *priv; - GList *l; - - priv = backend->priv; - - for (l = priv->clients; l; l = l->next) { - Cal *cal; - - cal = CAL (l->data); - cal_notify_remove (cal, uid); - } + g_assert (CLASS (backend)->get_events_in_range != NULL); + return (* CLASS (backend)->get_events_in_range) (backend, start, end); } /** @@ -1081,45 +257,15 @@ notify_remove (CalBackend *backend, const char *uid) * Return value: TRUE on success, FALSE on being passed an invalid object. **/ gboolean -cal_backend_update_object (CalBackend *backend, const char *uid, - const char *calobj) +cal_backend_update_object (CalBackend *backend, const char *uid, const char *calobj) { - CalBackendPrivate *priv; - iCalObject *ico, *new_ico; - CalObjFindStatus status; - g_return_val_if_fail (backend != NULL, FALSE); g_return_val_if_fail (IS_CAL_BACKEND (backend), FALSE); - - priv = backend->priv; - g_return_val_if_fail (priv->loaded, FALSE); - g_return_val_if_fail (uid != NULL, FALSE); g_return_val_if_fail (calobj != NULL, FALSE); - /* Pull the object from the string */ - - status = ical_object_find_in_string (uid, calobj, &new_ico); - - if (status != CAL_OBJ_FIND_SUCCESS){ - return FALSE; - } - - /* Update the object */ - - ico = lookup_object (backend, uid); - - if (ico) - remove_object (backend, ico); - - add_object (backend, new_ico); - save (backend); - - /* FIXME: do the notification asynchronously */ - - notify_update (backend, new_ico->uid); - - return TRUE; + g_assert (CLASS (backend)->update_object != NULL); + return (* CLASS (backend)->update_object) (backend, uid, calobj); } /** @@ -1136,29 +282,26 @@ cal_backend_update_object (CalBackend *backend, const char *uid, gboolean cal_backend_remove_object (CalBackend *backend, const char *uid) { - CalBackendPrivate *priv; - iCalObject *ico; - g_return_val_if_fail (backend != NULL, FALSE); g_return_val_if_fail (IS_CAL_BACKEND (backend), FALSE); - - priv = backend->priv; - g_return_val_if_fail (priv->loaded, FALSE); - g_return_val_if_fail (uid != NULL, FALSE); - ico = lookup_object (backend, uid); - if (!ico){ - return FALSE; - } - - remove_object (backend, ico); - - priv->dirty = TRUE; - save (backend); + g_assert (CLASS (backend)->remove_object != NULL); + return (* CLASS (backend)->remove_object) (backend, uid); +} - /* FIXME: do the notification asynchronously */ - notify_remove (backend, uid); +/** + * cal_backend_last_client_gone: + * @backend: A calendar backend. + * + * Emits the "last_client_gone" signal of a calendar backend. This function is + * to be used only by backend implementations. + **/ +void +cal_backend_last_client_gone (CalBackend *backend) +{ + g_return_if_fail (backend != NULL); + g_return_if_fail (IS_CAL_BACKEND (backend)); - return TRUE; + gtk_signal_emit (GTK_OBJECT (backend), cal_backend_signals[LAST_CLIENT_GONE]); } |