evolution r37125 - in branches/kill-bonobo: . addressbook/gui/component addressbook/gui/widgets calendar/gui/dialogs calendar/modules composer doc/reference/shell/tmpl e-util mail plugins/mark-all-read plugins/plugin-manager shell ui widgets/menus



Author: mbarnes
Date: Fri Jan 23 21:41:01 2009
New Revision: 37125
URL: http://svn.gnome.org/viewvc/evolution?rev=37125&view=rev

Log:
Redesign EPluginUI to accommodate merging and unmerging shell views.
Get the "mark-all-read" and "plugin-manager" plugins working.


Removed:
   branches/kill-bonobo/plugins/plugin-manager/org-gnome-plugin-manager.xml
Modified:
   branches/kill-bonobo/addressbook/gui/component/e-book-shell-view.c
   branches/kill-bonobo/addressbook/gui/widgets/eab-contact-display.c
   branches/kill-bonobo/calendar/gui/dialogs/event-editor.c
   branches/kill-bonobo/calendar/gui/dialogs/memo-editor.c
   branches/kill-bonobo/calendar/gui/dialogs/task-editor.c
   branches/kill-bonobo/calendar/modules/e-cal-shell-view.c
   branches/kill-bonobo/calendar/modules/e-memo-shell-view.c
   branches/kill-bonobo/calendar/modules/e-task-shell-view.c
   branches/kill-bonobo/composer/e-msg-composer.c
   branches/kill-bonobo/configure.in
   branches/kill-bonobo/doc/reference/shell/tmpl/e-shell-view.sgml
   branches/kill-bonobo/e-util/e-plugin-ui.c
   branches/kill-bonobo/e-util/e-plugin-ui.h
   branches/kill-bonobo/mail/e-mail-shell-view.c
   branches/kill-bonobo/plugins/mark-all-read/Makefile.am
   branches/kill-bonobo/plugins/mark-all-read/mark-all-read.c
   branches/kill-bonobo/plugins/mark-all-read/org-gnome-mark-all-read.eplug.xml
   branches/kill-bonobo/plugins/plugin-manager/Makefile.am
   branches/kill-bonobo/plugins/plugin-manager/org-gnome-plugin-manager.eplug.xml
   branches/kill-bonobo/plugins/plugin-manager/plugin-manager.c
   branches/kill-bonobo/shell/e-shell-view.c
   branches/kill-bonobo/shell/e-shell-view.h
   branches/kill-bonobo/shell/e-shell-window.c
   branches/kill-bonobo/ui/evolution-mail.ui
   branches/kill-bonobo/widgets/menus/gal-view-instance.c
   branches/kill-bonobo/widgets/menus/gal-view-instance.h

Modified: branches/kill-bonobo/addressbook/gui/component/e-book-shell-view.c
==============================================================================
--- branches/kill-bonobo/addressbook/gui/component/e-book-shell-view.c	(original)
+++ branches/kill-bonobo/addressbook/gui/component/e-book-shell-view.c	Fri Jan 23 21:41:01 2009
@@ -286,6 +286,7 @@
 	shell_view_class->label = _("Contacts");
 	shell_view_class->icon_name = "x-office-address-book";
 	shell_view_class->ui_definition = "evolution-contacts.ui";
+	shell_view_class->ui_manager_id = "org.gnome.evolution.contacts";
 	shell_view_class->search_options = "/contact-search-options";
 	shell_view_class->search_rules = "addresstypes.xml";
 	shell_view_class->type_module = type_module;

Modified: branches/kill-bonobo/addressbook/gui/widgets/eab-contact-display.c
==============================================================================
--- branches/kill-bonobo/addressbook/gui/widgets/eab-contact-display.c	(original)
+++ branches/kill-bonobo/addressbook/gui/widgets/eab-contact-display.c	Fri Jan 23 21:41:01 2009
@@ -1087,6 +1087,7 @@
 {
 	GtkActionGroup *action_group;
 	GtkHTML *html;
+	const gchar *id;
 
 	display->priv = EAB_CONTACT_DISPLAY_GET_PRIVATE (display);
 	display->priv->mode = EAB_CONTACT_DISPLAY_RENDER_NORMAL;
@@ -1146,8 +1147,9 @@
 		display->priv->invisible,
 		GDK_SELECTION_CLIPBOARD, GDK_SELECTION_TYPE_STRING, 1);
 
-	e_plugin_ui_register_manager (
-		"contact-display", display->priv->ui_manager, display);
+	id = "org.gnome.evolution.contact-display";
+	e_plugin_ui_register_manager (display->priv->ui_manager, id, display);
+	e_plugin_ui_enable_manager (display->priv->ui_manager, id);
 }
 
 GType

Modified: branches/kill-bonobo/calendar/gui/dialogs/event-editor.c
==============================================================================
--- branches/kill-bonobo/calendar/gui/dialogs/event-editor.c	(original)
+++ branches/kill-bonobo/calendar/gui/dialogs/event-editor.c	Fri Jan 23 21:41:01 2009
@@ -465,6 +465,7 @@
 	GtkUIManager *manager;
 	GtkActionGroup *action_group;
 	GtkAction *action;
+	const gchar *id;
 	GError *error = NULL;
 
 	ee->priv = EVENT_EDITOR_GET_PRIVATE (ee);
@@ -487,7 +488,10 @@
 
 	manager = comp_editor_get_ui_manager (editor);
 	gtk_ui_manager_add_ui_from_string (manager, ui, -1, &error);
