[evolution-patches] new new button



These patches redo the "New" button (and File->New submenu) to be
created and managed by each component rather than the shell. (This is
needed to get it to work correctly in Connector, and also moves us a
little bit more towards separate components with no shell.)

It also implements Anna's new item layout (Current component's objects,
current component's "folder" type, separator, other components' object,
separator, other components' "folder" types) and names ("Address book"
-> "Contacts Group", "Task List" -> "Tasks Group").

Also, while doing that, I fixed up the shortcuts to not conflict,
leaving us with:

      * Mail Message (M)
      * Contact (C)
      * Contact List (L)
      * Appointment (A)
      * All-Day Appointment (D)
      * Meeting (E)
      * Task (T)

      * Mail Folder (F)
      * Contacts Group (G)
      * Calendar (R)
      * Tasks Group (S)

The last 3 are new. "G" is ok, but "R" and "S" kinda suck...

Also, "Post" went missing from the mail creatable items list at some
point and needs to be added back...


Index: addressbook/gui/component/addressbook-component.c
===================================================================
RCS file: /cvs/gnome/evolution/addressbook/gui/component/addressbook-component.c,v
retrieving revision 1.121
diff -u -r1.121 addressbook-component.c
--- addressbook/gui/component/addressbook-component.c	30 Mar 2004 23:21:34 -0000	1.121
+++ addressbook/gui/component/addressbook-component.c	8 Apr 2004 20:42:57 -0000
@@ -553,6 +553,7 @@
 	list->_buffer[0].tooltip = _("Create a new contact");
 	list->_buffer[0].menuShortcut = 'c';
 	list->_buffer[0].iconName = "evolution-contacts-mini.png";
+	list->_buffer[0].type = GNOME_Evolution_CREATABLE_OBJECT;
 
 	list->_buffer[1].id = "contact_list";
 	list->_buffer[1].description = _("New Contact List");
@@ -560,13 +561,15 @@
 	list->_buffer[1].tooltip = _("Create a new contact list");
 	list->_buffer[1].menuShortcut = 'l';
 	list->_buffer[1].iconName = "contact-list-16.png";
+	list->_buffer[1].type = GNOME_Evolution_CREATABLE_OBJECT;
 
 	list->_buffer[2].id = "address_book";
-	list->_buffer[2].description = _("New Addressbook Book");
-	list->_buffer[2].menuDescription = _("_Address Book");
-	list->_buffer[2].tooltip = _("Create a new address book");
-	list->_buffer[2].menuShortcut = 'a';
+	list->_buffer[2].description = _("New Contacts Group");
+	list->_buffer[2].menuDescription = _("_Contacts Group");
+	list->_buffer[2].tooltip = _("Create a new contacts group");
+	list->_buffer[2].menuShortcut = 'g';
 	list->_buffer[2].iconName = "evolution-contacts-mini.png";
+	list->_buffer[2].type = GNOME_Evolution_CREATABLE_FOLDER;
 
 	return list;
 }
Index: addressbook/gui/component/addressbook.c
===================================================================
RCS file: /cvs/gnome/evolution/addressbook/gui/component/addressbook.c,v
retrieving revision 1.228
diff -u -r1.228 addressbook.c
--- addressbook/gui/component/addressbook.c	30 Mar 2004 21:38:41 -0000	1.228
+++ addressbook/gui/component/addressbook.c	8 Apr 2004 20:42:57 -0000
@@ -39,6 +39,7 @@
 #include <gal/util/e-util.h>
 
 #include "e-util/e-passwords.h"
+#include "shell/e-user-creatable-items-handler.h"
 
 #include "evolution-shell-component-utils.h"
 #include "e-activity-handler.h"
@@ -76,6 +77,7 @@
 	BonoboPropertyBag *properties;
 	ESourceList *source_list;
 	char *passwd;
+	EUserCreatableItemsHandler *creatable_items_handler;
 } AddressbookView;
 
 static void addressbook_view_ref (AddressbookView *);
@@ -458,6 +460,8 @@
 
 	e_pixmaps_update (uic, pixmaps);
 
+	e_user_creatable_items_handler_activate (view->creatable_items_handler, uic);
+
 	bonobo_ui_component_thaw (uic, NULL);
 
 	if (v)
@@ -1125,6 +1129,8 @@
 	g_signal_connect (view->source_list,
 			  "changed",
 			  G_CALLBACK (source_list_changed_cb), view);
+
+	view->creatable_items_handler = e_user_creatable_items_handler_new ("contacts");
 
 	g_signal_connect (view->control, "activate",
 			  G_CALLBACK (control_activate_cb), view);
Index: calendar/gui/calendar-commands.c
===================================================================
RCS file: /cvs/gnome/evolution/calendar/gui/calendar-commands.c,v
retrieving revision 1.149
diff -u -r1.149 calendar-commands.c
--- calendar/gui/calendar-commands.c	7 Apr 2004 16:12:22 -0000	1.149
+++ calendar/gui/calendar-commands.c	8 Apr 2004 20:42:57 -0000
@@ -787,7 +787,7 @@
 	uic = bonobo_control_get_ui_component (control);
 	g_assert (uic != NULL);
 
-	gnome_calendar_set_ui_component (gcal, uic);
+	gnome_calendar_set_ui_component (gcal, NULL);
 
 	focus = g_object_get_data (G_OBJECT (control), "focus_data");
 	g_assert (focus != NULL);
Index: calendar/gui/calendar-component.c
===================================================================
RCS file: /cvs/gnome/evolution/calendar/gui/calendar-component.c,v
retrieving revision 1.156
diff -u -r1.156 calendar-component.c
--- calendar/gui/calendar-component.c	30 Mar 2004 08:31:57 -0000	1.156
+++ calendar/gui/calendar-component.c	8 Apr 2004 20:42:58 -0000
@@ -925,6 +925,7 @@
 	list->_buffer[0].tooltip = _("Create a new appointment");
 	list->_buffer[0].menuShortcut = 'a';
 	list->_buffer[0].iconName = "new_appointment.xpm";
+	list->_buffer[0].type = GNOME_Evolution_CREATABLE_OBJECT;
 
 	list->_buffer[1].id = CREATE_MEETING_ID;
 	list->_buffer[1].description = _("New meeting");
@@ -932,6 +933,7 @@
 	list->_buffer[1].tooltip = _("Create a new meeting request");
 	list->_buffer[1].menuShortcut = 'e';
 	list->_buffer[1].iconName = "meeting-request-16.png";
+	list->_buffer[1].type = GNOME_Evolution_CREATABLE_OBJECT;
 
 	list->_buffer[2].id = CREATE_ALLDAY_EVENT_ID;
 	list->_buffer[2].description = _("New all day appointment");
@@ -939,13 +941,15 @@
 	list->_buffer[2].tooltip = _("Create a new all-day appointment");
 	list->_buffer[2].menuShortcut = 'd';
 	list->_buffer[2].iconName = "new_all_day_event.png";
+	list->_buffer[2].type = GNOME_Evolution_CREATABLE_OBJECT;
 
 	list->_buffer[3].id = CREATE_CALENDAR_ID;
 	list->_buffer[3].description = _("New calendar");
-	list->_buffer[3].menuDescription = _("C_alendar");
+	list->_buffer[3].menuDescription = _("Calenda_r");
 	list->_buffer[3].tooltip = _("Create a new calendar");
-	list->_buffer[3].menuShortcut = 'a';
+	list->_buffer[3].menuShortcut = 'r';
 	list->_buffer[3].iconName = "evolution-calendar-mini.png";
+	list->_buffer[3].type = GNOME_Evolution_CREATABLE_FOLDER;
 
 	return list;
 }
