diff options
-rw-r--r-- | shell/ChangeLog | 23 | ||||
-rw-r--r-- | shell/Evolution-Storage.idl | 20 | ||||
-rw-r--r-- | shell/e-corba-storage-registry.c | 170 | ||||
-rw-r--r-- | shell/e-corba-storage.c | 9 | ||||
-rw-r--r-- | shell/e-corba-storage.h | 1 |
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); |