-	e_plugin_ui_register_manager ("event-editor", manager, ee);
+
+	id = "org.gnome.evolution.event-editor";
+	e_plugin_ui_register_manager (manager, id, ee);
+	e_plugin_ui_enable_manager (manager, id);
 
 	if (error != NULL) {
 		g_critical ("%s: %s", G_STRFUNC, error->message);

Modified: branches/kill-bonobo/calendar/gui/dialogs/memo-editor.c
==============================================================================
--- branches/kill-bonobo/calendar/gui/dialogs/memo-editor.c	(original)
+++ branches/kill-bonobo/calendar/gui/dialogs/memo-editor.c	Fri Jan 23 21:41:01 2009
@@ -134,6 +134,7 @@
 {
 	CompEditor *editor = COMP_EDITOR (me);
 	GtkUIManager *manager;
+	const gchar *id;
 	GError *error = NULL;
 
 	me->priv = MEMO_EDITOR_GET_PRIVATE (me);
@@ -141,7 +142,10 @@
 
 	manager = comp_editor_get_ui_manager (editor);
 	gtk_ui_manager_add_ui_from_string (manager, ui, -1, &error);
-	e_plugin_ui_register_manager ("memo-editor", manager, me);
+
+	id = "org.gnome.evolution.memo-editor";
+	e_plugin_ui_register_manager (manager, id, me);
+	e_plugin_ui_enable_manager (manager, id);
 
 	if (error != NULL) {
 		g_critical ("%s: %s", G_STRFUNC, error->message);

Modified: branches/kill-bonobo/calendar/gui/dialogs/task-editor.c
==============================================================================
--- branches/kill-bonobo/calendar/gui/dialogs/task-editor.c	(original)
+++ branches/kill-bonobo/calendar/gui/dialogs/task-editor.c	Fri Jan 23 21:41:01 2009
@@ -303,6 +303,7 @@
 	CompEditor *editor = COMP_EDITOR (te);
 	GtkUIManager *manager;
 	GtkActionGroup *action_group;
+	const gchar *id;
 	GError *error = NULL;
 
 	te->priv = TASK_EDITOR_GET_PRIVATE (te);
@@ -345,7 +346,10 @@
 
 	manager = comp_editor_get_ui_manager (editor);
 	gtk_ui_manager_add_ui_from_string (manager, ui, -1, &error);
-	e_plugin_ui_register_manager ("task-editor", manager, te);
+
+	id = "org.gnome.evolution.task-editor";
+	e_plugin_ui_register_manager (manager, id, te);
+	e_plugin_ui_enable_manager (manager, id);
 
 	if (error != NULL) {
 		g_critical ("%s: %s", G_STRFUNC, error->message);

Modified: branches/kill-bonobo/calendar/modules/e-cal-shell-view.c
==============================================================================
--- branches/kill-bonobo/calendar/modules/e-cal-shell-view.c	(original)
+++ branches/kill-bonobo/calendar/modules/e-cal-shell-view.c	Fri Jan 23 21:41:01 2009
@@ -194,6 +194,7 @@
 	shell_view_class->label = _("Calendar");
 	shell_view_class->icon_name = "x-office-calendar";
 	shell_view_class->ui_definition = "evolution-calendars.ui";
+	shell_view_class->ui_manager_id = "org.gnome.evolution.calendars";
 	shell_view_class->search_options = "/calendar-search-options";
 	shell_view_class->search_rules = "caltypes.xml";
 	shell_view_class->type_module = type_module;

Modified: branches/kill-bonobo/calendar/modules/e-memo-shell-view.c
==============================================================================
--- branches/kill-bonobo/calendar/modules/e-memo-shell-view.c	(original)
+++ branches/kill-bonobo/calendar/modules/e-memo-shell-view.c	Fri Jan 23 21:41:01 2009
@@ -199,6 +199,7 @@
 	shell_view_class->label = _("Memos");
 	shell_view_class->icon_name = "evolution-memos";
 	shell_view_class->ui_definition = "evolution-memos.ui";
+	shell_view_class->ui_manager_id = "org.gnome.evolution.memos";
 	shell_view_class->search_options = "/memo-search-options";
 	shell_view_class->search_rules = "memotypes.xml";
 	shell_view_class->type_module = type_module;

Modified: branches/kill-bonobo/calendar/modules/e-task-shell-view.c
==============================================================================
--- branches/kill-bonobo/calendar/modules/e-task-shell-view.c	(original)
+++ branches/kill-bonobo/calendar/modules/e-task-shell-view.c	Fri Jan 23 21:41:01 2009
@@ -232,6 +232,7 @@
 	shell_view_class->label = _("Tasks");
 	shell_view_class->icon_name = "evolution-tasks";
 	shell_view_class->ui_definition = "evolution-tasks.ui";
+	shell_view_class->ui_manager_id = "org.gnome.evolution.tasks";
 	shell_view_class->search_options = "/task-search-options";
 	shell_view_class->search_rules = "tasktypes.xml";
 	shell_view_class->type_module = type_module;

Modified: branches/kill-bonobo/composer/e-msg-composer.c
==============================================================================
--- branches/kill-bonobo/composer/e-msg-composer.c	(original)
+++ branches/kill-bonobo/composer/e-msg-composer.c	Fri Jan 23 21:41:01 2009
@@ -2726,6 +2726,7 @@
 	GtkUIManager *manager;
 	GtkhtmlEditor *editor;
 	GtkHTML *html;
+	const gchar *id;
 
 	composer->priv = E_MSG_COMPOSER_GET_PRIVATE (composer);
 
@@ -2833,8 +2834,9 @@
 	/* Initialization may have tripped the "changed" state. */
 	gtkhtml_editor_set_changed (editor, FALSE);
 
-	e_plugin_ui_register_manager (
-		"org.gnome.evolution.composer", manager, composer);
+	id = "org.gnome.evolution.composer";
+	e_plugin_ui_register_manager (manager, id, composer);
+	e_plugin_ui_enable_manager (manager, id);
 }
 
 GType

Modified: branches/kill-bonobo/configure.in
==============================================================================
--- branches/kill-bonobo/configure.in	(original)
+++ branches/kill-bonobo/configure.in	Fri Jan 23 21:41:01 2009
@@ -1773,7 +1773,7 @@
 all_plugins_experimental="$plugins_experimental_always ipod-sync tnef-attachments"
 
 dnl Temporary KILL-BONOBO hack
-enable_plugins="addressbook-file audio-inline bbdb bogo-junk-plugin caldav calendar-file calendar-http copy-tool default-source external-editor google-account-setup hula-account-setup imap-features mail-notification mail-to-meeting profiler sa-junk-plugin save-attachments save-calendar subject-thread tnef-attachments webdav-account-setup"
+enable_plugins="addressbook-file audio-inline bbdb bogo-junk-plugin caldav calendar-file calendar-http copy-tool default-source external-editor google-account-setup hula-account-setup imap-features mail-notification mail-to-meeting mark-all-read plugin-manager profiler sa-junk-plugin save-attachments save-calendar subject-thread tnef-attachments webdav-account-setup"
 
 dnl PLUGINS NOT BUILDING YET
 dnl ------------------------
@@ -1791,9 +1791,7 @@
 dnl itip-formatter
 dnl mailing-list-actions
 dnl mail-to-task
-dnl mark-all-read
 dnl mono
-dnl plugin-manager
 dnl prefer-plain
 dnl pst-import
 dnl publish-calendar

Modified: branches/kill-bonobo/doc/reference/shell/tmpl/e-shell-view.sgml
==============================================================================
--- branches/kill-bonobo/doc/reference/shell/tmpl/e-shell-view.sgml	(original)
+++ branches/kill-bonobo/doc/reference/shell/tmpl/e-shell-view.sgml	Fri Jan 23 21:41:01 2009
@@ -91,6 +91,7 @@
 @label: 
 @icon_name: 
 @ui_definition: 
+ ui_manager_id: 
 @search_options: 
 @search_rules: 
 @type_module: 

Modified: branches/kill-bonobo/e-util/e-plugin-ui.c
==============================================================================
--- branches/kill-bonobo/e-util/e-plugin-ui.c	(original)
+++ branches/kill-bonobo/e-util/e-plugin-ui.c	Fri Jan 23 21:41:01 2009
@@ -25,7 +25,6 @@
 
 #define E_PLUGIN_UI_INIT_FUNC		"e_plugin_ui_init"
 #define E_PLUGIN_UI_HOOK_CLASS_ID       "org.gnome.evolution.ui:1.0"
-#define E_PLUGIN_UI_MANAGER_ID_KEY	"e-plugin-ui-manager-id"
 
 struct _EPluginUIHookPrivate {
 
@@ -33,9 +32,11 @@
 	 *
 	 * For example:
 	 *
-	 *     <ui-manager id="org.gnome.evolution.sample">
- 	 *             ... UI definition ...
-	 *     </ui-manager>
+	 *     <hook class="org.gnome.evolution.ui:1.0">
+	 *       <ui-manager id="org.gnome.evolution.sample">
+	 *               ... UI definition ...
+	 *       </ui-manager>
+	 *     </hook>
 	 *
 	 * Results in:
 	 *
@@ -49,201 +50,309 @@
 	 * optional.
 	 */
 	GHashTable *ui_definitions;
+
+	/* The registry is the heart of EPluginUI.  It tracks GtkUIManager
+	 * instances, GtkUIManager IDs, and UI merge IDs as a hash table of
+	 * hash tables:
+	 *
+	 *     GtkUIManager instance -> GtkUIManager ID -> UI Merge ID
+	 *
+	 * A GtkUIManager instance and ID form a unique key for looking up
+	 * UI merge IDs.  The reason both are needed is because the same
+	 * GtkUIManager instance and be registered under multiple IDs.
+	 *
+	 * This is done primarily to support shell views, which share a
+	 * common GtkUIManager instance for a particular shell window.
+	 * Each shell view registers the same GtkUIManager instance under
+	 * a unique ID:
+	 *
+	 *     "org.gnome.evolution.mail"      }
+	 *     "org.gnome.evolution.contacts"  }  aliases for a common
+	 *     "org.gnome.evolution.calendar"  }  GtkUIManager instance
+	 *     "org.gnome.evolution.memos"     }
+	 *     "org.gnome.evolution.tasks"     }
+	 *
+	 * Note: The shell window also registers the same GtkUIManager
+	 *       instance as "org.gnome.evolution.shell".
+	 *
+	 * This way, plugins that extend a shell view's UI will follow the
+	 * merging and unmerging of the shell view automatically.
+	 *
+	 * The presence or absence of GtkUIManager IDs in the registry is
+	 * significant.  Presence of a (instance, ID) pair indicates that
+	 * UI manager is active, absence indicates inactive.  Furthermore,
+	 * a non-zero merge ID for an active UI manager indicates the
+	 * plugin is enabled.  Zero indicates disabled.
+	 *
+	 * Here's a quick scenario to illustrate:
+	 *
+	 * Suppose we have a plugin that extends the mail shell view UI.
+	 * Its EPlugin definition file has this section:
+	 *
+	 *     <hook class="org.gnome.evolution.ui:1.0">
+	 *       <ui-manager id="org.gnome.evolution.mail">
+	 *               ... UI definition ...
+	 *       </ui-manager>
+	 *     </hook>
+	 *
+	 * The plugin is enabled and the active shell view is "mail".
+	 * Let "ManagerA" denote the common GtkUIManager instance for
+	 * this shell window.  Here's what happens to the registry as
+	 * the user performs various actions;
+	 *
+	 *     - Initial State                            Merge ID
+	 *                                                   V
+	 *       { "ManagerA", { "org.gnome.evolution.mail", 3 } }
+	 *
+	 *     - User Disables the Plugin
+	 *
+	 *       { "ManagerA", { "org.gnome.evolution.mail", 0 } }
+	 *
+	 *     - User Enables the Plugin
+	 *
+	 *       { "ManagerA", { "org.gnome.evolution.mail", 4 } }
+	 *
+	 *     - User Switches to Calendar View
+	 *
+	 *       { "ManagerA", { } }
+	 *
+	 *     - User Disables the Plugin
+	 *
+	 *       { "ManagerA", { } }
+	 *
+	 *     - User Switches to Mail View
+	 *
+	 *       { "ManagerA", { "org.gnome.evolution.mail", 0 } }
+	 *
+	 *     - User Enables the Plugin
+	 *
+	 *       { "ManagerA", { "org.gnome.evolution.mail", 5 } }
+	 */
+	GHashTable *registry;
 };
 
-/* The registry is a hash table of hash tables.  It maps
- *
- *    EPluginUIHook instance --> GtkUIManager instance --> UI merge id
- *
- * GtkUIManager instances are automatically removed when finalized.
- */
-static GHashTable *registry;
 static gpointer parent_class;
 
 static void
-plugin_ui_registry_remove (EPluginUIHook *hook,
-                           GtkUIManager *manager)
+plugin_ui_hook_unregister_manager (EPluginUIHook *hook,
+                                   GtkUIManager *manager)
 {
-	GHashTable *hash_table;
+	GHashTable *registry;
 
 	/* Note: Manager may already be finalized. */
-
-	hash_table = g_hash_table_lookup (registry, hook);
-	g_return_if_fail (hash_table != NULL);
-
-	g_hash_table_remove (hash_table, manager);
-	if (g_hash_table_size (hash_table) == 0)
-		g_hash_table_remove (registry, hook);
+	registry = hook->priv->registry;
+	g_hash_table_remove (registry, manager);
 }
 
 static void
-plugin_ui_registry_insert (EPluginUIHook *hook,
-                           GtkUIManager *manager,
-                           guint merge_id)
+plugin_ui_hook_register_manager (EPluginUIHook *hook,
+                                 GtkUIManager *manager,
+                                 gpointer user_data)
 {
+	EPlugin *plugin;
+	EPluginUIInitFunc func;
+	GHashTable *registry;
 	GHashTable *hash_table;
 
-	if (registry == NULL)
-		registry = g_hash_table_new_full (
-			g_direct_hash, g_direct_equal,
-			(GDestroyNotify) NULL,
-			(GDestroyNotify) g_hash_table_destroy);
+	plugin = ((EPluginHook *) hook)->plugin;
+	func = e_plugin_get_symbol (plugin, E_PLUGIN_UI_INIT_FUNC);
 
-	hash_table = g_hash_table_lookup (registry, hook);
-	if (hash_table == NULL) {
-		hash_table = g_hash_table_new (g_direct_hash, g_direct_equal);
-		g_hash_table_insert (registry, hook, hash_table);
-	}
+	/* Pass the manager and user_data to the plugin's e_plugin_ui_init()
+	 * function (if it defined one).  The plugin should install whatever
+	 * GtkActions and GtkActionGroups are neccessary to implement the
+	 * action names in its UI definition. */
+	if (func != NULL && !func (manager, user_data))
+		return;
 
 	g_object_weak_ref (
 		G_OBJECT (manager), (GWeakNotify)
-		plugin_ui_registry_remove, hook);
+		plugin_ui_hook_unregister_manager, hook);
+
+	registry = hook->priv->registry;
+	hash_table = g_hash_table_lookup (registry, manager);
 
-	g_hash_table_insert (hash_table, manager, GUINT_TO_POINTER (merge_id));
+	if (hash_table == NULL) {
+		hash_table = g_hash_table_new_full (
+			g_str_hash, g_str_equal,
+			(GDestroyNotify) g_free,
+			(GDestroyNotify) NULL);
+		g_hash_table_insert (registry, manager, hash_table);
+	}
 }
 
-/* Helper for plugin_ui_hook_merge_ui() */
-static void
-plugin_ui_hook_merge_foreach (GtkUIManager *manager,
-                              const gchar *ui_definition,
-                              GHashTable *hash_table)
+static guint
+plugin_ui_hook_merge_ui (EPluginUIHook *hook,
+                         GtkUIManager *manager,
+                         const gchar *id)
 {
+	GHashTable *hash_table;
+	const gchar *ui_definition;
 	guint merge_id;
 	GError *error = NULL;
 
-	/* Merge the UI definition into the manager. */
+	hash_table = hook->priv->ui_definitions;
+	ui_definition = g_hash_table_lookup (hash_table, id);
+	g_return_val_if_fail (ui_definition != NULL, 0);
+
 	merge_id = gtk_ui_manager_add_ui_from_string (
 		manager, ui_definition, -1, &error);
-	gtk_ui_manager_ensure_update (manager);
+
 	if (error != NULL) {
 		g_warning ("%s", error->message);
 		g_error_free (error);
 	}
 
-	/* Merge ID will be 0 on error, which is what we want. */
-	g_hash_table_insert (hash_table, manager, GUINT_TO_POINTER (merge_id));
+	return merge_id;
 }
 
 static void
-plugin_ui_hook_merge_ui (EPluginUIHook *hook)
+plugin_ui_enable_manager (EPluginUIHook *hook,
+                          GtkUIManager *manager,
+                          const gchar *id)
 {
-	GHashTable *old_merge_ids;
-	GHashTable *new_merge_ids;
-	GHashTable *intermediate;
+	GHashTable *hash_table;
+	GHashTable *ui_definitions;
 	GList *keys;
 
-	old_merge_ids = g_hash_table_lookup (registry, hook);
-	if (old_merge_ids == NULL)
-		return;
+	hash_table = hook->priv->registry;
+	hash_table = g_hash_table_lookup (hash_table, manager);
 
-	/* The GtkUIManager instances and UI definitions live in separate
-	 * tables, so we need to build an intermediate table that we can
-	 * easily iterate over. */
-	keys = g_hash_table_get_keys (old_merge_ids);
-	intermediate = g_hash_table_new (g_direct_hash, g_direct_equal);
+	if (hash_table == NULL)
+		return;
 
-	while (keys != NULL) {
-		GtkUIManager *manager = keys->data;
-		gchar *ui_definition;
+	if (id != NULL)
+		keys = g_list_prepend (NULL, (gpointer) id);
+	else
+		keys = g_hash_table_get_keys (hash_table);
 
-		ui_definition = g_hash_table_lookup (
-			hook->priv->ui_definitions,
-			e_plugin_ui_get_manager_id (manager));
+	ui_definitions = hook->priv->ui_definitions;
 
-		g_hash_table_insert (intermediate, manager, ui_definition);
+	while (keys != NULL) {
+		guint merge_id;
+		gpointer data;
 
+		id = keys->data;
 		keys = g_list_delete_link (keys, keys);
-	}
 
-	new_merge_ids = g_hash_table_new (g_direct_hash, g_direct_equal);
+		if (g_hash_table_lookup (ui_definitions, id) == NULL)
+			continue;
 
-	g_hash_table_foreach (
-		intermediate, (GHFunc)
-		plugin_ui_hook_merge_foreach, new_merge_ids);
+		data = g_hash_table_lookup (hash_table, id);
+		merge_id = GPOINTER_TO_UINT (data);
 
-	g_hash_table_insert (registry, hook, new_merge_ids);
+		if (merge_id > 0)
+			continue;
 
-	g_hash_table_destroy (intermediate);
+		if (((EPluginHook *) hook)->plugin->enabled)
+			merge_id = plugin_ui_hook_merge_ui (hook, manager, id);
+
+		/* Merge ID will be 0 on error, which is what we want. */
+		data = GUINT_TO_POINTER (merge_id);
+		g_hash_table_insert (hash_table, g_strdup (id), data);
+	}
 }
 
-/* Helper for plugin_ui_hook_unmerge_ui() */
 static void
-plugin_ui_hook_unmerge_foreach (GtkUIManager *manager,
-                                gpointer value,
-                                GHashTable *hash_table)
+plugin_ui_disable_manager (EPluginUIHook *hook,
+                           GtkUIManager *manager,
+                           const gchar *id,
+                           gboolean remove)
 {
-	guint merge_id;
+	GHashTable *hash_table;
+	GHashTable *ui_definitions;
+	GList *keys;
+
+	hash_table = hook->priv->registry;
+	hash_table = g_hash_table_lookup (hash_table, manager);
+
+	if (hash_table == NULL)
+		return;
+
+	if (id != NULL)
+		keys = g_list_prepend (NULL, (gpointer) id);
+	else
+		keys = g_hash_table_get_keys (hash_table);
+
+	ui_definitions = hook->priv->ui_definitions;
+
+	while (keys != NULL) {
+		guint merge_id;
+		gpointer data;
+
+		id = keys->data;
+		keys = g_list_delete_link (keys, keys);
+
+		if (g_hash_table_lookup (ui_definitions, id) == NULL)
+			continue;
 
-	merge_id = GPOINTER_TO_UINT (value);
-	gtk_ui_manager_remove_ui (manager, merge_id);
+		data = g_hash_table_lookup (hash_table, id);
+		merge_id = GPOINTER_TO_UINT (data);
 
-	g_hash_table_insert (hash_table, manager, GUINT_TO_POINTER (0));
+		/* Merge ID could be 0 if the plugin is disabled. */
+		if (merge_id > 0)
+			gtk_ui_manager_remove_ui (manager, merge_id);
+
+		if (remove)
+			g_hash_table_remove (hash_table, id);
+		else
+			g_hash_table_insert (hash_table, g_strdup (id), NULL);
+	}
 }
 
 static void
-plugin_ui_hook_unmerge_ui (EPluginUIHook *hook)
+plugin_ui_enable_hook (EPluginUIHook *hook)
 {
-	GHashTable *old_merge_ids;
-	GHashTable *new_merge_ids;
-
-	old_merge_ids = g_hash_table_lookup (registry, hook);
-	if (old_merge_ids == NULL)
-		return;
+	GHashTable *hash_table;
+	GHashTableIter iter;
+	gpointer key;
 
-	new_merge_ids = g_hash_table_new (g_direct_hash, g_direct_equal);
+	/* Enable all GtkUIManagers for this hook. */
 
-	g_hash_table_foreach (
-		old_merge_ids, (GHFunc)
-		plugin_ui_hook_unmerge_foreach, new_merge_ids);
+	hash_table = hook->priv->registry;
+	g_hash_table_iter_init (&iter, hash_table);
 
-	g_hash_table_insert (registry, hook, new_merge_ids);
+	while (g_hash_table_iter_next (&iter, &key, NULL)) {
+		GtkUIManager *manager = key;
+		plugin_ui_enable_manager (hook, manager, NULL);
+	}
 }
 
 static void
-plugin_ui_hook_register_manager (EPluginUIHook *hook,
-                                 GtkUIManager *manager,
-                                 const gchar *ui_definition,
-                                 gpointer user_data)
+plugin_ui_disable_hook (EPluginUIHook *hook)
 {
-	EPlugin *plugin;
-	EPluginUIInitFunc func;
-	guint merge_id = 0;
+	GHashTable *hash_table;
+	GHashTableIter iter;
+	gpointer key;
 
-	plugin = ((EPluginHook *) hook)->plugin;
-	func = e_plugin_get_symbol (plugin, E_PLUGIN_UI_INIT_FUNC);
+	/* Disable all GtkUIManagers for this hook. */
 
-	/* Pass the manager and user_data to the plugin's e_plugin_ui_init()
-	 * function (if it defined one).  The plugin should install whatever
-	 * GtkActions and GtkActionGroups are neccessary to implement the
-	 * action names in its UI definition. */
-	if (func != NULL && !func (manager, user_data))
-		return;
-
-	if (plugin->enabled) {
-		GError *error = NULL;
+	hash_table = hook->priv->registry;
+	g_hash_table_iter_init (&iter, hash_table);
 
-		/* Merge the UI definition into the manager. */
-		merge_id = gtk_ui_manager_add_ui_from_string (
-			manager, ui_definition, -1, &error);
-		gtk_ui_manager_ensure_update (manager);
-		if (error != NULL) {
-			g_warning ("%s", error->message);
-			g_error_free (error);
-		}
+	while (g_hash_table_iter_next (&iter, &key, NULL)) {
+		GtkUIManager *manager = key;
+		plugin_ui_disable_manager (hook, manager, NULL, FALSE);
 	}
-
-	/* Save merge ID's for later use. */
-	plugin_ui_registry_insert (hook, manager, merge_id);
 }
 
 static void
 plugin_ui_hook_finalize (GObject *object)
 {
 	EPluginUIHookPrivate *priv;
+	GHashTableIter iter;
+	gpointer manager;
 
 	priv = E_PLUGIN_UI_HOOK_GET_PRIVATE (object);
 
+	/* Remove weak reference callbacks to GtkUIManagers. */
+	g_hash_table_iter_init (&iter, priv->registry);
+	while (g_hash_table_iter_next (&iter, &manager, NULL))
+		g_object_weak_unref (
+			G_OBJECT (manager), (GWeakNotify)
+			plugin_ui_hook_unregister_manager, object);
+
 	g_hash_table_destroy (priv->ui_definitions);
+	g_hash_table_destroy (priv->registry);
 
 	/* Chain up to parent's dispose() method. */
 	G_OBJECT_CLASS (parent_class)->dispose (object);
@@ -304,9 +413,9 @@
                        gint state)
 {
 	if (state)
-		plugin_ui_hook_merge_ui (E_PLUGIN_UI_HOOK (hook));
+		plugin_ui_enable_hook (E_PLUGIN_UI_HOOK (hook));
 	else
-		plugin_ui_hook_unmerge_ui (E_PLUGIN_UI_HOOK (hook));
+		plugin_ui_disable_hook (E_PLUGIN_UI_HOOK (hook));
 }
 
 static void
@@ -331,14 +440,18 @@
 plugin_ui_hook_init (EPluginUIHook *hook)
 {
 	GHashTable *ui_definitions;
+	GHashTable *registry;
 
 	ui_definitions = g_hash_table_new_full (
 		g_str_hash, g_str_equal,
 		(GDestroyNotify) g_free,
 		(GDestroyNotify) g_free);
 
+	registry = g_hash_table_new (g_direct_hash, g_direct_equal);
+
 	hook->priv = E_PLUGIN_UI_HOOK_GET_PRIVATE (hook);
 	hook->priv->ui_definitions = ui_definitions;
+	hook->priv->registry = registry;
 }
 
 GType
@@ -368,17 +481,14 @@
 }
 
 void
-e_plugin_ui_register_manager (const gchar *id,
-                              GtkUIManager *manager,
+e_plugin_ui_register_manager (GtkUIManager *manager,
+                              const gchar *id,
                               gpointer user_data)
 {
-	const gchar *key = E_PLUGIN_UI_MANAGER_ID_KEY;
 	GSList *plugin_list;
 
-	g_return_if_fail (id != NULL);
 	g_return_if_fail (GTK_IS_UI_MANAGER (manager));
-
-	g_object_set_data (G_OBJECT (manager), key, (gpointer) id);
+	g_return_if_fail (id != NULL);
 
 	/* Loop over all installed plugins. */
 	plugin_list = e_plugin_list_plugins ();
@@ -386,36 +496,84 @@
 		EPlugin *plugin = plugin_list->data;
 		GSList *iter;
 
+		plugin_list = g_slist_next (plugin_list);
+
 		/* Look for hooks of type EPluginUIHook. */
 		for (iter = plugin->hooks; iter != NULL; iter = iter->next) {
 			EPluginUIHook *hook = iter->data;
-			const gchar *ui_definition;
+			GHashTable *hash_table;
 
 			if (!E_IS_PLUGIN_UI_HOOK (hook))
 				continue;
 
+			hash_table = hook->priv->ui_definitions;
+
 			/* Check if the hook has a UI definition
 			 * for the GtkUIManager being registered. */
-			ui_definition = g_hash_table_lookup (
-				hook->priv->ui_definitions, id);
-			if (ui_definition == NULL)
+			if (g_hash_table_lookup (hash_table, id) == NULL)
 				continue;
 
 			/* Register the manager with the hook. */
 			plugin_ui_hook_register_manager (
-				hook, manager, ui_definition, user_data);
+				hook, manager, user_data);
 		}
+	}
+}
+
+void
+e_plugin_ui_enable_manager (GtkUIManager *manager,
+                            const gchar *id)
+{
+	GSList *plugin_list;
+
+	g_return_if_fail (GTK_IS_UI_MANAGER (manager));
+	g_return_if_fail (id != NULL);
+
+	/* Loop over all installed plugins. */
+	plugin_list = e_plugin_list_plugins ();
+	while (plugin_list != NULL) {
+		EPlugin *plugin = plugin_list->data;
+		GSList *iter;
 
 		plugin_list = g_slist_next (plugin_list);
+
+		/* Look for hooks of type EPluginUIHook. */
+		for (iter = plugin->hooks; iter != NULL; iter = iter->next) {
+			EPluginUIHook *hook = iter->data;
+
+			if (!E_IS_PLUGIN_UI_HOOK (hook))
+				continue;
+
+			plugin_ui_enable_manager (hook, manager, id);
+		}
 	}
 }
 
-const gchar *
-e_plugin_ui_get_manager_id (GtkUIManager *manager)
+void
+e_plugin_ui_disable_manager (GtkUIManager *manager,
+                             const gchar *id)
 {
-	const gchar *key = E_PLUGIN_UI_MANAGER_ID_KEY;
+	GSList *plugin_list;
 
-	g_return_val_if_fail (GTK_IS_UI_MANAGER (manager), NULL);
+	g_return_if_fail (GTK_IS_UI_MANAGER (manager));
+	g_return_if_fail (id != NULL);
+
+	/* Loop over all installed plugins. */
+	plugin_list = e_plugin_list_plugins ();
+	while (plugin_list != NULL) {
+		EPlugin *plugin = plugin_list->data;
+		GSList *iter;
+
+		plugin_list = g_slist_next (plugin_list);
 
-	return g_object_get_data (G_OBJECT (manager), key);
+		/* Look for hooks of type EPluginUIHook. */
+		for (iter = plugin->hooks; iter != NULL; iter = iter->next) {
+			EPluginUIHook *hook = iter->data;
+
+			if (!E_IS_PLUGIN_UI_HOOK (hook))
+				continue;
+
+			plugin_ui_disable_manager (hook, manager, id, TRUE);
+		}
+	}
 }

Modified: branches/kill-bonobo/e-util/e-plugin-ui.h
==============================================================================
--- branches/kill-bonobo/e-util/e-plugin-ui.h	(original)
+++ branches/kill-bonobo/e-util/e-plugin-ui.h	Fri Jan 23 21:41:01 2009
@@ -62,10 +62,13 @@
 
 GType		e_plugin_ui_hook_get_type	(void);
 
-void		e_plugin_ui_register_manager	(const gchar *id,
-						 GtkUIManager *manager,
+void		e_plugin_ui_register_manager	(GtkUIManager *manager,
+						 const gchar *id,
 						 gpointer user_data);
-const gchar *	e_plugin_ui_get_manager_id	(GtkUIManager *manager);
+void		e_plugin_ui_enable_manager	(GtkUIManager *manager,
+						 const gchar *id);
+void		e_plugin_ui_disable_manager	(GtkUIManager *manager,
+						 const gchar *id);
 
 G_END_DECLS
 

Modified: branches/kill-bonobo/mail/e-mail-shell-view.c
==============================================================================
--- branches/kill-bonobo/mail/e-mail-shell-view.c	(original)
+++ branches/kill-bonobo/mail/e-mail-shell-view.c	Fri Jan 23 21:41:01 2009
@@ -211,6 +211,7 @@
 	shell_view_class->label = _("Mail");
 	shell_view_class->icon_name = "evolution-mail";
 	shell_view_class->ui_definition = "evolution-mail.ui";
+	shell_view_class->ui_manager_id = "org.gnome.evolution.mail";
 	shell_view_class->search_options = "/mail-search-options";
 	shell_view_class->search_rules = "searchtypes.xml";
 	shell_view_class->type_module = type_module;

Modified: branches/kill-bonobo/plugins/mark-all-read/Makefile.am
==============================================================================
--- branches/kill-bonobo/plugins/mark-all-read/Makefile.am	(original)
+++ branches/kill-bonobo/plugins/mark-all-read/Makefile.am	Fri Jan 23 21:41:01 2009
@@ -12,7 +12,7 @@
 liborg_gnome_mark_all_read_la_LDFLAGS = -module -avoid-version $(NO_UNDEFINED)
 liborg_gnome_mark_all_read_la_LIBADD = 			\
 	$(top_builddir)/e-util/libeutil.la		\
-	$(top_builddir)/mail/libevolution-mail.la	\
+	$(top_builddir)/mail/libevolution-module-mail.la	\
 	$(EVOLUTION_MAIL_LIBS)
 
 EXTRA_DIST = org-gnome-mark-all-read.eplug.xml

Modified: branches/kill-bonobo/plugins/mark-all-read/mark-all-read.c
==============================================================================
--- branches/kill-bonobo/plugins/mark-all-read/mark-all-read.c	(original)
+++ branches/kill-bonobo/plugins/mark-all-read/mark-all-read.c	Fri Jan 23 21:41:01 2009
@@ -28,20 +28,27 @@
 #include <glib.h>
 #include <gtk/gtk.h>
 #include <glib/gi18n.h>
-#include <e-util/e-config.h>
-#include <mail/em-popup.h>
+#include <e-util/e-plugin-ui.h>
+#include <mail/e-mail-shell-sidebar.h>
+#include <mail/em-folder-tree.h>
 #include <mail/mail-ops.h>
 #include <mail/mail-mt.h>
 #include <camel/camel-vee-folder.h>
 #include "e-util/e-error.h"
 
+#include <shell/e-shell-sidebar.h>
+#include <shell/e-shell-window.h>
+#include <shell/e-shell-window-actions.h>
+
 #define PRIMARY_TEXT \
 	N_("Also mark messages in subfolders?")
 #define SECONDARY_TEXT \
 	N_("Do you want to mark messages as read in the current folder " \
 	   "only, or in the current folder as well as all subfolders?")
 
-void org_gnome_mark_all_read (EPlugin *ep, EMPopupTargetFolder *target);
+gboolean	e_plugin_ui_init		(GtkUIManager *manager,
+						 EShellView *shell_view);
+
 static void mar_got_folder (char *uri, CamelFolder *folder, void *data);
 static void mar_all_sub_folders (CamelStore *store, CamelFolderInfo *fi, CamelException *ex);
 
@@ -190,16 +197,6 @@
 	return response;
 }
 
-void
-org_gnome_mark_all_read (EPlugin *ep, EMPopupTargetFolder *t)
-{
-	if (t->uri == NULL) {
-		return;
-	}
-
-	mail_get_folder(t->uri, 0, mar_got_folder, NULL, mail_msg_unordered_push);
-}
-
 static void
 mark_all_as_read (CamelFolder *folder)
 {
@@ -270,3 +267,52 @@
 		fi = fi->next;
 	}
 }