Index: calendar/gui/e-tasks.c
===================================================================
RCS file: /cvs/gnome/evolution/calendar/gui/e-tasks.c,v
retrieving revision 1.83
diff -u -r1.83 e-tasks.c
--- calendar/gui/e-tasks.c	25 Mar 2004 17:56:06 -0000	1.83
+++ calendar/gui/e-tasks.c	8 Apr 2004 20:42:58 -0000
@@ -36,6 +36,7 @@
 #include "e-util/e-categories-config.h"
 #include "e-util/e-time-utils.h"
 #include "e-util/e-url.h"
+#include "shell/e-user-creatable-items-handler.h"
 #include <libecal/e-cal-time-util.h>
 #include "widgets/menus/gal-view-menus.h"
 #include "dialogs/delete-error.h"
@@ -75,6 +76,8 @@
 	GalViewMenus *view_menus;
 
 	GList *notifications;
+
+	EUserCreatableItemsHandler *creatable_items_handler;
 };
 
 
@@ -692,6 +695,14 @@
 	g_return_if_fail (ui_component == NULL || BONOBO_IS_UI_COMPONENT (ui_component));
 
 	e_search_bar_set_ui_component (E_SEARCH_BAR (tasks->priv->search_bar), ui_component);
+
+	if (ui_component) {
+		if (!tasks->priv->creatable_items_handler) {
+			tasks->priv->creatable_items_handler =
+				e_user_creatable_items_handler_new ("tasks");
+		}
+		e_user_creatable_items_handler_activate (tasks->priv->creatable_items_handler, ui_component);
+	}
 }
 
 
@@ -733,6 +744,11 @@
 			calendar_config_remove_notification (GPOINTER_TO_UINT (l->data));
 		priv->notifications = NULL;
 		
+		if (priv->creatable_items_handler) {
+			g_object_unref (priv->creatable_items_handler);
+			priv->creatable_items_handler = NULL;
+		}
+
 		g_free (priv);
 		tasks->priv = NULL;
 	}
Index: calendar/gui/gnome-cal.c
===================================================================
RCS file: /cvs/gnome/evolution/calendar/gui/gnome-cal.c,v
retrieving revision 1.317
diff -u -r1.317 gnome-cal.c
--- calendar/gui/gnome-cal.c	7 Apr 2004 16:12:22 -0000	1.317
+++ calendar/gui/gnome-cal.c	8 Apr 2004 20:42:58 -0000
@@ -42,6 +42,7 @@
 #include <libgnomeui/gnome-dialog-util.h>
 #include <bonobo/bonobo-exception.h>
 #include "e-util/e-url.h"
+#include "shell/e-user-creatable-items-handler.h"
 #include <libecal/e-cal-time-util.h>
 #include <gal/menus/gal-view-factory-etable.h>
 #include <gal/menus/gal-view-etable.h>
@@ -154,6 +155,9 @@
 	   'dates-shown-changed' signal.*/
 	time_t visible_start;
 	time_t visible_end;
+
+	/* Our associated creatable items handler */
+	EUserCreatableItemsHandler *creatable_items_handler;
 };
 
 /* Signal IDs */
@@ -1193,6 +1197,11 @@
 			priv->view_menus = NULL;
 		}
 
+		if (priv->creatable_items_handler) {
+			g_object_unref (priv->creatable_items_handler);
+			priv->creatable_items_handler = NULL;
+		}
+
 		g_free (priv);
 		gcal->priv = NULL;
 	}
@@ -1992,6 +2001,14 @@
 	g_return_if_fail (ui_component == NULL || BONOBO_IS_UI_COMPONENT (ui_component));
 
 	e_search_bar_set_ui_component (E_SEARCH_BAR (gcal->priv->search_bar), ui_component);
+
+	if (ui_component) {
+		if (!gcal->priv->creatable_items_handler) {
+			gcal->priv->creatable_items_handler =
+				e_user_creatable_items_handler_new ("calendar");
+		}
+		e_user_creatable_items_handler_activate (gcal->priv->creatable_items_handler, ui_component);
+	}
 }
 
 /**
Index: calendar/gui/tasks-component.c
===================================================================
RCS file: /cvs/gnome/evolution/calendar/gui/tasks-component.c,v
retrieving revision 1.58
diff -u -r1.58 tasks-component.c
--- calendar/gui/tasks-component.c	29 Mar 2004 22:06:53 -0000	1.58
+++ calendar/gui/tasks-component.c	8 Apr 2004 20:42:58 -0000
@@ -562,13 +562,15 @@
 	list->_buffer[0].tooltip = _("Create a new task");
 	list->_buffer[0].menuShortcut = 't';
 	list->_buffer[0].iconName = "new_task-16.png";
+	list->_buffer[0].type = GNOME_Evolution_CREATABLE_OBJECT;
 
 	list->_buffer[1].id = CREATE_TASK_LIST_ID;
-	list->_buffer[1].description = _("New task list");
-	list->_buffer[1].menuDescription = _("_Task List");
-	list->_buffer[1].tooltip = _("Create a new task list");
-	list->_buffer[1].menuShortcut = 'n';
+	list->_buffer[1].description = _("New tasks group");
+	list->_buffer[1].menuDescription = _("Task_s Group");
+	list->_buffer[1].tooltip = _("Create a new tasks group");
+	list->_buffer[1].menuShortcut = 's';
 	list->_buffer[1].iconName = "evolution-tasks-mini.png";
+	list->_buffer[1].type = GNOME_Evolution_CREATABLE_FOLDER;
 
 	return list;
 }
Index: mail/em-folder-view.c
===================================================================
RCS file: /cvs/gnome/evolution/mail/em-folder-view.c,v
retrieving revision 1.47
diff -u -r1.47 em-folder-view.c
--- mail/em-folder-view.c	8 Apr 2004 08:00:06 -0000	1.47
+++ mail/em-folder-view.c	8 Apr 2004 20:42:59 -0000
@@ -55,6 +55,7 @@
 #include <bonobo/bonobo-ui-util.h>
 
 #include "widgets/misc/e-charset-picker.h"
+#include "shell/e-user-creatable-items-handler.h"
 
 #include <e-util/e-dialog-utils.h>
 
@@ -117,6 +118,8 @@
 
 	GtkWidget *invisible;
 	char *selection_uri;
+
+	EUserCreatableItemsHandler *creatable_items_handler;
 };
 
 static GtkVBoxClass *emfv_parent;
@@ -173,6 +176,8 @@
 
 	emfv->async = mail_async_event_new();
 
+	p->creatable_items_handler = e_user_creatable_items_handler_new ("mail");
+
 	emfv_setting_setup(emfv);
 }
 
@@ -192,6 +197,9 @@
 		g_free(emfv->folder_uri);
 	}
 
+	if (p->creatable_items_handler)
+		g_object_unref (p->creatable_items_handler);
+
 	g_slist_free(emfv->ui_files);
 	g_slist_free(emfv->enable_map);
 
@@ -1647,6 +1655,8 @@
 		emfv_enable_menus(emfv);
 		if (emfv->statusbar_active)
 			bonobo_ui_component_set_translate (uic, "/", "<status><item name=\"main\"/></status>", NULL);
+
+		e_user_creatable_items_handler_activate (emfv->priv->creatable_items_handler, uic);
 	} else {
 		const BonoboUIVerb *v;
 
Index: mail/mail-component.c
===================================================================
RCS file: /cvs/gnome/evolution/mail/mail-component.c,v
retrieving revision 1.67
diff -u -r1.67 mail-component.c
--- mail/mail-component.c	8 Apr 2004 08:00:06 -0000	1.67
+++ mail/mail-component.c	8 Apr 2004 20:42:59 -0000
@@ -622,6 +622,7 @@
 	list->_buffer[0].tooltip = _("Compose a new mail message");
 	list->_buffer[0].menuShortcut = 'm';
 	list->_buffer[0].iconName = "new-message.xpm";
+	list->_buffer[0].type = GNOME_Evolution_CREATABLE_OBJECT;
 
 	list->_buffer[1].id = "folder";
 	list->_buffer[1].description = _("New Mail Folder");
@@ -629,6 +630,7 @@
 	list->_buffer[1].tooltip = _("Create a new mail folder");
 	list->_buffer[1].menuShortcut = 'f';
 	list->_buffer[1].iconName = "folder-mini.png";
+	list->_buffer[1].type = GNOME_Evolution_CREATABLE_FOLDER;
 
 	return list;
 }
Index: shell/Evolution-Component.idl
===================================================================
RCS file: /cvs/gnome/evolution/shell/Evolution-Component.idl,v
retrieving revision 1.13
diff -u -r1.13 Evolution-Component.idl
--- shell/Evolution-Component.idl	4 Feb 2004 10:55:24 -0000	1.13
+++ shell/Evolution-Component.idl	8 Apr 2004 20:42:59 -0000
@@ -12,6 +12,11 @@
 
 module GNOME {
 module Evolution {
+	enum CreatableItem {
+		CREATABLE_OBJECT,
+		CREATABLE_FOLDER
+	};
+
 	/* A type of item that the component can create when asked by the user,
 	   e.g. a mail message or an appointment.  */
 	struct CreatableItemType {
@@ -21,6 +26,7 @@
 		string tooltip;
 		char menuShortcut;
 		string iconName;
+		CreatableItem type;
 	};
 	typedef sequence <CreatableItemType> CreatableItemTypeList;
 
