[gnome-builder/wip/chergert/grep: 2/15] project-tree: allow plugins to extend the project tree



commit b9102bf7a65905e3b2b4b44c9eb0d47461160433
Author: Christian Hergert <chergert redhat com>
Date:   Tue Oct 30 11:15:21 2018 -0700

    project-tree: allow plugins to extend the project tree
    
    The project tree easily supports multiple builders. We can use this to
    allow other plugins to extend the project tree by registering new builders.
    
    Longer term, we may change the root of the tree to be the context, so that
    we can have "virtual folders".

 src/libide/ide.h                                   |  1 +
 src/libide/projects/ide-project-tree-addin.c       | 98 ++++++++++++++++++++++
 src/libide/projects/ide-project-tree-addin.h       | 51 +++++++++++
 src/libide/projects/meson.build                    |  2 +
 src/plugins/project-tree/gb-project-tree-private.h |  9 +-
 src/plugins/project-tree/gb-project-tree.c         | 75 ++++++++++++++++-
 6 files changed, 228 insertions(+), 8 deletions(-)
---
diff --git a/src/libide/ide.h b/src/libide/ide.h
index 497f423b1..353f83052 100644
--- a/src/libide/ide.h
+++ b/src/libide/ide.h
@@ -143,6 +143,7 @@ G_BEGIN_DECLS
 #include "projects/ide-project-info.h"
 #include "projects/ide-project-item.h"
 #include "projects/ide-project.h"
+#include "projects/ide-project-tree-addin.h"
 #include "projects/ide-recent-projects.h"
 #include "rename/ide-rename-provider.h"
 #include "runner/ide-run-manager.h"
