[gnome-builder] libide: load menus from application and plugins



commit 1f2408f5dfb261fbbba50511ef20ef279ca963f5
Author: Christian Hergert <chergert redhat com>
Date:   Thu Dec 3 15:01:51 2015 -0800

    libide: load menus from application and plugins
    
    Uses the new EggMenuManager to provide application menus with overrides
    provided by plugins.

 libide/ide-application-plugins.c |   72 ++++++++++++++++++++++++++++++++++++++
 libide/ide-application-private.h |    7 +++-
 libide/ide-application.c         |   34 ++++++++++++++++--
 libide/ide-application.h         |    2 +
 4 files changed, 110 insertions(+), 5 deletions(-)
---
diff --git a/libide/ide-application-plugins.c b/libide/ide-application-plugins.c
index 5af0eba..82bbd11 100644
--- a/libide/ide-application-plugins.c
+++ b/libide/ide-application-plugins.c
@@ -189,3 +189,75 @@ ide_application_load_addins (IdeApplication *self)
                               ide_application_addin_added,
                               self);
 }
+
+static void
+ide_application_load_plugin_menus (IdeApplication *self,
+                                   PeasPluginInfo *plugin_info,
+                                   PeasEngine     *engine)
+{
+  const gchar *module_name;
+  gchar *path;
+  guint merge_id;
+
+  g_assert (IDE_IS_APPLICATION (self));
+  g_assert (plugin_info != NULL);
+  g_assert (PEAS_IS_ENGINE (engine));
+
+  module_name = peas_plugin_info_get_module_name (plugin_info);
+  path = g_strdup_printf ("/org/gnome/builder/plugins/%s/gtk/menus.ui", module_name);
+  g_print ("Loading %s\n", path);
+  merge_id = egg_menu_manager_add_resource (self->menu_manager, path, NULL);
+  if (merge_id != 0)
+    g_hash_table_insert (self->merge_ids, g_strdup (module_name), GINT_TO_POINTER (merge_id));
+  g_print (" merge_id = %d\n", merge_id);
+  g_free (path);
+}
+
+static void
+ide_application_unload_plugin_menus (IdeApplication *self,
+                                     PeasPluginInfo *plugin_info,
+                                     PeasEngine     *engine)
+{
+  const gchar *module_name;
+  guint merge_id;
+
+  g_assert (IDE_IS_APPLICATION (self));
+  g_assert (plugin_info != NULL);
+  g_assert (PEAS_IS_ENGINE (engine));
+
+  module_name = peas_plugin_info_get_module_name (plugin_info);
+  merge_id = GPOINTER_TO_INT (g_hash_table_lookup (self->merge_ids, module_name));
+  if (merge_id != 0)
+    egg_menu_manager_remove (self->menu_manager, merge_id);
+  g_hash_table_remove (self->merge_ids, module_name);
+}
+
+void
+ide_application_init_plugin_menus (IdeApplication *self)
+{
+  const GList *list;
+  PeasEngine *engine;
+
+  g_assert (IDE_IS_APPLICATION (self));
+
+  self->merge_ids = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
+
+  engine = peas_engine_get_default ();
+
+  g_signal_connect_object (engine,
+                           "load-plugin",
+                           G_CALLBACK (ide_application_load_plugin_menus),
+                           self,
+                           G_CONNECT_AFTER | G_CONNECT_SWAPPED);
+
+  g_signal_connect_object (engine,
+                           "unload-plugin",
+                           G_CALLBACK (ide_application_unload_plugin_menus),
+                           self,
+                           G_CONNECT_SWAPPED);
+
+  list = peas_engine_get_plugin_list (engine);
+
+  for (; list != NULL; list = list->next)
+    ide_application_load_plugin_menus (self, list->data, engine);
+}
diff --git a/libide/ide-application-private.h b/libide/ide-application-private.h
index 529bf49..52ad8bd 100644
--- a/libide/ide-application-private.h
+++ b/libide/ide-application-private.h
@@ -22,8 +22,9 @@
 #include <gio/gio.h>
 #include <libpeas/peas.h>
 
+#include "egg-menu-manager.h"
+
 #include "ide-application.h"