Index: shell/Makefile.am
===================================================================
RCS file: /cvs/gnome/evolution/shell/Makefile.am,v
retrieving revision 1.192
diff -u -r1.192 Makefile.am
--- shell/Makefile.am	4 Feb 2004 21:08:30 -0000	1.192
+++ shell/Makefile.am	8 Apr 2004 20:42:59 -0000
@@ -104,6 +104,7 @@
 	e-icon-factory.h			\
 	e-shell-corba-icon-utils.h		\
 	e-shell-utils.h				\
+	e-user-creatable-items-handler.h	\
 	evolution-config-control.h		\
 	evolution-shell-component-utils.h	\
 	evolution-wizard.h
@@ -114,13 +115,15 @@
 	e-icon-factory.c			\
 	e-shell-corba-icon-utils.c		\
 	e-shell-utils.c				\
+	e-user-creatable-items-handler.c	\
 	evolution-config-control.c		\
 	evolution-shell-component-utils.c	\
 	evolution-wizard.c			\
 	$(eshellinclude_HEADERS)
 
 libeshell_la_LIBADD =				\
-	$(top_builddir)/e-util/libeutil.la
+	$(top_builddir)/e-util/libeutil.la	\
+	$(top_builddir)/widgets/misc/libemiscwidgets.la
 
 # Evolution executable
 
@@ -156,8 +159,6 @@
 	e-shell.h				\
 	e-sidebar.c				\
 	e-sidebar.h				\
-	e-user-creatable-items-handler.c	\
-	e-user-creatable-items-handler.h	\
 	main.c
 
 evolution_LDADD =							\
Index: shell/e-shell-window.c
===================================================================
RCS file: /cvs/gnome/evolution/shell/e-shell-window.c,v
retrieving revision 1.18
diff -u -r1.18 e-shell-window.c
--- shell/e-shell-window.c	26 Jan 2004 21:56:03 -0000	1.18
+++ shell/e-shell-window.c	8 Apr 2004 20:42:59 -0000
@@ -738,8 +738,6 @@
 				     gconf_client_get_int (gconf_client, "/apps/evolution/shell/view_defaults/width", NULL),
 				     gconf_client_get_int (gconf_client, "/apps/evolution/shell/view_defaults/height", NULL));
 
-	e_user_creatable_items_handler_attach_menus (e_shell_peek_user_creatable_items_handler (shell), window);
-
 	g_object_unref (gconf_client);
 	return GTK_WIDGET (window);
 }
Index: shell/e-shell.c
===================================================================
RCS file: /cvs/gnome/evolution/shell/e-shell.c,v
retrieving revision 1.239
diff -u -r1.239 e-shell.c
--- shell/e-shell.c	12 Mar 2004 07:58:20 -0000	1.239
+++ shell/e-shell.c	8 Apr 2004 20:42:59 -0000
@@ -77,7 +77,6 @@
 
 	GList *windows;
 
-	EUserCreatableItemsHandler *user_creatable_items_handler;
 	/* EUriSchemaRegistry *uri_schema_registry; FIXME */
 	EComponentRegistry *component_registry;
 
@@ -340,11 +339,6 @@
 
 	priv->is_initialized = FALSE;
 
-	if (priv->user_creatable_items_handler != NULL) {
-		g_object_unref (priv->user_creatable_items_handler);
-		priv->user_creatable_items_handler = NULL;
-	}
-
 #if 0				/* FIXME */
 	if (priv->uri_schema_registry != NULL) {
 		g_object_unref (priv->uri_schema_registry);
@@ -465,7 +459,6 @@
 	priv = g_new0 (EShellPrivate, 1);
 	priv->line_status                  = E_SHELL_LINE_STATUS_OFFLINE;
 	priv->component_registry           = e_component_registry_new ();
-	priv->user_creatable_items_handler = e_user_creatable_items_handler_new (priv->component_registry);
 
 	shell->priv = priv;
 }
@@ -1164,14 +1157,5 @@
 
 	return can_quit;
 }
-
-EUserCreatableItemsHandler *
-e_shell_peek_user_creatable_items_handler (EShell *shell)
-{
-	g_return_val_if_fail (E_IS_SHELL (shell), NULL);
-
-	return shell->priv->user_creatable_items_handler;
-}
-
 
 BONOBO_TYPE_FUNC_FULL (EShell, GNOME_Evolution_Shell, PARENT_TYPE, e_shell)
Index: shell/e-shell.h
===================================================================
RCS file: /cvs/gnome/evolution/shell/e-shell.h,v
retrieving revision 1.66
diff -u -r1.66 e-shell.h
--- shell/e-shell.h	4 Feb 2004 10:55:25 -0000	1.66
+++ shell/e-shell.h	8 Apr 2004 20:42:59 -0000
@@ -39,7 +39,6 @@
 
 #include "e-component-registry.h"
 #include "e-shell-window.h"
-#include "e-user-creatable-items-handler.h"
 
 
 #define E_TYPE_SHELL			(e_shell_get_type ())
@@ -136,8 +135,6 @@
 gboolean e_shell_quit (EShell *shell);
 
 const char *e_shell_construct_result_to_string (EShellConstructResult result);
-
-EUserCreatableItemsHandler *e_shell_peek_user_creatable_items_handler (EShell *shell);
 
 
 #ifdef __cplusplus
Index: shell/e-user-creatable-items-handler.c
===================================================================
RCS file: /cvs/gnome/evolution/shell/e-user-creatable-items-handler.c,v
retrieving revision 1.5
diff -u -r1.5 e-user-creatable-items-handler.c
--- shell/e-user-creatable-items-handler.c	14 Dec 2003 15:54:39 -0000	1.5
+++ shell/e-user-creatable-items-handler.c	8 Apr 2004 20:42:59 -0000
@@ -1,7 +1,7 @@
 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
