[gnome-builder] editor: add IdeEditorAddin



commit d12db0b2508fe0bca94769264bfa328efbb5c782
Author: Christian Hergert <chergert redhat com>
Date:   Fri Jul 14 15:48:16 2017 -0700

    editor: add IdeEditorAddin
    
    This addin interface is used to extend the editor perspective.
    This can be handy over the workbench addin because it allows you
    to write a bit less code and use some of the view tracking that
    is specific to the editor perspective.

 libide/editor/ide-editor-addin.c       |  149 ++++++++++++++++++++++++++++++++
 libide/editor/ide-editor-addin.h       |   52 +++++++++++
 libide/editor/ide-editor-perspective.c |  121 ++++++++++++++++++++++++++
 libide/ide.h                           |    1 +
 libide/meson.build                     |    2 +
 5 files changed, 325 insertions(+), 0 deletions(-)
---
diff --git a/libide/editor/ide-editor-addin.c b/libide/editor/ide-editor-addin.c
new file mode 100644
index 0000000..982847c
--- /dev/null
+++ b/libide/editor/ide-editor-addin.c
@@ -0,0 +1,149 @@
+/* ide-editor-addin.c
+ *
+ * Copyright (C) 2017 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define G_LOG_DOMAIN "ide-editor-addin"
+
+#include "editor/ide-editor-addin.h"
+#include "editor/ide-editor-private.h"
+
+/**
+ * SECTION:ide-editor-addin
+ * @title: IdeEditorAddin
+ * @short_description: Addins for the editor perspective
+ *
+ * The #IdeEditorAddin interface provides a simplified interface for
+ * plugins that want to perform operations in, or extend, the editor
+ * perspective.
+ *
+ * This differs from the #IdeWorkbenchAddin in that you are given access
+ * to the editor perspective directly. This can be convenient if all you
+ * need to do is add panels or perform view tracking of the current
+ * focus view.
+ */
+
+G_DEFINE_INTERFACE (IdeEditorAddin, ide_editor_addin, G_TYPE_OBJECT)
+
+static void
+ide_editor_addin_default_init (IdeEditorAddinInterface *iface)
+{
+}
+
+/**
+ * ide_editor_addin_load:
+ * @self: an #IdeEditorAddin
+ * @perspective: an #IdeEditorPeprsective
+ *
+ * This method is called to load the addin.
+ *
+ * The addin should add any necessary UI components.
+ *
+ * Since: 3.26
+ */
+void
+ide_editor_addin_load (IdeEditorAddin       *self,
+                       IdeEditorPerspective *perspective)
+{
+  g_return_if_fail (IDE_IS_EDITOR_ADDIN (self));
+  g_return_if_fail (IDE_IS_EDITOR_PERSPECTIVE (perspective));
+
+  if (IDE_EDITOR_ADDIN_GET_IFACE (self)->load)
+    IDE_EDITOR_ADDIN_GET_IFACE (self)->load (self, perspective);
+}
+
+/**
+ * ide_editor_addin_unload:
+ * @self: an #IdeEditorAddin
+ * @perspective: an #IdeEditorPerspective
+ *
+ * This method is called to unload the addin.
+ *
+ * The addin is responsible for undoing anything it setup in load
+ * and cancel any in-flight or pending tasks immediately.
+ *
+ * Since: 3.26
+ */
+void
+ide_editor_addin_unload (IdeEditorAddin       *self,
+                         IdeEditorPerspective *perspective)
+{
+  g_return_if_fail (IDE_IS_EDITOR_ADDIN (self));
+  g_return_if_fail (IDE_IS_EDITOR_PERSPECTIVE (perspective));
+
+  if (IDE_EDITOR_ADDIN_GET_IFACE (self)->unload)
+    IDE_EDITOR_ADDIN_GET_IFACE (self)->unload (self, perspective);
+}
+
+/**
+ * ide_editor_addin_view_set:
+ * @self: an #IdeEditorAddin
+ * @view: (nullable): an #IdeLayoutView or %NULL
+ *
+ * This function is called when the current view has changed in the
+ * editor perspective. This could happen when the user focus another
+ * view, either with the keyboard, mouse, touch, or by opening a new
+ * buffer.
+ *
+ * Note that @view may not be an #IdeEditorView, so consumers of this
+ * interface should take appropriate action based on the type.
+ *
+ * When the last view is removed, @view will be %NULL to indicate to the
+ * addin that there is no active view.
+ *
+ * Since: 3.26
+ */
+void
+ide_editor_addin_view_set (IdeEditorAddin *self,
+                           IdeLayoutView  *view)
+{
+  g_return_if_fail (IDE_IS_EDITOR_ADDIN (self));
+  g_return_if_fail (!view || IDE_IS_LAYOUT_VIEW (view));
+
+  if (IDE_EDITOR_ADDIN_GET_IFACE (self)->view_set)
+    IDE_EDITOR_ADDIN_GET_IFACE (self)->view_set (self, view);
+}
+
+/**
+ * ide_editor_addin_find_by_module_name:
+ * @editor: an #IdeEditorPerspective
+ * @module_name: the module name of the addin
+ *
+ * This function allows locating an #IdeEditorAddin that is attached
+ * to the #IdeEditorPerspective by the addin module name. The module name
+ * should match the value specified in the ".plugin" module definition.
+ *
+ * Returns: (transfer none) (nullable): An #IdeEditorAddin or %NULL
+ */
+IdeEditorAddin *
+ide_editor_addin_find_by_module_name (IdeEditorPerspective *editor,
+                                      const gchar          *module_name)
+{
+  PeasExtension *ret = NULL;
+  PeasPluginInfo *plugin_info;
+
+  g_return_val_if_fail (IDE_IS_EDITOR_PERSPECTIVE (editor), NULL);
+  g_return_val_if_fail (module_name != NULL, NULL);
+
+  plugin_info = peas_engine_get_plugin_info (peas_engine_get_default (), module_name);
+
+  if (plugin_info != NULL)
+    ret = peas_extension_set_get_extension (editor->addins, plugin_info);
+  else
+    g_warning ("No such module found \"%s\"", module_name);
+
+  return ret ? IDE_EDITOR_ADDIN (ret) : NULL;
+}
diff --git a/libide/editor/ide-editor-addin.h b/libide/editor/ide-editor-addin.h
new file mode 100644
index 0000000..1a9e995
--- /dev/null
+++ b/libide/editor/ide-editor-addin.h
@@ -0,0 +1,52 @@
+/* ide-editor-addin.h
+ *
+ * Copyright (C) 2017 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include "editor/ide-editor-perspective.h"
+#include "layout/ide-layout-view.h"
+
+G_BEGIN_DECLS
+
+#define IDE_TYPE_EDITOR_ADDIN (ide_editor_addin_get_type())
+
+G_DECLARE_INTERFACE (IdeEditorAddin, ide_editor_addin, IDE, EDITOR_ADDIN, GObject)
+
+struct _IdeEditorAddinInterface
+{
+  GTypeInterface parent_iface;
+
+  void (*load)     (IdeEditorAddin       *self,
+                    IdeEditorPerspective *perspective);
+  void (*unload)   (IdeEditorAddin       *self,
+                    IdeEditorPerspective *perspective);
+  void (*view_set) (IdeEditorAddin       *self,
+                    IdeLayoutView        *view);
+};
+
+void ide_editor_addin_load     (IdeEditorAddin       *self,
+                                IdeEditorPerspective *perspective);
+void ide_editor_addin_unload   (IdeEditorAddin       *self,
+                                IdeEditorPerspective *perspective);
+void ide_editor_addin_view_set (IdeEditorAddin       *self,
+                                IdeLayoutView        *view);
+
+IdeEditorAddin *ide_editor_addin_find_by_module_name (IdeEditorPerspective *editor,
+                                                      const gchar          *module_name);
+
+G_END_DECLS
diff --git a/libide/editor/ide-editor-perspective.c b/libide/editor/ide-editor-perspective.c
index 9e9bacb..b6111b5 100644
--- a/libide/editor/ide-editor-perspective.c
+++ b/libide/editor/ide-editor-perspective.c
@@ -23,6 +23,7 @@
 #include "buffers/ide-buffer.h"
 #include "buffers/ide-buffer-manager.h"
 #include "diagnostics/ide-source-location.h"
+#include "editor/ide-editor-addin.h"
 #include "editor/ide-editor-perspective.h"
 #include "editor/ide-editor-private.h"
 #include "editor/ide-editor-properties.h"
@@ -48,6 +49,107 @@ G_DEFINE_TYPE_WITH_CODE (IdeEditorPerspective, ide_editor_perspective, IDE_TYPE_
                          G_IMPLEMENT_INTERFACE (IDE_TYPE_PERSPECTIVE, perspective_iface_init))
 
 static void
+ide_editor_perspective_addin_added (PeasExtensionSet *set,
+                                    PeasPluginInfo   *plugin_info,
+                                    PeasExtension    *exten,
+                                    gpointer          user_data)
+{
+  IdeEditorPerspective *self = user_data;
+  IdeEditorAddin *addin = (IdeEditorAddin *)exten;
+  IdeLayoutView *view;
+
+  g_assert (IDE_IS_EDITOR_PERSPECTIVE (self));
+  g_assert (IDE_IS_EDITOR_ADDIN (addin));
+  g_assert (PEAS_IS_EXTENSION_SET (set));
+  g_assert (plugin_info != NULL);
+
+  ide_editor_addin_load (addin, self);
+
+  view = ide_layout_grid_get_current_view (self->grid);
+  if (view != NULL)
+    ide_editor_addin_view_set (addin, view);
+}
+
+static void
+ide_editor_perspective_addin_removed (PeasExtensionSet *set,
+                                      PeasPluginInfo   *plugin_info,
+                                      PeasExtension    *exten,
+                                      gpointer          user_data)
+{
+  IdeEditorPerspective *self = user_data;
+  IdeEditorAddin *addin = (IdeEditorAddin *)exten;
+  IdeLayoutView *view;
+
+  g_assert (IDE_IS_EDITOR_PERSPECTIVE (self));
+  g_assert (IDE_IS_EDITOR_ADDIN (addin));
+  g_assert (PEAS_IS_EXTENSION_SET (set));
+  g_assert (plugin_info != NULL);
+
+  view = ide_layout_grid_get_current_view (self->grid);
+  if (view != NULL)
+    ide_editor_addin_view_set (addin, NULL);
+
+  ide_editor_addin_unload (addin, self);
+}
+
+static void
+ide_editor_perspective_hierarchy_changed (GtkWidget *widget,
+                                          GtkWidget *old_toplevel)
+{
+  IdeEditorPerspective *self = (IdeEditorPerspective *)widget;
+
+  g_assert (IDE_IS_EDITOR_PERSPECTIVE (self));
+  g_assert (!old_toplevel || GTK_IS_WIDGET (old_toplevel));
+
+  if (self->addins == NULL)
+    {
+      GtkWidget *toplevel;
+
+      /*
+       * If we just got a new toplevel and it is a workbench,
+       * and we have not yet created our addins, do so now.
+       */
+
+      toplevel = gtk_widget_get_ancestor (widget, IDE_TYPE_WORKBENCH);
+
+      if (toplevel != NULL)
+        {
+          self->addins = peas_extension_set_new (peas_engine_get_default (),
+                                                 IDE_TYPE_EDITOR_ADDIN,
+                                                 NULL);
+          g_signal_connect (self->addins,
+                            "extension-added",
+                            G_CALLBACK (ide_editor_perspective_addin_added),
+                            self);
+          g_signal_connect (self->addins,
+                            "extension-removed",
+                            G_CALLBACK (ide_editor_perspective_addin_removed),
+                            self);
+          peas_extension_set_foreach (self->addins,
+                                      ide_editor_perspective_addin_added,
+                                      self);
+        }
+    }
+}
+
+static void
+ide_editor_perspective_addins_view_set (PeasExtensionSet *set,
+                                        PeasPluginInfo   *plugin_info,
+                                        PeasExtension    *exten,
+                                        gpointer          user_data)
+{
+  IdeEditorAddin *addin = (IdeEditorAddin *)exten;
+  IdeLayoutView *view = user_data;
+
+  g_assert (PEAS_IS_EXTENSION_SET (set));
+  g_assert (plugin_info != NULL);
+  g_assert (IDE_IS_EDITOR_ADDIN (addin));
+  g_assert (!view || IDE_IS_LAYOUT_VIEW (view));
+
+  ide_editor_addin_view_set (addin, view);
+}
+
+static void
 ide_editor_perspective_notify_current_view (IdeEditorPerspective *self,
                                             GParamSpec           *pspec,
                                             IdeLayoutGrid        *grid)