+
+static void
+action_mail_mark_read_recursive_cb (GtkAction *action,
+                                    EShellView *shell_view)
+{
+	EMailShellSidebar *mail_shell_sidebar;
+	EShellSidebar *shell_sidebar;
+	EMFolderTree *folder_tree;
+	const gchar *folder_uri;
+
+	shell_sidebar = e_shell_view_get_shell_sidebar (shell_view);
+	g_return_if_fail (E_IS_MAIL_SHELL_SIDEBAR (shell_sidebar));
+
+	mail_shell_sidebar = E_MAIL_SHELL_SIDEBAR (shell_sidebar);
+	folder_tree = e_mail_shell_sidebar_get_folder_tree (mail_shell_sidebar);
+	folder_uri = em_folder_tree_get_selected_uri (folder_tree);
+	g_return_if_fail (folder_uri != NULL);
+
+	mail_get_folder (
+		folder_uri, 0, mar_got_folder, NULL, mail_msg_unordered_push);
+}
+
+static GtkActionEntry entries[] = {
+
+	{ "mail-mark-read-recursive",
+	  "mail-mark-read",
+	  N_("Mark Me_ssages as Read"),
+	  NULL,
+	  NULL,  /* XXX Add a tooltip! */
+	  G_CALLBACK (action_mail_mark_read_recursive_cb) }
+};
+
+gboolean
+e_plugin_ui_init (GtkUIManager *manager,
+                  EShellView *shell_view)
+{
+	EShellWindow *shell_window;
+	GtkActionGroup *action_group;
+
+	shell_window = e_shell_view_get_shell_window (shell_view);
+	action_group = E_SHELL_WINDOW_ACTION_GROUP_SHELL (shell_window);
+
+	/* Add actions to the "shell" action group. */
+	gtk_action_group_add_actions (
+		action_group, entries,
+		G_N_ELEMENTS (entries), shell_view);
+
+	return TRUE;
+}