-/* e-shell-user-creatable-items-handler.c
+/* e-user-creatable-items-handler.c
  *
- * Copyright (C) 2001  Ximian, Inc.
+ * Copyright (C) 2001-2004 Novell, Inc.
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of version 2 of the GNU General Public
@@ -27,10 +27,10 @@
 #include "e-user-creatable-items-handler.h"
 
 #include "e-shell-utils.h"
-
-#include "widgets/misc/e-combo-button.h"
+#include "Evolution.h"
 
 #include "e-util/e-corba-utils.h"
+#include "widgets/misc/e-combo-button.h"
 
 #include <gal/util/e-util.h>
 
@@ -40,6 +40,11 @@
 
 #include <libgnome/gnome-i18n.h>
 
+#include <gtk/gtkaccelgroup.h>
+#include <gtk/gtkimage.h>
+#include <gtk/gtkimagemenuitem.h>
+#include <gtk/gtkmenu.h>
+#include <gtk/gtkseparatormenuitem.h>
 #include <gtk/gtksignal.h>
 #include <gtk/gtktooltips.h>
 
@@ -52,16 +57,8 @@
 static GObjectClass *parent_class = NULL;
 
 
-#define VERB_PREFIX "ShellUserCreatableItemVerb"
-
-#define EVOLUTION_MAIL_OAFIID "OAFIID:GNOME_Evolution_Mail_ShellComponent:" BASE_VERSION
-
-#define SHELL_WINDOW_KEY          "EUserCreatableItemsHandler:shell_window"
-#define COMBO_BUTTON_WIDGET_KEY "EUserCreatableItemsHandler:combo_button"
-#define TOOLTIPS_KEY            "EUserCreatableItemsHandler:tooltips"
-
 struct _Component {
-	char *id;
+	char *id, *alias;
 	GNOME_Evolution_Component component;
 	GNOME_Evolution_CreatableItemTypeList *type_list;
 };
@@ -73,23 +70,38 @@
 	char shortcut;
 	char *verb;
 	char *tooltip;
-	char *component_id;
+	char *component;
 	GdkPixbuf *icon;
 };
 typedef struct _MenuItem MenuItem;
 
 struct _EUserCreatableItemsHandlerPrivate {
+	/* This component's alias */
+	char *this_component;
+
 	/* The components that register user creatable items.  */
 	GSList *components;	/* Component */
 
 	/* The "New ..." menu items.  */
-	GSList *menu_items;     /* MenuItem */
+	GSList *objects;     /* MenuItem */
+	GSList *folders;     /* MenuItem */
 
 	/* The default item (the mailer's "message" item).  To be used when the
 	   component in the view we are in doesn't provide a default user
 	   creatable type.  This pointer always points to one of the menu items
-	   in ->menu_items.  */
+	   in ->objects.  */
 	const MenuItem *default_menu_item;
+
+	char *menu_xml;
+	GtkWidget *new_button, *new_menu;
+	BonoboControl *new_control;
+	GtkTooltips *tooltips;
+	GtkAccelGroup *accel_group;
+};
+
+enum {
+	PROP_THIS_COMPONENT = 1,
+	LAST_PROP
 };
 
 
@@ -97,6 +109,7 @@
 
 static Component *
 component_new (const char *id,
+	       const char *component_alias,
 	       GNOME_Evolution_Component component)
 {
 	CORBA_Environment ev;
@@ -106,6 +119,7 @@
 
 	new = g_new (Component, 1);
 	new->id = g_strdup (id);
+	new->alias = g_strdup (component_alias);
 
 	new->type_list = GNOME_Evolution_Component__get_userCreatableItems (component, &ev);
 	if (BONOBO_EX (&ev))
@@ -132,6 +146,7 @@
 	Bonobo_Unknown_unref (component->component, &ev);
 
 	g_free (component->id);
+	g_free (component->alias);
 
 	if (component->type_list != NULL)
 		CORBA_free (component->type_list);
@@ -141,25 +156,47 @@
 	g_free (component);
 }
 
+static const char *component_query =
+	"repo_ids.has ('IDL:GNOME/Evolution/Component:" BASE_VERSION "')";
+
 static void
-get_components_from_registry (EUserCreatableItemsHandler *handler,
-			      EComponentRegistry *registry)
+get_components_from_bonobo (EUserCreatableItemsHandler *handler)
 {
-	GSList *registry_list = e_component_registry_peek_list (registry);
-	GSList *p;
+	Bonobo_ServerInfoList *info_list;
+	Bonobo_ActivationProperty *property;
+	CORBA_Environment ev;
+	char *iid, *alias;
+	GNOME_Evolution_Component corba_component;
+	Component *component;
+	int i;
 
-	for (p = registry_list; p != NULL; p = p->next) {
-		EComponentInfo *info = p->data;
-		Component *component = NULL;
+	CORBA_exception_init (&ev);
+	info_list = bonobo_activation_query (component_query, NULL, &ev);
+	if (BONOBO_EX (&ev)) {
+		char *ex_text = bonobo_exception_get_text (&ev);
+		g_warning ("Cannot query for components: %s\n", ex_text);
+		g_free (ex_text);
+		CORBA_exception_free (&ev);
+		return;
+	}
 
-		e_component_registry_activate (registry, info->id, NULL);
+	for (i = 0; i < info_list->_length; i++) {
+		iid = info_list->_buffer[i].iid;
+		corba_component = bonobo_activation_activate_from_id (iid, Bonobo_ACTIVATION_FLAG_EXISTING_ONLY, NULL, &ev);
+		if (BONOBO_EX (&ev)) {
+			CORBA_exception_free (&ev);
+			continue;
+		}
 
-		if (info->iface != CORBA_OBJECT_NIL)
-			component = component_new (info->id, info->iface);
+		property = bonobo_server_info_prop_find (&info_list->_buffer[i],
+							 "evolution:component_alias");
+		alias = property ? property->v._u.value_string : "unknown";
 
-		if (component)
-			handler->priv->components = g_slist_prepend (handler->priv->components, component);
+		component = component_new (iid, alias, corba_component);
+		handler->priv->components = g_slist_prepend (handler->priv->components, component);
 	}
+
+	CORBA_free (info_list);
 }
 
 
@@ -167,22 +204,24 @@
 
 static gboolean
 item_is_default (const MenuItem *item,
-		 const char *component_id)
+		 const char *component)
 {
-	if (component_id == NULL)
+	if (component == NULL)
 		return FALSE;
 
-	if (strcmp (item->component_id, component_id) == 0)
+	if (strcmp (item->component, component) == 0)
 		return TRUE;
 	else
 		return FALSE;
 }
 
 static char *
-create_verb_from_component_number_and_type_id (int component_num,
-					       const char *type_id)
+create_verb (EUserCreatableItemsHandler *handler,
+	     int component_num, const char *type_id)
 {
-	return g_strdup_printf (VERB_PREFIX ":%d:%s", component_num, type_id);
+	return g_strdup_printf ("EUserCreatableItemsHandler-%s:%d:%s",
+				handler->priv->this_component,
+				component_num, type_id);
 }
 
 
