diff options
-rw-r--r-- | shell/ChangeLog | 53 | ||||
-rw-r--r-- | shell/Evolution-ShellComponent.idl | 12 | ||||
-rw-r--r-- | shell/Makefile.am | 2 | ||||
-rw-r--r-- | shell/e-component-registry.h | 5 | ||||
-rw-r--r-- | shell/e-shell-user-creatable-items-handler.c | 432 | ||||
-rw-r--r-- | shell/e-shell-user-creatable-items-handler.h | 72 | ||||
-rw-r--r-- | shell/e-shell-view.c | 7 | ||||
-rw-r--r-- | shell/e-shell.c | 66 | ||||
-rw-r--r-- | shell/e-shell.h | 6 | ||||
-rw-r--r-- | shell/evolution-shell-component.c | 164 | ||||
-rw-r--r-- | shell/evolution-shell-component.h | 10 | ||||
-rw-r--r-- | shell/evolution-test-component.c | 13 |
12 files changed, 804 insertions, 38 deletions
diff --git a/shell/ChangeLog b/shell/ChangeLog index 6523acfa49..4a7ea0a64c 100644 --- a/shell/ChangeLog +++ b/shell/ChangeLog @@ -1,3 +1,56 @@ +2001-08-09 Ettore Perazzoli <ettore@ximian.com> + + * e-shell-view.c (e_shell_view_construct): Add the menu items + using the EShellUserCreatableItemsHandler. + + * e-shell-user-creatable-items-handler.c: New. + * e-shell-user-creatable-items-handler.h: New. + + * e-shell.c: New member `user_creatable_items_handler' in + `EShellPrivate'. + (init): Initialize to NULL. + (destroy): Unref. + (e_shell_construct): Create here. + (e_shell_get_user_creatable_items_handler): New accessor. + (setup_components): Add the registered components to the + user_creatable_items_handler. + + * evolution-test-component.c (factory_fn): Add a couple sample + user-creatable items. + (user_create_new_item_callback): New callback for the + "user_create_new_item" signal on the EvolutionShellComponent. + (factory_fn): Connect. + + * e-shell.c (e_shell_get_component_registry): New. + + * evolution-shell-component.c: New enum value + `USER_CREATE_NEW_ITEM'. New member `user_create_item_types' in + `_EvolutionShellComponentPrivate'. + (init): Init to NULL. + (impl_destroy): Free it. + (user_creatable_item_type_free): New helper function. + (user_creatable_item_type_new): New helper function. + (impl_userCreateNewItem): New, implementation for + ::userCreateNewItem. + (class_init): Install the "user_create_new_item" signal and the + userCreateNewItem impl. + (impl__get_external_uri_schemas): Renamed from + `impl_ShellComponent__get_external_uri_schemas'. + (impl___get_supported_types): Renamed from + `impl_ShellComponent__get_supported_types'. + (impl__get_user_creatable_item_types): New, implementation for the + `user_creatable_item_types' attribute. + (class_init): Install it. + (evolution_shell_component_add_user_creatable_item): New. + + * evolution-shell-component.h: Added signal + `user_create_new_item'. + + * Evolution-ShellComponent.idl: Added typedefs + `UserCreatableItemType', `UserCreatableItemTypeList'. New + attribute `user_creatable_item_types'. + (userCreateNewItem): New. + 2001-08-09 Federico Mena Quintero <federico@ximian.com> * e-component-registry.c (destroy): Chain to the destroy handler diff --git a/shell/Evolution-ShellComponent.idl b/shell/Evolution-ShellComponent.idl index 7c65544c01..101d23d4f3 100644 --- a/shell/Evolution-ShellComponent.idl +++ b/shell/Evolution-ShellComponent.idl @@ -28,11 +28,20 @@ module Evolution { typedef string URISchema; typedef sequence<URISchema> URISchemaList; + struct UserCreatableItemType { + string id; + string description; + string menuDescription; + char menuShortcut; + }; + typedef sequence<UserCreatableItemType> UserCreatableItemTypeList; + interface ShellComponentListener; interface ShellComponent : Bonobo::Unknown { readonly attribute FolderTypeList supported_types; readonly attribute URISchemaList external_uri_schemas; + readonly attribute UserCreatableItemTypeList user_creatable_item_types; /* FIXME: Can we use an attribute here? */ exception AlreadyOwned {}; @@ -82,6 +91,9 @@ module Evolution { void populateFolderContextMenu (in Bonobo::UIContainer uih, in string physical_uri, in string type); + + void userCreateNewItem (in string id) + raises (UnsupportedType); }; interface ShellComponentListener { diff --git a/shell/Makefile.am b/shell/Makefile.am index 19fa11e45f..b5904ef965 100644 --- a/shell/Makefile.am +++ b/shell/Makefile.am @@ -125,6 +125,8 @@ evolution_SOURCES = \ e-shell-importer.h \ e-shell-offline-handler.c \ e-shell-offline-handler.h \ + e-shell-user-creatable-items-handler.c \ + e-shell-user-creatable-items-handler.h \ e-shell-utils.c \ e-shell-utils.h \ e-shell-view-menu.c \ diff --git a/shell/e-component-registry.h b/shell/e-component-registry.h index 1da20879ef..280aef74a6 100644 --- a/shell/e-component-registry.h +++ b/shell/e-component-registry.h @@ -26,8 +26,6 @@ #include <gtk/gtkobject.h> -#include "e-shell.h" - #ifdef __cplusplus extern "C" { #pragma } @@ -44,6 +42,9 @@ typedef struct _EComponentRegistry EComponentRegistry; typedef struct _EComponentRegistryPrivate EComponentRegistryPrivate; typedef struct _EComponentRegistryClass EComponentRegistryClass; +#include "e-shell.h" +#include "evolution-shell-component-client.h" + struct _EComponentRegistry { GtkObject parent; diff --git a/shell/e-shell-user-creatable-items-handler.c b/shell/e-shell-user-creatable-items-handler.c new file mode 100644 index 0000000000..340f0b50bc --- /dev/null +++ b/shell/e-shell-user-creatable-items-handler.c @@ -0,0 +1,432 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* e-shell-user-creatable-items-handler.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 <ettore@ximian.com> + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include "e-shell-user-creatable-items-handler.h" + +#include <gal/util/e-util.h> + +#include <bonobo/bonobo-ui-util.h> + +#include <stdlib.h> +#include <ctype.h> + + +#define PARENT_TYPE gtk_object_get_type () +static GtkObjectClass *parent_class = NULL; + + +#define VERB_PREFIX "ShellUserCreatableItemVerb" + +struct _Component { + EvolutionShellComponentClient *component_client; + + GNOME_Evolution_UserCreatableItemTypeList *type_list; +}; +typedef struct _Component Component; + +struct _EShellUserCreatableItemsHandlerPrivate { + GSList *components; /* Component */ + + char *menu_xml; +}; + + +/* Component struct handling. */ + +static Component * +component_new_from_client (EvolutionShellComponentClient *client) +{ + CORBA_Environment ev; + Component *new; + GNOME_Evolution_ShellComponent objref; + + new = g_new (Component, 1); + + new->component_client = client; + gtk_object_ref (GTK_OBJECT (client)); + + CORBA_exception_init (&ev); + + objref = bonobo_object_corba_objref (BONOBO_OBJECT (client)); + new->type_list = GNOME_Evolution_ShellComponent__get_user_creatable_item_types (objref, &ev); + + if (ev._major != CORBA_NO_EXCEPTION) + new->type_list = NULL; + + CORBA_exception_free (&ev); + + return new; +} + +static void +component_free (Component *component) +{ + gtk_object_unref (GTK_OBJECT (component->component_client)); + CORBA_free (component->type_list); + + g_free (component); +} + + +/* Helper functions. */ + +static char * +create_verb_from_component_number_and_type_id (int component_num, + const char *type_id) +{ + return g_strdup_printf (VERB_PREFIX ":%d:%s", component_num, type_id); +} + + +/* Setting up the XML for the menus. */ + +struct _MenuItem { + const char *label; + char shortcut; + char *verb; +}; +typedef struct _MenuItem MenuItem; + +static int +item_types_sort_func (const void *a, + const void *b) +{ + const MenuItem *item_a; + const MenuItem *item_b; + const char *p1, *p2; + + item_a = (const MenuItem *) a; + item_b = (const MenuItem *) b; + + p1 = item_a->label; + p2 = item_b->label; + + while (*p1 != '\0' && *p2 != '\0') { + if (*p1 == '_') { + p1 ++; + continue; + } + + if (*p2 == '_') { + p2 ++; + continue; + } + + if (toupper ((int) *p1) < toupper ((int) *p2)) + return -1; + else if (toupper ((int) *p1) > toupper ((int) *p2)) + return +1; + + p1 ++, p2 ++; + } + + if (*p1 == '\0') { + if (*p2 == '\0') + return 0; + else + return -1; + } else { + return +1; + } + +} + +static char * +create_xml_from_menu_items (GSList *items) +{ + GString *xml; + GSList *p; + char *str; + + xml = g_string_new (""); + + g_string_append (xml, "<Root> <menu> <submenu name=\"File\"> <submenu name=\"New\"> <placeholder name=\"NewItems\">"); + + g_string_append (xml, "<separator/> "); + + for (p = items; p != NULL; p = p->next) { + const MenuItem *item; + char *encoded_label; + + item = (const MenuItem *) p->data; + + encoded_label = bonobo_ui_util_encode_str (item->label); + + g_string_sprintfa (xml, "<menuitem name=\"New:%s\" verb=\"%s\" label=\"%s\"", + item->verb, item->verb, encoded_label); + + if (item->shortcut != '\0') + g_string_sprintfa (xml, " accel=\"*Control**Shift*%c\"", item->shortcut); + + g_string_append (xml, "/> "); + + g_free (encoded_label); + } + + g_string_append (xml, "</placeholder> </submenu> </submenu> </menu> </Root>"); + + str = xml->str; + g_string_free (xml, FALSE); + + return str; +} + +static void +setup_menu_xml (EShellUserCreatableItemsHandler *handler) +{ + EShellUserCreatableItemsHandlerPrivate *priv; + GSList *menu_items; + GSList *p; + int component_num; + + priv = handler->priv; + g_assert (priv->menu_xml == NULL); + + menu_items = NULL; + component_num = 0; + for (p = priv->components; p != NULL; p = p->next) { + const Component *component; + int i; + + component = (const Component *) p->data; + for (i = 0; i < component->type_list->_length; i ++) { + const GNOME_Evolution_UserCreatableItemType *type; + MenuItem *item; + + type = (const GNOME_Evolution_UserCreatableItemType *) component->type_list->_buffer + i; + + item = g_new (MenuItem, 1); + item->label = type->menuDescription; + item->shortcut = type->menuShortcut; + item->verb = create_verb_from_component_number_and_type_id (component_num, type->id); + + menu_items = g_slist_prepend (menu_items, item); + } + + component_num ++; + } + + if (menu_items == NULL) { + priv->menu_xml = g_strdup (""); + return; + } + + menu_items = g_slist_sort (menu_items, item_types_sort_func); + + priv->menu_xml = create_xml_from_menu_items (menu_items); + + for (p = menu_items; p != NULL; p = p->next) { + MenuItem *item; + + item = (MenuItem *) p->data; + g_free (item->verb); + g_free (item); + } + g_slist_free (menu_items); +} + + +/* Verb handling. */ + +static void +verb_fn (BonoboUIComponent *ui_component, + void *data, + const char *verb_name) +{ + EShellUserCreatableItemsHandler *handler; + EShellUserCreatableItemsHandlerPrivate *priv; + const Component *component; + int component_number; + const char *p; + const char *id; + GSList *component_list_item; + int i; + + handler = E_SHELL_USER_CREATABLE_ITEMS_HANDLER (data); + priv = handler->priv; + + p = strchr (verb_name, ':'); + g_assert (p != NULL); + component_number = atoi (p + 1); + + p = strchr (p + 1, ':'); + g_assert (p != NULL); + id = p + 1; + + component_list_item = g_slist_nth (priv->components, component_number); + g_assert (component_list_item != NULL); + + component = (const Component *) component_list_item->data; + + for (i = 0; i < component->type_list->_length; i ++) { + if (strcmp (component->type_list->_buffer[i].id, id) == 0) { + CORBA_Environment ev; + + CORBA_exception_init (&ev); + + GNOME_Evolution_ShellComponent_userCreateNewItem + (bonobo_object_corba_objref (BONOBO_OBJECT (component->component_client)), id, &ev); + + if (ev._major != CORBA_NO_EXCEPTION) + g_warning ("Error in userCreateNewItem -- %s", ev._repo_id); + + CORBA_exception_free (&ev); + return; + } + } +} + +static void +add_verbs_to_ui_component (EShellUserCreatableItemsHandler *handler, + BonoboUIComponent *ui_component) +{ + EShellUserCreatableItemsHandlerPrivate *priv; + int component_num; + GSList *p; + + priv = handler->priv; + + component_num = 0; + for (p = priv->components; p != NULL; p = p->next) { + const Component *component; + int i; + + component = (const Component *) p->data; + for (i = 0; i < component->type_list->_length; i ++) { + char *verb_name; + + verb_name = create_verb_from_component_number_and_type_id (component_num, + component->type_list->_buffer[i].id); + + bonobo_ui_component_add_verb (ui_component, verb_name, verb_fn, handler); + + g_free (verb_name); + } + + component_num ++; + } +} + + +/* GtkObject methods. */ + +static void +impl_destroy (GtkObject *object) +{ + EShellUserCreatableItemsHandler *handler; + EShellUserCreatableItemsHandlerPrivate *priv; + GSList *p; + + handler = E_SHELL_USER_CREATABLE_ITEMS_HANDLER (object); + priv = handler->priv; + + for (p = priv->components; p != NULL; p = p->next) + component_free ((Component *) p->data); + + g_slist_free (priv->components); + + g_free (priv->menu_xml); + + 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 (EShellUserCreatableItemsHandler *shell_user_creatable_items_handler) +{ + EShellUserCreatableItemsHandlerPrivate *priv; + + priv = g_new (EShellUserCreatableItemsHandlerPrivate, 1); + priv->components = NULL; + priv->menu_xml = NULL; + + shell_user_creatable_items_handler->priv = priv; +} + + +EShellUserCreatableItemsHandler * +e_shell_user_creatable_items_handler_new (void) +{ + EShellUserCreatableItemsHandler *new; + + new = gtk_type_new (e_shell_user_creatable_items_handler_get_type ()); + + return new; +} + +void +e_shell_user_creatable_items_handler_add_component (EShellUserCreatableItemsHandler *handler, + EvolutionShellComponentClient *shell_component_client) +{ + EShellUserCreatableItemsHandlerPrivate *priv; + + g_return_if_fail (handler != NULL); + g_return_if_fail (E_IS_SHELL_USER_CREATABLE_ITEMS_HANDLER (handler)); + g_return_if_fail (shell_component_client != NULL); + g_return_if_fail (EVOLUTION_IS_SHELL_COMPONENT_CLIENT (shell_component_client)); + + priv = handler->priv; + g_return_if_fail (priv->menu_xml == NULL); + + priv->components = g_slist_prepend (priv->components, component_new_from_client (shell_component_client)); +} + +void +e_shell_user_creatable_items_handler_setup_menus (EShellUserCreatableItemsHandler *handler, + BonoboUIComponent *ui_component) +{ + EShellUserCreatableItemsHandlerPrivate *priv; + + g_return_if_fail (handler != NULL); + g_return_if_fail (E_IS_SHELL_USER_CREATABLE_ITEMS_HANDLER (handler)); + g_return_if_fail (ui_component != NULL); + g_return_if_fail (BONOBO_IS_UI_COMPONENT (ui_component)); + + priv = handler->priv; + + if (priv->menu_xml == NULL) + setup_menu_xml (handler); + + add_verbs_to_ui_component (handler, ui_component); + + bonobo_ui_component_set (ui_component, "/", priv->menu_xml, NULL); +} + + +E_MAKE_TYPE (e_shell_user_creatable_items_handler, + "EShellUserCreatableItemsHandler", EShellUserCreatableItemsHandler, + class_init, init, PARENT_TYPE) diff --git a/shell/e-shell-user-creatable-items-handler.h b/shell/e-shell-user-creatable-items-handler.h new file mode 100644 index 0000000000..ffe8a608b5 --- /dev/null +++ b/shell/e-shell-user-creatable-items-handler.h @@ -0,0 +1,72 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* e-shell-user-creatable-items-handler.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 <ettore@ximian.com> + */ + +#ifndef _E_SHELL_USER_CREATABLE_ITEMS_HANDLER_H_ +#define _E_SHELL_USER_CREATABLE_ITEMS_HANDLER_H_ + +#include "evolution-shell-component-client.h" + +#include <gtk/gtkobject.h> +#include <bonobo/bonobo-ui-component.h> + +#ifdef __cplusplus +extern "C" { +#pragma } +#endif /* __cplusplus */ + +#define E_TYPE_SHELL_USER_CREATABLE_ITEMS_HANDLER (e_shell_user_creatable_items_handler_get_type ()) +#define E_SHELL_USER_CREATABLE_ITEMS_HANDLER(obj) (GTK_CHECK_CAST ((obj), E_TYPE_SHELL_USER_CREATABLE_ITEMS_HANDLER, EShellUserCreatableItemsHandler)) +#define E_SHELL_USER_CREATABLE_ITEMS_HANDLER_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), E_TYPE_SHELL_USER_CREATABLE_ITEMS_HANDLER, EShellUserCreatableItemsHandlerClass)) +#define E_IS_SHELL_USER_CREATABLE_ITEMS_HANDLER(obj) (GTK_CHECK_TYPE ((obj), E_TYPE_SHELL_USER_CREATABLE_ITEMS_HANDLER)) +#define E_IS_SHELL_USER_CREATABLE_ITEMS_HANDLER_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((obj), E_TYPE_SHELL_USER_CREATABLE_ITEMS_HANDLER)) + + +typedef struct _EShellUserCreatableItemsHandler EShellUserCreatableItemsHandler; +typedef struct _EShellUserCreatableItemsHandlerPrivate EShellUserCreatableItemsHandlerPrivate; +typedef struct _EShellUserCreatableItemsHandlerClass EShellUserCreatableItemsHandlerClass; + +struct _EShellUserCreatableItemsHandler { + GtkObject parent; + + EShellUserCreatableItemsHandlerPrivate *priv; +}; + +struct _EShellUserCreatableItemsHandlerClass { + GtkObjectClass parent_class; +}; + + +GtkType e_shell_user_creatable_items_handler_get_type (void); +EShellUserCreatableItemsHandler *e_shell_user_creatable_items_handler_new (void); + +void e_shell_user_creatable_items_handler_add_component (EShellUserCreatableItemsHandler *handler, + EvolutionShellComponentClient *shell_component_client); + +void e_shell_user_creatable_items_handler_setup_menus (EShellUserCreatableItemsHandler *handler, + BonoboUIComponent *ui_component); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _E_SHELL_USER_CREATABLE_ITEMS_HANDLER_H_ */ diff --git a/shell/e-shell-view.c b/shell/e-shell-view.c index 4e72bc1cf5..696c4e5643 100644 --- a/shell/e-shell-view.c +++ b/shell/e-shell-view.c @@ -31,6 +31,7 @@ #include <sys/stat.h> #include <sys/types.h> #include <fcntl.h> +#include <ctype.h> #include <glib.h> #include <libgnome/gnome-defs.h> @@ -49,6 +50,7 @@ #include <gal/widgets/e-scroll-frame.h> #include "widgets/misc/e-clipped-label.h" +#include "widgets/misc/e-bonobo-widget.h" #include "evolution-shell-view.h" @@ -1210,6 +1212,9 @@ e_shell_view_construct (EShellView *shell_view, GTK_SIGNAL_FUNC (shell_line_status_changed_cb), view, GTK_OBJECT (view)); + e_shell_user_creatable_items_handler_setup_menus (e_shell_get_user_creatable_items_handler (priv->shell), + priv->ui_component); + return view; } @@ -1710,7 +1715,7 @@ get_control_for_uri (EShellView *shell_view, return NULL; container = bonobo_ui_component_get_container (priv->ui_component); - control = bonobo_widget_new_control_from_objref (corba_control, container); + control = e_bonobo_widget_new_control_from_objref (corba_control, container); socket = find_socket (GTK_CONTAINER (control)); destroy_connection_id = gtk_signal_connect (GTK_OBJECT (socket), "destroy", diff --git a/shell/e-shell.c b/shell/e-shell.c index 2d2d11565b..3d1fec1ff5 100644 --- a/shell/e-shell.c +++ b/shell/e-shell.c @@ -88,6 +88,8 @@ struct _EShellPrivate { EComponentRegistry *component_registry; + EShellUserCreatableItemsHandler *user_creatable_items_handler; + /* ::StorageRegistry interface handler. */ ECorbaStorageRegistry *corba_storage_registry; /* <aggregate> */ @@ -575,10 +577,14 @@ setup_components (EShell *shell, info = info_list->_buffer + i; - if (! e_component_registry_register_component (priv->component_registry, info->iid)) + if (! e_component_registry_register_component (priv->component_registry, info->iid)) { g_warning ("Cannot activate Evolution component -- %s", info->iid); - else + } else { + e_shell_user_creatable_items_handler_add_component + (priv->user_creatable_items_handler, + e_component_registry_get_component_by_id (priv->component_registry, info->iid)); g_print ("Evolution component activated successfully -- %s\n", info->iid); + } if (splash != NULL) e_splash_set_icon_highlight (splash, i, TRUE); @@ -707,6 +713,9 @@ destroy (GtkObject *object) if (priv->component_registry != NULL) gtk_object_unref (GTK_OBJECT (priv->component_registry)); + if (priv->user_creatable_items_handler != NULL) + gtk_object_unref (GTK_OBJECT (priv->user_creatable_items_handler)); + for (p = priv->views; p != NULL; p = p->next) { EShellView *view; @@ -795,22 +804,23 @@ init (EShell *shell) priv->views = NULL; - priv->iid = NULL; - priv->local_directory = NULL; - priv->storage_set = NULL; - priv->local_storage = NULL; - priv->summary_storage = NULL; - priv->shortcuts = NULL; - priv->component_registry = NULL; - priv->folder_type_registry = NULL; - priv->uri_schema_registry = NULL; - priv->corba_storage_registry = NULL; - priv->activity_handler = NULL; - priv->corba_shortcuts = NULL; - priv->offline_handler = NULL; - priv->crash_type_names = NULL; - priv->line_status = E_SHELL_LINE_STATUS_ONLINE; - priv->db = CORBA_OBJECT_NIL; + priv->iid = NULL; + priv->local_directory = NULL; + priv->storage_set = NULL; + priv->local_storage = NULL; + priv->summary_storage = NULL; + priv->shortcuts = NULL; + priv->component_registry = NULL; + priv->user_creatable_items_handler = NULL; + priv->folder_type_registry = NULL; + priv->uri_schema_registry = NULL; + priv->corba_storage_registry = NULL; + priv->activity_handler = NULL; + priv->corba_shortcuts = NULL; + priv->offline_handler = NULL; + priv->crash_type_names = NULL; + priv->line_status = E_SHELL_LINE_STATUS_ONLINE; + priv->db = CORBA_OBJECT_NIL; shell->priv = priv; } @@ -896,6 +906,8 @@ e_shell_construct (EShell *shell, while (gtk_events_pending ()) gtk_main_iteration (); + priv->user_creatable_items_handler = e_shell_user_creatable_items_handler_new (); + if (show_splash) setup_components (shell, E_SPLASH (splash)); else @@ -1554,6 +1566,24 @@ e_shell_get_config_db (EShell *shell) return shell->priv->db; } +EComponentRegistry * +e_shell_get_component_registry (EShell *shell) +{ + g_return_val_if_fail (shell != NULL, NULL); + g_return_val_if_fail (E_IS_SHELL (shell), NULL); + + return shell->priv->component_registry; +} + +EShellUserCreatableItemsHandler * +e_shell_get_user_creatable_items_handler (EShell *shell) +{ + g_return_val_if_fail (shell != NULL, NULL); + g_return_val_if_fail (E_IS_SHELL (shell), NULL); + + return shell->priv->user_creatable_items_handler; +} + void e_shell_unregister_all (EShell *shell) diff --git a/shell/e-shell.h b/shell/e-shell.h index 8aaa2d5060..3e09b3f072 100644 --- a/shell/e-shell.h +++ b/shell/e-shell.h @@ -39,9 +39,11 @@ typedef struct _EShellClass EShellClass; #include "Evolution.h" +#include "e-component-registry.h" #include "e-shortcuts.h" #include "e-shell-view.h" #include "e-uri-schema-registry.h" +#include "e-shell-user-creatable-items-handler.h" #include "e-local-storage.h" @@ -126,7 +128,9 @@ void e_shell_go_offline (EShell *shell, void e_shell_go_online (EShell *shell, EShellView *action_view); -Bonobo_ConfigDatabase e_shell_get_config_db (EShell *shell); +Bonobo_ConfigDatabase e_shell_get_config_db (EShell *shell); +EComponentRegistry *e_shell_get_component_registry (EShell *shell); +EShellUserCreatableItemsHandler *e_shell_get_user_creatable_items_handler (EShell *shell); const char *e_shell_construct_result_to_string (EShellConstructResult result); diff --git a/shell/evolution-shell-component.c b/shell/evolution-shell-component.c index bb1e7481f9..2ff908aa68 100644 --- a/shell/evolution-shell-component.c +++ b/shell/evolution-shell-component.c @@ -42,6 +42,14 @@ static GtkObjectClass *parent_class = NULL; +struct _UserCreatableItemType { + char *id; + char *description; + char *menu_description; + char menu_shortcut; +}; +typedef struct _UserCreatableItemType UserCreatableItemType; + struct _EvolutionShellComponentPrivate { GList *folder_types; /* EvolutionShellComponentFolderType */ GList *external_uri_schemas; /* char * */ @@ -55,6 +63,8 @@ struct _EvolutionShellComponentPrivate { EvolutionShellClient *owner_client; + GSList *user_creatable_item_types; /* UserCreatableItemType */ + void *closure; }; @@ -63,12 +73,43 @@ enum { OWNER_UNSET, DEBUG, HANDLE_EXTERNAL_URI, + USER_CREATE_NEW_ITEM, LAST_SIGNAL }; static guint signals[LAST_SIGNAL] = { 0 }; +/* UserCreatableItemType handling. */ + +static UserCreatableItemType * +user_creatable_item_type_new (const char *id, + const char *description, + const char *menu_description, + char menu_shortcut) +{ + UserCreatableItemType *type; + + type = g_new (UserCreatableItemType, 1); + type->id = g_strdup (id); + type->description = g_strdup (description); + type->menu_description = g_strdup (menu_description); + type->menu_shortcut = menu_shortcut; + + return type; +} + +static void +user_creatable_item_type_free (UserCreatableItemType *type) +{ + g_free (type->id); + g_free (type->description); + g_free (type->menu_description); + + g_free (type); +} + + /* Helper functions. */ /* Notice that, if passed a NULL pointer, this string will construct a @@ -127,8 +168,8 @@ fill_corba_sequence_from_null_terminated_string_array (CORBA_sequence_CORBA_stri /* CORBA interface implementation. */ static GNOME_Evolution_FolderTypeList * -impl_ShellComponent__get_supported_types (PortableServer_Servant servant, - CORBA_Environment *ev) +impl__get_supported_types (PortableServer_Servant servant, + CORBA_Environment *ev) { BonoboObject *bonobo_object; EvolutionShellComponent *shell_component; @@ -168,8 +209,8 @@ impl_ShellComponent__get_supported_types (PortableServer_Servant servant, } static GNOME_Evolution_URISchemaList * -impl_ShellComponent__get_external_uri_schemas (PortableServer_Servant servant, - CORBA_Environment *ev) +impl__get_external_uri_schemas (PortableServer_Servant servant, + CORBA_Environment *ev) { EvolutionShellComponent *shell_component; EvolutionShellComponentPrivate *priv; @@ -207,6 +248,42 @@ impl_ShellComponent__get_external_uri_schemas (PortableServer_Servant servant, return uri_schema_list; } +static GNOME_Evolution_UserCreatableItemTypeList * +impl__get_user_creatable_item_types (PortableServer_Servant servant, + CORBA_Environment *ev) +{ + EvolutionShellComponent *shell_component; + EvolutionShellComponentPrivate *priv; + GNOME_Evolution_UserCreatableItemTypeList *list; + GSList *p; + int i; + + shell_component = EVOLUTION_SHELL_COMPONENT (bonobo_object_from_servant (servant)); + priv = shell_component->priv; + + list = GNOME_Evolution_UserCreatableItemTypeList__alloc (); + list->_maximum = g_slist_length (priv->user_creatable_item_types); + list->_length = list->_maximum; + list->_buffer = CORBA_sequence_GNOME_Evolution_UserCreatableItemType_allocbuf (list->_maximum); + + for (p = priv->user_creatable_item_types, i = 0; p != NULL; p = p->next, i ++) { + GNOME_Evolution_UserCreatableItemType *corba_type; + const UserCreatableItemType *type; + + corba_type = list->_buffer + i; + type = (const UserCreatableItemType *) p->data; + + corba_type->id = CORBA_string_dup (type->id); + corba_type->description = CORBA_string_dup (type->description); + corba_type->menuDescription = CORBA_string_dup (type->menu_description); + corba_type->menuShortcut = type->menu_shortcut; + } + + CORBA_sequence_set_release (list, TRUE); + + return list; +} + static void impl_setOwner (PortableServer_Servant servant, const GNOME_Evolution_Shell shell, @@ -449,6 +526,22 @@ impl_populateFolderContextMenu (PortableServer_Servant servant, bonobo_object_unref (BONOBO_OBJECT (uic)); } +static void +impl_userCreateNewItem (PortableServer_Servant servant, + const CORBA_char *id, + CORBA_Environment *ev) +{ + EvolutionShellComponent *shell_component; + EvolutionShellComponentPrivate *priv; + + shell_component = EVOLUTION_SHELL_COMPONENT (bonobo_object_from_servant (servant)); + priv = shell_component->priv; + + /* FIXME: Check that the type is good. */ + + gtk_signal_emit (GTK_OBJECT (shell_component), signals[USER_CREATE_NEW_ITEM], id); +} + /* GtkObject methods. */ @@ -458,7 +551,7 @@ destroy (GtkObject *object) EvolutionShellComponent *shell_component; EvolutionShellComponentPrivate *priv; CORBA_Environment ev; - GList *p; + GSList *p; shell_component = EVOLUTION_SHELL_COMPONENT (object); @@ -487,6 +580,10 @@ destroy (GtkObject *object) e_free_string_list (priv->external_uri_schemas); + for (p = priv->user_creatable_item_types; p != NULL; p = p->next) + user_creatable_item_type_free ((UserCreatableItemType *) p->data); + g_slist_free (priv->user_creatable_item_types); + g_free (priv); parent_class->destroy (object); @@ -538,21 +635,32 @@ class_init (EvolutionShellComponentClass *klass) GTK_TYPE_NONE, 1, GTK_TYPE_STRING); + signals[USER_CREATE_NEW_ITEM] + = gtk_signal_new ("user_create_new_item", + GTK_RUN_FIRST, + object_class->type, + GTK_SIGNAL_OFFSET (EvolutionShellComponentClass, user_create_new_item), + gtk_marshal_NONE__STRING, + GTK_TYPE_NONE, 1, + GTK_TYPE_STRING); + gtk_object_class_add_signals (object_class, signals, LAST_SIGNAL); parent_class = gtk_type_class (PARENT_TYPE); - epv->_get_supported_types = impl_ShellComponent__get_supported_types; - epv->_get_external_uri_schemas = impl_ShellComponent__get_external_uri_schemas; - epv->setOwner = impl_setOwner; - epv->unsetOwner = impl_unsetOwner; - epv->debug = impl_debug; - epv->createView = impl_createView; - epv->handleExternalURI = impl_handleExternalURI; - epv->createFolderAsync = impl_createFolderAsync; - epv->removeFolderAsync = impl_removeFolderAsync; - epv->xferFolderAsync = impl_xferFolderAsync; - epv->populateFolderContextMenu = impl_populateFolderContextMenu; + epv->_get_supported_types = impl__get_supported_types; + epv->_get_external_uri_schemas = impl__get_external_uri_schemas; + epv->_get_user_creatable_item_types = impl__get_user_creatable_item_types; + epv->setOwner = impl_setOwner; + epv->unsetOwner = impl_unsetOwner; + epv->debug = impl_debug; + epv->createView = impl_createView; + epv->handleExternalURI = impl_handleExternalURI; + epv->createFolderAsync = impl_createFolderAsync; + epv->removeFolderAsync = impl_removeFolderAsync; + epv->xferFolderAsync = impl_xferFolderAsync; + epv->populateFolderContextMenu = impl_populateFolderContextMenu; + epv->userCreateNewItem = impl_userCreateNewItem; } static void @@ -677,6 +785,30 @@ evolution_shell_component_get_owner (EvolutionShellComponent *shell_component) } +void +evolution_shell_component_add_user_creatable_item (EvolutionShellComponent *shell_component, + const char *id, + const char *description, + const char *menu_description, + char menu_shortcut) +{ + EvolutionShellComponentPrivate *priv; + UserCreatableItemType *type; + + g_return_if_fail (shell_component != NULL); + g_return_if_fail (EVOLUTION_IS_SHELL_COMPONENT (shell_component)); + g_return_if_fail (id != NULL); + g_return_if_fail (description != NULL); + g_return_if_fail (menu_description != NULL); + + priv = shell_component->priv; + + type = user_creatable_item_type_new (id, description, menu_description, menu_shortcut); + + priv->user_creatable_item_types = g_slist_prepend (priv->user_creatable_item_types, type); +} + + E_MAKE_X_TYPE (evolution_shell_component, "EvolutionShellComponent", EvolutionShellComponent, class_init, init, PARENT_TYPE, POA_GNOME_Evolution_ShellComponent__init, diff --git a/shell/evolution-shell-component.h b/shell/evolution-shell-component.h index de48b84108..69a17f69a9 100644 --- a/shell/evolution-shell-component.h +++ b/shell/evolution-shell-component.h @@ -43,6 +43,7 @@ extern "C" { #define EVOLUTION_IS_SHELL_COMPONENT_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((obj), EVOLUTION_TYPE_SHELL_COMPONENT)) #define EVOLUTION_SHELL_COMPONENT_POPUP_PLACEHOLDER "/popups/FolderPopup/ComponentPlaceholder" + typedef struct _EvolutionShellComponent EvolutionShellComponent; typedef struct _EvolutionShellComponentPrivate EvolutionShellComponentPrivate; @@ -138,6 +139,9 @@ struct _EvolutionShellComponentClass { void (* handle_external_uri) (EvolutionShellComponent *shell_component, const char *uri); + + void (* user_create_new_item) (EvolutionShellComponent *shell_component, + const char *id); }; @@ -163,6 +167,12 @@ EvolutionShellComponent *evolution_shell_component_new (const EvolutionSh void *closure); EvolutionShellClient *evolution_shell_component_get_owner (EvolutionShellComponent *shell_component); +void evolution_shell_component_add_user_creatable_item (EvolutionShellComponent *shell_component, + const char *id, + const char *description, + const char *menu_description, + char menu_shortcut); + #ifdef cplusplus } #endif /* cplusplus */ diff --git a/shell/evolution-test-component.c b/shell/evolution-test-component.c index 4d70525c40..336912cb8c 100644 --- a/shell/evolution-test-component.c +++ b/shell/evolution-test-component.c @@ -268,6 +268,13 @@ owner_unset_callback (EvolutionShellComponent *shell_component, g_idle_add_full (G_PRIORITY_LOW, owner_unset_idle_callback, NULL, NULL); } +static void +user_create_new_item_callback (EvolutionShellComponent *shell_component, + const char *id) +{ + g_print ("\n*** Should create -- %s\n", id); +} + static BonoboObject * factory_fn (BonoboGenericFactory *factory, @@ -285,6 +292,12 @@ factory_fn (BonoboGenericFactory *factory, gtk_signal_connect (GTK_OBJECT (shell_component), "owner_unset", GTK_SIGNAL_FUNC (owner_unset_callback), NULL); + evolution_shell_component_add_user_creatable_item (shell_component, "Stuff", "New Stuff", "New _Stuff", '\0'); + evolution_shell_component_add_user_creatable_item (shell_component, "MoreStuff", "New More Stuff", "New _More Stuff", 'n'); + + gtk_signal_connect (GTK_OBJECT (shell_component), "user_create_new_item", + GTK_SIGNAL_FUNC (user_create_new_item_callback), NULL); + return BONOBO_OBJECT (shell_component); } |