diff --git a/src/libide/projects/ide-project-tree-addin.c b/src/libide/projects/ide-project-tree-addin.c
new file mode 100644
index 000000000..4883ef5de
--- /dev/null
+++ b/src/libide/projects/ide-project-tree-addin.c
@@ -0,0 +1,98 @@
+/* ide-project-tree-addin.c
+ *
+ * Copyright 2018 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/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#include "config.h"
+
+#define G_LOG_DOMAIN "ide-project-tree-addin"
+
+#include "projects/ide-project-tree-addin.h"
+
+/**
+ * SECTION:ide-project-tree-addin
+ * @title: IdeProjectTreeAddin
+ * @short_description: Addins to extend the project tree
+ *
+ * The #IdeProjectTreeAddin is used to extend the project tree. Plugins
+ * can add new tree builders to the tree in the load virtual function. They
+ * should remove the tree builders from the unload virtual function.
+ *
+ * Since: 3.32
+ */
+
+G_DEFINE_INTERFACE (IdeProjectTreeAddin, ide_project_tree_addin, G_TYPE_OBJECT)
+
+static void
+ide_project_tree_addin_default_init (IdeProjectTreeAddinInterface *iface)
+{
+}
+
+/**
+ * ide_project_tree_addin_load:
+ * @self: a #IdeProjectTreeAddin
+ * @tree: a #DzlTree
+ *
+ * This function will call the IdeProjectTreeAddin::load vfunc of @self.
+ *
+ * This is used to initialize the project tree so that plugins can extend
+ * the contents of the tree.
+ *
+ * Plugins should add a #DzlTreeBuilder to the tree when loading, and remove
+ * them when unloading.
+ *
+ * See also: ide_project_tree_addin_unload()
+ *
+ * Since: 3.32
+ */
+void
+ide_project_tree_addin_load (IdeProjectTreeAddin *self,
+                             DzlTree             *tree)
+{
+  g_return_if_fail (IDE_IS_PROJECT_TREE_ADDIN (self));
+  g_return_if_fail (DZL_IS_TREE (tree));
+
+  if (IDE_PROJECT_TREE_ADDIN_GET_IFACE (self)->load)
+    IDE_PROJECT_TREE_ADDIN_GET_IFACE (self)->load (self, tree);
+}
+
+/**
+ * ide_project_tree_addin_unload:
+ * @self: a #IdeProjectTreeAddin
+ * @tree: a #DzlTree
+ *
+ * This function will call the IdeProjectTreeAddin::unload vfunc of @self.
+ *
+ * This is used to unload the project tree so that plugins can clealy be
+ * disabled by the user at runtime. Any changes to @tree done during load
+ * should be undone here.
+ *
+ * See also: ide_project_tree_addin_load()
+ *
+ * Since: 3.32
+ */
+void
+ide_project_tree_addin_unload (IdeProjectTreeAddin *self,
+                               DzlTree             *tree)
+{
+  g_return_if_fail (IDE_IS_PROJECT_TREE_ADDIN (self));
+  g_return_if_fail (DZL_IS_TREE (tree));
+
+  if (IDE_PROJECT_TREE_ADDIN_GET_IFACE (self)->unload)
+    IDE_PROJECT_TREE_ADDIN_GET_IFACE (self)->unload (self, tree);
+}
diff --git a/src/libide/projects/ide-project-tree-addin.h b/src/libide/projects/ide-project-tree-addin.h
new file mode 100644
index 000000000..cb38ce583
--- /dev/null
+++ b/src/libide/projects/ide-project-tree-addin.h
@@ -0,0 +1,51 @@
+/* ide-project-tree-addin.h
+ *
+ * Copyright 2018 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/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#pragma once
+
+#include <dazzle.h>
+
+#include "ide-version-macros.h"
+
+G_BEGIN_DECLS
+
+#define IDE_TYPE_PROJECT_TREE_ADDIN (ide_project_tree_addin_get_type())
+
+IDE_AVAILABLE_IN_3_32
+G_DECLARE_INTERFACE (IdeProjectTreeAddin, ide_project_tree_addin, IDE, PROJECT_TREE_ADDIN, GObject)
+
+struct _IdeProjectTreeAddinInterface
+{
+  GTypeInterface parent_iface;
+
+  void (*load)   (IdeProjectTreeAddin *self,
+                  DzlTree             *tree);
+  void (*unload) (IdeProjectTreeAddin *self,
+                  DzlTree             *tree);
+};
+
+IDE_AVAILABLE_IN_3_32
+void ide_project_tree_addin_load   (IdeProjectTreeAddin *self,
+                                    DzlTree             *tree);
+IDE_AVAILABLE_IN_3_32
+void ide_project_tree_addin_unload (IdeProjectTreeAddin *self,
+                                    DzlTree             *tree);
+
+G_END_DECLS
diff --git a/src/libide/projects/meson.build b/src/libide/projects/meson.build
index aa68a2029..ab7587693 100644
--- a/src/libide/projects/meson.build
+++ b/src/libide/projects/meson.build
@@ -3,6 +3,7 @@ projects_headers = [
   'ide-project-info.h',
   'ide-project-item.h',
   'ide-project.h',
+  'ide-project-tree-addin.h',
   'ide-recent-projects.h',
 ]
 
@@ -11,6 +12,7 @@ projects_sources = [
   'ide-project-info.c',
   'ide-project-item.c',
   'ide-project.c',
+  'ide-project-tree-addin.c',
   'ide-recent-projects.c',
 ]
 
diff --git a/src/plugins/project-tree/gb-project-tree-private.h 
b/src/plugins/project-tree/gb-project-tree-private.h
index 66c40c423..fd986563b 100644
--- a/src/plugins/project-tree/gb-project-tree-private.h
+++ b/src/plugins/project-tree/gb-project-tree-private.h
@@ -24,12 +24,13 @@ G_BEGIN_DECLS
 
 struct _GbProjectTree
 {
-  DzlTree     parent_instance;
+  DzlTree           parent_instance;
 
-  GSettings *settings;
+  GSettings        *settings;
+  PeasExtensionSet *addins;
 
-  guint      expanded_in_new : 1;
-  guint      show_ignored_files : 1;
+  guint             expanded_in_new : 1;
+  guint             show_ignored_files : 1;
 };
 
 void      _gb_project_tree_init_shortcuts       (GbProjectTree *self);
diff --git a/src/plugins/project-tree/gb-project-tree.c b/src/plugins/project-tree/gb-project-tree.c
index 8484d414e..f08df6e08 100644
--- a/src/plugins/project-tree/gb-project-tree.c
+++ b/src/plugins/project-tree/gb-project-tree.c
@@ -20,6 +20,7 @@
 
 #include <glib/gi18n.h>
 #include <ide.h>
+#include <libpeas/peas.h>
 
 #include "gb-project-file.h"
 #include "gb-project-tree.h"
@@ -213,7 +214,6 @@ gb_project_tree_set_context (GbProjectTree *self,
     }
 }
 
-
 static void
 gb_project_tree_notify_selection (GbProjectTree *self)
 {
@@ -223,13 +223,77 @@ gb_project_tree_notify_selection (GbProjectTree *self)
 }
 
 static void
-gb_project_tree_finalize (GObject *object)
+gb_project_tree_extension_added_cb (PeasExtensionSet *set,
+                                    PeasPluginInfo   *plugin_info,
+                                    PeasExtension    *exten,
+                                    gpointer          user_data)
+{
+  IdeProjectTreeAddin *addin = (IdeProjectTreeAddin *)exten;
+  GbProjectTree *self = user_data;
+
+  g_assert (PEAS_IS_EXTENSION_SET (set));
+  g_assert (plugin_info != NULL);
+  g_assert (IDE_IS_PROJECT_TREE_ADDIN (exten));
+  g_assert (GB_IS_PROJECT_TREE (self));
+
+  g_debug ("Loading project tree addin %s", G_OBJECT_TYPE_NAME (addin));
+
+  ide_project_tree_addin_load (addin, DZL_TREE (self));
+}
+
+static void
+gb_project_tree_extension_removed_cb (PeasExtensionSet *set,
+                                      PeasPluginInfo   *plugin_info,
+                                      PeasExtension    *exten,
+                                      gpointer          user_data)
+{
+  IdeProjectTreeAddin *addin = (IdeProjectTreeAddin *)exten;
+  GbProjectTree *self = user_data;
+
+  g_assert (PEAS_IS_EXTENSION_SET (set));
+  g_assert (plugin_info != NULL);
+  g_assert (IDE_IS_PROJECT_TREE_ADDIN (exten));
+  g_assert (GB_IS_PROJECT_TREE (self));
+
+  g_debug ("Unloading project tree addin %s", G_OBJECT_TYPE_NAME (addin));
+
+  ide_project_tree_addin_unload (addin, DZL_TREE (self));
+}
+
+static void
+gb_project_tree_constructed (GObject *object)
 {
   GbProjectTree *self = (GbProjectTree *)object;
 
+  g_assert (GB_IS_PROJECT_TREE (self));
+
+  G_OBJECT_CLASS (gb_project_tree_parent_class)->constructed (object);
+
+  self->addins = peas_extension_set_new (NULL, IDE_TYPE_PROJECT_TREE_ADDIN, NULL);
+  g_signal_connect (self->addins,
+                    "extension-added",
+                    G_CALLBACK (gb_project_tree_extension_added_cb),
+                    self);
+  g_signal_connect (self->addins,
+                    "extension-removed",
+                    G_CALLBACK (gb_project_tree_extension_removed_cb),
+                    self);
+  peas_extension_set_foreach (self->addins,
+                              gb_project_tree_extension_added_cb,
+                              self);
+}
+
+static void
+gb_project_tree_destroy (GtkWidget *widget)
+{
+  GbProjectTree *self = (GbProjectTree *)widget;
+
+  g_assert (GB_IS_PROJECT_TREE (self));
+
   g_clear_object (&self->settings);
+  g_clear_object (&self->addins);
 
-  G_OBJECT_CLASS (gb_project_tree_parent_class)->finalize (object);
+  GTK_WIDGET_CLASS (gb_project_tree_parent_class)->destroy (widget);
 }
 
 static void
@@ -274,11 +338,14 @@ static void
 gb_project_tree_class_init (GbProjectTreeClass *klass)
 {
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
+  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
 
-  object_class->finalize = gb_project_tree_finalize;
+  object_class->constructed = gb_project_tree_constructed;
   object_class->get_property = gb_project_tree_get_property;
   object_class->set_property = gb_project_tree_set_property;
 
+  widget_class->destroy = gb_project_tree_destroy;
+
   properties [PROP_SHOW_IGNORED_FILES] =
     g_param_spec_boolean ("show-ignored-files",
                           "Show Ignored Files",


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