@@ -193,16 +232,16 @@
 ensure_menu_items (EUserCreatableItemsHandler *handler)
 {
 	EUserCreatableItemsHandlerPrivate *priv;
-	GSList *menu_items;
+	GSList *objects, *folders;
 	GSList *p;
 	int component_num;
 	const char *default_verb;
 
 	priv = handler->priv;
-	if (priv->menu_items != NULL)
+	if (priv->objects != NULL)
 		return;
 
-	menu_items = NULL;
+	objects = folders = NULL;
 	component_num = 0;
 	default_verb = NULL;
 	for (p = priv->components; p != NULL; p = p->next) {
@@ -212,42 +251,46 @@
 		component = (const Component *) p->data;
 		if (component->type_list != NULL) {
 			for (i = 0; i < component->type_list->_length; i ++) {
-				const GNOME_Evolution_CreatableItemType *type;
+				const GNOME_Evolution_CreatableItemType *corba_item;
 				MenuItem *item;
 
-				type = (const GNOME_Evolution_CreatableItemType *) component->type_list->_buffer + i;
+				corba_item = (const GNOME_Evolution_CreatableItemType *) 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);
-				item->tooltip      = type->tooltip;
-				item->component_id = g_strdup (component->id);
+				item->label        = corba_item->menuDescription;
+				item->shortcut     = corba_item->menuShortcut;
+				item->verb         = create_verb (handler, component_num, corba_item->id);
+				item->tooltip      = corba_item->tooltip;
+				item->component    = g_strdup (component->alias);
 
-				if (strcmp (item->component_id, EVOLUTION_MAIL_OAFIID) == 0
-				    && strcmp (type->id, "message") == 0)
+				if (strcmp (item->component, "mail") == 0
+				    && strcmp (corba_item->id, "message") == 0)
 					default_verb = item->verb;
 
-				if (type->iconName == "") {
+				if (corba_item->iconName == "") {
 					item->icon = NULL;
 				} else {
-					char *icon_path = e_shell_get_icon_path (type->iconName, TRUE);
+					char *icon_path = e_shell_get_icon_path (corba_item->iconName, TRUE);
 					item->icon = gdk_pixbuf_new_from_file (icon_path, NULL);
 					g_free (icon_path);
 				}
 
-				menu_items = g_slist_prepend (menu_items, item);
+				if (corba_item->type == GNOME_Evolution_CREATABLE_OBJECT)
+					objects = g_slist_prepend (objects, item);
+				else
+					folders = g_slist_prepend (folders, item);
 			}
 		}
 
 		component_num ++;
 	}
 
-	priv->menu_items = g_slist_reverse (menu_items);
+	priv->objects = g_slist_reverse (objects);
+	priv->folders = g_slist_reverse (folders);
 
 	priv->default_menu_item = NULL;
 	if (default_verb != NULL) {
-		for (p = priv->menu_items; p != NULL; p = p->next) {
+		for (p = priv->objects; p != NULL; p = p->next) {
 			const MenuItem *item;
 
 			item = (const MenuItem *) p->data;
@@ -274,7 +317,7 @@
 		if (item->icon != NULL)
 			g_object_unref (item->icon);
 
-		g_free (item->component_id);
+		g_free (item->component);
 		g_free (item);
 	}
 
@@ -282,24 +325,18 @@
 }
 
 static const MenuItem *
-get_default_action_for_view (EUserCreatableItemsHandler *handler,
-			     EShellWindow *window)
+get_default_action_for_view (EUserCreatableItemsHandler *handler)
 {
 	EUserCreatableItemsHandlerPrivate *priv;
-	const char *window_component_id;
 	const GSList *p;
 
 	priv = handler->priv;
 
-	window_component_id = e_shell_window_peek_current_component_id (window);
-	if (window_component_id == NULL)
-		return priv->default_menu_item;
-
-	for (p = priv->menu_items; p != NULL; p = p->next) {
+	for (p = priv->objects; p != NULL; p = p->next) {
 		const MenuItem *item;
 
 		item = (const MenuItem *) p->data;
-		if (item_is_default (item, window_component_id))
+		if (item_is_default (item, priv->this_component))
 			return item;
 	}
 
@@ -307,163 +344,10 @@
 }
 
 
-/* The XML description for "File -> New".  */
-
-/* This adds a menu item for @item.  If @first is true, the keyboard shortcut
-   is going to be "Control-N" instead of whatever the component defines.  */
-static void
-append_xml_for_menu_item (GString *xml,
-			  const MenuItem *item,
-			  gboolean first)
-{
-	char *encoded_label;
-	char *encoded_tooltip;
-
-	encoded_label = bonobo_ui_util_encode_str (item->label);
-	g_string_append_printf (xml, "<menuitem name=\"New:%s\" verb=\"%s\" label=\"%s\"",
-				item->verb, item->verb, encoded_label);
-
-	if (first)
-		g_string_append_printf (xml, " accel=\"*Control*N\"");
-	else if (item->shortcut != '\0')
-		g_string_append_printf (xml, " accel=\"*Control**Shift*%c\"", item->shortcut);
-
-	if (item->icon != NULL) {
-		char *icon_xml;
-
-		icon_xml = bonobo_ui_util_pixbuf_to_xml (item->icon);
-		g_string_append_printf (xml, " pixtype=\"pixbuf\" pixname=\"%s\"", icon_xml);
-		g_free (icon_xml);
-	}
-
-	encoded_tooltip = bonobo_ui_util_encode_str (item->tooltip);
-	g_string_append_printf (xml, " tip=\"%s\"", encoded_tooltip);
-
-	g_string_append (xml, "/> ");
-
-	g_free (encoded_label);
-	g_free (encoded_tooltip);
-}
-
-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_menu_xml (EUserCreatableItemsHandler *handler,
-		 const char *component_id)
-{
-	EUserCreatableItemsHandlerPrivate *priv;
-	GString *xml;
-	GSList *p;
-	GSList *non_default_items;
-	char *retval;
-
-	priv = handler->priv;
-
-	ensure_menu_items (handler);
-
-	xml = g_string_new ("");
-
-	g_string_append (xml, "<placeholder name=\"ComponentItems\">");
-	g_string_append (xml, "<placeholder name=\"EUserCreatableItemsPlaceholder\">");
-
-	/* 1. Add all the elements that are default for this component.  (Note
-	   that we don't need to do any sorting since the items are already
-	   sorted alphabetically.)  */
-
-	if (component_id != NULL) {
-		gboolean first = TRUE;
-
-		for (p = priv->menu_items; p != NULL; p = p->next) {
-			const MenuItem *item;
-
-			item = (const MenuItem *) p->data;
-			if (item_is_default (item, component_id)) {
-				append_xml_for_menu_item (xml, item, first);
-				first = FALSE;
-			}
-		}
-	}
-
-	/* 2. Add a separator. */
-
-	if (component_id != NULL)
-		g_string_append_printf (xml,
-					"<separator f=\"\" name=\"EUserCreatableItemsHandlerSeparator\"/>");
-
-	/* 3. Add the elements that are not default for this component.  */
-
-	non_default_items = NULL;
-	for (p = priv->menu_items; p != NULL; p = p->next) {
-		const MenuItem *item;
-
-		item = (const MenuItem *) p->data;
-		if (! item_is_default (item, component_id))
-			non_default_items = g_slist_prepend (non_default_items, (void *) item);
-	}
-
-	non_default_items = g_slist_sort (non_default_items, item_types_sort_func);
-	for (p = non_default_items; p != NULL; p = p->next)
-		append_xml_for_menu_item (xml, (const MenuItem *) p->data, FALSE);
-	g_slist_free (non_default_items);
-
-	/* Done...  */
-
-	g_string_append (xml, "</placeholder>"); /* EUserCreatableItemsPlaceholder */
-	g_string_append (xml, "</placeholder>"); /* ComponentItems */
-
-	retval = xml->str;
-	g_string_free (xml, FALSE);
-
-	return retval;
-}
-
-
 /* Verb handling.  */
 
 static void
 execute_verb (EUserCreatableItemsHandler *handler,
-	      EShellWindow *window,
 	      const char *verb_name)
 {
 	EUserCreatableItemsHandlerPrivate *priv;
@@ -514,31 +398,22 @@
 	 void *data,
 	 const char *verb_name)
 {
-	EUserCreatableItemsHandler *handler;
-	EShellWindow *shell_window;
-
-	shell_window = g_object_get_data (G_OBJECT (ui_component), SHELL_WINDOW_KEY);
-	g_assert (E_IS_SHELL_WINDOW (shell_window));
-
-	handler = E_USER_CREATABLE_ITEMS_HANDLER (data);
+	EUserCreatableItemsHandler *handler=
+		E_USER_CREATABLE_ITEMS_HANDLER (data);
 
-	execute_verb (handler, shell_window, verb_name);
+	execute_verb (handler, verb_name);
 }
 
 static void
 add_verbs (EUserCreatableItemsHandler *handler,
-	   EShellWindow *window)
+	   BonoboUIComponent *ui_component)
 {
 	EUserCreatableItemsHandlerPrivate *priv;
-	BonoboUIComponent *ui_component;
 	int component_num;
 	GSList *p;
 
 	priv = handler->priv;
 
-	ui_component = e_shell_window_peek_bonobo_ui_component (window);
-	g_object_set_data (G_OBJECT (ui_component), SHELL_WINDOW_KEY, window);
-
 	component_num = 0;
 	for (p = priv->components; p != NULL; p = p->next) {
 		const Component *component;
@@ -550,8 +425,9 @@
 			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);
+				verb_name = create_verb (handler,
+							 component_num,
+							 component->type_list->_buffer[i].id);
 
 				bonobo_ui_component_add_verb (ui_component, verb_name, verb_fn, handler);
 
@@ -564,119 +440,298 @@
 }
 
 
-/* The "New" button in the toolbar.  */
+/* Generic menu construction code */
 
-static void
-combo_button_activate_default_callback (EComboButton *combo_button,
-					void *data)
+static int
+item_types_sort_func (const void *a,
+		      const void *b)
 {
-	EShellWindow *shell_window;
-	EUserCreatableItemsHandler *handler;
-	const MenuItem *menu_item;
+	const MenuItem *item_a;
+	const MenuItem *item_b;
+	const char *p1, *p2;
 
-	shell_window = E_SHELL_WINDOW (data);
-	handler = e_shell_peek_user_creatable_items_handler (e_shell_window_peek_shell (shell_window));
+	item_a = (const MenuItem *) a;
+	item_b = (const MenuItem *) b;
+
+	p1 = item_a->label;
+	p2 = item_b->label;
 
-	menu_item = get_default_action_for_view (handler, shell_window);
-	execute_verb (handler, shell_window, menu_item->verb);
+	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;
+	}
 }
 
+typedef void (*EUserCreatableItemsHandlerMenuItemFunc) (EUserCreatableItemsHandler *, gpointer, MenuItem *, gboolean);
+typedef void (*EUserCreatableItemsHandlerSeparatorFunc) (EUserCreatableItemsHandler *, gpointer, int);
+
 static void
-setup_toolbar_button (EUserCreatableItemsHandler *handler,
-		      EShellWindow *window)
+construct_menu (EUserCreatableItemsHandler *handler, gpointer menu,
+		EUserCreatableItemsHandlerMenuItemFunc menu_item_func,
+		EUserCreatableItemsHandlerSeparatorFunc separator_func)
 {
 	EUserCreatableItemsHandlerPrivate *priv;
-	BonoboUIComponent *ui_component;
-	GtkWidget *combo_button;
-	GtkWidget *menu;
-	GtkTooltips *tooltips;
-	BonoboControl *control;
+	MenuItem *item;
+	GSList *p, *items;
+	gboolean first = TRUE;
 
 	priv = handler->priv;
 
-	menu = gtk_menu_new ();
+	/* First add the current component's creatable objects */
+	for (p = priv->objects; p != NULL; p = p->next) {
+		item = p->data;
+		if (item_is_default (item, priv->this_component)) {
+			menu_item_func (handler, menu, item, first);
+			first = FALSE;
+		}
+	}
+
+	/* Then its creatable folders */
+	for (p = priv->folders; p != NULL; p = p->next) {
+		item = p->data;
+		if (item_is_default (item, priv->this_component))
+			menu_item_func (handler, menu, item, FALSE);
+	}
+
+	/* Then a separator */
+	separator_func (handler, menu, 1);
+
+	/* Then the objects from other components. */
+	items = NULL;
+	for (p = priv->objects; p != NULL; p = p->next) {
+		item = p->data;
+		if (! item_is_default (item, priv->this_component))
+			items = g_slist_prepend (items, item);
+	}
+
+	items = g_slist_sort (items, item_types_sort_func);
+	for (p = items; p != NULL; p = p->next)
+		menu_item_func (handler, menu, p->data, FALSE);
+	g_slist_free (items);
+
+	/* Another separator */
+	separator_func (handler, menu, 2);
+
+	/* And finally the folders from other components */
+	items = NULL;
+	for (p = priv->folders; p != NULL; p = p->next) {
+		item = p->data;
+		if (! item_is_default (item, priv->this_component))
+			items = g_slist_prepend (items, item);
+	}
+
+	items = g_slist_sort (items, item_types_sort_func);
+	for (p = items; p != NULL; p = p->next)
+		menu_item_func (handler, menu, p->data, FALSE);
+	g_slist_free (items);
+}
+
+/* The XML description for "File -> New".  */
+
+static void
+xml_menu_item_func (EUserCreatableItemsHandler *handler, gpointer menu,
+		    MenuItem *item, gboolean first)
+{
+	GString *xml = menu;
+	char *encoded_label;
+	char *encoded_tooltip;
 
-	combo_button = e_combo_button_new ();
-	e_combo_button_set_menu (E_COMBO_BUTTON (combo_button), GTK_MENU (menu));
-	e_combo_button_set_label (E_COMBO_BUTTON (combo_button), _("New"));
-	gtk_widget_show (combo_button);
+	encoded_label = bonobo_ui_util_encode_str (item->label);
+	g_string_append_printf (xml, "<menuitem name=\"New:%s\" verb=\"%s\" label=\"%s\"",
+				item->verb, item->verb, encoded_label);
 
-	g_signal_connect (combo_button, "activate_default", G_CALLBACK (combo_button_activate_default_callback), window);
+	if (first)
+		g_string_append_printf (xml, " accel=\"*Control*N\"");
+	else if (item->shortcut != '\0')
+		g_string_append_printf (xml, " accel=\"*Control**Shift*%c\"", item->shortcut);
 
-	ui_component = e_shell_window_peek_bonobo_ui_component (window);
-	bonobo_window_add_popup (BONOBO_WINDOW (window), GTK_MENU (menu), "/popups/NewPopup");
+	if (item->icon != NULL) {
+		char *icon_xml;
 
-	control = bonobo_control_new (combo_button);
+		icon_xml = bonobo_ui_util_pixbuf_to_xml (item->icon);
+		g_string_append_printf (xml, " pixtype=\"pixbuf\" pixname=\"%s\"", icon_xml);
+		g_free (icon_xml);
+	}
 
-	bonobo_ui_component_object_set (ui_component, "/Toolbar/NewComboButton",
-					BONOBO_OBJREF (control), NULL);
+	encoded_tooltip = bonobo_ui_util_encode_str (item->tooltip);
+	g_string_append_printf (xml, " tip=\"%s\"", encoded_tooltip);
 
-	bonobo_object_unref (control);
-	
-	g_object_set_data (G_OBJECT (window), COMBO_BUTTON_WIDGET_KEY, combo_button);
+	g_string_append (xml, "/> ");
 
-	tooltips = gtk_tooltips_new ();
-	g_object_set_data (G_OBJECT (combo_button), TOOLTIPS_KEY, tooltips);
+	g_free (encoded_label);
+	g_free (encoded_tooltip);
 }
 
+static void
+xml_separator_func (EUserCreatableItemsHandler *handler, gpointer menu, int nth)
+{
+	GString *xml = menu;
+
+	g_string_append_printf (xml, "<separator f=\"\" name=\"EUserCreatableItemsHandlerSeparator%d\"/>", nth);
+}
 
 static void
-update_for_window (EUserCreatableItemsHandler *handler,
-		   EShellWindow *window)
+create_menu_xml (EUserCreatableItemsHandler *handler)
 {
-	GtkWidget *combo_button_widget;
-	GtkTooltips *tooltips;
-	BonoboUIComponent *ui_component;
-	const MenuItem *default_menu_item;
-	char *menu_xml;
+	GString *xml;
 
-	combo_button_widget = g_object_get_data (G_OBJECT (window), COMBO_BUTTON_WIDGET_KEY);
-	g_assert (E_IS_COMBO_BUTTON (combo_button_widget));
+	xml = g_string_new ("<placeholder name=\"NewMenu\">");
+	construct_menu (handler, xml, xml_menu_item_func, xml_separator_func);
+	g_string_append (xml, "</placeholder>");
 
-	tooltips = g_object_get_data (G_OBJECT (combo_button_widget), TOOLTIPS_KEY);
-	g_assert (tooltips != NULL);
+	handler->priv->menu_xml = xml->str;
+	g_string_free (xml, FALSE);
+}
 
-	default_menu_item = get_default_action_for_view (handler, window);
-	if (default_menu_item == NULL) {
-		gtk_widget_set_sensitive (combo_button_widget, FALSE);
-		e_combo_button_set_label (E_COMBO_BUTTON (combo_button_widget), _("New"));
-		e_combo_button_set_icon (E_COMBO_BUTTON (combo_button_widget), NULL);
-		gtk_tooltips_set_tip (tooltips, combo_button_widget, NULL, NULL);
-		return;
-	}
 
-	gtk_widget_set_sensitive (combo_button_widget, TRUE);
+/* The GtkMenu for the toolbar button.  */
 
-	e_combo_button_set_icon (E_COMBO_BUTTON (combo_button_widget), default_menu_item->icon);
-	gtk_tooltips_set_tip (tooltips, combo_button_widget, default_menu_item->tooltip, NULL);
+static void
+menuitem_activate (GtkMenuItem *item, gpointer data)
+{
+	EUserCreatableItemsHandler *handler = data;
+	const char *verb;
 
-	ui_component = e_shell_window_peek_bonobo_ui_component (window);
-	bonobo_ui_component_rm (ui_component, "/menu/File/New/ComponentItems/EUserCreatableItemsPlaceholder", NULL);
-	bonobo_ui_component_rm (ui_component, "/popups/NewPopup/ComponentItems/EUserCreatableItemsPlaceholder", NULL);
+	verb = g_object_get_data (G_OBJECT (item), "EUserCreatableItemsHandler:verb");
+	execute_verb (handler, verb);
+}
 
-	menu_xml = create_menu_xml (handler, e_shell_window_peek_current_component_id (window));
+static void
+default_activate (EComboButton *combo_button, gpointer data)
+{
+	EUserCreatableItemsHandler *handler = data;
 
-	bonobo_ui_component_set (ui_component, "/menu/File/New", menu_xml, NULL);
-	bonobo_ui_component_set (ui_component, "/popups/NewPopup", menu_xml, NULL);
-	g_free (menu_xml);
+	execute_verb (handler, handler->priv->default_menu_item->verb);
 }
 
+static void
+gtk_menu_item_func (EUserCreatableItemsHandler *handler, gpointer menu,
+		    MenuItem *item, gboolean first)
+{
+	GtkWidget *menuitem, *icon;
+
+	menuitem = gtk_image_menu_item_new_with_mnemonic (item->label);
 
-/* This handles the menus for a given EShellWindow.  We have to rebuild the menu
-   and set the toolbar button every time the view changes, and clean up when
-   the view is destroyed.  */
+	if (item->icon) {
+		icon = gtk_image_new_from_pixbuf (item->icon);
+		gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem),
+					       icon);
+	}
+
+	if (first) {
+		gtk_widget_add_accelerator (menuitem, "activate",
+					    handler->priv->accel_group,
+					    'n', GDK_CONTROL_MASK,
+					    GTK_ACCEL_VISIBLE);
+	} else {
+		gtk_widget_add_accelerator (menuitem, "activate",
+					    handler->priv->accel_group,
+					    item->shortcut,
+					    GDK_CONTROL_MASK | GDK_SHIFT_MASK,
+					    GTK_ACCEL_VISIBLE);
+	}
+
+	g_object_set_data (G_OBJECT (menuitem), "EUserCreatableItemsHandler:verb", item->verb);
+	g_signal_connect (menuitem, "activate",
+			  G_CALLBACK (menuitem_activate), handler);
+
+	gtk_menu_shell_append (menu, menuitem);
+}
 
 static void
