aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthew Barnes <mbarnes@src.gnome.org>2009-01-24 05:41:01 +0800
committerMatthew Barnes <mbarnes@src.gnome.org>2009-01-24 05:41:01 +0800
commitbd9f473a896496b95b9896d30940f2ab27493432 (patch)
tree7c314e4776bcfbff0c483ee7995818519fbc43bb
parent3c7a575407bef757d434808904a4c4dc1ba60cb3 (diff)
downloadgsoc2013-evolution-bd9f473a896496b95b9896d30940f2ab27493432.tar
gsoc2013-evolution-bd9f473a896496b95b9896d30940f2ab27493432.tar.gz
gsoc2013-evolution-bd9f473a896496b95b9896d30940f2ab27493432.tar.bz2
gsoc2013-evolution-bd9f473a896496b95b9896d30940f2ab27493432.tar.lz
gsoc2013-evolution-bd9f473a896496b95b9896d30940f2ab27493432.tar.xz
gsoc2013-evolution-bd9f473a896496b95b9896d30940f2ab27493432.tar.zst
gsoc2013-evolution-bd9f473a896496b95b9896d30940f2ab27493432.zip
Redesign EPluginUI to accommodate merging and unmerging shell views.
Get the "mark-all-read" and "plugin-manager" plugins working. svn path=/branches/kill-bonobo/; revision=37125
-rw-r--r--addressbook/gui/component/e-book-shell-view.c1
-rw-r--r--addressbook/gui/widgets/eab-contact-display.c6
-rw-r--r--calendar/gui/dialogs/event-editor.c6
-rw-r--r--calendar/gui/dialogs/memo-editor.c6
-rw-r--r--calendar/gui/dialogs/task-editor.c6
-rw-r--r--calendar/modules/e-cal-shell-view.c1
-rw-r--r--calendar/modules/e-memo-shell-view.c1
-rw-r--r--calendar/modules/e-task-shell-view.c1
-rw-r--r--composer/e-msg-composer.c6
-rw-r--r--configure.in4
-rw-r--r--doc/reference/shell/tmpl/e-shell-view.sgml1
-rw-r--r--e-util/e-plugin-ui.c434
-rw-r--r--e-util/e-plugin-ui.h9
-rw-r--r--mail/e-mail-shell-view.c1
-rw-r--r--plugins/mark-all-read/Makefile.am2
-rw-r--r--plugins/mark-all-read/mark-all-read.c72
-rw-r--r--plugins/mark-all-read/org-gnome-mark-all-read.eplug.xml31
-rw-r--r--plugins/plugin-manager/Makefile.am7
-rw-r--r--plugins/plugin-manager/org-gnome-plugin-manager.eplug.xml23
-rw-r--r--plugins/plugin-manager/org-gnome-plugin-manager.xml15
-rw-r--r--plugins/plugin-manager/plugin-manager.c83
-rw-r--r--shell/e-shell-view.c57
-rw-r--r--shell/e-shell-view.h6
-rw-r--r--shell/e-shell-window.c6
-rw-r--r--ui/evolution-mail.ui1
-rw-r--r--widgets/menus/gal-view-instance.c141
-rw-r--r--widgets/menus/gal-view-instance.h5
27 files changed, 512 insertions, 420 deletions
diff --git a/addressbook/gui/component/e-book-shell-view.c b/addressbook/gui/component/e-book-shell-view.c
index 11cdaf6594..6244384390 100644
--- a/addressbook/gui/component/e-book-shell-view.c
+++ b/addressbook/gui/component/e-book-shell-view.c
@@ -286,6 +286,7 @@ book_shell_view_class_init (EBookShellViewClass *class,
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;
diff --git a/addressbook/gui/widgets/eab-contact-display.c b/addressbook/gui/widgets/eab-contact-display.c
index 02aa5b81f0..42cc65294f 100644
--- a/addressbook/gui/widgets/eab-contact-display.c
+++ b/addressbook/gui/widgets/eab-contact-display.c
@@ -1087,6 +1087,7 @@ eab_contact_display_init (EABContactDisplay *display)
{
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 @@ eab_contact_display_init (EABContactDisplay *display)
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
diff --git a/calendar/gui/dialogs/event-editor.c b/calendar/gui/dialogs/event-editor.c
index 72cbf37823..620600369e 100644
--- a/calendar/gui/dialogs/event-editor.c
+++ b/calendar/gui/dialogs/event-editor.c
@@ -465,6 +465,7 @@ event_editor_init (EventEditor *ee)
GtkUIManager *manager;
GtkActionGroup *action_group;
GtkAction *action;
+ const gchar *id;
GError *error = NULL;
ee->priv = EVENT_EDITOR_GET_PRIVATE (ee);
@@ -487,7 +488,10 @@ event_editor_init (EventEditor *ee)
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);
diff --git a/calendar/gui/dialogs/memo-editor.c b/calendar/gui/dialogs/memo-editor.c
index 90c77f2349..5e01327703 100644
--- a/calendar/gui/dialogs/memo-editor.c
+++ b/calendar/gui/dialogs/memo-editor.c
@@ -134,6 +134,7 @@ memo_editor_init (MemoEditor *me)
{
CompEditor *editor = COMP_EDITOR (me);
GtkUIManager *manager;
+ const gchar *id;
GError *error = NULL;
me->priv = MEMO_EDITOR_GET_PRIVATE (me);
@@ -141,7 +142,10 @@ memo_editor_init (MemoEditor *me)
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);
diff --git a/calendar/gui/dialogs/task-editor.c b/calendar/gui/dialogs/task-editor.c
index 656e7b4836..773dea4a47 100644
--- a/calendar/gui/dialogs/task-editor.c
+++ b/calendar/gui/dialogs/task-editor.c
@@ -303,6 +303,7 @@ task_editor_init (TaskEditor *te)
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 @@ task_editor_init (TaskEditor *te)
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);
diff --git a/calendar/modules/e-cal-shell-view.c b/calendar/modules/e-cal-shell-view.c
index ca6264efef..67f7d788a4 100644
--- a/calendar/modules/e-cal-shell-view.c
+++ b/calendar/modules/e-cal-shell-view.c
@@ -194,6 +194,7 @@ cal_shell_view_class_init (ECalShellViewClass *class,
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;
diff --git a/calendar/modules/e-memo-shell-view.c b/calendar/modules/e-memo-shell-view.c
index 0237e84e27..89efd8f15d 100644
--- a/calendar/modules/e-memo-shell-view.c
+++ b/calendar/modules/e-memo-shell-view.c
@@ -199,6 +199,7 @@ memo_shell_view_class_init (EMemoShellViewClass *class,
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;
diff --git a/calendar/modules/e-task-shell-view.c b/calendar/modules/e-task-shell-view.c
index 9c893d259a..3bf84100cc 100644
--- a/calendar/modules/e-task-shell-view.c
+++ b/calendar/modules/e-task-shell-view.c
@@ -232,6 +232,7 @@ task_shell_view_class_init (ETaskShellViewClass *class,
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;
diff --git a/composer/e-msg-composer.c b/composer/e-msg-composer.c
index 1fb66a03dd..3e2faf1cfe 100644
--- a/composer/e-msg-composer.c
+++ b/composer/e-msg-composer.c
@@ -2726,6 +2726,7 @@ msg_composer_init (EMsgComposer *composer)
GtkUIManager *manager;
GtkhtmlEditor *editor;
GtkHTML *html;
+ const gchar *id;
composer->priv = E_MSG_COMPOSER_GET_PRIVATE (composer);
@@ -2833,8 +2834,9 @@ msg_composer_init (EMsgComposer *composer)
/* 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
diff --git a/configure.in b/configure.in
index 73867d042d..3797b85e4a 100644
--- a/configure.in
+++ b/configure.in
@@ -1773,7 +1773,7 @@ plugins_experimental="$plugins_experimental_always $IPOD_SYNC $TNEF_ATTACHMENTS
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 ipod-sync
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
diff --git a/doc/reference/shell/tmpl/e-shell-view.sgml b/doc/reference/shell/tmpl/e-shell-view.sgml
index 4eff37a0eb..fb10778576 100644
--- a/doc/reference/shell/tmpl/e-shell-view.sgml
+++ b/doc/reference/shell/tmpl/e-shell-view.sgml
@@ -91,6 +91,7 @@ EShellView
@label:
@icon_name:
@ui_definition:
+@ui_manager_id:
@search_options:
@search_rules:
@type_module:
diff --git a/e-util/e-plugin-ui.c b/e-util/e-plugin-ui.c
index 0b28adda5d..2528efd0fa 100644
--- a/e-util/e-plugin-ui.c
+++ b/e-util/e-plugin-ui.c
@@ -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 @@ struct _EPluginUIHookPrivate {
*
* 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 @@ struct _EPluginUIHookPrivate {
* 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);
- g_hash_table_insert (hash_table, manager, GUINT_TO_POINTER (merge_id));
+ registry = hook->priv->registry;
+ hash_table = g_hash_table_lookup (registry, manager);
+
+ 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;
+
+ data = g_hash_table_lookup (hash_table, id);
+ merge_id = GPOINTER_TO_UINT (data);
- g_hash_table_foreach (
- intermediate, (GHFunc)
- plugin_ui_hook_merge_foreach, new_merge_ids);
+ if (merge_id > 0)
+ continue;
- g_hash_table_insert (registry, hook, new_merge_ids);
+ if (((EPluginHook *) hook)->plugin->enabled)
+ merge_id = plugin_ui_hook_merge_ui (hook, manager, id);
- g_hash_table_destroy (intermediate);
+ /* 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;
- merge_id = GPOINTER_TO_UINT (value);
- gtk_ui_manager_remove_ui (manager, merge_id);
+ id = keys->data;
+ keys = g_list_delete_link (keys, keys);
+
+ if (g_hash_table_lookup (ui_definitions, id) == NULL)
+ continue;
+
+ data = g_hash_table_lookup (hash_table, id);
+ merge_id = GPOINTER_TO_UINT (data);
+
+ /* Merge ID could be 0 if the plugin is disabled. */
+ if (merge_id > 0)
+ gtk_ui_manager_remove_ui (manager, merge_id);
- g_hash_table_insert (hash_table, manager, GUINT_TO_POINTER (0));
+ 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;
-
- plugin = ((EPluginHook *) hook)->plugin;
- func = e_plugin_get_symbol (plugin, E_PLUGIN_UI_INIT_FUNC);
+ GHashTable *hash_table;
+ GHashTableIter iter;
+ gpointer key;
- /* 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;
+ /* Disable all GtkUIManagers for this hook. */
- 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 @@ plugin_ui_hook_enable (EPluginHook *hook,
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 @@ static void
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 @@ e_plugin_ui_hook_get_type (void)
}
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 @@ e_plugin_ui_register_manager (const gchar *id,
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_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;
- g_return_val_if_fail (GTK_IS_UI_MANAGER (manager), NULL);
+ 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;
- return g_object_get_data (G_OBJECT (manager), key);
+ if (!E_IS_PLUGIN_UI_HOOK (hook))
+ continue;
+
+ plugin_ui_disable_manager (hook, manager, id, TRUE);
+ }
+ }
}
diff --git a/e-util/e-plugin-ui.h b/e-util/e-plugin-ui.h
index 00e6ed5fcf..d1a380d91e 100644
--- a/e-util/e-plugin-ui.h
+++ b/e-util/e-plugin-ui.h
@@ -62,10 +62,13 @@ typedef gboolean (*EPluginUIInitFunc) (GtkUIManager *manager,
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
diff --git a/mail/e-mail-shell-view.c b/mail/e-mail-shell-view.c
index 5a338ab011..dbca7b479c 100644
--- a/mail/e-mail-shell-view.c
+++ b/mail/e-mail-shell-view.c
@@ -211,6 +211,7 @@ mail_shell_view_class_init (EMailShellViewClass *class,
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;
diff --git a/plugins/mark-all-read/Makefile.am b/plugins/mark-all-read/Makefile.am
index 756e945d00..c13125c7a5 100644
--- a/plugins/mark-all-read/Makefile.am
+++ b/plugins/mark-all-read/Makefile.am
@@ -12,7 +12,7 @@ liborg_gnome_mark_all_read_la_SOURCES = mark-all-read.c
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
diff --git a/plugins/mark-all-read/mark-all-read.c b/plugins/mark-all-read/mark-all-read.c
index c9ea67ca61..c98b33edd1 100644
--- a/plugins/mark-all-read/mark-all-read.c
+++ b/plugins/mark-all-read/mark-all-read.c
@@ -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 @@ prompt_user (void)
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 @@ mar_all_sub_folders (CamelStore *store, CamelFolderInfo *fi, CamelException *ex)
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;
+}
diff --git a/plugins/mark-all-read/org-gnome-mark-all-read.eplug.xml b/plugins/mark-all-read/org-gnome-mark-all-read.eplug.xml
index a4542572a5..76c0864fa1 100644
--- a/plugins/mark-all-read/org-gnome-mark-all-read.eplug.xml
+++ b/plugins/mark-all-read/org-gnome-mark-all-read.eplug.xml
@@ -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>
diff --git a/plugins/plugin-manager/Makefile.am b/plugins/plugin-manager/Makefile.am
index f9d6642521..22e4ca7d51 100644
--- a/plugins/plugin-manager/Makefile.am
+++ b/plugins/plugin-manager/Makefile.am
@@ -4,7 +4,7 @@ INCLUDES = \
@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 @@ liborg_gnome_plugin_manager_la_LIBADD = \
$(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
diff --git a/plugins/plugin-manager/org-gnome-plugin-manager.eplug.xml b/plugins/plugin-manager/org-gnome-plugin-manager.eplug.xml
index d8e4849f2f..c931b5c968 100644
--- a/plugins/plugin-manager/org-gnome-plugin-manager.eplug.xml
+++ b/plugins/plugin-manager/org-gnome-plugin-manager.eplug.xml
@@ -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>
diff --git a/plugins/plugin-manager/org-gnome-plugin-manager.xml b/plugins/plugin-manager/org-gnome-plugin-manager.xml
deleted file mode 100644
index 3f74a2dd4c..0000000000
--- a/plugins/plugin-manager/org-gnome-plugin-manager.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<Root>
- <commands>
- <cmd name="EPluginManagerManage" _label="_Plugins"
- _tip="Enable and disable plugins"/>
- </commands>
-
- <menu>
- <submenu name="Edit">
- <placeholder name="PluginManagerPlaceholder">
- <menuitem name="EPluginManagerManage" verb=""/>
- </placeholder>
- </submenu>
-
- </menu>
-</Root>
diff --git a/plugins/plugin-manager/plugin-manager.c b/plugins/plugin-manager/plugin-manager.c
index 19af3eeb7e..129ff0a74f 100644
--- a/plugins/plugin-manager/plugin-manager.c
+++ b/plugins/plugin-manager/plugin-manager.c
@@ -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 @@ static struct {
typedef struct _Manager Manager;
struct _Manager {
- GtkDialog *dialog;
GtkTreeView *treeview;
GtkTreeModel *model;
@@ -75,13 +75,13 @@ struct _Manager {
};
/* 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 @@ eppm_free (void *data)
}
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 @@ org_gnome_plugin_manager_manage (void *ep, ESMenuTargetShell *t)
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 @@ org_gnome_plugin_manager_manage (void *ep, ESMenuTargetShell *t)
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 @@ org_gnome_plugin_manager_manage (void *ep, ESMenuTargetShell *t)
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;
}
diff --git a/shell/e-shell-view.c b/shell/e-shell-view.c
index f1f1ffb476..d7a564c567 100644
--- a/shell/e-shell-view.c
+++ b/shell/e-shell-view.c
@@ -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 gpointer parent_class;
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 @@ shell_view_init_view_collection (EShellViewClass *shell_view_class)
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 @@ shell_view_init_view_collection (EShellViewClass *shell_view_class)
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 @@ shell_view_finalize (GObject *object)
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 @@ static void
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 @@ shell_view_class_init (EShellViewClass *class)
static void
shell_view_init (EShellView *shell_view,
- EShellViewClass *shell_view_class)
+ EShellViewClass *class)
{
GtkSizeGroup *size_group;
@@ -590,8 +601,8 @@ shell_view_init (EShellView *shell_view,
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 @@ e_shell_view_get_shell_window (EShellView *shell_view)
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 @@ GalViewInstance *
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 (
diff --git a/shell/e-shell-view.h b/shell/e-shell-view.h
index 3159b5a71b..78987d9db6 100644
--- a/shell/e-shell-view.h
+++ b/shell/e-shell-view.h
@@ -85,6 +85,9 @@ struct _EShellView {
* 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 @@ struct _EShellViewClass {
/* 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;
diff --git a/shell/e-shell-window.c b/shell/e-shell-window.c
index 2a9adc67ac..53074d2352 100644
--- a/shell/e-shell-window.c
+++ b/shell/e-shell-window.c
@@ -353,6 +353,7 @@ static void
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 @@ shell_window_init (EShellWindow *shell_window)
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
diff --git a/ui/evolution-mail.ui b/ui/evolution-mail.ui
index 5369802139..c8a9960d72 100644
--- a/ui/evolution-mail.ui
+++ b/ui/evolution-mail.ui
@@ -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'/>
diff --git a/widgets/menus/gal-view-instance.c b/widgets/menus/gal-view-instance.c
index a1eac04b6c..19ec402fa3 100644
--- a/widgets/menus/gal-view-instance.c
+++ b/widgets/menus/gal-view-instance.c
@@ -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 @@ gal_view_instance_exists (GalViewInstance *instance)
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);
-}
diff --git a/widgets/menus/gal-view-instance.h b/widgets/menus/gal-view-instance.h
index 37c8ad6869..096cc2b967 100644
--- a/widgets/menus/gal-view-instance.h
+++ b/widgets/menus/gal-view-instance.h
@@ -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 @@ const char *gal_view_instance_get_default_view (GalViewInstance *inst
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_ */