Modified: branches/kill-bonobo/plugins/mark-all-read/org-gnome-mark-all-read.eplug.xml
==============================================================================
--- branches/kill-bonobo/plugins/mark-all-read/org-gnome-mark-all-read.eplug.xml	(original)
+++ branches/kill-bonobo/plugins/mark-all-read/org-gnome-mark-all-read.eplug.xml	Fri Jan 23 21:41:01 2009
@@ -1,18 +1,21 @@
 <?xml version="1.0"?>
 <e-plugin-list>
-		<e-plugin
-			id="org.gnome.evolution.mail.folder.mark_all_read"
-			type="shlib"
-			domain="@GETTEXT_PACKAGE@"
-			_name="Mark All Read"
-			location="@PLUGINDIR@/liborg-gnome-mark-all-read SOEXT@">
-		<author name="Chenthill Palanisamy" email="pchenthill novell com"/>
-		<_description>Used for marking all the messages under a folder as read</_description>
+  <e-plugin id="org.gnome.evolution.mail.folder.mark_all_read"
+        type="shlib"
+        domain="@GETTEXT_PACKAGE@"
+        _name="Mark All Read"
+        location="@PLUGINDIR@/liborg-gnome-mark-all-read SOEXT@">
+    <author name="Chenthill Palanisamy" email="pchenthill novell com"/>
+    <_description>Used for marking all the messages under a folder as read</_description>
 