-shell_window_component_changed_callback (EShellWindow *shell_window,
-					 EUserCreatableItemsHandler *handler)
+gtk_separator_func (EUserCreatableItemsHandler *handler, gpointer menu, int nth)
 {
-	update_for_window (handler, shell_window);
+	gtk_menu_shell_append (menu, gtk_separator_menu_item_new ());
+}
+
+static void
+setup_toolbar_button (EUserCreatableItemsHandler *handler)
+{
+	EUserCreatableItemsHandlerPrivate *priv;
+	const MenuItem *default_menu_item;
+
+	priv = handler->priv;
+
+	priv->new_button = e_combo_button_new ();
+	priv->new_menu = gtk_menu_new ();
+	priv->accel_group = gtk_accel_group_new ();
+	construct_menu (handler, priv->new_menu,
+			gtk_menu_item_func, gtk_separator_func);
+	gtk_widget_show_all (priv->new_menu);
+	e_combo_button_set_menu (E_COMBO_BUTTON (priv->new_button),
+				 GTK_MENU (priv->new_menu));
+	e_combo_button_set_label (E_COMBO_BUTTON (priv->new_button), _("New"));
+	gtk_widget_show (priv->new_button);
+
+	g_signal_connect (priv->new_button, "activate_default",
+			  G_CALLBACK (default_activate), handler);
+
+	priv->new_control = bonobo_control_new (priv->new_button);
+
+	default_menu_item = get_default_action_for_view (handler);
+	if (!default_menu_item) {
+		gtk_widget_set_sensitive (priv->new_button, FALSE);
+		return;
+	}
+
+	gtk_widget_set_sensitive (priv->new_button, TRUE);
+
+	e_combo_button_set_icon (E_COMBO_BUTTON (priv->new_button),
+				 default_menu_item->icon);
+
+	priv->tooltips = gtk_tooltips_new ();
+	gtk_object_ref (GTK_OBJECT (priv->tooltips));
+	gtk_object_sink (GTK_OBJECT (priv->tooltips));
+	gtk_tooltips_set_tip (priv->tooltips, priv->new_button,
+			      default_menu_item->tooltip, NULL);
 }
 
 
 /* GObject methods.  */
 
 static void
