aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--calendar/ChangeLog20
-rw-r--r--calendar/cal-backend.c49
-rw-r--r--calendar/cal-backend.h1
-rw-r--r--calendar/cal-factory.c150
-rw-r--r--calendar/cal.c3
-rw-r--r--calendar/pcs/cal-backend.c49
-rw-r--r--calendar/pcs/cal-backend.h1
-rw-r--r--calendar/pcs/cal-factory.c150
-rw-r--r--calendar/pcs/cal.c3
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 <federico@helixcode.com>
+
+ * 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 <federico@helixcode.com>
+ * 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,10 +297,43 @@ 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.
* @uri: URI that contains the calendar data.
@@ -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 <config.h>
+#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,10 +297,43 @@ 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.
* @uri: URI that contains the calendar data.
@@ -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 <config.h>
+#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) {