-		<hook class="org.gnome.evolution.mail.popup:1.0">
-			<menu id="org.gnome.evolution.mail.foldertree.popup" target="folder">
-				<item type="item" path="30.emc.01" icon="mail-mark-read" _label="Mark Me_ssages as Read" activate="org_gnome_mark_all_read" enable="folder" visible="folder"/>
-			</menu>
-		</hook>
-	</e-plugin>
+    <hook class="org.gnome.evolution.ui:1.0">
+      <ui-manager id="org.gnome.evolution.mail">
+        <popup name="mail-folder-popup">
+          <placeholder name="mail-folder-popup-actions">
+            <menuitem action="mail-mark-read-recursive"/>
+          </placeholder>
+        </popup>
+      </ui-manager>
+    </hook>
+  </e-plugin>
 </e-plugin-list>

Modified: branches/kill-bonobo/plugins/plugin-manager/Makefile.am
==============================================================================
--- branches/kill-bonobo/plugins/plugin-manager/Makefile.am	(original)
+++ branches/kill-bonobo/plugins/plugin-manager/Makefile.am	Fri Jan 23 21:41:01 2009
@@ -4,7 +4,7 @@
 
 @EVO_PLUGIN_RULE@
 
-plugin_DATA = org-gnome-plugin-manager.eplug org-gnome-plugin-manager.xml
+plugin_DATA = org-gnome-plugin-manager.eplug
 plugin_LTLIBRARIES = liborg-gnome-plugin-manager.la
 
 liborg_gnome_plugin_manager_la_SOURCES = plugin-manager.c
