From 13429d5ff13d94a68148a7f16bf954c8939f3f19 Mon Sep 17 00:00:00 2001 From: Federico Mena Quintero Date: Mon, 24 Jan 2000 08:40:57 +0000 Subject: New function to remove a calendar client interface object from a backend. 2000-01-24 Federico Mena Quintero * cal-backend.c (cal_backend_remove_cal): New function to remove a calendar client interface object from a backend. (cal_backend_load): Convert the URI to string and use Parse_MIME_FromFileName(). The conversion is not very smart, though. * cal-factory.c (load_backend): Moved most of the error handling upstream to load_fn(). (load_fn): Handle failure in case the backend could not be loaded. (cal_factory_destroy): Free the backends and the backend hash table. (add_calendar_client): Implemented. We create a Cal client interface object and attach it to the backend, and we notify the listener. svn path=/trunk/; revision=1618 --- calendar/ChangeLog | 20 ++++++ calendar/cal-backend.c | 49 ++++++++++++++- calendar/cal-backend.h | 1 + calendar/cal-factory.c | 150 +++++++++++++++++++++++++++++++++------------ calendar/cal.c | 3 - calendar/pcs/cal-backend.c | 49 ++++++++++++++- calendar/pcs/cal-backend.h | 1 + calendar/pcs/cal-factory.c | 150 +++++++++++++++++++++++++++++++++------------ calendar/pcs/cal.c | 3 - 9 files changed, 342 insertions(+), 84 deletions(-) diff --git a/calendar/ChangeLog b/calendar/ChangeLog index 6df4329dd9..7a4887f927 100644 --- a/calendar/ChangeLog +++ b/calendar/ChangeLog @@ -1,5 +1,25 @@ +2000-01-24 Federico Mena Quintero + + * cal-backend.c (cal_backend_remove_cal): New function to remove a + calendar client interface object from a backend. + (cal_backend_load): Convert the URI to string and use + Parse_MIME_FromFileName(). The conversion is not very smart, + though. + + * cal-factory.c (load_backend): Moved most of the error handling + upstream to load_fn(). + (load_fn): Handle failure in case the backend could not be loaded. + (cal_factory_destroy): Free the backends and the backend hash + table. + (add_calendar_client): Implemented. We create a Cal client + interface object and attach it to the backend, and we notify the + listener. + 2000-01-22 Federico Mena Quintero + * cal-factory.c (lookup_backend): Renamed from lookup_calendar(). + Also, return a backend instead of a Cal client object. + * cal-backend.c (cal_backend_load): Take in a GnomeVFSURI, not a string. diff --git a/calendar/cal-backend.c b/calendar/cal-backend.c index 0d90e7a2dd..649a1dd8f4 100644 --- a/calendar/cal-backend.c +++ b/calendar/cal-backend.c @@ -297,9 +297,42 @@ cal_backend_add_cal (CalBackend *backend, Cal *cal) g_return_if_fail (cal != NULL); g_return_if_fail (IS_CAL (cal)); + gtk_object_ref (cal); priv->clients = g_list_prepend (priv->clients, cal); } +/** + * cal_backend_remove_cal: + * @backend: A calendar backend. + * @cal: A calendar client interface object. + * + * Removes a calendar client interface object from a calendar backend. The + * calendar backend must already have a loaded calendar. + **/ +void +cal_backend_remove_cal (CalBackend *backend, Cal *cal) +{ + CalBackendPrivate *priv; + GList *l; + + 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)); + + l = g_list_find (priv->clients, cal); + if (!l) + return; + + gtk_object_unref (cal); + priv->clients = g_list_remove_link (priv->clients, l); + g_list_free1 (l); +} + /** * cal_backend_load: * @backend: A calendar backend. @@ -315,6 +348,7 @@ cal_backend_load (CalBackend *backend, GnomeVFSURI *uri) { CalBackendPrivate *priv; VObject *vobject; + char *str_uri; g_return_val_if_fail (backend != NULL, CAL_BACKEND_LOAD_ERROR); g_return_val_if_fail (IS_CAL_BACKEND (backend), CAL_BACKEND_LOAD_ERROR); @@ -323,7 +357,20 @@ cal_backend_load (CalBackend *backend, GnomeVFSURI *uri) priv = backend->priv; g_return_val_if_fail (!priv->loaded, CAL_BACKEND_LOAD_ERROR); - vobject = Parse_MIME_FromURI (uri); + /* FIXME: this looks rather bad; maybe we should check for local files + * and fail if they are remote. + */ + + str_uri = gnome_vfs_uri_to_string (uri, + (GNOME_VFS_URI_HIDE_USER_NAME + | GNOME_VFS_URI_HIDE_PASSWORD + | GNOME_VFS_URI_HIDE_HOST_NAME + | GNOME_VFS_URI_HIDE_HOST_PORT + | GNOME_VFS_URI_HIDE_TOPLEVEL_METHOD)); + + vobject = Parse_MIME_FromFileName (str_uri); + g_free (str_uri); + if (!vobject) return CAL_BACKEND_LOAD_ERROR; diff --git a/calendar/cal-backend.h b/calendar/cal-backend.h index cffc3c5cc3..3c60b6961c 100644 --- a/calendar/cal-backend.h +++ b/calendar/cal-backend.h @@ -61,6 +61,7 @@ CalBackend *cal_backend_new (void); GnomeVFSURI *cal_backend_get_uri (CalBackend *backend); void cal_backend_add_cal (CalBackend *backend, Cal *cal); +void cal_backend_remove_cal (CalBackend *backend, Cal *cal); CalBackendLoadStatus cal_backend_load (CalBackend *backend, GnomeVFSURI *uri); diff --git a/calendar/cal-factory.c b/calendar/cal-factory.c index 75c281d235..2f31355e73 100644 --- a/calendar/cal-factory.c +++ b/calendar/cal-factory.c @@ -20,6 +20,7 @@ */ #include +#include "cal.h" #include "cal-backend.h" #include "cal-factory.h" #include "job.h" @@ -29,7 +30,7 @@ /* Private part of the CalFactory structure */ typedef struct { /* Hash table from GnomeVFSURI structures to CalBackend objects */ - GHashTable *calendars; + GHashTable *backends; } CalFactoryPrivate; @@ -108,7 +109,21 @@ cal_factory_init (CalFactory *factory) priv = g_new0 (CalFactoryPrivate, 1); factory->priv = priv; - priv->calendars = g_hash_table_new (gnome_vfs_uri_hash, gnome_vfs_uri_hequal); + priv->backends = g_hash_table_new (gnome_vfs_uri_hash, gnome_vfs_uri_hequal); +} + +/* Frees a uri/backend pair from the backends hash table */ +static void +free_backend (gpointer key, gpointer value, gpointer data) +{ + GnomeVFSURI *uri; + CalBackend *backend; + + uri = key; + backend = value; + + gnome_vfs_uri_unref (uri); + gtk_object_unref (GTK_OBJECT (backend)); } /* Destroy handler for the calendar */ @@ -124,7 +139,9 @@ cal_factory_destroy (GtkObject *object) factory = CAL_FACTORY (object); priv = factory->priv; - /* FIXME: free the calendar hash table */ + g_hash_table_foreach (priv->backends, free_backend, NULL); + g_hash_table_destroy (priv->backends); + priv->backends = NULL; g_free (priv); @@ -199,57 +216,94 @@ typedef struct { GNOME_Calendar_Listener listener; } LoadCreateJobData; -/* Looks up a calendar in a factory's hash table of uri->cal */ -static Cal * -lookup_calendar (CalFactory *factory, GnomeVFSURI *uri) +/* Looks up a calendar backend in a factory's hash table of uri->cal */ +static CalBackend * +lookup_backend (CalFactory *factory, GnomeVFSURI *uri) { CalFactoryPrivate *priv; - Cal *cal; + CalBackend *backend; priv = factory->priv; - cal = g_hash_table_lookup (priv->calendars, uri); + backend = g_hash_table_lookup (priv->backends, uri); return cal; } -/* Loads a calendar and puts it in the factory's hash table */ -static void -load_calendar (CalFactory *factory, GnomeVFSURI *uri, GNOME_Calendar_Listener listener) +/* Loads a calendar backend and puts it in the factory's backend hash table */ +static CalBackend * +load_backend (CalFactory *factory, GnomeVFSURI *uri, GNOME_Calendar_Listener listener) { CalFactoryPrivate *priv; CalBackend *backend; CalBackendLoadStatus status; + CORBA_Environment ev; priv = factory->priv; backend = cal_backend_new (); if (!backend) { - CORBA_Environment ev; + g_message ("load_backend(): could not create the backend"); + return NULL; + } + + status = cal_backend_load (backend, uri); - g_message ("load_calendar(): could not create the backend"); + switch (status) { + case CAL_BACKEND_LOAD_SUCCESS: + gnome_vfs_uri_ref (uri); + g_hash_table_insert (priv->backends, uri, backend); + + return backend; + + case CAL_BACKEND_LOAD_ERROR: + gtk_object_unref (backend); + return NULL; + + default: + g_assert_not_reached (); + return NULL; + } +} + +/* Adds a listener to a calendar backend by creating a calendar client interface + * object. + */ +static void +add_calendar_client (CalFactory *factory, CalBackend *backend, GNOME_Calendar_Listener listener) +{ + Cal *cal; + CORBA_Environment ev; + + cal = cal_new (backend, listener); + if (!cal) { + g_message ("add_calendar_client(): could not create the calendar client interface"); CORBA_exception_init (&ev); GNOME_Calendar_Listener_cal_loaded (listener, GNOME_Calendar_Listener_ERROR, CORBA_OBJECT_NIL, &ev); - if (ev._major != CORBA_NO_EXCEPTION) { - g_message ("load_calendar(): could not notify the listener"); - CORBA_exception_free (&ev); - gtk_object_unref (backend); - return; - } + if (ev._major != CORBA_NO_EXCEPTION) + g_message ("add_calendar_client(): could not notify the listener"); + CORBA_exception_free (&ev); + return; } - status = cal_backend_load (backend, uri); -} + cal_backend_add_cal (backend, cal); -/* Adds a listener to a calendar */ -static void -add_calendar_listener (CalFactory *factory, Cal *cal, GNOME_Calendar_Listener listener) -{ - /* FIXME */ + CORBA_exception_init (&ev); + GNOME_Calendar_Listener_cal_loaded (listener, + GNOME_Calendar_Listener_SUCESSS, + gnome_object_corba_objref (GNOME_OBJECT (cal)), + &ev); + + if (ev._major != CORBA_NO_EXCEPTION) { + g_message ("add_calendar_client(): could not notify the listener"); + cal_backend_remove_cal (backend, cal); + } + + gtk_object_unref (GTK_OBJECT (cal)); } /* Job handler for the load calendar command */ @@ -257,8 +311,10 @@ static void load_fn (gpointer data) { LoadCreateJobData jd; + CalFactory *factory; GnomeVFSURI *uri; - Cal *cal; + GNOME_Calendar_Listener listener; + CalBackend *backend; CORBA_Environment ev; jd = data; @@ -266,27 +322,45 @@ load_fn (gpointer data) /* Look up the calendar */ uri = gnome_vfs_uri_new (jd->uri); - cal = lookup_calendar (jd->factory, uri); + g_free (jd->uri); + + factory = jd->factory; + listener = jd->listener; + g_free (jd); + + backend = lookup_backend (factory, uri); - if (!cal) - load_calendar (factory, uri, jd->listener); - else - add_calendar_listener (factory, cal, jd->listener); + if (!backend) + backend = load_backend (factory, uri, listener); gnome_vfs_uri_unref (uri); - g_free (jd->uri); + + if (!backend) { + g_message ("load_fn(): could not load the backend"); + CORBA_exception_init (&ev); + GNOME_Calendar_Listener_cal_loaded (listener, + GNOME_Calendar_Listener_ERROR, + CORBA_OBJECT_NIL, + &ev); + + if (ev._major != CORBA_NO_EXCEPTION) + g_message ("load_fn(): could not notify the listener"); + + CORBA_exception_free (&ev); + goto out; + } + + add_calendar_client (factory, backend, listener); + + out: CORBA_exception_init (&ev); - CORBA_Object_release (jd->listener, &ev); + CORBA_Object_release (listener, &ev); if (ev._major != CORBA_NO_EXCEPTION) g_message ("load_fn(): could not release the listener"); CORBA_exception_free (&ev); - - /* Done */ - - g_free (jd); } diff --git a/calendar/cal.c b/calendar/cal.c index 26c0581ff7..be7c8e74eb 100644 --- a/calendar/cal.c +++ b/calendar/cal.c @@ -128,9 +128,6 @@ cal_destroy (GtkObject *object) cal = CAL (object); priv = cal->priv; - if (priv->uri) - g_free (priv->uri); - CORBA_exception_init (&ev); for (l = priv->listeners; l; l = l->next) { diff --git a/calendar/pcs/cal-backend.c b/calendar/pcs/cal-backend.c index 0d90e7a2dd..649a1dd8f4 100644 --- a/calendar/pcs/cal-backend.c +++ b/calendar/pcs/cal-backend.c @@ -297,9 +297,42 @@ cal_backend_add_cal (CalBackend *backend, Cal *cal) g_return_if_fail (cal != NULL); g_return_if_fail (IS_CAL (cal)); + gtk_object_ref (cal); priv->clients = g_list_prepend (priv->clients, cal); } +/** + * cal_backend_remove_cal: + * @backend: A calendar backend. + * @cal: A calendar client interface object. + * + * Removes a calendar client interface object from a calendar backend. The + * calendar backend must already have a loaded calendar. + **/ +void +cal_backend_remove_cal (CalBackend *backend, Cal *cal) +{ + CalBackendPrivate *priv; + GList *l; + + 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)); + + l = g_list_find (priv->clients, cal); + if (!l) + return; + + gtk_object_unref (cal); + priv->clients = g_list_remove_link (priv->clients, l); + g_list_free1 (l); +} + /** * cal_backend_load: * @backend: A calendar backend. @@ -315,6 +348,7 @@ cal_backend_load (CalBackend *backend, GnomeVFSURI *uri) { CalBackendPrivate *priv; VObject *vobject; + char *str_uri; g_return_val_if_fail (backend != NULL, CAL_BACKEND_LOAD_ERROR); g_return_val_if_fail (IS_CAL_BACKEND (backend), CAL_BACKEND_LOAD_ERROR); @@ -323,7 +357,20 @@ cal_backend_load (CalBackend *backend, GnomeVFSURI *uri) priv = backend->priv; g_return_val_if_fail (!priv->loaded, CAL_BACKEND_LOAD_ERROR); - vobject = Parse_MIME_FromURI (uri); + /* FIXME: this looks rather bad; maybe we should check for local files + * and fail if they are remote. + */ + + str_uri = gnome_vfs_uri_to_string (uri, + (GNOME_VFS_URI_HIDE_USER_NAME + | GNOME_VFS_URI_HIDE_PASSWORD + | GNOME_VFS_URI_HIDE_HOST_NAME + | GNOME_VFS_URI_HIDE_HOST_PORT + | GNOME_VFS_URI_HIDE_TOPLEVEL_METHOD)); + + vobject = Parse_MIME_FromFileName (str_uri); + g_free (str_uri); + if (!vobject) return CAL_BACKEND_LOAD_ERROR; diff --git a/calendar/pcs/cal-backend.h b/calendar/pcs/cal-backend.h index cffc3c5cc3..3c60b6961c 100644 --- a/calendar/pcs/cal-backend.h +++ b/calendar/pcs/cal-backend.h @@ -61,6 +61,7 @@ CalBackend *cal_backend_new (void); GnomeVFSURI *cal_backend_get_uri (CalBackend *backend); void cal_backend_add_cal (CalBackend *backend, Cal *cal); +void cal_backend_remove_cal (CalBackend *backend, Cal *cal); CalBackendLoadStatus cal_backend_load (CalBackend *backend, GnomeVFSURI *uri); diff --git a/calendar/pcs/cal-factory.c b/calendar/pcs/cal-factory.c index 75c281d235..2f31355e73 100644 --- a/calendar/pcs/cal-factory.c +++ b/calendar/pcs/cal-factory.c @@ -20,6 +20,7 @@ */ #include +#include "cal.h" #include "cal-backend.h" #include "cal-factory.h" #include "job.h" @@ -29,7 +30,7 @@ /* Private part of the CalFactory structure */ typedef struct { /* Hash table from GnomeVFSURI structures to CalBackend objects */ - GHashTable *calendars; + GHashTable *backends; } CalFactoryPrivate; @@ -108,7 +109,21 @@ cal_factory_init (CalFactory *factory) priv = g_new0 (CalFactoryPrivate, 1); factory->priv = priv; - priv->calendars = g_hash_table_new (gnome_vfs_uri_hash, gnome_vfs_uri_hequal); + priv->backends = g_hash_table_new (gnome_vfs_uri_hash, gnome_vfs_uri_hequal); +} + +/* Frees a uri/backend pair from the backends hash table */ +static void +free_backend (gpointer key, gpointer value, gpointer data) +{ + GnomeVFSURI *uri; + CalBackend *backend; + + uri = key; + backend = value; + + gnome_vfs_uri_unref (uri); + gtk_object_unref (GTK_OBJECT (backend)); } /* Destroy handler for the calendar */ @@ -124,7 +139,9 @@ cal_factory_destroy (GtkObject *object) factory = CAL_FACTORY (object); priv = factory->priv; - /* FIXME: free the calendar hash table */ + g_hash_table_foreach (priv->backends, free_backend, NULL); + g_hash_table_destroy (priv->backends); + priv->backends = NULL; g_free (priv); @@ -199,57 +216,94 @@ typedef struct { GNOME_Calendar_Listener listener; } LoadCreateJobData; -/* Looks up a calendar in a factory's hash table of uri->cal */ -static Cal * -lookup_calendar (CalFactory *factory, GnomeVFSURI *uri) +/* Looks up a calendar backend in a factory's hash table of uri->cal */ +static CalBackend * +lookup_backend (CalFactory *factory, GnomeVFSURI *uri) { CalFactoryPrivate *priv; - Cal *cal; + CalBackend *backend; priv = factory->priv; - cal = g_hash_table_lookup (priv->calendars, uri); + backend = g_hash_table_lookup (priv->backends, uri); return cal; } -/* Loads a calendar and puts it in the factory's hash table */ -static void -load_calendar (CalFactory *factory, GnomeVFSURI *uri, GNOME_Calendar_Listener listener) +/* Loads a calendar backend and puts it in the factory's backend hash table */ +static CalBackend * +load_backend (CalFactory *factory, GnomeVFSURI *uri, GNOME_Calendar_Listener listener) { CalFactoryPrivate *priv; CalBackend *backend; CalBackendLoadStatus status; + CORBA_Environment ev; priv = factory->priv; backend = cal_backend_new (); if (!backend) { - CORBA_Environment ev; + g_message ("load_backend(): could not create the backend"); + return NULL; + } + + status = cal_backend_load (backend, uri); - g_message ("load_calendar(): could not create the backend"); + switch (status) { + case CAL_BACKEND_LOAD_SUCCESS: + gnome_vfs_uri_ref (uri); + g_hash_table_insert (priv->backends, uri, backend); + + return backend; + + case CAL_BACKEND_LOAD_ERROR: + gtk_object_unref (backend); + return NULL; + + default: + g_assert_not_reached (); + return NULL; + } +} + +/* Adds a listener to a calendar backend by creating a calendar client interface + * object. + */ +static void +add_calendar_client (CalFactory *factory, CalBackend *backend, GNOME_Calendar_Listener listener) +{ + Cal *cal; + CORBA_Environment ev; + + cal = cal_new (backend, listener); + if (!cal) { + g_message ("add_calendar_client(): could not create the calendar client interface"); CORBA_exception_init (&ev); GNOME_Calendar_Listener_cal_loaded (listener, GNOME_Calendar_Listener_ERROR, CORBA_OBJECT_NIL, &ev); - if (ev._major != CORBA_NO_EXCEPTION) { - g_message ("load_calendar(): could not notify the listener"); - CORBA_exception_free (&ev); - gtk_object_unref (backend); - return; - } + if (ev._major != CORBA_NO_EXCEPTION) + g_message ("add_calendar_client(): could not notify the listener"); + CORBA_exception_free (&ev); + return; } - status = cal_backend_load (backend, uri); -} + cal_backend_add_cal (backend, cal); -/* Adds a listener to a calendar */ -static void -add_calendar_listener (CalFactory *factory, Cal *cal, GNOME_Calendar_Listener listener) -{ - /* FIXME */ + CORBA_exception_init (&ev); + GNOME_Calendar_Listener_cal_loaded (listener, + GNOME_Calendar_Listener_SUCESSS, + gnome_object_corba_objref (GNOME_OBJECT (cal)), + &ev); + + if (ev._major != CORBA_NO_EXCEPTION) { + g_message ("add_calendar_client(): could not notify the listener"); + cal_backend_remove_cal (backend, cal); + } + + gtk_object_unref (GTK_OBJECT (cal)); } /* Job handler for the load calendar command */ @@ -257,8 +311,10 @@ static void load_fn (gpointer data) { LoadCreateJobData jd; + CalFactory *factory; GnomeVFSURI *uri; - Cal *cal; + GNOME_Calendar_Listener listener; + CalBackend *backend; CORBA_Environment ev; jd = data; @@ -266,27 +322,45 @@ load_fn (gpointer data) /* Look up the calendar */ uri = gnome_vfs_uri_new (jd->uri); - cal = lookup_calendar (jd->factory, uri); + g_free (jd->uri); + + factory = jd->factory; + listener = jd->listener; + g_free (jd); + + backend = lookup_backend (factory, uri); - if (!cal) - load_calendar (factory, uri, jd->listener); - else - add_calendar_listener (factory, cal, jd->listener); + if (!backend) + backend = load_backend (factory, uri, listener); gnome_vfs_uri_unref (uri); - g_free (jd->uri); + + if (!backend) { + g_message ("load_fn(): could not load the backend"); + CORBA_exception_init (&ev); + GNOME_Calendar_Listener_cal_loaded (listener, + GNOME_Calendar_Listener_ERROR, + CORBA_OBJECT_NIL, + &ev); + + if (ev._major != CORBA_NO_EXCEPTION) + g_message ("load_fn(): could not notify the listener"); + + CORBA_exception_free (&ev); + goto out; + } + + add_calendar_client (factory, backend, listener); + + out: CORBA_exception_init (&ev); - CORBA_Object_release (jd->listener, &ev); + CORBA_Object_release (listener, &ev); if (ev._major != CORBA_NO_EXCEPTION) g_message ("load_fn(): could not release the listener"); CORBA_exception_free (&ev); - - /* Done */ - - g_free (jd); } diff --git a/calendar/pcs/cal.c b/calendar/pcs/cal.c index 26c0581ff7..be7c8e74eb 100644 --- a/calendar/pcs/cal.c +++ b/calendar/pcs/cal.c @@ -128,9 +128,6 @@ cal_destroy (GtkObject *object) cal = CAL (object); priv = cal->priv; - if (priv->uri) - g_free (priv->uri); - CORBA_exception_init (&ev); for (l = priv->listeners; l; l = l->next) { -- cgit v1.2.3