@@ -64,6 +166,10 @@ ide_editor_perspective_notify_current_view (IdeEditorPerspective *self,
     ide_editor_properties_set_view (self->properties, IDE_EDITOR_VIEW (view));
   else
     ide_editor_properties_set_view (self->properties, NULL);
+
+  peas_extension_set_foreach (self->addins,
+                              ide_editor_perspective_addins_view_set,
+                              view);
 }
 
 static void
@@ -107,12 +213,27 @@ ide_editor_perspective_create_edge (DzlDockBin      *dock_bin,
 }
 
 static void
+ide_editor_perspective_destroy (GtkWidget *widget)
+{
+  IdeEditorPerspective *self = (IdeEditorPerspective *)widget;
+
+  g_assert (IDE_IS_EDITOR_PERSPECTIVE (self));
+
+  g_clear_object (&self->addins);
+
+  GTK_WIDGET_CLASS (ide_editor_perspective_parent_class)->destroy (widget);
+}
+
+static void
 ide_editor_perspective_class_init (IdeEditorPerspectiveClass *klass)
 {
   GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
   GtkContainerClass *container_class = GTK_CONTAINER_CLASS (klass);
   DzlDockBinClass *dock_bin_class = DZL_DOCK_BIN_CLASS (klass);
 
+  widget_class->destroy = ide_editor_perspective_destroy;
+  widget_class->hierarchy_changed = ide_editor_perspective_hierarchy_changed;
+
   container_class->add = ide_editor_perspective_add;
 
   dock_bin_class->create_edge = ide_editor_perspective_create_edge;
diff --git a/libide/ide.h b/libide/ide.h
index 54508dd..b6ca24a 100644
--- a/libide/ide.h
+++ b/libide/ide.h
@@ -72,6 +72,7 @@ G_BEGIN_DECLS
 #include "diagnostics/ide-source-range.h"
 #include "doap/ide-doap-person.h"
 #include "doap/ide-doap.h"
+#include "editor/ide-editor-addin.h"
 #include "editor/ide-editor-perspective.h"
 #include "editor/ide-editor-sidebar.h"
 #include "editor/ide-editor-view-addin.h"
diff --git a/libide/meson.build b/libide/meson.build
index eac7089..99e7635 100644
--- a/libide/meson.build
+++ b/libide/meson.build
@@ -98,6 +98,7 @@ libide_public_headers = [
   'directory/ide-directory-vcs.h',
   'doap/ide-doap-person.h',
   'doap/ide-doap.h',
+  'editor/ide-editor-addin.h',
   'editor/ide-editor-perspective.h',
   'editor/ide-editor-sidebar.h',
   'editor/ide-editor-view-addin.h',
@@ -294,6 +295,7 @@ libide_public_sources = [
   'directory/ide-directory-vcs.c',
   'doap/ide-doap-person.c',
   'doap/ide-doap.c',
+  'editor/ide-editor-addin.c',
   'editor/ide-editor-perspective.c',
   'editor/ide-editor-sidebar.c',
   'editor/ide-editor-view-addin.c',


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