+impl_set_property (GObject *object, guint prop_id,
+		   const GValue *value, GParamSpec *pspec)
+{
+	EUserCreatableItemsHandler *handler =
+		E_USER_CREATABLE_ITEMS_HANDLER (object);
+
+	switch (prop_id) {
+	case PROP_THIS_COMPONENT:
+		handler->priv->this_component = g_value_dup_string (value);
+
+		get_components_from_bonobo (handler);	
+		ensure_menu_items (handler);
+		break;
+	default:
+		break;
+	}
+}
+
+static void
 impl_dispose (GObject *object)
 {
 	EUserCreatableItemsHandler *handler;
@@ -692,7 +747,21 @@
 	g_slist_free (priv->components);
 	priv->components = NULL;
 
-	
+	if (priv->new_control) {
+		bonobo_object_unref (priv->new_control);
+		priv->new_control = NULL;
+	}
+
+	if (priv->tooltips) {
+		g_object_unref (priv->tooltips);
+		priv->tooltips = NULL;
+	}
+
+	if (priv->accel_group) {
+		g_object_unref (priv->accel_group);
+		priv->accel_group = NULL;
+	}
+
 	(* G_OBJECT_CLASS (parent_class)->dispose) (object);
 }
 
@@ -705,7 +774,10 @@
 	handler = E_USER_CREATABLE_ITEMS_HANDLER (object);
 	priv = handler->priv;
 
-	free_menu_items (priv->menu_items);
+	g_free (priv->this_component);
+
+	free_menu_items (priv->objects);
+	free_menu_items (priv->folders);
 
 	g_free (priv);
 