@@ -13,9 +13,8 @@
 	$(top_builddir)/e-util/libeutil.la		\
 	$(EVOLUTION_MAIL_LIBS)
 
-EXTRA_DIST =						\
-	org-gnome-plugin-manager.eplug.xml		\
-	org-gnome-plugin-manager.xml
+EXTRA_DIST = \
+	org-gnome-plugin-manager.eplug.xml
 
 BUILT_SOURCES = org-gnome-plugin-manager.eplug
 

Modified: branches/kill-bonobo/plugins/plugin-manager/org-gnome-plugin-manager.eplug.xml
==============================================================================
--- branches/kill-bonobo/plugins/plugin-manager/org-gnome-plugin-manager.eplug.xml	(original)
+++ branches/kill-bonobo/plugins/plugin-manager/org-gnome-plugin-manager.eplug.xml	Fri Jan 23 21:41:01 2009
@@ -6,18 +6,19 @@
     location="@PLUGINDIR@/liborg-gnome-plugin-manager SOEXT@"
     _name="Plugin Manager"
     system_plugin="true">
-    <_description>A plugin for managing which plugins are enabled or disabled.</_description>
     <author name="Michael Zucchi" email="notzed ximian com"/>
-    <hook class="org.gnome.evolution.shell.bonobomenu:1.0">
-      <menu id="org.gnome.evolution.shell" target="shell">
-	<!-- the path to the bonobo menu description -->
-	<ui file="@PLUGINDIR@/org-gnome-plugin-manager.xml"/>
-	<item
-	  type="item"
-	  verb="EPluginManagerManage"
-	  path="/commands/EPluginManagerManage"
-	  activate="org_gnome_plugin_manager_manage"/>
-      </menu>
+    <_description>A plugin for managing which plugins are enabled or disabled.</_description>
+
+    <hook class="org.gnome.evolution.ui:1.0">
+      <ui-manager id="org.gnome.evolution.shell">
+        <menubar name="main-menu">
+          <menu action="edit-menu">
+            <placeholder name="administrative-actions">
+              <menuitem action="plugin-manager"/>
+            </placeholder>
+          </menu>
+        </menubar>
+      </ui-manager>
     </hook>
   </e-plugin>
 </e-plugin-list>

Modified: branches/kill-bonobo/plugins/plugin-manager/plugin-manager.c
==============================================================================
--- branches/kill-bonobo/plugins/plugin-manager/plugin-manager.c	(original)
+++ branches/kill-bonobo/plugins/plugin-manager/plugin-manager.c	Fri Jan 23 21:41:01 2009
@@ -32,7 +32,8 @@
 #include <stdio.h>
 
 #include "e-util/e-plugin.h"
-#include "shell/es-menu.h"
+#include "shell/e-shell-window.h"
+#include "shell/e-shell-window-actions.h"
 
 #define d(S) (S)
 
@@ -61,7 +62,6 @@
 
 typedef struct _Manager Manager;
 struct _Manager {
-	GtkDialog *dialog;
 	GtkTreeView *treeview;
 	GtkTreeModel *model;
 
@@ -75,13 +75,13 @@
 };
 
 /* for tracking if we're shown */
-static GtkDialog *dialog;
 static GtkWidget *notebook;
 static GtkWidget *configure_page;
 static gint last_selected_page;
 static gulong switch_page_handler_id;
 
-void org_gnome_plugin_manager_manage(void *ep, ESMenuTargetShell *t);
+gboolean	e_plugin_ui_init		(GtkUIManager *manager,
+						 EShellWindow *shell_window);
 
 static void
 eppm_set_label (GtkLabel *l, const char *v)
@@ -221,19 +221,15 @@
 }
 
 static void
-eppm_response (GtkDialog *w, int button, Manager *m)
-{
-	gtk_widget_destroy (GTK_WIDGET (w));
-	dialog = NULL;
-}
-
-void
-org_gnome_plugin_manager_manage (void *ep, ESMenuTargetShell *t)
+action_plugin_manager_cb (GtkAction *action,
+                          EShellWindow *shell_window)
 {
 	Manager *m;
 	int i;
+	GtkWidget *dialog;
 	GtkWidget *hbox, *w;
 	GtkWidget *overview_page;
+	GtkWidget *content_area;
 	GtkListStore *store;
 	GtkTreeSelection *selection;
 	GtkCellRenderer *renderer;
@@ -241,26 +237,23 @@
 	char *string;
 	GtkWidget *subvbox;
 
-	if (dialog) {
-		gtk_window_present (GTK_WINDOW (dialog));
-		return;
-	}
-
 	m = g_malloc0 (sizeof (*m));
 
 	/* Setup the ui */
-	m->dialog = GTK_DIALOG (gtk_dialog_new_with_buttons (_("Plugin Manager"),
-							     GTK_WINDOW (gtk_widget_get_toplevel (t->target.widget)),
-							     GTK_DIALOG_DESTROY_WITH_PARENT,
-							     GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
-							     NULL));
+	dialog = gtk_dialog_new_with_buttons (
+		_("Plugin Manager"),
+		GTK_WINDOW (shell_window),
+		GTK_DIALOG_DESTROY_WITH_PARENT,
+		GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE, NULL);
+
+	content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
 
-	gtk_window_set_default_size (GTK_WINDOW (m->dialog), 640, 400);
-	g_object_set (G_OBJECT (m->dialog), "has_separator", FALSE, NULL);
+	gtk_window_set_default_size (GTK_WINDOW (dialog), 640, 400);
+	g_object_set (dialog, "has_separator", FALSE, NULL);
 
 	hbox = gtk_hbox_new (FALSE, 0);
 	gtk_container_set_border_width (GTK_CONTAINER (hbox), 12);
-	gtk_box_pack_start (GTK_BOX (m->dialog->vbox), hbox, TRUE, TRUE, 0);
+	gtk_box_pack_start (GTK_BOX (content_area), hbox, TRUE, TRUE, 0);
 
 	string = g_strdup_printf ("<i>%s</i>", _("Note: Some changes will not take effect until restart"));
 
@@ -272,7 +265,7 @@
 	gtk_widget_show (w);
 	g_free (string);
 
-	gtk_box_pack_start (GTK_BOX (m->dialog->vbox), w, FALSE, TRUE, 6);
+	gtk_box_pack_start (GTK_BOX (content_area), w, FALSE, TRUE, 6);
 
 	notebook = gtk_notebook_new ();
 	gtk_notebook_set_show_tabs (GTK_NOTEBOOK (notebook), TRUE);
@@ -423,24 +416,34 @@
 
 	atk_object_set_name (gtk_widget_get_accessible (GTK_WIDGET (m->treeview)), _("Plugin"));
 
-	g_object_set_data_full (G_OBJECT (m->dialog), "plugin-manager", m, eppm_free);
-	g_signal_connect (m->dialog, "response", G_CALLBACK (eppm_response), m);
-
-	dialog = m->dialog;
+	gtk_dialog_run (GTK_DIALOG (dialog));
 
-	gtk_widget_show (GTK_WIDGET (m->dialog));
+	gtk_widget_destroy (dialog);
+	eppm_free (m);
 }
 
