From 764cfb5a6ba195958b1b3b814fdb584d6a5ff63b Mon Sep 17 00:00:00 2001 From: Ettore Perazzoli Date: Thu, 28 Jun 2001 02:22:40 +0000 Subject: Added a URI schema registry to the shell, and changed the bootstrap sequence to get the schema lists from the components and register them into it. svn path=/trunk/; revision=10553 --- shell/ChangeLog | 24 ++++++ shell/Evolution-Shell.idl | 21 ++++- shell/Makefile.am | 2 + shell/e-activity-handler.c | 56 ++++++++++++- shell/e-component-registry.c | 26 ++++++- shell/e-shell.c | 66 ++++++++++++++++ shell/e-shell.h | 2 + shell/e-uri-schema-registry.c | 177 ++++++++++++++++++++++++++++++++++++++++++ shell/e-uri-schema-registry.h | 71 +++++++++++++++++ 9 files changed, 440 insertions(+), 5 deletions(-) create mode 100644 shell/e-uri-schema-registry.c create mode 100644 shell/e-uri-schema-registry.h diff --git a/shell/ChangeLog b/shell/ChangeLog index 60cbb044c1..b170ebec6c 100644 --- a/shell/ChangeLog +++ b/shell/ChangeLog @@ -1,3 +1,27 @@ +2001-06-27 Ettore Perazzoli + + * e-component-registry.c (register_component): Get the supported + schemas and register them into the schema registry. + + * e-shell.c: New member `uri_schema_registry' in `EShellPrivate'. + (e_shell_construct): Init. + (destroy): Unref. + (impl_Shell_createNewView): Raise exception `UnsupportedSchema' if + it's not an `evolution:' URI. Raise exception `NotFound' if + `e_shell_new_view()' returns NULL. + (impl_Shell_handleURI): New, implementation for the `::handleURI' + method. + (e_shell_get_uri_schema_registry): New. + + * Evolution-Shell.idl: New exceptions `UnsupportedSchema' and + `InvalidURI'. + (createNewView): Make this able to raise `NotFound', + `UnsupportedSchema' and `InvalidURI'. + (handleURI): New method. + + * e-uri-schema-registry.h: New. + * e-uri-schema-registry.c: New. + 2001-06-27 Ettore Perazzoli * evolution-shell-component-client.c: Remove redundant declaration diff --git a/shell/Evolution-Shell.idl b/shell/Evolution-Shell.idl index 38b47b40f5..0426c037b0 100644 --- a/shell/Evolution-Shell.idl +++ b/shell/Evolution-Shell.idl @@ -18,8 +18,12 @@ module Evolution { interface Shell : Bonobo::Unknown { exception NotFound {}; + exception UnsupportedSchema {}; + exception InvalidURI {}; exception Busy {}; + typedef sequence FolderTypeNameList; + /** * getComponentByType: * @type: name of a valid folder type @@ -32,15 +36,26 @@ module Evolution { ShellComponent getComponentByType (in string type) raises (NotFound); - typedef sequence FolderTypeNameList; - /** * createNewView: * @uri: URI for the view to open * * Return value: the new view. */ - ShellView createNewView (in string uri); + ShellView createNewView (in string uri) + raises (NotFound, UnsupportedSchema, InvalidURI); + + /** + * handleURI: + * @uri: URI to handle + * + * This handles the specified URI. It is different from + * `::createNewView' as it doesn't necessarily imply creating a + * new ShellView. (For example, a `mailto:' URI will invoke + * the message composer.) + */ + void handleURI (in string uri) + raises (NotFound, UnsupportedSchema, InvalidURI); /** * selectUserFolder: diff --git a/shell/Makefile.am b/shell/Makefile.am index 8c64b05801..55a2700995 100644 --- a/shell/Makefile.am +++ b/shell/Makefile.am @@ -149,6 +149,8 @@ evolution_SOURCES = \ e-task-bar.h \ e-task-widget.c \ e-task-widget.h \ + e-uri-schema-registry.c \ + e-uri-schema-registry.h \ evolution-storage-set-view.c \ evolution-storage-set-view.h \ evolution-storage-set-view-factory.c \ diff --git a/shell/e-activity-handler.c b/shell/e-activity-handler.c index 32076f1f94..a7d42a361b 100644 --- a/shell/e-activity-handler.c +++ b/shell/e-activity-handler.c @@ -30,7 +30,10 @@ #include #include +#include + #include +#include #define PARENT_TYPE bonobo_x_object_get_type () @@ -134,7 +137,46 @@ lookup_activity (GList *list, } -/* ETaskWidget callbacks. */ +/* ETaskWidget actions. */ + +static void +task_widget_cancel_callback (GtkWidget *widget, + void *data) +{ + ActivityInfo *activity_info; + CORBA_Environment ev; + CORBA_any *null_value; + + CORBA_exception_init (&ev); + + activity_info = (ActivityInfo *) data; + + null_value = CORBA_any__alloc (); + null_value->_type = TC_null; + + Bonobo_Listener_event (activity_info->event_listener, "Cancelled", null_value, &ev); + if (ev._major != CORBA_NO_EXCEPTION) + g_warning ("EActivityHandler: Cannot report `Cancelled' event -- %s", + ev._repo_id); + + CORBA_free (null_value); + + CORBA_exception_free (&ev); +} + +static void +show_cancellation_popup (ActivityInfo *activity_info, + GtkWidget *task_widget, + GdkEventButton *button_event) +{ + GtkMenu *popup; + EPopupMenu items[] = { + { N_("Cancel"), NULL, task_widget_cancel_callback, NULL, 0 }, + { NULL } + }; + + popup = e_popup_menu_create (items, 0, 0, activity_info); +} static int task_widget_button_press_event_callback (GtkWidget *widget, @@ -147,6 +189,18 @@ task_widget_button_press_event_callback (GtkWidget *widget, activity_info = (ActivityInfo *) data; + if (button_event->button == 2) { + if (! activity_info->cancellable) { + return FALSE; + } else { + show_cancellation_popup (activity_info, widget, button_event); + return TRUE; + } + } + + if (button_event->button != 1) + return FALSE; + CORBA_exception_init (&ev); null_value = CORBA_any__alloc (); diff --git a/shell/e-component-registry.c b/shell/e-component-registry.c index aa76ff0656..b5df6601da 100644 --- a/shell/e-component-registry.c +++ b/shell/e-component-registry.c @@ -142,6 +142,7 @@ register_component (EComponentRegistry *component_registry, GNOME_Evolution_ShellComponent component_corba_interface; GNOME_Evolution_Shell shell_corba_interface; GNOME_Evolution_FolderTypeList *supported_types; + GNOME_Evolution_URISchemaList *supported_schemas; Component *component; EvolutionShellComponentClient *client; CORBA_Environment ev; @@ -166,6 +167,8 @@ register_component (EComponentRegistry *component_registry, component_corba_interface = bonobo_object_corba_objref (BONOBO_OBJECT (client)); shell_corba_interface = bonobo_object_corba_objref (BONOBO_OBJECT (priv->shell)); + /* Register the supported folder types. */ + supported_types = GNOME_Evolution_ShellComponent__get_supported_types (component_corba_interface, &ev); if (ev._major != CORBA_NO_EXCEPTION || supported_types->_length == 0) { bonobo_object_unref (BONOBO_OBJECT (client)); @@ -178,7 +181,7 @@ register_component (EComponentRegistry *component_registry, component = component_new (id, client); g_hash_table_insert (priv->component_id_to_component, component->id, component); bonobo_object_unref (BONOBO_OBJECT (client)); - + for (i = 0; i < supported_types->_length; i++) { const GNOME_Evolution_FolderType *type; @@ -201,6 +204,27 @@ register_component (EComponentRegistry *component_registry, CORBA_free (supported_types); + /* Register the supported external URI schemas. */ + + supported_schemas = GNOME_Evolution_ShellComponent__get_external_uri_schemas (component_corba_interface, &ev); + if (ev._major == CORBA_NO_EXCEPTION) { + EUriSchemaRegistry *uri_schema_registry; + + uri_schema_registry = e_shell_get_uri_schema_registry (priv->shell); + + for (i = 0; i < supported_schemas->_length; i++) { + const CORBA_char *schema; + + schema = supported_schemas->_buffer[i]; + if (! e_uri_schema_registry_set_handler_for_schema (uri_schema_registry, schema, component->client)) + g_warning ("Cannot register schema `%s' for component %s", schema, component->id); + else + g_print ("Registered handler for schema `%s' -- %s\n", schema, component->id); + } + + CORBA_free (supported_schemas); + } + return TRUE; } diff --git a/shell/e-shell.c b/shell/e-shell.c index f0e86aa96a..30d48430a3 100644 --- a/shell/e-shell.c +++ b/shell/e-shell.c @@ -50,6 +50,7 @@ #include "e-shortcuts.h" #include "e-storage-set.h" #include "e-splash.h" +#include "e-uri-schema-registry.h" #include "evolution-storage-set-view-factory.h" @@ -74,6 +75,7 @@ struct _EShellPrivate { EShortcuts *shortcuts; EFolderTypeRegistry *folder_type_registry; + EUriSchemaRegistry *uri_schema_registry; EComponentRegistry *component_registry; @@ -211,13 +213,56 @@ impl_Shell_createNewView (PortableServer_Servant servant, bonobo_object = bonobo_object_from_servant (servant); shell = E_SHELL (bonobo_object); + if (strncmp (uri, E_SHELL_URI_PREFIX, E_SHELL_URI_PREFIX_LEN) != 0) { + CORBA_exception_set (ev, CORBA_USER_EXCEPTION, + ex_GNOME_Evolution_Shell_UnsupportedSchema, + NULL); + return CORBA_OBJECT_NIL; + } + shell_view = e_shell_new_view (shell, uri); + if (shell_view == NULL) { + CORBA_exception_set (ev, CORBA_USER_EXCEPTION, + ex_GNOME_Evolution_Shell_NotFound, NULL); + return CORBA_OBJECT_NIL; + } + shell_view_interface = e_shell_view_get_corba_interface (shell_view); Bonobo_Unknown_ref (shell_view_interface, ev); return CORBA_Object_duplicate ((CORBA_Object) shell_view_interface, ev); } +static void +impl_Shell_handleURI (PortableServer_Servant servant, + const CORBA_char *uri, + CORBA_Environment *ev) +{ + EShell *shell; + EShellPrivate *priv; + const char *colon_p; + const char *schema; + + shell = E_SHELL (bonobo_object_from_servant (servant)); + priv = shell->priv; + + if (strncmp (uri, E_SHELL_URI_PREFIX, E_SHELL_URI_PREFIX_LEN) == 0) { + GNOME_Evolution_Shell_createNewView (servant, uri, ev); + return; + } + + /* Extract the schema. */ + + colon_p = strchr (uri, ':'); + if (colon_p == NULL || colon_p == uri) { + CORBA_exception_set (ev, CORBA_USER_EXCEPTION, + ex_GNOME_Evolution_Shell_InvalidURI, NULL); + return; + } + + schema = g_strndup (uri, colon_p - uri); +} + static void corba_listener_destroy_notify (void *data) { @@ -578,6 +623,9 @@ destroy (GtkObject *object) if (priv->folder_type_registry != NULL) gtk_object_unref (GTK_OBJECT (priv->folder_type_registry)); + if (priv->uri_schema_registry != NULL) + gtk_object_unref (GTK_OBJECT (priv->uri_schema_registry)); + if (priv->component_registry != NULL) gtk_object_unref (GTK_OBJECT (priv->component_registry)); @@ -728,6 +776,7 @@ e_shell_construct (EShell *shell, priv->iid = g_strdup (iid); priv->local_directory = g_strdup (local_directory); priv->folder_type_registry = e_folder_type_registry_new (); + priv->uri_schema_registry = e_uri_schema_registry_new (); priv->storage_set = e_storage_set_new (priv->folder_type_registry); /* CORBA storages must be set up before the components, because otherwise components @@ -918,6 +967,23 @@ e_shell_get_folder_type_registry (EShell *shell) return shell->priv->folder_type_registry; } +/** + * e_shell_get_uri_schema_registry: + * @shell: An EShell object. + * + * Get the schema registry associated to @shell. + * + * Return value: A pointer to the EUriSchemaRegistry associated to @shell. + **/ +EUriSchemaRegistry * +e_shell_get_uri_schema_registry (EShell *shell) +{ + g_return_val_if_fail (shell != NULL, NULL); + g_return_val_if_fail (E_IS_SHELL (shell), NULL); + + return shell->priv->uri_schema_registry; +} + /** * e_shell_get_local_storage: * @shell: An EShell object. diff --git a/shell/e-shell.h b/shell/e-shell.h index 4e7f8a4fe1..5c0ec4df74 100644 --- a/shell/e-shell.h +++ b/shell/e-shell.h @@ -40,6 +40,7 @@ typedef struct _EShellClass EShellClass; #include "e-shortcuts.h" #include "e-shell-view.h" +#include "e-uri-schema-registry.h" #include "e-local-storage.h" @@ -93,6 +94,7 @@ EShortcuts *e_shell_get_shortcuts (EShell *shell); EStorageSet *e_shell_get_storage_set (EShell *shell); ELocalStorage *e_shell_get_local_storage (EShell *shell); EFolderTypeRegistry *e_shell_get_folder_type_registry (EShell *shell); +EUriSchemaRegistry *e_shell_get_uri_schema_registry (EShell *shell); gboolean e_shell_save_settings (EShell *shell); gboolean e_shell_restore_from_settings (EShell *shell); diff --git a/shell/e-uri-schema-registry.c b/shell/e-uri-schema-registry.c new file mode 100644 index 0000000000..e27648359f --- /dev/null +++ b/shell/e-uri-schema-registry.c @@ -0,0 +1,177 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* e-uri-schema-registry.c + * + * Copyright (C) 2001 Ximian, Inc. + * + * 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. + * + * Author: Ettore Perazzoli + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "e-uri-schema-registry.h" + +#include + + +#define PARENT_TYPE gtk_object_get_type () +static GtkObjectClass *parent_class = NULL; + +struct _SchemaHandler { + char *schema; + EvolutionShellComponentClient *component; +}; +typedef struct _SchemaHandler SchemaHandler; + +struct _EUriSchemaRegistryPrivate { + GHashTable *schema_to_handler; +}; + + +/* SchemaHandler. */ + +static SchemaHandler * +schema_handler_new (const char *schema, + EvolutionShellComponentClient *component) +{ + SchemaHandler *handler; + + handler = g_new (SchemaHandler, 1); + handler->schema = g_strdup (schema); + handler->component = component; + + bonobo_object_ref (BONOBO_OBJECT (component)); + + return handler; +} + +static void +schema_handler_free (SchemaHandler *handler) +{ + g_free (handler->schema); + bonobo_object_unref (BONOBO_OBJECT (handler->component)); + + g_free (handler); +} + + +static void +schema_to_handler_destroy_foreach_callback (void *key, + void *value, + void *data) +{ + schema_handler_free ((SchemaHandler *) value); +} + + +/* GtkObject methods. */ + +static void +impl_destroy (GtkObject *object) +{ + EUriSchemaRegistry *registry; + EUriSchemaRegistryPrivate *priv; + + registry = E_URI_SCHEMA_REGISTRY (object); + priv = registry->priv; + + g_hash_table_foreach (priv->schema_to_handler, schema_to_handler_destroy_foreach_callback, NULL); + g_hash_table_destroy (priv->schema_to_handler); + g_free (priv); + + (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); +} + + +static void +class_init (GtkObjectClass *object_class) +{ + parent_class = gtk_type_class (PARENT_TYPE); + + object_class->destroy = impl_destroy; +} + +static void +init (EUriSchemaRegistry *uri_schema_registry) +{ + EUriSchemaRegistryPrivate *priv; + + priv = g_new (EUriSchemaRegistryPrivate, 1); + priv->schema_to_handler = g_hash_table_new (g_str_hash, g_str_equal); + + uri_schema_registry->priv = priv; +} + + +EUriSchemaRegistry * +e_uri_schema_registry_new (void) +{ + EUriSchemaRegistry *registry; + + registry = gtk_type_new (e_uri_schema_registry_get_type ()); + + return registry; +} + + +gboolean +e_uri_schema_registry_set_handler_for_schema (EUriSchemaRegistry *registry, + const char *schema, + EvolutionShellComponentClient *shell_component) +{ + EUriSchemaRegistryPrivate *priv; + SchemaHandler *existing_handler; + SchemaHandler *new_handler; + + g_return_val_if_fail (registry != NULL, FALSE); + g_return_val_if_fail (E_IS_URI_SCHEMA_REGISTRY (registry), FALSE); + g_return_val_if_fail (schema != NULL, FALSE); + g_return_val_if_fail (shell_component == NULL || EVOLUTION_IS_SHELL_COMPONENT_CLIENT (shell_component), FALSE); + + priv = registry->priv; + + existing_handler = g_hash_table_lookup (priv->schema_to_handler, schema); + if (existing_handler != NULL) + return FALSE; + + new_handler = schema_handler_new (schema, shell_component); + g_hash_table_insert (priv->schema_to_handler, new_handler->schema, new_handler); + + return TRUE; +} + +EvolutionShellComponentClient * +e_uri_schema_get_handler_for_schema (EUriSchemaRegistry *registry, + const char *schema) +{ + EUriSchemaRegistryPrivate *priv; + const SchemaHandler *handler; + + g_return_val_if_fail (registry != NULL, NULL); + g_return_val_if_fail (E_IS_URI_SCHEMA_REGISTRY (registry), NULL); + g_return_val_if_fail (schema != NULL, NULL); + + priv = registry->priv; + + handler = g_hash_table_lookup (priv->schema_to_handler, schema); + return handler->component; +} + + +E_MAKE_TYPE (e_uri_schema_registry, "EUriSchemaRegistry", EUriSchemaRegistry, class_init, init, PARENT_TYPE) diff --git a/shell/e-uri-schema-registry.h b/shell/e-uri-schema-registry.h new file mode 100644 index 0000000000..1462c26200 --- /dev/null +++ b/shell/e-uri-schema-registry.h @@ -0,0 +1,71 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* e-uri-schema-registry.h + * + * Copyright (C) 2001 Ximian, Inc. + * + * 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. + * + * Author: Ettore Perazzoli + */ + +#ifndef _E_URI_SCHEMA_REGISTRY_H_ +#define _E_URI_SCHEMA_REGISTRY_H_ + +#include "evolution-shell-component-client.h" + +#include + +#ifdef __cplusplus +extern "C" { +#pragma } +#endif /* __cplusplus */ + +#define E_TYPE_URI_SCHEMA_REGISTRY (e_uri_schema_registry_get_type ()) +#define E_URI_SCHEMA_REGISTRY(obj) (GTK_CHECK_CAST ((obj), E_TYPE_URI_SCHEMA_REGISTRY, EUriSchemaRegistry)) +#define E_URI_SCHEMA_REGISTRY_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), E_TYPE_URI_SCHEMA_REGISTRY, EUriSchemaRegistryClass)) +#define E_IS_URI_SCHEMA_REGISTRY(obj) (GTK_CHECK_TYPE ((obj), E_TYPE_URI_SCHEMA_REGISTRY)) +#define E_IS_URI_SCHEMA_REGISTRY_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((obj), E_TYPE_URI_SCHEMA_REGISTRY)) + + +typedef struct _EUriSchemaRegistry EUriSchemaRegistry; +typedef struct _EUriSchemaRegistryPrivate EUriSchemaRegistryPrivate; +typedef struct _EUriSchemaRegistryClass EUriSchemaRegistryClass; + +struct _EUriSchemaRegistry { + GtkObject parent; + + EUriSchemaRegistryPrivate *priv; +}; + +struct _EUriSchemaRegistryClass { + GtkObjectClass parent_class; +}; + + +GtkType e_uri_schema_registry_get_type (void); +EUriSchemaRegistry *e_uri_schema_registry_new (void); + +gboolean e_uri_schema_registry_set_handler_for_schema (EUriSchemaRegistry *registry, + const char *schema, + EvolutionShellComponentClient *shell_component); +EvolutionShellComponentClient *e_uri_schema_get_handler_for_schema (EUriSchemaRegistry *registry, + const char *schema); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _E_URI_SCHEMA_REGISTRY_H_ */ -- cgit v1.2.3