@@ -718,73 +790,69 @@
 {
 	parent_class = g_type_class_ref(PARENT_TYPE);
 
-	object_class->dispose  = impl_dispose;
-	object_class->finalize = impl_finalize;
+	object_class->dispose      = impl_dispose;
+	object_class->finalize     = impl_finalize;
+	object_class->set_property = impl_set_property;
+
+	g_object_class_install_property (
+		object_class, PROP_THIS_COMPONENT,
+		g_param_spec_string ("this_component", "Component alias",
+				     "The component_alias of this component",
+				     NULL,
+				     G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
 }
 
 static void
-init (EUserCreatableItemsHandler *shell_user_creatable_items_handler)
+init (EUserCreatableItemsHandler *handler)
 {
 	EUserCreatableItemsHandlerPrivate *priv;
 
-	priv = g_new (EUserCreatableItemsHandlerPrivate, 1);
-	priv->components 	= NULL;
-	priv->menu_items 	= NULL;
-	priv->default_menu_item = NULL;
+	priv = g_new0 (EUserCreatableItemsHandlerPrivate, 1);
 
-	shell_user_creatable_items_handler->priv = priv;
+	handler->priv = priv;
 }
 
 
 EUserCreatableItemsHandler *
-e_user_creatable_items_handler_new (EComponentRegistry *registry)
+e_user_creatable_items_handler_new (const char *component_alias)
 {
-	EUserCreatableItemsHandler *new;
-
-	new = g_object_new (e_user_creatable_items_handler_get_type (), NULL);
-
-	get_components_from_registry (new, registry);
-
-	return new;
+	return g_object_new (e_user_creatable_items_handler_get_type (),
+			     "this_component", component_alias,
+			     NULL);
 }
 
 
 /**
- * e_user_creatable_items_handler_attach_menus:
- * @handler: 
- * @shell_window: 
+ * e_user_creatable_items_handler_activate:
+ * @handler: the #EUserCreatableItemsHandler
+ * @ui_component: the #BonoboUIComponent to attach to
  * 
- * Set up the menus and toolbar items for @shell_window.  When the shell changes
- * view, the menu and the toolbar item will update automatically (i.e. the
- * actions for the current folder will go on top etc.).
+ * Set up the menus and toolbar items for @ui_component.
  **/
 void
-e_user_creatable_items_handler_attach_menus (EUserCreatableItemsHandler *handler,
-					     EShellWindow *window)
+e_user_creatable_items_handler_activate (EUserCreatableItemsHandler *handler,
+					 BonoboUIComponent *ui_component)
 {
-	BonoboUIComponent *ui_component;
 	EUserCreatableItemsHandlerPrivate *priv;
-	char *menu_xml;
 
 	g_return_if_fail (E_IS_USER_CREATABLE_ITEMS_HANDLER (handler));
-	g_return_if_fail (E_IS_SHELL_WINDOW (window));
+	g_return_if_fail (BONOBO_IS_UI_COMPONENT (ui_component));
 
 	priv = handler->priv;
 
-	setup_toolbar_button (handler, window);
-	g_signal_connect (window, "component_changed", G_CALLBACK (shell_window_component_changed_callback), handler);
-
-	add_verbs (handler, window);
-	menu_xml = create_menu_xml (handler, e_shell_window_peek_current_component_id (window));
-
-	ui_component = e_shell_window_peek_bonobo_ui_component (window);
-	bonobo_ui_component_set (ui_component, "/menu/File/New", menu_xml, NULL);
-	bonobo_ui_component_set (ui_component, "/popups/NewPopup", menu_xml, NULL);
-
-	g_free (menu_xml);
+	if (!priv->menu_xml) {
+		create_menu_xml (handler);
+		setup_toolbar_button (handler);
+		add_verbs (handler, ui_component);
+	}
 
-	update_for_window (handler, window);
+	bonobo_ui_component_set (ui_component, "/menu/File/New",
+				 priv->menu_xml, NULL);
+
+	bonobo_ui_component_object_set (ui_component,
+					"/Toolbar/NewComboButton",
+					BONOBO_OBJREF (priv->new_control),
+					NULL);
 }
-
 
 E_MAKE_TYPE (e_user_creatable_items_handler, "EUserCreatableItemsHandler", EUserCreatableItemsHandler, class_init, init, PARENT_TYPE)
Index: shell/e-user-creatable-items-handler.h
===================================================================
RCS file: /cvs/gnome/evolution/shell/e-user-creatable-items-handler.h,v
retrieving revision 1.1
diff -u -r1.1 e-user-creatable-items-handler.h
--- shell/e-user-creatable-items-handler.h	13 Nov 2003 05:56:14 -0000	1.1
+++ shell/e-user-creatable-items-handler.h	8 Apr 2004 20:42:59 -0000
@@ -1,7 +1,7 @@
 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
-/* e-shell-user-creatable-items-handler.h
+/* e-user-creatable-items-handler.h
  *
- * Copyright (C) 2001  Ximian, Inc.
+ * Copyright (C) 2001-2004 Novell, Inc.
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of version 2 of the GNU General Public
@@ -25,6 +25,7 @@
 
 #include <glib-object.h>
 #include <bonobo/bonobo-ui-component.h>
+#include <bonobo/bonobo-window.h>
 
 #ifdef __cplusplus
 extern "C" {
@@ -43,9 +44,6 @@
 typedef struct _EUserCreatableItemsHandlerClass   EUserCreatableItemsHandlerClass;
 
 
-#include "e-shell-window.h"
-
-
 struct _EUserCreatableItemsHandler {
 	GObject parent;
 
@@ -57,14 +55,11 @@
 };
 
 
-GtkType                     e_user_creatable_items_handler_get_type  (void);
-EUserCreatableItemsHandler *e_user_creatable_items_handler_new       (EComponentRegistry *registry);
+GType                       e_user_creatable_items_handler_get_type   (void);
+EUserCreatableItemsHandler *e_user_creatable_items_handler_new        (const char *component_alias);
 
-void  e_user_creatable_items_handler_add_component  (EUserCreatableItemsHandler *handler,
-						     const char                 *id,
-						     GNOME_Evolution_Component   component);
-void  e_user_creatable_items_handler_attach_menus   (EUserCreatableItemsHandler *handler,
-						     EShellWindow               *window);
+void                        e_user_creatable_items_handler_activate   (EUserCreatableItemsHandler *handler,
+								       BonoboUIComponent          *ui_component);
 
 #ifdef __cplusplus
 }
Index: ui/evolution.xml
===================================================================
RCS file: /cvs/gnome/evolution/ui/evolution.xml,v
retrieving revision 1.89
diff -u -r1.89 evolution.xml
--- ui/evolution.xml	27 Jan 2004 21:02:50 -0000	1.89
+++ ui/evolution.xml	8 Apr 2004 20:42:59 -0000
@@ -1,5 +1,9 @@
 <Root>
   <commands>
+    <cmd name="OpenNewWindow" _label="New _Window"
+      _tip="Create a new window displaying this folder"
+      accel="*Control**Shift*w"/>
+
     <cmd name="FileClose" _label="Close" _tip="Close this window"
       pixtype="stock" pixname="Close" accel="*Control*w"/>
 
@@ -30,18 +34,11 @@
   <menu>
     <submenu name="File" _label="_File">
       <submenu name="New" _label="_New">
-	<placeholder name="NewFirstItem"/>
 	<placeholder name="ComponentItems"/>
-
-	<separator f="" name="eshell8"/>
-
-	<menuitem name="EvolutionWindow"
-	  verb="OpenNewWindow"
-	  _label="_Window"
-	  _tip="Open a new window"
-	  accel="*Control**Shift*w"/>
       </submenu>
 
+      <menuitem name="OpenNewWindow" verb=""/>
+
       <placeholder name="FileOps"/>
 
       <separator f="" name="eshell4"/>
@@ -131,14 +128,6 @@
   <popups>
     <popup name="NewPopup">
     	<placeholder name="ComponentItems"/>
-
-	<separator f="" name="eshell7"/>
-
-	<menuitem name="EvolutionWindow"
-	          verb="OpenNewWindow"
-		  _label="_Window"
-		  _tip="Create a new window"
-		  accel="*Control**Shift*w"/>
     </popup>
   </popups>
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]