-int e_plugin_lib_enable (EPluginLib *ep, int enable);
+static GtkActionEntry entries[] = {
 
-int
-e_plugin_lib_enable (EPluginLib *ep, int enable)
+	{ "plugin-manager",
+	  NULL,
+	  N_("_Plugins"),
+	  NULL,
+	  N_("Enable and disable plugins"),
+	  G_CALLBACK (action_plugin_manager_cb) }
+};
+
+gboolean
+e_plugin_ui_init (GtkUIManager *manager,
+                  EShellWindow *shell_window)
 {
-	if (enable) {
-	} else {
-		/* This plugin can't be disabled ... */
-		return -1;
-	}
+	GtkActionGroup *action_group;
+
+	action_group = E_SHELL_WINDOW_ACTION_GROUP_SHELL (shell_window);
+
+	/* Add actions to the "shell" action group. */
+	gtk_action_group_add_actions (
+		action_group, entries,
+		G_N_ELEMENTS (entries), shell_window);
 
-	return 0;
+	return TRUE;
 }

Modified: branches/kill-bonobo/shell/e-shell-view.c
==============================================================================
--- branches/kill-bonobo/shell/e-shell-view.c	(original)
+++ branches/kill-bonobo/shell/e-shell-view.c	Fri Jan 23 21:41:01 2009
@@ -25,6 +25,7 @@
 #include <glib/gi18n.h>
 
 #include "e-util/e-util.h"
+#include "e-util/e-plugin-ui.h"
 
 #include "e-shell-content.h"
 #include "e-shell-module.h"
@@ -76,7 +77,7 @@
 static gulong signals[LAST_SIGNAL];
 
 static void
-shell_view_init_view_collection (EShellViewClass *shell_view_class)
+shell_view_init_view_collection (EShellViewClass *class)
 {
 	EShellModule *shell_module;
 	const gchar *base_dir;
@@ -84,8 +85,8 @@
 	gchar *system_dir;
 	gchar *local_dir;
 
-	shell_module = E_SHELL_MODULE (shell_view_class->type_module);
-	module_name = shell_view_class->type_module->name;
+	shell_module = E_SHELL_MODULE (class->type_module);
+	module_name = class->type_module->name;
 
 	base_dir = EVOLUTION_GALVIEWSDIR;
 	system_dir = g_build_filename (base_dir, module_name, NULL);
@@ -94,15 +95,13 @@
 	local_dir = g_build_filename (base_dir, "views", NULL);
 
 	/* The view collection is never destroyed. */
-	shell_view_class->view_collection = gal_view_collection_new ();
+	class->view_collection = gal_view_collection_new ();
 
 	gal_view_collection_set_title (
-		shell_view_class->view_collection,
-		shell_view_class->label);
+		class->view_collection, class->label);
 
 	gal_view_collection_set_storage_directories (
-		shell_view_class->view_collection,
-		system_dir, local_dir);
+		class->view_collection, system_dir, local_dir);
 
 	g_free (system_dir);
 	g_free (local_dir);
