aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--shell/ChangeLog23
-rw-r--r--shell/Evolution-Storage.idl20
-rw-r--r--shell/e-corba-storage-registry.c170
-rw-r--r--shell/e-corba-storage.c9
-rw-r--r--shell/e-corba-storage.h1
5 files changed, 221 insertions, 2 deletions
diff --git a/shell/ChangeLog b/shell/ChangeLog
index 4a7312c7a4..e187ebe073 100644
--- a/shell/ChangeLog
+++ b/shell/ChangeLog
@@ -1,3 +1,26 @@
+2002-03-04 Iain Holmes <iain@ximian.com>
+
+ * Evolution-Storage.idl: Add some methods to the StorageRegistry
+ interface to get a storage, and add or remove listeners. Also add a
+ new exception and some structs and enums for messages.
+
+ * e-corba_storage-registry.c: Add a GSList to the private stuct for
+ recording the listeners.
+ (listener_notify): Send a message to the listeners.
+ (impl_StorageRegistry_getStorageByName): Implementation of the
+ getStorageByName method. Returns the associated storage interface
+ (storage_set_foreach): Loop through all the storages in the storageset
+ and notify the listeners about them.
+ (find_listener): Find a listener in the list of them.
+ (impl_StorageRegistry_addListener): Add a new listener to the
+ registry.
+ (impl_StorageRegistry_removeListener): Remove a listener.
+ (corba_class_init): Add the new methods to the EPV.
+ (init): NULL the listeners list.
+
+ * e-corba-storage.[ch] (e_corba_storage_get_corba_objref): Get the CORBA
+ interface from the GtkObject.
+
2002-03-04 Ettore Perazzoli <ettore@ximian.com>
[Fix #20234, Deleting Folder gratuitiously causes /local to open.]
diff --git a/shell/Evolution-Storage.idl b/shell/Evolution-Storage.idl
index d5fd5e2d0d..68758ff009 100644
--- a/shell/Evolution-Storage.idl
+++ b/shell/Evolution-Storage.idl
@@ -87,7 +87,18 @@ module Evolution {
interface StorageRegistry : Bonobo::Unknown {
exception Exists {};
exception NotFound {};
+ exception AlreadyListening {};
+
+ enum MessageType {
+ STORAGE_CREATED,
+ STORAGE_DESTROYED
+ };
+ struct NotifyResult {
+ MessageType type;
+ string name;
+ };
+
/* FIXME: The toplevel attributes should probably be attributes
of the storage instead of being passed here. */
StorageListener addStorage (in Storage storage,
@@ -95,9 +106,18 @@ module Evolution {
in string toplevel_node_uri,
in string toplevel_node_type)
raises (Exists);
+
+ Storage getStorageByName (in string name)
+ raises (NotFound);
void removeStorageByName (in string name)
raises (NotFound);
+
+ void addListener (in Bonobo::Listener listener)
+ raises (AlreadyListening);
+
+ void removeListener (in Bonobo::Listener listener)
+ raises (NotFound);
};
};
};
diff --git a/shell/e-corba-storage-registry.c b/shell/e-corba-storage-registry.c
index 982ae6fc48..4451f0751a 100644
--- a/shell/e-corba-storage-registry.c
+++ b/shell/e-corba-storage-registry.c
@@ -29,6 +29,7 @@
#include "e-corba-storage.h"
#include "e-corba-storage-registry.h"
+#include <bonobo/bonobo-exception.h>
#define PARENT_TYPE BONOBO_OBJECT_TYPE
@@ -36,6 +37,8 @@ static BonoboObjectClass *parent_class = NULL;
struct _ECorbaStorageRegistryPrivate {
EStorageSet *storage_set;
+
+ GSList *listeners;
};
@@ -66,6 +69,33 @@ create_servant (void)
return servant;
}
+static void
+listener_notify (Bonobo_Listener listener,
+ GNOME_Evolution_StorageRegistry_MessageType type,
+ const char *name)
+{
+ CORBA_any any;
+ GNOME_Evolution_StorageRegistry_NotifyResult nr;
+ CORBA_Environment ev;
+
+ nr.type = type;
+ nr.name = CORBA_string_dup (name ? name : "");
+
+ any._type = (CORBA_TypeCode) TC_GNOME_Evolution_StorageRegistry_NotifyResult;
+ any._value = &nr;
+
+ CORBA_exception_init (&ev);
+ Bonobo_Listener_event (listener,
+ "Evolution::StorageRegistry::NotifyResult",
+ &any, &ev);
+ if (BONOBO_EX (&ev)) {
+ g_warning ("Could not send notify event for %s\n%s", name,
+ CORBA_exception_id (&ev));
+ }
+
+ CORBA_exception_free (&ev);
+}
+
static GNOME_Evolution_StorageListener
impl_StorageRegistry_addStorage (PortableServer_Servant servant,
const GNOME_Evolution_Storage storage_interface,
@@ -110,6 +140,35 @@ impl_StorageRegistry_addStorage (PortableServer_Servant servant,
return listener_interface;
}
+static GNOME_Evolution_Storage
+impl_StorageRegistry_getStorageByName (PortableServer_Servant servant,
+ const CORBA_char *name,
+ CORBA_Environment *ev)
+{
+ BonoboObject *bonobo_object;
+ ECorbaStorageRegistry *storage_registry;
+ ECorbaStorageRegistryPrivate *priv;
+ GNOME_Evolution_Storage corba_storage;
+ EStorage *storage;
+
+ bonobo_object = bonobo_object_from_servant (servant);
+ storage_registry = E_CORBA_STORAGE_REGISTRY (bonobo_object);
+ priv = storage_registry->priv;
+
+ storage = e_storage_set_get_storage (priv->storage_set, name);
+ if (storage == NULL) {
+ CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
+ ex_GNOME_Evolution_StorageRegistry_NotFound,
+ NULL);
+ return CORBA_OBJECT_NIL;
+ }
+
+ corba_storage = CORBA_Object_duplicate (e_corba_storage_get_corba_objref
+ (E_CORBA_STORAGE (storage)), ev);
+
+ return corba_storage;
+}
+
static void
impl_StorageRegistry_removeStorageByName (PortableServer_Servant servant,
const CORBA_char *name,
@@ -137,6 +196,109 @@ impl_StorageRegistry_removeStorageByName (PortableServer_Servant servant,
e_storage_set_remove_storage (priv->storage_set, storage);
}
+static void
+storage_set_foreach (EStorageSet *set,
+ Bonobo_Listener listener)
+{
+ GList *storage_list, *p;
+
+ storage_list = e_storage_set_get_storage_list (set);
+ for (p = storage_list; p; p = p->next) {
+ const char *name;
+
+ name = e_storage_get_name (E_STORAGE (p->data));
+
+ listener_notify (listener, GNOME_Evolution_StorageRegistry_STORAGE_CREATED, name);
+ gtk_object_unref (GTK_OBJECT (p->data));
+ }
+
+ g_list_free (storage_list);
+}
+
+static GSList *
+find_listener (GSList *p,
+ Bonobo_Listener listener)
+{
+ CORBA_Environment ev;
+
+ CORBA_exception_init (&ev);
+ for (; p; p = p->next) {
+ if (CORBA_Object_is_equivalent (p->data, listener, &ev) == TRUE) {
+ CORBA_exception_free (&ev);
+ return p;
+ }
+ }
+
+ CORBA_exception_free (&ev);
+ return NULL;
+}
+
+static void
+impl_StorageRegistry_addListener (PortableServer_Servant servant,
+ Bonobo_Listener listener,
+ CORBA_Environment *ev)
+{
+ BonoboObject *bonobo_object;
+ ECorbaStorageRegistry *storage_registry;
+ ECorbaStorageRegistryPrivate *priv;
+ Bonobo_Listener listener_copy;
+ CORBA_Environment ev2;
+
+ bonobo_object = bonobo_object_from_servant (servant);
+ storage_registry = E_CORBA_STORAGE_REGISTRY (bonobo_object);
+ priv = storage_registry->priv;
+
+ if (find_listener (priv->listeners, listener) != NULL) {
+ CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
+ ex_GNOME_Evolution_StorageRegistry_AlreadyListening,
+ NULL);
+ return;
+ }
+
+ CORBA_exception_init (&ev2);
+ listener_copy = CORBA_Object_duplicate ((CORBA_Object) listener, &ev2);
+ if (BONOBO_EX (&ev2)) {
+ g_warning ("EvolutionStorageRegistry -- Cannot duplicate listener.");
+ CORBA_exception_free (&ev2);
+ return;
+ }
+
+ CORBA_exception_free (&ev2);
+ priv->listeners = g_slist_prepend (priv->listeners, listener_copy);
+ storage_set_foreach (priv->storage_set, listener_copy);
+}
+
+static void
+impl_StorageRegistry_removeListener (PortableServer_Servant servant,
+ Bonobo_Listener listener,
+ CORBA_Environment *ev)
+{
+ BonoboObject *bonobo_object;
+ ECorbaStorageRegistry *storage_registry;
+ ECorbaStorageRegistryPrivate *priv;
+ CORBA_Environment ev2;
+ GList *p;
+
+ bonobo_object = bonobo_object_from_servant (servant);
+ storage_registry = E_CORBA_STORAGE_REGISTRY (bonobo_object);
+ priv = storage_registry->priv;
+
+ p = find_listener (priv->listeners, listener);
+ if (p == NULL) {
+ CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
+ ex_GNOME_Evolution_StorageRegistry_NotFound,
+ NULL);
+ return;
+ }
+
+ CORBA_exception_init (&ev2);
+ CORBA_Object_release ((CORBA_Object) p->data, &ev2);
+ CORBA_exception_free (&ev2);
+
+ priv->listeners = g_slist_remove_link (priv->listeners, p);
+ g_list_free (p);
+}
+
/* GtkObject methods. */
@@ -173,8 +335,11 @@ corba_class_init (void)
epv = g_new0 (POA_GNOME_Evolution_StorageRegistry__epv, 1);
epv->addStorage = impl_StorageRegistry_addStorage;
+ epv->getStorageByName = impl_StorageRegistry_getStorageByName;
epv->removeStorageByName = impl_StorageRegistry_removeStorageByName;
-
+ epv->addListener = impl_StorageRegistry_addListener;
+ epv->removeListener = impl_StorageRegistry_removeListener;
+
vepv = &storage_registry_vepv;
vepv->_base_epv = base_epv;
vepv->Bonobo_Unknown_epv = bonobo_object_get_epv ();
@@ -201,7 +366,8 @@ init (ECorbaStorageRegistry *corba_storage_registry)
priv = g_new (ECorbaStorageRegistryPrivate, 1);
priv->storage_set = NULL;
-
+ priv->listeners = NULL;
+
corba_storage_registry->priv = priv;
}
diff --git a/shell/e-corba-storage.c b/shell/e-corba-storage.c
index 3aae784489..1aa1c67674 100644
--- a/shell/e-corba-storage.c
+++ b/shell/e-corba-storage.c
@@ -585,5 +585,14 @@ e_corba_storage_get_StorageListener (ECorbaStorage *corba_storage)
return corba_storage->priv->storage_listener_interface;
}
+GNOME_Evolution_Storage
+e_corba_storage_get_corba_objref (ECorbaStorage *corba_storage)
+{
+ g_return_val_if_fail (corba_storage != NULL, CORBA_OBJECT_NIL);
+ g_return_val_if_fail (E_IS_CORBA_STORAGE (corba_storage), CORBA_OBJECT_NIL);
+
+ return corba_storage->priv->storage_interface;
+}
+
E_MAKE_TYPE (e_corba_storage, "ECorbaStorage", ECorbaStorage, class_init, init, PARENT_TYPE)
diff --git a/shell/e-corba-storage.h b/shell/e-corba-storage.h
index 0bd8b6cf37..843e41c92e 100644
--- a/shell/e-corba-storage.h
+++ b/shell/e-corba-storage.h
@@ -65,6 +65,7 @@ EStorage *e_corba_storage_new (const char *toplevel_no
const GNOME_Evolution_Storage storage_interface,
const char *name);
+GNOME_Evolution_Storage e_corba_storage_get_corba_objref (ECorbaStorage *corba_storage);
/* FIXME: I don't like this call. */
const GNOME_Evolution_StorageListener e_corba_storage_get_StorageListener (ECorbaStorage *corba_storage);