aboutsummaryrefslogtreecommitdiffstats
path: root/calendar/pcs/cal-backend.c
diff options
context:
space:
mode:
authorFederico Mena Quintero <federico@helixcode.com>2000-05-09 00:58:27 +0800
committerFederico Mena Quintero <federico@src.gnome.org>2000-05-09 00:58:27 +0800
commit8160d7388e27c6f97e3ed96bc5d61fbf20ff2d16 (patch)
treeff1ff2df49f02deccc5424fdf6004f1b90e05553 /calendar/pcs/cal-backend.c
parentc2dde9ab64a79b483804cddbd9622827b4b2baf2 (diff)
downloadgsoc2013-evolution-8160d7388e27c6f97e3ed96bc5d61fbf20ff2d16.tar
gsoc2013-evolution-8160d7388e27c6f97e3ed96bc5d61fbf20ff2d16.tar.gz
gsoc2013-evolution-8160d7388e27c6f97e3ed96bc5d61fbf20ff2d16.tar.bz2
gsoc2013-evolution-8160d7388e27c6f97e3ed96bc5d61fbf20ff2d16.tar.lz
gsoc2013-evolution-8160d7388e27c6f97e3ed96bc5d61fbf20ff2d16.tar.xz
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.c933
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]);
}