aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--calendar/ChangeLog25
-rw-r--r--calendar/cal-backend.c344
-rw-r--r--calendar/cal-backend.h71
-rw-r--r--calendar/cal-common.h41
-rw-r--r--calendar/cal-factory.c45
-rw-r--r--calendar/cal.c152
-rw-r--r--calendar/cal.h17
-rw-r--r--calendar/evolution-calendar.idl2
-rw-r--r--calendar/idl/evolution-calendar.idl2
-rw-r--r--calendar/pcs/cal-backend.c344
-rw-r--r--calendar/pcs/cal-backend.h71
-rw-r--r--calendar/pcs/cal-common.h41
-rw-r--r--calendar/pcs/cal-factory.c45
-rw-r--r--calendar/pcs/cal.c152
-rw-r--r--calendar/pcs/cal.h17
15 files changed, 1147 insertions, 222 deletions
diff --git a/calendar/ChangeLog b/calendar/ChangeLog
index a934f5145e..3b32e80de3 100644
--- a/calendar/ChangeLog
+++ b/calendar/ChangeLog
@@ -1,5 +1,20 @@
2000-01-18 Federico Mena Quintero <federico@helixcode.com>
+ * cal-backend.c cal-backend.h: Moved the calendar backend here.
+ This is the actual calendar-handling object.
+ (load_from_vobject): Moved over from calendar.c. Modified to use
+ a CalBackend instead of the old Calendar structure.
+ (add_object): Likewise.
+
+ * cal.c: Now the Cal object is just a calendar client interface
+ object; we use it as a "viewport" onto a CalBackend. This also
+ lets us do correct resource management.
+
+ * cal-common.h: New file with common forward declarations; we
+ can't have circular dependencies between headers.
+
+2000-01-18 Federico Mena Quintero <federico@helixcode.com>
+
* cal-factory.c (cal_factory_load): Queue a load job.
(load_fn): Load job handler. Lookup the calendar by URI, load it
if it is not loaded, or just report it to the new listener if it is.
@@ -13,6 +28,16 @@
* cal-listener.c (Listener_cal_loaded): Ref the calendar GNOME
object. We unref it when the listener is destroyed.
+2000-01-17 Federico Mena Quintero <federico@helixcode.com>
+
+ The files from the gncal directory of the gnome-pim module on CVS
+ were moved here, to evolution/calendar, in preparation for the
+ Evolution work. The calendar is being split into a model/view
+ architecture. The model is a personal calendar server (PAS): it
+ provides storage, notification, and event generation; the
+ views/controllers are the calendar user agents and things like
+ Pilot synchronizers.
+
2000-01-11 Federico Mena Quintero <federico@helixcode.com>
* cal.c: Removed the CORBA listener methods, adjusted for the new
diff --git a/calendar/cal-backend.c b/calendar/cal-backend.c
new file mode 100644
index 0000000000..2fb523dc14
--- /dev/null
+++ b/calendar/cal-backend.c
@@ -0,0 +1,344 @@
+/* GNOME calendar backend
+ *
+ * Copyright (C) 2000 Helix Code, Inc.
+ *
+ * Author: Federico Mena-Quintero <federico@helixcode.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+#include "cal-backend.h"
+#include "../libversit/vcc.h"
+
+
+
+/* Private part of the CalBackend structure */
+typedef struct {
+ /* URI where the calendar data is stored */
+ GnomeVFSURI *uri;
+
+ /* List of Cal client interface objects, each with its listener */
+ GList *clients;
+
+ /* All events in the calendar and uri->event hash */
+ GList *events;
+ GHashTable *event_hash;
+
+ /* All TODOs in the calendar */
+ GList *todos;
+
+ /* All journals in the calendar */
+ GList *journals;
+
+ /* Whether a calendar has been loaded */
+ guint loaded : 1;
+} CalBackendPrivate;
+
+
+
+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;
+
+
+
+/**
+ * cal_backend_get_type:
+ * @void:
+ *
+ * Registers the #CalBackend class if necessary, and returns the type ID
+ * associated to it.
+ *
+ * Return value: The type ID of the #CalBackend class.
+ **/
+GtkType
+cal_backend_get_type (void)
+{
+ static GtkType cal_backend_type = 0;
+
+ if (!cal_backend_type) {
+ static const GtkTypeInfo cal_backend_info = {
+ "CalBackend",
+ sizeof (CalBackend),
+ sizeof (CalBackendClass),
+ (GtkClassInitFunc) cal_backend_class_init,
+ (GtkObjectInitFunc) cal_backend_init,
+ NULL, /* reserved_1 */
+ NULL, /* reserved_2 */
+ (GtkClassInitFunc) NULL
+ };
+
+ cal_backend_type = gtk_type_unique (GTK_TYPE_OBJECT, &cal_backend_info);
+ }
+
+ return cal_backend_type;
+}
+
+/* Class initialization function for the calendar backend */
+static void
+cal_backend_class_init (CalBackendClass *class)
+{
+ GtkObjectClass *object_class;
+
+ object_class = (GtkObjectClass *) class;
+
+ parent_class = gtk_type_class (GTK_TYPE_OBJECT);
+
+ 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;
+}
+
+/* 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;
+
+ /* FIXME: free stuff */
+
+ g_free (priv);
+
+ if (GTK_OBJECT_CLASS (parent_class)->destroy)
+ (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
+}
+
+
+
+/* Adds an object to the calendar backend */
+static void
+add_object (CalBackend *backend, iCalObject *ico)
+{
+ CalBackendPrivate *priv;
+
+ g_assert (ico != NULL);
+ g_assert (ico->uid != NULL);
+
+ priv = backend->priv;
+
+ ico->new = 0;
+ switch (ico->type) {
+ case ICAL_EVENT:
+ g_hash_table_insert (priv->event_hash, ico->uid, ico);
+ 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 ();
+ }
+
+ /* FIXME: things must come with an UID! */
+
+ if (!ico->uid) {
+ char buffer [80];
+
+ snprintf (buffer, sizeof (buffer), "GnomeCalendar-%ld\n", time (NULL));
+ ico->uid = g_strdup (buffer);
+ }
+#if 0
+ /* FIXME: gnomecal old code */
+ ico->last_mod = time (NULL);
+#endif
+}
+
+/* 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->event_hash == NULL);
+ priv->event_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? */
+ 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);
+
+ 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 (TYPE_CAL_BACKEND));
+}
+
+/**
+ * cal_backend_get_uri:
+ * @backend: A calendar backend.
+ *
+ * Queries the URI of a calendar backend, which must already have a loaded
+ * calendar.
+ *
+ * Return value: The URI where the calendar is stored.
+ **/
+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, NULL);
+
+ priv = backend->priv;
+ g_return_val_if_fail (priv->loaded, NULL);
+ g_assert (priv->uri != NULL);
+
+ return priv->uri;
+}
+
+/**
+ * cal_backend_add_cal:
+ * @backend: A calendar backend.
+ * @cal: A calendar client interface object.
+ *
+ * Adds a calendar client interface object to a calendar @backend. The calendar
+ * backend must already have a loaded calendar.
+ **/
+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));
+
+ priv->clients = g_list_prepend (priv->clients, cal);
+}
+
+/**
+ * cal_backend_load:
+ * @backend: A calendar backend.
+ * @str_uri: URI that contains the calendar data.
+ *
+ * Loads a calendar backend with data from a calendar stored at the specified
+ * URI.
+ *
+ * Return value: An operation result code.
+ **/
+CalBackendLoadResult
+cal_backend_load (CalBackend *backend, char *str_uri)
+{
+ CalBackendPrivate *priv;
+ GnomeVFSURI *uri;
+ VObject *vobject;
+
+ g_return_val_if_fail (backend != NULL, CAL_BACKEND_LOAD_ERROR);
+ g_return_val_if_fail (IS_CAL_BACKEND (backend), CAL_BACKEND_LOAD_ERROR);
+ g_return_val_if_fail (str_uri != NULL, CAL_BACKEND_LOAD_ERROR);
+
+ priv = backend->priv;
+ g_return_val_if_fail (!priv->loaded, CAL_BACKEND_LOAD_ERROR);
+
+ uri = gnome_vfs_uri_new (str_uri);
+ if (!uri)
+ return CAL_BACKEND_LOAD_ERROR;
+
+ vobject = Parse_MIME_FromURI (uri);
+ if (!vobject) {
+ gnome_vfs_uri_unref (uri);
+ return CAL_BACKEND_LOAD_ERROR;
+ }
+
+ load_from_vobject (backend, vobject);
+ cleanVObject (vobject);
+ cleanStrTbl ();
+
+ priv->uri = uri;
+ priv->loaded = TRUE;
+ return CAL_BACKEND_LOAD_SUCCESS;
+}
diff --git a/calendar/cal-backend.h b/calendar/cal-backend.h
new file mode 100644
index 0000000000..14cc903ae6
--- /dev/null
+++ b/calendar/cal-backend.h
@@ -0,0 +1,71 @@
+/* GNOME calendar backend
+ *
+ * Copyright (C) 2000 Helix Code, Inc.
+ *
+ * Author: Federico Mena-Quintero <federico@helixcode.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef CAL_BACKEND_H
+#define CAL_BACKEND_H
+
+#include <libgnome/gnome-defs.h>
+#include "gnome-calendar.h"
+#include "cal-common.h"
+#include "cal.h"
+
+BEGIN_GNOME_DECLS
+
+
+
+#define CAL_BACKEND_TYPE (cal_backend_get_type ())
+#define CAL_BACKEND(obj) (GTK_CHECK_CAST ((obj), CAL_BACKEND_TYPE, CalBackend))
+#define CAL_BACKEND_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), CAL_BACKEND_TYPE, \
+ CalBackendClass))
+#define IS_CAL_BACKEND(obj) (GTK_CHECK_TYPE ((obj), CAL_BACKEND_TYPE))
+#define IS_CAL_BACKEND_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), CAL_BACKEND_TYPE))
+
+typedef enum {
+ CAL_BACKEND_LOAD_SUCCESS, /* Loading OK */
+ CAL_BACKEND_LOAD_ERROR /* We need better error reporting in libversit */
+} CalBackendLoadResult;
+
+struct _CalBackend {
+ GtkObject object;
+
+ /* Private data */
+ gpointer priv;
+};
+
+struct _CalBackendClass {
+ GtkObjectClass parent_class;
+};
+
+GtkType cal_backend_get_type (void);
+
+CalBackend *cal_backend_new (void);
+
+GnomeVFSURI *cal_backend_get_uri (CalBackend *backend);
+
+void cal_backend_add_cal (CalBackend *backend, Cal *cal);
+
+CalBackendLoadResult cal_backend_load (CalBackend *backend, char *str_uri);
+
+
+
+END_GNOME_DECLS
+
+#endif
diff --git a/calendar/cal-common.h b/calendar/cal-common.h
new file mode 100644
index 0000000000..4177dbb096
--- /dev/null
+++ b/calendar/cal-common.h
@@ -0,0 +1,41 @@
+/* GNOME calendar server - common declarations
+ *
+ * Copyright (C) 2000 Helix Code, Inc.
+ *
+ * Author: Federico Mena-Quintero <federico@helixcode.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef CAL_COMMON_H
+#define CAL_COMMON_H
+
+#include <libgnome/gnome-defs.h>
+
+BEGIN_GNOME_DECLS
+
+
+
+typedef struct _CalBackend CalBackend;
+typedef struct _CalBackendClass CalBackendClass;
+
+typedef struct _Cal Cal;
+typedef struct _CalClass CalClass;
+
+
+
+END_GNOME_DECLS
+
+#endif
diff --git a/calendar/cal-factory.c b/calendar/cal-factory.c
index ac1043bc10..053baebe5c 100644
--- a/calendar/cal-factory.c
+++ b/calendar/cal-factory.c
@@ -187,20 +187,6 @@ cal_factory_get_epv (void)
return epv;
}
-/* Returns whether a CORBA object is nil */
-static gboolean
-corba_object_is_nil (CORBA_Object object)
-{
- CORBA_Environment ev;
- gboolean retval;
-
- CORBA_exception_init (&ev);
- retval = CORBA_Object_is_nil (object, &ev);
- CORBA_exception_free (&ev);
-
- return retval;
-}
-
/* Loading and creating calendars */
@@ -288,7 +274,6 @@ cal_factory_construct (CalFactory *factory, GNOME_Calendar_CalFactory corba_fact
{
g_return_val_if_fail (factory != NULL, NULL);
g_return_val_if_fail (IS_CAL_FACTORY (factory), NULL);
- g_return_val_if_fail (!corba_object_is_nil (corba_factory), NULL);
gnome_object_construct (GNOME_OBJECT (factory), corba_factory);
return factory;
@@ -319,6 +304,7 @@ cal_factory_corba_object_create (GnomeObject *object)
CORBA_exception_init (&ev);
POA_GNOME_Calendar_CalFactory__init ((PortableServer_Servant) servant, &ev);
if (ev._major != CORBA_NO_EXCEPTION) {
+ g_message ("cal_factory_corba_object_create(): could not init the servant");
g_free (servant);
CORBA_exception_free (&ev);
return CORBA_OBJECT_NIL;
@@ -341,15 +327,25 @@ CalFactory *
cal_factory_new (void)
{
CalFactory *factory;
+ CORBA_Environment ev;
GNOME_Calendar_CalFactory corba_factory;
+ gboolean retval;
factory = gtk_type_new (CAL_FACTORY_TYPE);
+
corba_factory = cal_factory_corba_object_create (GNOME_OBJECT (factory));
- if (corba_object_is_nil (corba_factory)) {
- gtk_object_destroy (factory);
+ CORBA_exception_init (&ev);
+ retval = CORBA_Object_is_nil (corba_factory, &ev);
+
+ if (ev._major != CORBA_NO_EXCEPTION || retval) {
+ g_message ("cal_factory_new(): could not create the CORBA object");
+ gtk_object_unref (factory);
+ CORBA_exception_free (&ev);
return NULL;
}
+ CORBA_exception_free (&ev);
+
return cal_factory_construct (factory, corba_factory);
}
@@ -358,18 +354,25 @@ cal_factory_load (CalFactory *factory, const char *uri, GNOME_Calendar_Listener
{
LoadCreateJobData *jd;
CORBA_Environment ev;
+ GNOME_Calendar_Listener listener_copy;
CORBA_exception_init (&ev);
+ listener_copy = CORBA_Object_duplicate (listener, &ev);
+ if (ev._major != CORBA_NO_EXCEPTION) {
+ g_message ("cal_factory_load(): could not duplicate the listener");
+ CORBA_exception_free (&ev);
+ return;
+ }
+
+ CORBA_exception_free (&ev);
+
jd = g_new (LoadCreateJobData, 1);
jd->factory = factory;
jd->uri = g_strdup (uri);
- jd->listener = CORBA_Object_duplicate (listener, &ev);
- GNOME_Unknown_ref (jd->listener);
+ jd->listener = listener_copy;
job_add (load_fn, jd);
-
- CORBA_exception_free (&ev);
}
void
diff --git a/calendar/cal.c b/calendar/cal.c
index 3394ead5d8..26c0581ff7 100644
--- a/calendar/cal.c
+++ b/calendar/cal.c
@@ -1,4 +1,4 @@
-/* GNOME calendar object
+/* GNOME calendar client interface object
*
* Copyright (C) 2000 Helix Code, Inc.
*
@@ -21,16 +21,17 @@
#include <config.h>
#include "cal.h"
+#include "cal-backend.h"
/* Private part of the Cal structure */
typedef struct {
- /* The URI where this calendar is stored */
- char *uri;
+ /* Our backend */
+ CalBackend *backend;
- /* List of listeners for this calendar */
- GList *listeners;
+ /* Listener on the client we notify */
+ GNOME_Calendar_listener listener;
} CalPrivate;
@@ -71,7 +72,7 @@ cal_get_type (void)
(GtkClassInitFunc) NULL
};
- cal_type = gtk_type_unique (gnome_object_get_type (), &cal_info);
+ cal_type = gtk_type_unique (GNOME_OBJECT_TYPE, &cal_info);
}
return cal_type;
@@ -93,7 +94,7 @@ cal_class_init (CalClass *class)
object_class = (GtkObjectClass *) class;
- parent_class = gtk_type_class (gnome_object_get_type ());
+ parent_class = gtk_type_class (GNOME_OBJECT_TYPE);
object_class->destroy = cal_destroy;
@@ -108,6 +109,8 @@ cal_init (Cal *cal)
priv = g_new0 (CalPrivate, 1);
cal->priv = priv;
+
+ priv->listener = CORBA_OBJECT_NIL;
}
/* Destroy handler for the calendar */
@@ -183,35 +186,47 @@ cal_get_epv (void)
-/* Returns whether a CORBA object is nil */
-static gboolean
-corba_object_is_nil (CORBA_Object object)
-{
- CORBA_Environment ev;
- gboolean retval;
-
- CORBA_exception_init (&ev);
- retval = CORBA_Object_is_nil (object, &ev);
- CORBA_exception_free (&ev);
-
- return retval;
-}
-
/**
* cal_construct:
- * @cal: A calendar.
+ * @cal: A calendar client interface.
* @corba_cal: CORBA object for the calendar.
+ * @backend: Calendar backend that this @cal presents an interface to.
+ * @listener: Calendar listener for notification.
*
- * Constructs a calendar by binding the corresponding CORBA object to it.
+ * Constructs a calendar client interface object by binding the corresponding
+ * CORBA object to it. The calendar interface is bound to the specified
+ * @backend, and will notify the @listener about changes to the calendar.
*
* Return value: The same object as the @cal argument.
**/
Cal *
-cal_construct (Cal *cal, GNOME_Calendar_Cal corba_cal)
+cal_construct (Cal *cal,
+ GNOME_Calendar_Cal corba_cal,
+ CalBackend *backend,
+ GNOME_Calendar_Listener listener)
{
+ CalPrivate *priv;
+ CORBA_Environment ev;
+
g_return_val_if_fail (cal != NULL, NULL);
g_return_val_if_fail (IS_CAL (cal), NULL);
- g_return_val_if_fail (!corba_object_is_nil (corba_cal), NULL);
+ g_return_val_if_fail (backend != NULL);
+ g_return_val_if_fail (IS_CAL_BACKEND (backend));
+
+ priv = cal->priv;
+
+ CORBA_exception_init (&ev);
+ priv->listener = CORBA_Object_duplicate (listener, &ev);
+ if (ev._major != CORBA_NO_EXCEPTION) {
+ g_message ("cal_construct: could not duplicate the listener");
+ priv->listener = CORBA_OBJECT_NIL;
+ CORBA_exception_free (&ev);
+ return NULL;
+ }
+
+ CORBA_exception_free (&ev);
+
+ priv->backend = backend;
gnome_object_construct (GNOME_OBJECT (cal), corba_cal);
return cal;
@@ -222,7 +237,7 @@ cal_construct (Cal *cal, GNOME_Calendar_Cal corba_cal)
* @object: #GnomeObject that will wrap the CORBA object.
*
* Creates and activates the CORBA object that is wrapped by the specified
- * calendar @object.
+ * calendar client interface @object.
*
* Return value: An activated object reference or #CORBA_OBJECT_NIL in case of
* failure.
@@ -242,6 +257,7 @@ cal_corba_object_create (GnomeObject *object)
CORBA_exception_init (&ev);
POA_GNOME_Calendar_Cal__init ((PortableServer_Servant) servant, &ev);
if (ev._major != CORBA_NO_EXCEPTION) {
+ g_message ("cal_corba_object_create(): could not init the servant");
g_free (servant);
CORBA_exception_free (&ev);
return CORBA_OBJECT_NIL;
@@ -252,69 +268,47 @@ cal_corba_object_create (GnomeObject *object)
}
/**
- * cal_add_listener:
- * @cal: A calendar.
- * @listener: A listener.
+ * cal_new:
+ * @backend: A calendar backend.
+ * @listener: A calendar listener.
+ *
+ * Creates a new calendar client interface object and binds it to the specified
+ * @backend and @listener objects.
*
- * Adds a listener for changes to a calendar. The specified listener object
- * will be used for notification when objects are added, removed, or changed in
- * the calendar.
+ * Return value: A newly-created #Cal calendar client interface object, or NULL
+ * if its corresponding CORBA object could not be created.
**/
-void
-cal_add_listener (Cal *cal, GNOME_Calendar_Listener listener)
+Cal *
+cal_new (CalBackend *backend, GNOME_Calendar_Listener listener)
{
- CalPrivate *priv;
+ Cal *cal, *retval;
+ GNOME_Calendar_Cal corba_cal;
CORBA_Environment ev;
+ gboolean ret;
- g_return_if_fail (cal != NULL);
- g_return_if_fail (IS_CAL (cal));
- g_return_if_fail (!corba_object_is_nil (listener));
+ g_return_val_if_fail (backend != NULL);
+ g_return_val_if_fail (IS_CAL_BACKEND (backend));
- priv = cal->priv;
+ cal = CAL (gtk_type_new (CAL_TYPE));
+ corba_cal = cal_corba_object_create (GNOME_OBJECT (cal));
CORBA_exception_init (&ev);
-
- GNOME_Unknown_ref (listener, &ev);
- priv->listeners = g_list_prepend (priv->listeners, CORBA_Object_duplicate (listener, &ev));
+ ret = CORBA_object_is_nil (corba_cal, &ev);
+ if (ev._major != CORBA_NO_EXCEPTION || ret) {
+ g_message ("cal_new(): could not create the CORBA object");
+ gtk_object_unref (GTK_OBJECT (cal));
+ CORBA_exception_free (&ev);
+ return NULL;
+ }
CORBA_exception_free (&ev);
-}
-/**
- * cal_remove_listener:
- * @cal: A calendar.
- * @listener: A listener.
- *
- * Removes a listener from a calendar so that no more notification events will
- * be sent to the listener.
- **/
-void
-cal_remove_listener (Cal *cal, GNOME_Calendar_Listener listener)
-{
- CalPrivate *priv;
- CORBA_Environment ev;
- GList *l;
-
- g_return_if_fail (cal != NULL);
- g_return_if_fail (IS_CAL (cal));
-
- priv = cal->priv;
-
- CORBA_exception_init (&ev);
-
- /* FIXME: CORBA_Object_is_equivalent() is not what one thinks. This
- * code could fail in situtations subtle enough that I don't understand
- * them. Someone has to figure out the standard CORBA idiom for
- * listeners or notification.
- */
- for (l = priv->listeners; l; l = l->next)
- if (CORBA_Object_is_equivalent (listener, l->data)) {
- GNOME_Unknown_unref (listener, &ev);
- CORBA_Object_release (listener, &ev);
- priv->listeners = g_list_remove_link (priv->listeners, l);
- g_list_free_1 (l);
- break;
- }
+ retval = cal_construct (cal, corba_cal, backend, listener);
+ if (!retval) {
+ g_message ("cal_new(): could not construct the calendar client interface");
+ gtk_object_unref (cal);
+ return NULL;
+ }
- CORBA_exception_free (&ev);
+ return retval;
}
diff --git a/calendar/cal.h b/calendar/cal.h
index 959331595c..80d349d44d 100644
--- a/calendar/cal.h
+++ b/calendar/cal.h
@@ -1,4 +1,4 @@
-/* GNOME calendar object
+/* GNOME calendar client interface object
*
* Copyright (C) 2000 Helix Code, Inc.
*
@@ -25,6 +25,7 @@
#include <libgnome/gnome-defs.h>
#include <bonobo/gnome-object.h>
#include "gnome-calendar.h"
+#include "cal-common.h"
BEGIN_GNOME_DECLS
@@ -36,9 +37,6 @@ BEGIN_GNOME_DECLS
#define IS_CAL(obj) (GTK_CHECK_TYPE ((obj), CAL_TYPE))
#define IS_CAL_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), CAL_TYPE))
-typedef struct _Cal Cal;
-typedef struct _CalClass CalClass;
-
struct _Cal {
GnomeObject object;
@@ -52,14 +50,13 @@ struct _CalClass {
GtkType cal_get_type (void);
-Cal *cal_construct (Cal *cal, GNOME_Calendar_Cal corba_cal);
+Cal *cal_construct (Cal *cal,
+ GNOME_Calendar_Cal corba_cal,
+ CalBackend *backend,
+ GNOME_Calendar_Listener listener);
GNOME_Calendar_Cal cal_corba_object_create (GnomeObject *object);
-Cal *cal_new (char *uri);
-Cal *cal_new_from_file (char *uri);
-
-void cal_add_listener (Cal *cal, GNOME_Calendar_Listener listener);
-void cal_remove_listener (Cal *cal, GNOME_Calendar_Listener listener);
+Cal *cal_new (CalBackend *backend, GNOME_Calendar_Listener listener);
POA_GNOME_Calendar_Cal__epv *cal_get_epv (void);
diff --git a/calendar/evolution-calendar.idl b/calendar/evolution-calendar.idl
index 77d4c1193c..9ff87f62f6 100644
--- a/calendar/evolution-calendar.idl
+++ b/calendar/evolution-calendar.idl
@@ -25,7 +25,7 @@ module Calendar {
interface Listener;
- /* A calendar handle */
+ /* Calendar client interface */
interface Cal : Unknown {
/* A calendar is identified by its URI */
readonly attribute string uri;
diff --git a/calendar/idl/evolution-calendar.idl b/calendar/idl/evolution-calendar.idl
index 77d4c1193c..9ff87f62f6 100644
--- a/calendar/idl/evolution-calendar.idl
+++ b/calendar/idl/evolution-calendar.idl
@@ -25,7 +25,7 @@ module Calendar {
interface Listener;
- /* A calendar handle */
+ /* Calendar client interface */
interface Cal : Unknown {
/* A calendar is identified by its URI */
readonly attribute string uri;
diff --git a/calendar/pcs/cal-backend.c b/calendar/pcs/cal-backend.c
new file mode 100644
index 0000000000..2fb523dc14
--- /dev/null
+++ b/calendar/pcs/cal-backend.c
@@ -0,0 +1,344 @@
+/* GNOME calendar backend
+ *
+ * Copyright (C) 2000 Helix Code, Inc.
+ *
+ * Author: Federico Mena-Quintero <federico@helixcode.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+#include "cal-backend.h"
+#include "../libversit/vcc.h"
+
+
+
+/* Private part of the CalBackend structure */
+typedef struct {
+ /* URI where the calendar data is stored */
+ GnomeVFSURI *uri;
+
+ /* List of Cal client interface objects, each with its listener */
+ GList *clients;
+
+ /* All events in the calendar and uri->event hash */
+ GList *events;
+ GHashTable *event_hash;
+
+ /* All TODOs in the calendar */
+ GList *todos;
+
+ /* All journals in the calendar */
+ GList *journals;
+
+ /* Whether a calendar has been loaded */
+ guint loaded : 1;
+} CalBackendPrivate;
+
+
+
+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;
+
+
+
+/**
+ * cal_backend_get_type:
+ * @void:
+ *
+ * Registers the #CalBackend class if necessary, and returns the type ID
+ * associated to it.
+ *
+ * Return value: The type ID of the #CalBackend class.
+ **/
+GtkType
+cal_backend_get_type (void)
+{
+ static GtkType cal_backend_type = 0;
+
+ if (!cal_backend_type) {
+ static const GtkTypeInfo cal_backend_info = {
+ "CalBackend",
+ sizeof (CalBackend),
+ sizeof (CalBackendClass),
+ (GtkClassInitFunc) cal_backend_class_init,
+ (GtkObjectInitFunc) cal_backend_init,
+ NULL, /* reserved_1 */
+ NULL, /* reserved_2 */
+ (GtkClassInitFunc) NULL
+ };
+
+ cal_backend_type = gtk_type_unique (GTK_TYPE_OBJECT, &cal_backend_info);
+ }
+
+ return cal_backend_type;
+}
+
+/* Class initialization function for the calendar backend */
+static void
+cal_backend_class_init (CalBackendClass *class)
+{
+ GtkObjectClass *object_class;
+
+ object_class = (GtkObjectClass *) class;
+
+ parent_class = gtk_type_class (GTK_TYPE_OBJECT);
+
+ 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;
+}
+
+/* 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;
+
+ /* FIXME: free stuff */
+
+ g_free (priv);
+
+ if (GTK_OBJECT_CLASS (parent_class)->destroy)
+ (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
+}
+
+
+
+/* Adds an object to the calendar backend */
+static void
+add_object (CalBackend *backend, iCalObject *ico)
+{
+ CalBackendPrivate *priv;
+
+ g_assert (ico != NULL);
+ g_assert (ico->uid != NULL);
+
+ priv = backend->priv;
+
+ ico->new = 0;
+ switch (ico->type) {
+ case ICAL_EVENT:
+ g_hash_table_insert (priv->event_hash, ico->uid, ico);
+ 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 ();
+ }
+
+ /* FIXME: things must come with an UID! */
+
+ if (!ico->uid) {
+ char buffer [80];
+
+ snprintf (buffer, sizeof (buffer), "GnomeCalendar-%ld\n", time (NULL));
+ ico->uid = g_strdup (buffer);
+ }
+#if 0
+ /* FIXME: gnomecal old code */
+ ico->last_mod = time (NULL);
+#endif
+}
+
+/* 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->event_hash == NULL);
+ priv->event_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? */
+ 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);
+
+ 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 (TYPE_CAL_BACKEND));
+}
+
+/**
+ * cal_backend_get_uri:
+ * @backend: A calendar backend.
+ *
+ * Queries the URI of a calendar backend, which must already have a loaded
+ * calendar.
+ *
+ * Return value: The URI where the calendar is stored.
+ **/
+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, NULL);
+
+ priv = backend->priv;
+ g_return_val_if_fail (priv->loaded, NULL);
+ g_assert (priv->uri != NULL);
+
+ return priv->uri;
+}
+
+/**
+ * cal_backend_add_cal:
+ * @backend: A calendar backend.
+ * @cal: A calendar client interface object.
+ *
+ * Adds a calendar client interface object to a calendar @backend. The calendar
+ * backend must already have a loaded calendar.
+ **/
+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));
+
+ priv->clients = g_list_prepend (priv->clients, cal);
+}
+
+/**
+ * cal_backend_load:
+ * @backend: A calendar backend.
+ * @str_uri: URI that contains the calendar data.
+ *
+ * Loads a calendar backend with data from a calendar stored at the specified
+ * URI.
+ *
+ * Return value: An operation result code.
+ **/
+CalBackendLoadResult
+cal_backend_load (CalBackend *backend, char *str_uri)
+{
+ CalBackendPrivate *priv;
+ GnomeVFSURI *uri;
+ VObject *vobject;
+
+ g_return_val_if_fail (backend != NULL, CAL_BACKEND_LOAD_ERROR);
+ g_return_val_if_fail (IS_CAL_BACKEND (backend), CAL_BACKEND_LOAD_ERROR);
+ g_return_val_if_fail (str_uri != NULL, CAL_BACKEND_LOAD_ERROR);
+
+ priv = backend->priv;
+ g_return_val_if_fail (!priv->loaded, CAL_BACKEND_LOAD_ERROR);
+
+ uri = gnome_vfs_uri_new (str_uri);
+ if (!uri)
+ return CAL_BACKEND_LOAD_ERROR;
+
+ vobject = Parse_MIME_FromURI (uri);
+ if (!vobject) {
+ gnome_vfs_uri_unref (uri);
+ return CAL_BACKEND_LOAD_ERROR;
+ }
+
+ load_from_vobject (backend, vobject);
+ cleanVObject (vobject);
+ cleanStrTbl ();
+
+ priv->uri = uri;
+ priv->loaded = TRUE;
+ return CAL_BACKEND_LOAD_SUCCESS;
+}
diff --git a/calendar/pcs/cal-backend.h b/calendar/pcs/cal-backend.h
new file mode 100644
index 0000000000..14cc903ae6
--- /dev/null
+++ b/calendar/pcs/cal-backend.h
@@ -0,0 +1,71 @@
+/* GNOME calendar backend
+ *
+ * Copyright (C) 2000 Helix Code, Inc.
+ *
+ * Author: Federico Mena-Quintero <federico@helixcode.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef CAL_BACKEND_H
+#define CAL_BACKEND_H
+
+#include <libgnome/gnome-defs.h>
+#include "gnome-calendar.h"
+#include "cal-common.h"
+#include "cal.h"
+
+BEGIN_GNOME_DECLS
+
+
+
+#define CAL_BACKEND_TYPE (cal_backend_get_type ())
+#define CAL_BACKEND(obj) (GTK_CHECK_CAST ((obj), CAL_BACKEND_TYPE, CalBackend))
+#define CAL_BACKEND_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), CAL_BACKEND_TYPE, \
+ CalBackendClass))
+#define IS_CAL_BACKEND(obj) (GTK_CHECK_TYPE ((obj), CAL_BACKEND_TYPE))
+#define IS_CAL_BACKEND_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), CAL_BACKEND_TYPE))
+
+typedef enum {
+ CAL_BACKEND_LOAD_SUCCESS, /* Loading OK */
+ CAL_BACKEND_LOAD_ERROR /* We need better error reporting in libversit */
+} CalBackendLoadResult;
+
+struct _CalBackend {
+ GtkObject object;
+
+ /* Private data */
+ gpointer priv;
+};
+
+struct _CalBackendClass {
+ GtkObjectClass parent_class;
+};
+
+GtkType cal_backend_get_type (void);
+
+CalBackend *cal_backend_new (void);
+
+GnomeVFSURI *cal_backend_get_uri (CalBackend *backend);
+
+void cal_backend_add_cal (CalBackend *backend, Cal *cal);
+
+CalBackendLoadResult cal_backend_load (CalBackend *backend, char *str_uri);
+
+
+
+END_GNOME_DECLS
+
+#endif
diff --git a/calendar/pcs/cal-common.h b/calendar/pcs/cal-common.h
new file mode 100644
index 0000000000..4177dbb096
--- /dev/null
+++ b/calendar/pcs/cal-common.h
@@ -0,0 +1,41 @@
+/* GNOME calendar server - common declarations
+ *
+ * Copyright (C) 2000 Helix Code, Inc.
+ *
+ * Author: Federico Mena-Quintero <federico@helixcode.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef CAL_COMMON_H
+#define CAL_COMMON_H
+
+#include <libgnome/gnome-defs.h>
+
+BEGIN_GNOME_DECLS
+
+
+
+typedef struct _CalBackend CalBackend;
+typedef struct _CalBackendClass CalBackendClass;
+
+typedef struct _Cal Cal;
+typedef struct _CalClass CalClass;
+
+
+
+END_GNOME_DECLS
+
+#endif
diff --git a/calendar/pcs/cal-factory.c b/calendar/pcs/cal-factory.c
index ac1043bc10..053baebe5c 100644
--- a/calendar/pcs/cal-factory.c
+++ b/calendar/pcs/cal-factory.c
@@ -187,20 +187,6 @@ cal_factory_get_epv (void)
return epv;
}
-/* Returns whether a CORBA object is nil */
-static gboolean
-corba_object_is_nil (CORBA_Object object)
-{
- CORBA_Environment ev;
- gboolean retval;
-
- CORBA_exception_init (&ev);
- retval = CORBA_Object_is_nil (object, &ev);
- CORBA_exception_free (&ev);
-
- return retval;
-}
-
/* Loading and creating calendars */
@@ -288,7 +274,6 @@ cal_factory_construct (CalFactory *factory, GNOME_Calendar_CalFactory corba_fact
{
g_return_val_if_fail (factory != NULL, NULL);
g_return_val_if_fail (IS_CAL_FACTORY (factory), NULL);
- g_return_val_if_fail (!corba_object_is_nil (corba_factory), NULL);
gnome_object_construct (GNOME_OBJECT (factory), corba_factory);
return factory;
@@ -319,6 +304,7 @@ cal_factory_corba_object_create (GnomeObject *object)
CORBA_exception_init (&ev);
POA_GNOME_Calendar_CalFactory__init ((PortableServer_Servant) servant, &ev);
if (ev._major != CORBA_NO_EXCEPTION) {
+ g_message ("cal_factory_corba_object_create(): could not init the servant");
g_free (servant);
CORBA_exception_free (&ev);
return CORBA_OBJECT_NIL;
@@ -341,15 +327,25 @@ CalFactory *
cal_factory_new (void)
{
CalFactory *factory;
+ CORBA_Environment ev;
GNOME_Calendar_CalFactory corba_factory;
+ gboolean retval;
factory = gtk_type_new (CAL_FACTORY_TYPE);
+
corba_factory = cal_factory_corba_object_create (GNOME_OBJECT (factory));
- if (corba_object_is_nil (corba_factory)) {
- gtk_object_destroy (factory);
+ CORBA_exception_init (&ev);
+ retval = CORBA_Object_is_nil (corba_factory, &ev);
+
+ if (ev._major != CORBA_NO_EXCEPTION || retval) {
+ g_message ("cal_factory_new(): could not create the CORBA object");
+ gtk_object_unref (factory);
+ CORBA_exception_free (&ev);
return NULL;
}
+ CORBA_exception_free (&ev);
+
return cal_factory_construct (factory, corba_factory);
}
@@ -358,18 +354,25 @@ cal_factory_load (CalFactory *factory, const char *uri, GNOME_Calendar_Listener
{
LoadCreateJobData *jd;
CORBA_Environment ev;
+ GNOME_Calendar_Listener listener_copy;
CORBA_exception_init (&ev);
+ listener_copy = CORBA_Object_duplicate (listener, &ev);
+ if (ev._major != CORBA_NO_EXCEPTION) {
+ g_message ("cal_factory_load(): could not duplicate the listener");
+ CORBA_exception_free (&ev);
+ return;
+ }
+
+ CORBA_exception_free (&ev);
+
jd = g_new (LoadCreateJobData, 1);
jd->factory = factory;
jd->uri = g_strdup (uri);
- jd->listener = CORBA_Object_duplicate (listener, &ev);
- GNOME_Unknown_ref (jd->listener);
+ jd->listener = listener_copy;
job_add (load_fn, jd);
-
- CORBA_exception_free (&ev);
}
void
diff --git a/calendar/pcs/cal.c b/calendar/pcs/cal.c
index 3394ead5d8..26c0581ff7 100644
--- a/calendar/pcs/cal.c
+++ b/calendar/pcs/cal.c
@@ -1,4 +1,4 @@
-/* GNOME calendar object
+/* GNOME calendar client interface object
*
* Copyright (C) 2000 Helix Code, Inc.
*
@@ -21,16 +21,17 @@
#include <config.h>
#include "cal.h"
+#include "cal-backend.h"
/* Private part of the Cal structure */
typedef struct {
- /* The URI where this calendar is stored */
- char *uri;
+ /* Our backend */
+ CalBackend *backend;
- /* List of listeners for this calendar */
- GList *listeners;
+ /* Listener on the client we notify */
+ GNOME_Calendar_listener listener;
} CalPrivate;
@@ -71,7 +72,7 @@ cal_get_type (void)
(GtkClassInitFunc) NULL
};
- cal_type = gtk_type_unique (gnome_object_get_type (), &cal_info);
+ cal_type = gtk_type_unique (GNOME_OBJECT_TYPE, &cal_info);
}
return cal_type;
@@ -93,7 +94,7 @@ cal_class_init (CalClass *class)
object_class = (GtkObjectClass *) class;
- parent_class = gtk_type_class (gnome_object_get_type ());
+ parent_class = gtk_type_class (GNOME_OBJECT_TYPE);
object_class->destroy = cal_destroy;
@@ -108,6 +109,8 @@ cal_init (Cal *cal)
priv = g_new0 (CalPrivate, 1);
cal->priv = priv;
+
+ priv->listener = CORBA_OBJECT_NIL;
}
/* Destroy handler for the calendar */
@@ -183,35 +186,47 @@ cal_get_epv (void)
-/* Returns whether a CORBA object is nil */
-static gboolean
-corba_object_is_nil (CORBA_Object object)
-{
- CORBA_Environment ev;
- gboolean retval;
-
- CORBA_exception_init (&ev);
- retval = CORBA_Object_is_nil (object, &ev);
- CORBA_exception_free (&ev);
-
- return retval;
-}
-
/**
* cal_construct:
- * @cal: A calendar.
+ * @cal: A calendar client interface.
* @corba_cal: CORBA object for the calendar.
+ * @backend: Calendar backend that this @cal presents an interface to.
+ * @listener: Calendar listener for notification.
*
- * Constructs a calendar by binding the corresponding CORBA object to it.
+ * Constructs a calendar client interface object by binding the corresponding
+ * CORBA object to it. The calendar interface is bound to the specified
+ * @backend, and will notify the @listener about changes to the calendar.
*
* Return value: The same object as the @cal argument.
**/
Cal *
-cal_construct (Cal *cal, GNOME_Calendar_Cal corba_cal)
+cal_construct (Cal *cal,
+ GNOME_Calendar_Cal corba_cal,
+ CalBackend *backend,
+ GNOME_Calendar_Listener listener)
{
+ CalPrivate *priv;
+ CORBA_Environment ev;
+
g_return_val_if_fail (cal != NULL, NULL);
g_return_val_if_fail (IS_CAL (cal), NULL);
- g_return_val_if_fail (!corba_object_is_nil (corba_cal), NULL);
+ g_return_val_if_fail (backend != NULL);
+ g_return_val_if_fail (IS_CAL_BACKEND (backend));
+
+ priv = cal->priv;
+
+ CORBA_exception_init (&ev);
+ priv->listener = CORBA_Object_duplicate (listener, &ev);
+ if (ev._major != CORBA_NO_EXCEPTION) {
+ g_message ("cal_construct: could not duplicate the listener");
+ priv->listener = CORBA_OBJECT_NIL;
+ CORBA_exception_free (&ev);
+ return NULL;
+ }
+
+ CORBA_exception_free (&ev);
+
+ priv->backend = backend;
gnome_object_construct (GNOME_OBJECT (cal), corba_cal);
return cal;
@@ -222,7 +237,7 @@ cal_construct (Cal *cal, GNOME_Calendar_Cal corba_cal)
* @object: #GnomeObject that will wrap the CORBA object.
*
* Creates and activates the CORBA object that is wrapped by the specified
- * calendar @object.
+ * calendar client interface @object.
*
* Return value: An activated object reference or #CORBA_OBJECT_NIL in case of
* failure.
@@ -242,6 +257,7 @@ cal_corba_object_create (GnomeObject *object)
CORBA_exception_init (&ev);
POA_GNOME_Calendar_Cal__init ((PortableServer_Servant) servant, &ev);
if (ev._major != CORBA_NO_EXCEPTION) {
+ g_message ("cal_corba_object_create(): could not init the servant");
g_free (servant);
CORBA_exception_free (&ev);
return CORBA_OBJECT_NIL;
@@ -252,69 +268,47 @@ cal_corba_object_create (GnomeObject *object)
}
/**
- * cal_add_listener:
- * @cal: A calendar.
- * @listener: A listener.
+ * cal_new:
+ * @backend: A calendar backend.
+ * @listener: A calendar listener.
+ *
+ * Creates a new calendar client interface object and binds it to the specified
+ * @backend and @listener objects.
*
- * Adds a listener for changes to a calendar. The specified listener object
- * will be used for notification when objects are added, removed, or changed in
- * the calendar.
+ * Return value: A newly-created #Cal calendar client interface object, or NULL
+ * if its corresponding CORBA object could not be created.
**/
-void
-cal_add_listener (Cal *cal, GNOME_Calendar_Listener listener)
+Cal *
+cal_new (CalBackend *backend, GNOME_Calendar_Listener listener)
{
- CalPrivate *priv;
+ Cal *cal, *retval;
+ GNOME_Calendar_Cal corba_cal;
CORBA_Environment ev;
+ gboolean ret;
- g_return_if_fail (cal != NULL);
- g_return_if_fail (IS_CAL (cal));
- g_return_if_fail (!corba_object_is_nil (listener));
+ g_return_val_if_fail (backend != NULL);
+ g_return_val_if_fail (IS_CAL_BACKEND (backend));
- priv = cal->priv;
+ cal = CAL (gtk_type_new (CAL_TYPE));
+ corba_cal = cal_corba_object_create (GNOME_OBJECT (cal));
CORBA_exception_init (&ev);
-
- GNOME_Unknown_ref (listener, &ev);
- priv->listeners = g_list_prepend (priv->listeners, CORBA_Object_duplicate (listener, &ev));
+ ret = CORBA_object_is_nil (corba_cal, &ev);
+ if (ev._major != CORBA_NO_EXCEPTION || ret) {
+ g_message ("cal_new(): could not create the CORBA object");
+ gtk_object_unref (GTK_OBJECT (cal));
+ CORBA_exception_free (&ev);
+ return NULL;
+ }
CORBA_exception_free (&ev);
-}
-/**
- * cal_remove_listener:
- * @cal: A calendar.
- * @listener: A listener.
- *
- * Removes a listener from a calendar so that no more notification events will
- * be sent to the listener.
- **/
-void
-cal_remove_listener (Cal *cal, GNOME_Calendar_Listener listener)
-{
- CalPrivate *priv;
- CORBA_Environment ev;
- GList *l;
-
- g_return_if_fail (cal != NULL);
- g_return_if_fail (IS_CAL (cal));
-
- priv = cal->priv;
-
- CORBA_exception_init (&ev);
-
- /* FIXME: CORBA_Object_is_equivalent() is not what one thinks. This
- * code could fail in situtations subtle enough that I don't understand
- * them. Someone has to figure out the standard CORBA idiom for
- * listeners or notification.
- */
- for (l = priv->listeners; l; l = l->next)
- if (CORBA_Object_is_equivalent (listener, l->data)) {
- GNOME_Unknown_unref (listener, &ev);
- CORBA_Object_release (listener, &ev);
- priv->listeners = g_list_remove_link (priv->listeners, l);
- g_list_free_1 (l);
- break;
- }
+ retval = cal_construct (cal, corba_cal, backend, listener);
+ if (!retval) {
+ g_message ("cal_new(): could not construct the calendar client interface");
+ gtk_object_unref (cal);
+ return NULL;
+ }
- CORBA_exception_free (&ev);
+ return retval;
}
diff --git a/calendar/pcs/cal.h b/calendar/pcs/cal.h
index 959331595c..80d349d44d 100644
--- a/calendar/pcs/cal.h
+++ b/calendar/pcs/cal.h
@@ -1,4 +1,4 @@
-/* GNOME calendar object
+/* GNOME calendar client interface object
*
* Copyright (C) 2000 Helix Code, Inc.
*
@@ -25,6 +25,7 @@
#include <libgnome/gnome-defs.h>
#include <bonobo/gnome-object.h>
#include "gnome-calendar.h"
+#include "cal-common.h"
BEGIN_GNOME_DECLS
@@ -36,9 +37,6 @@ BEGIN_GNOME_DECLS
#define IS_CAL(obj) (GTK_CHECK_TYPE ((obj), CAL_TYPE))
#define IS_CAL_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), CAL_TYPE))
-typedef struct _Cal Cal;
-typedef struct _CalClass CalClass;
-
struct _Cal {
GnomeObject object;
@@ -52,14 +50,13 @@ struct _CalClass {
GtkType cal_get_type (void);
-Cal *cal_construct (Cal *cal, GNOME_Calendar_Cal corba_cal);
+Cal *cal_construct (Cal *cal,
+ GNOME_Calendar_Cal corba_cal,
+ CalBackend *backend,
+ GNOME_Calendar_Listener listener);
GNOME_Calendar_Cal cal_corba_object_create (GnomeObject *object);
-Cal *cal_new (char *uri);
-Cal *cal_new_from_file (char *uri);
-
-void cal_add_listener (Cal *cal, GNOME_Calendar_Listener listener);
-void cal_remove_listener (Cal *cal, GNOME_Calendar_Listener listener);
+Cal *cal_new (CalBackend *backend, GNOME_Calendar_Listener listener);
POA_GNOME_Calendar_Cal__epv *cal_get_epv (void);