From bd4e64bd780fc0e39832f5c5abf1a15522fa6076 Mon Sep 17 00:00:00 2001 From: Federico Mena Quintero Date: Wed, 19 Jan 2000 03:32:45 +0000 Subject: Moved the calendar backend here. This is the actual calendar-handling 2000-01-18 Federico Mena Quintero * 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 * 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. * job.c job.h: New files with a simple job queue manager. * gnome-calendar.idl (Listener::cal_loaded): Do not return the whole calendar object string. The client will be able to query the calendar for the events it needs. * 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 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. svn path=/trunk/; revision=1591 --- calendar/ChangeLog | 25 +++ calendar/cal-backend.c | 344 ++++++++++++++++++++++++++++++++++++ calendar/cal-backend.h | 71 ++++++++ calendar/cal-common.h | 41 +++++ calendar/cal-factory.c | 45 ++--- calendar/cal.c | 152 ++++++++-------- calendar/cal.h | 17 +- calendar/evolution-calendar.idl | 2 +- calendar/idl/evolution-calendar.idl | 2 +- calendar/pcs/cal-backend.c | 344 ++++++++++++++++++++++++++++++++++++ calendar/pcs/cal-backend.h | 71 ++++++++ calendar/pcs/cal-common.h | 41 +++++ calendar/pcs/cal-factory.c | 45 ++--- calendar/pcs/cal.c | 152 ++++++++-------- calendar/pcs/cal.h | 17 +- 15 files changed, 1147 insertions(+), 222 deletions(-) create mode 100644 calendar/cal-backend.c create mode 100644 calendar/cal-backend.h create mode 100644 calendar/cal-common.h create mode 100644 calendar/pcs/cal-backend.c create mode 100644 calendar/pcs/cal-backend.h create mode 100644 calendar/pcs/cal-common.h diff --git a/calendar/ChangeLog b/calendar/ChangeLog index a934f5145e..3b32e80de3 100644 --- a/calendar/ChangeLog +++ b/calendar/ChangeLog @@ -1,3 +1,18 @@ +2000-01-18 Federico Mena Quintero + + * 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 * cal-factory.c (cal_factory_load): Queue a load job. @@ -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 + + 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 * 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 + * + * 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 +#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 + * + * 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 +#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 + * + * 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 + +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 #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 #include #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 + * + * 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 +#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 + * + * 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 +#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 + * + * 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 + +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 #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 #include #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); -- cgit v1.2.3