@@ -319,13 +318,22 @@
 static void
 shell_view_constructed (GObject *object)
 {
+	EShellWindow *shell_window;
 	EShellView *shell_view;
 	EShellViewClass *class;
+	GtkUIManager *ui_manager;
 	GtkWidget *widget;
+	const gchar *id;
 
 	shell_view = E_SHELL_VIEW (object);
 	class = E_SHELL_VIEW_GET_CLASS (object);
 
+	shell_window = e_shell_view_get_shell_window (shell_view);
+	ui_manager = e_shell_window_get_ui_manager (shell_window);
+	id = class->ui_manager_id;
+
+	e_plugin_ui_register_manager (ui_manager, id, shell_view);
+
 	/* Invoke factory methods. */
 
 	widget = class->new_shell_content (shell_view);
@@ -345,21 +353,24 @@
 shell_view_toggled (EShellView *shell_view)
 {
 	EShellViewPrivate *priv = shell_view->priv;
-	EShellViewClass *shell_view_class;
+	EShellViewClass *class;
 	EShellWindow *shell_window;
 	GtkUIManager *ui_manager;
 	const gchar *basename;
 	gboolean view_is_active;
 
-	shell_view_class = E_SHELL_VIEW_GET_CLASS (shell_view);
+	class = E_SHELL_VIEW_GET_CLASS (shell_view);
 	shell_window = e_shell_view_get_shell_window (shell_view);
 	ui_manager = e_shell_window_get_ui_manager (shell_window);
 	view_is_active = e_shell_view_is_active (shell_view);
-	basename = shell_view_class->ui_definition;
+	basename = class->ui_definition;
 
-	if (view_is_active && priv->merge_id == 0)
+	if (view_is_active && priv->merge_id == 0) {
 		priv->merge_id = e_load_ui_definition (ui_manager, basename);
-	else if (!view_is_active && priv->merge_id != 0) {
+		e_plugin_ui_enable_manager (ui_manager, class->ui_manager_id);
+
+	} else if (!view_is_active && priv->merge_id != 0) {
+		e_plugin_ui_disable_manager (ui_manager, class->ui_manager_id);
 		gtk_ui_manager_remove_ui (ui_manager, priv->merge_id);
 		priv->merge_id = 0;
 	}
@@ -581,7 +592,7 @@
 
 static void
 shell_view_init (EShellView *shell_view,
-                 EShellViewClass *shell_view_class)
+                 EShellViewClass *class)
 {
 	GtkSizeGroup *size_group;
 
@@ -590,8 +601,8 @@
 	shell_view->priv = E_SHELL_VIEW_GET_PRIVATE (shell_view);
 	shell_view->priv->size_group = size_group;
 
-	if (shell_view_class->view_collection == NULL)
-		shell_view_init_view_collection (shell_view_class);
+	if (class->view_collection == NULL)
+		shell_view_init_view_collection (class);
 }
 
 GType
@@ -785,17 +796,17 @@
 EShellModule *
 e_shell_view_get_shell_module (EShellView *shell_view)
 {
-	EShellViewClass *shell_view_class;
+	EShellViewClass *class;
 
 	g_return_val_if_fail (E_IS_SHELL_VIEW (shell_view), NULL);
 
 	/* Calling this function during the shell view's instance
 	 * initialization function will return the wrong result,
 	 * so watch for that and emit a warning. */
-	shell_view_class = E_SHELL_VIEW_GET_CLASS (shell_view);
-	g_return_val_if_fail (E_IS_SHELL_VIEW_CLASS (shell_view_class), NULL);
+	class = E_SHELL_VIEW_GET_CLASS (shell_view);
+	g_return_val_if_fail (E_IS_SHELL_VIEW_CLASS (class), NULL);
 
-	return E_SHELL_MODULE (shell_view_class->type_module);
+	return E_SHELL_MODULE (class->type_module);
 }
 
 /**
@@ -1018,15 +1029,15 @@
 e_shell_view_new_view_instance (EShellView *shell_view,
                                 const gchar *instance_id)
 {
-	EShellViewClass *shell_view_class;
+	EShellViewClass *class;
 	GalViewCollection *view_collection;
 	GalViewInstance *view_instance;
 
 	g_return_val_if_fail (E_IS_SHELL_VIEW (shell_view), NULL);
 
-	shell_view_class = E_SHELL_VIEW_GET_CLASS (shell_view);
+	class = E_SHELL_VIEW_GET_CLASS (shell_view);
 
-	view_collection = shell_view_class->view_collection;
+	view_collection = class->view_collection;
 	view_instance = gal_view_instance_new (view_collection, instance_id);
 
 	g_signal_connect_swapped (

Modified: branches/kill-bonobo/shell/e-shell-view.h
==============================================================================
--- branches/kill-bonobo/shell/e-shell-view.h	(original)
+++ branches/kill-bonobo/shell/e-shell-view.h	Fri Jan 23 21:41:01 2009
@@ -85,6 +85,9 @@
  * 			e_shell_view_get_action().
  * @ui_definition:	Base name of the UI definintion file to add
  * 			when the shell view is activated.
+ * @ui_manager_id:	The #GtkUIManager ID for #EPluginUI.  Plugins
+ * 			should use to this ID in their "eplug" files to
+ * 			add menu and toolbar items to the shell view.
  * @search_options:	Widget path in the UI definition to the search
  * 			options popup menu.  The menu gets shown when the
  * 			user clicks the "find" icon in the search entry.
@@ -129,6 +132,9 @@
 	/* Base name of the UI definition file. */
 	const gchar *ui_definition;
 
+	/* GtkUIManager ID for use with EPluginUI. */
+	const gchar *ui_manager_id;
+
 	/* Widget path to the search options popup menu. */
 	const gchar *search_options;
 

Modified: branches/kill-bonobo/shell/e-shell-window.c
==============================================================================
--- branches/kill-bonobo/shell/e-shell-window.c	(original)
+++ branches/kill-bonobo/shell/e-shell-window.c	Fri Jan 23 21:41:01 2009
@@ -353,6 +353,7 @@
 shell_window_init (EShellWindow *shell_window)
 {
 	GtkUIManager *ui_manager;
+	const gchar *id;
 
 	shell_window->priv = E_SHELL_WINDOW_GET_PRIVATE (shell_window);
 
@@ -362,8 +363,9 @@
 
 	ui_manager = e_shell_window_get_ui_manager (shell_window);
 
-	e_plugin_ui_register_manager (
-		"org.gnome.evolution.shell", ui_manager, shell_window);
+	id = "org.gnome.evolution.shell";
+	e_plugin_ui_register_manager (ui_manager, id, shell_window);
+	e_plugin_ui_enable_manager (ui_manager, id);
 }
 
 GType

Modified: branches/kill-bonobo/ui/evolution-mail.ui
==============================================================================
--- branches/kill-bonobo/ui/evolution-mail.ui	(original)
+++ branches/kill-bonobo/ui/evolution-mail.ui	Fri Jan 23 21:41:01 2009
@@ -74,6 +74,7 @@
     <separator/>
     <menuitem action='mail-popup-folder-delete'/>
     <separator/>
+    <placeholder name='mail-folder-popup-actions'/>
     <menuitem action='mail-popup-folder-rename'/>
     <menuitem action='mail-popup-folder-refresh'/>
     <menuitem action='mail-popup-flush-outbox'/>

Modified: branches/kill-bonobo/widgets/menus/gal-view-instance.c
==============================================================================
--- branches/kill-bonobo/widgets/menus/gal-view-instance.c	(original)
+++ branches/kill-bonobo/widgets/menus/gal-view-instance.c	Fri Jan 23 21:41:01 2009
@@ -46,10 +46,6 @@
 
 G_DEFINE_TYPE (GalViewInstance, gal_view_instance, G_TYPE_OBJECT)
 
-static const EPopupMenu separator = E_POPUP_SEPARATOR;
-static const EPopupMenu terminator = E_POPUP_TERMINATOR;
-
-
 #define d(x)
 
 enum {
@@ -467,140 +463,3 @@
 		return FALSE;
 
 }
-
-typedef struct {
-	GalViewInstance *instance;
-	char *id;
-} ListenerClosure;
-
-static void
-view_item_cb (GtkWidget *widget,
-	      gpointer user_data)
-{
-	ListenerClosure *closure = user_data;
-
-	if (GTK_CHECK_MENU_ITEM (widget)->active) {
-		gal_view_instance_set_current_view_id (closure->instance, closure->id);
-	}
-}
-
-static void
-add_popup_radio_item (EPopupMenu *menu_item,
-		      gchar *title,
-		      GCallback fn,
-		      gpointer closure,
-		      gboolean value)
-{
-	EPopupMenu menu_item_struct =
-		E_POPUP_RADIO_ITEM_CC (title,
-				       fn,
-				       closure,
-				       0,
-				       0);
-	menu_item_struct.is_active = value;
-
-	e_popup_menu_copy_1 (menu_item, &menu_item_struct);
-}
-
-static void
-add_popup_menu_item (EPopupMenu *menu_item,
-		     gchar *title,
-		     GCallback fn,
-		     gpointer closure)
-{
-	EPopupMenu menu_item_struct =
-		E_POPUP_ITEM_CC (title,
-				 fn,
-				 closure,
-				 0);
-
-	e_popup_menu_copy_1 (menu_item, &menu_item_struct);
-}
-
-static void
-define_views_dialog_response(GtkWidget *dialog, int id, GalViewInstance *instance)
-{
-	if (id == GTK_RESPONSE_OK) {
-		gal_view_collection_save(instance->collection);
-	}
-	gtk_widget_destroy (dialog);
-}
-
-static void
-define_views_cb(GtkWidget *widget,
-		GalViewInstance *instance)
-{
-	GtkWidget *dialog = gal_define_views_dialog_new(instance->collection);
-	g_signal_connect(dialog, "response",
-			 G_CALLBACK(define_views_dialog_response), instance);
-	gtk_widget_show(dialog);
-}
-
-static void
-save_current_view_cb(GtkWidget *widget,
-		     GalViewInstance      *instance)
-{
-	gal_view_instance_save_as (instance);
-}
-
-EPopupMenu *
-gal_view_instance_get_popup_menu (GalViewInstance *instance)
-{
-	EPopupMenu *ret_val;
-	int length;
-	int i;
-	gboolean found = FALSE;
-	char *id;
-
-	length = gal_view_collection_get_count(instance->collection);
-	id = gal_view_instance_get_current_view_id (instance);
-
-	ret_val = g_new (EPopupMenu, length + 6);
-
-	for (i = 0; i < length; i++) {
-		gboolean value = FALSE;
-		GalViewCollectionItem *item = gal_view_collection_get_view_item(instance->collection, i);
-		ListenerClosure *closure;
-
-		closure            = g_new (ListenerClosure, 1);
-		closure->instance  = instance;
-		closure->id        = item->id;
-		g_object_ref (closure->instance);
-
-		if (!found && id && !strcmp (id, item->id)) {
-			found = TRUE;
-			value = TRUE;
-		}
-
-		add_popup_radio_item (ret_val + i, item->title, G_CALLBACK (view_item_cb), closure, value);
-	}
-
-	if (!found) {
-		e_popup_menu_copy_1 (ret_val + i++, &separator);
-
-		add_popup_radio_item (ret_val + i++, N_("Custom View"), NULL, NULL, TRUE);
-		add_popup_menu_item (ret_val + i++, N_("Save Custom View"), G_CALLBACK (save_current_view_cb), instance);
-	}
-
-	e_popup_menu_copy_1 (ret_val + i++, &separator);
-	add_popup_menu_item (ret_val + i++, N_("Define Views..."), G_CALLBACK (define_views_cb), instance);
-	e_popup_menu_copy_1 (ret_val + i++, &terminator);
-
-	if (id)
-		g_free (id);
-
-	return ret_val;
-}
-
-void
-gal_view_instance_free_popup_menu (GalViewInstance *instance, EPopupMenu *menu)
-{
-	int i;
-	/* This depends on the first non-custom closure to be a separator or a terminator. */
-	for (i = 0; menu[i].name && *(menu[i].name); i++) {
-		g_object_unref (((ListenerClosure *)(menu[i].closure))->instance);
-		g_free (menu[i].closure);
-	}
-
-	e_popup_menu_free (menu);
-}

Modified: branches/kill-bonobo/widgets/menus/gal-view-instance.h
==============================================================================
--- branches/kill-bonobo/widgets/menus/gal-view-instance.h	(original)
+++ branches/kill-bonobo/widgets/menus/gal-view-instance.h	Fri Jan 23 21:41:01 2009
@@ -26,7 +26,6 @@
 
 #include <glib-object.h>
 #include <widgets/menus/gal-view-collection.h>
-#include <misc/e-popup-menu.h>
 
 G_BEGIN_DECLS
 
@@ -107,10 +106,6 @@
 void             gal_view_instance_set_default_view     (GalViewInstance   *instance,
 							 const char        *id);
 
-EPopupMenu      *gal_view_instance_get_popup_menu       (GalViewInstance   *instance);
-void             gal_view_instance_free_popup_menu      (GalViewInstance   *instance,
-							 EPopupMenu        *menu);
-
 G_END_DECLS
 
 #endif /* _GAL_VIEW_INSTANCE_H_ */



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