aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--shell/ChangeLog53
-rw-r--r--shell/Evolution-ShellComponent.idl12
-rw-r--r--shell/Makefile.am2
-rw-r--r--shell/e-component-registry.h5
-rw-r--r--shell/e-shell-user-creatable-items-handler.c432
-rw-r--r--shell/e-shell-user-creatable-items-handler.h72
-rw-r--r--shell/e-shell-view.c7
-rw-r--r--shell/e-shell.c66
-rw-r--r--shell/e-shell.h6
-rw-r--r--shell/evolution-shell-component.c164
-rw-r--r--shell/evolution-shell-component.h10
-rw-r--r--shell/evolution-test-component.c13
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);
}