-#include "ide-menu-merger.h"
 #include "ide-keybindings.h"
 #include "ide-recent-projects.h"
 #include "ide-theme-manager.h"
@@ -54,12 +55,14 @@ struct _IdeApplication
 
   IdeThemeManager     *theme_manager;
 
-  IdeMenuMerger       *menu_merger;
+  EggMenuManager      *menu_manager;
+  GHashTable          *merge_ids;
 };
 
 void     ide_application_discover_plugins   (IdeApplication   *self) G_GNUC_INTERNAL;
 void     ide_application_load_plugins       (IdeApplication   *self) G_GNUC_INTERNAL;
 void     ide_application_load_addins        (IdeApplication   *self) G_GNUC_INTERNAL;
+void     ide_application_init_plugin_menus  (IdeApplication   *self) G_GNUC_INTERNAL;
 gboolean ide_application_local_command_line (GApplication     *application,
                                              gchar          ***arguments,
                                              gint             *exit_status) G_GNUC_INTERNAL;
diff --git a/libide/ide-application.c b/libide/ide-application.c
index 1363ffe..8098300 100644
--- a/libide/ide-application.c
+++ b/libide/ide-application.c
@@ -122,7 +122,9 @@ ide_application_register_menus (IdeApplication *self)
 
   g_assert (IDE_IS_APPLICATION (self));
 
-  self->menu_merger = ide_menu_merger_new ();
+  self->menu_manager = egg_menu_manager_new ();
+  egg_menu_manager_add_resource (self->menu_manager, "/org/gnome/builder/gtk/menus.ui", NULL);
+  ide_application_init_plugin_menus (self);
 
   IDE_EXIT;
 }
@@ -366,11 +368,12 @@ ide_application_finalize (GObject *object)
   g_clear_pointer (&self->dbus_address, g_free);
   g_clear_pointer (&self->tool_arguments, g_strfreev);
   g_clear_pointer (&self->started_at, g_date_time_unref);
+  g_clear_pointer (&self->merge_ids, g_hash_table_unref);
   g_clear_object (&self->worker_manager);
   g_clear_object (&self->keybindings);
   g_clear_object (&self->recent_projects);
   g_clear_object (&self->theme_manager);
-  g_clear_object (&self->menu_merger);
+  g_clear_object (&self->menu_manager);
 
   G_OBJECT_CLASS (ide_application_parent_class)->finalize (object);
 }
@@ -476,7 +479,7 @@ ide_application_get_worker_async (IdeApplication      *self,
   g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
 
   if (self->mode != IDE_APPLICATION_MODE_PRIMARY)
-    return NULL;
+    return;
 
   if (self->worker_manager == NULL)
     self->worker_manager = ide_worker_manager_new ();
@@ -606,3 +609,28 @@ ide_application_get_started_at (IdeApplication *self)
 {
   return self->started_at;
 }
+
+/**
+ * ide_application_get_menu_by_id:
+ * @self: An #IdeApplication.
+ * @id: The id of the menu to lookup.
+ *
+ * Similar to gtk_application_get_menu_by_id() but takes into account merging
+ * the menus provided by, and extended by, plugins.
+ *
+ * Returns: (transfer none): A #GMenu.
+ */
+GMenu *
+ide_application_get_menu_by_id (IdeApplication *self,
+                                const gchar    *id)
+{
+  g_return_val_if_fail (IDE_IS_APPLICATION (self), NULL);
+  g_return_val_if_fail (id != NULL, NULL);
+
+  if (self->menu_manager != NULL)
+    return egg_menu_manager_get_menu_by_id (self->menu_manager, id);
+
+  g_critical ("%s() called by non-UI process", G_STRFUNC);
+
+  return NULL;
+}
diff --git a/libide/ide-application.h b/libide/ide-application.h
index 1d50245..ebc1247 100644
--- a/libide/ide-application.h
+++ b/libide/ide-application.h
@@ -51,6 +51,8 @@ void                ide_application_get_worker_async     (IdeApplication       *
 GDBusProxy         *ide_application_get_worker_finish    (IdeApplication       *self,
                                                           GAsyncResult         *result,
                                                           GError              **error);
+GMenu              *ide_application_get_menu_by_id       (IdeApplication       *self,
+                                                          const gchar          *id);
 
 G_END_DECLS
 


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