[gnome-builder] libide/plugins: add listmodels for plugin access
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder] libide/plugins: add listmodels for plugin access
- Date: Thu, 18 Aug 2022 01:04:47 +0000 (UTC)
commit 757b16fea763628668904330f0c6cc07c7016f35
Author: Christian Hergert <chergert redhat com>
Date: Wed Aug 17 18:01:34 2022 -0700
libide/plugins: add listmodels for plugin access
src/libide/plugins/ide-plugin-private.h | 29 ++++
src/libide/plugins/ide-plugin-section-private.h | 29 ++++
src/libide/plugins/ide-plugin-section.c | 202 ++++++++++++++++++++++++
src/libide/plugins/ide-plugin-section.h | 43 +++++
src/libide/plugins/ide-plugin.c | 182 ++++++++++++++++++++-
src/libide/plugins/ide-plugin.h | 10 +-
src/libide/plugins/libide-plugins.h | 1 +
src/libide/plugins/meson.build | 4 +
8 files changed, 497 insertions(+), 3 deletions(-)
---
diff --git a/src/libide/plugins/ide-plugin-private.h b/src/libide/plugins/ide-plugin-private.h
new file mode 100644
index 000000000..a1f96aa03
--- /dev/null
+++ b/src/libide/plugins/ide-plugin-private.h
@@ -0,0 +1,29 @@
+/* ide-plugin-private.h
+ *
+ * Copyright 2022 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 <gio/gio.h>
+
+G_BEGIN_DECLS
+
+GListModel *_ide_plugin_get_all (void);
+
+G_END_DECLS
diff --git a/src/libide/plugins/ide-plugin-section-private.h b/src/libide/plugins/ide-plugin-section-private.h
new file mode 100644
index 000000000..9f93271a8
--- /dev/null
+++ b/src/libide/plugins/ide-plugin-section-private.h
@@ -0,0 +1,29 @@
+/* ide-plugin-section-private.h
+ *
+ * Copyright 2022 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 <gio/gio.h>
+
+G_BEGIN_DECLS
+
+GListModel *_ide_plugin_section_get_all (void);
+
+G_END_DECLS
diff --git a/src/libide/plugins/ide-plugin-section.c b/src/libide/plugins/ide-plugin-section.c
new file mode 100644
index 000000000..b4a207822
--- /dev/null
+++ b/src/libide/plugins/ide-plugin-section.c
@@ -0,0 +1,202 @@
+/* ide-plugin-section.c
+ *
+ * Copyright 2022 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
+ */
+
+#define G_LOG_DOMAIN "ide-plugin-section"
+
+#include "config.h"
+
+#include <gtk/gtk.h>
+
+#include "ide-plugin.h"
+#include "ide-plugin-private.h"
+#include "ide-plugin-section.h"
+#include "ide-plugin-section-private.h"
+
+struct _IdePluginSection
+{
+ GObject parent_instance;
+ const char *id;
+ GListModel *plugins;
+};
+
+enum {
+ PROP_0,
+ PROP_ID,
+ PROP_PLUGINS,
+ N_PROPS
+};
+
+G_DEFINE_FINAL_TYPE (IdePluginSection, ide_plugin_section, G_TYPE_OBJECT)
+
+static GParamSpec *properties [N_PROPS];
+
+static void
+ide_plugin_section_dispose (GObject *object)
+{
+ IdePluginSection *self = (IdePluginSection *)object;
+
+ g_clear_object (&self->plugins);
+
+ G_OBJECT_CLASS (ide_plugin_section_parent_class)->dispose (object);
+}
+
+static void
+ide_plugin_section_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ IdePluginSection *self = IDE_PLUGIN_SECTION (object);
+
+ switch (prop_id)
+ {
+ case PROP_ID:
+ g_value_set_static_string (value, self->id);
+ break;
+
+ case PROP_PLUGINS:
+ g_value_set_object (value, self->plugins);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+ide_plugin_section_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ IdePluginSection *self = IDE_PLUGIN_SECTION (object);
+
+ switch (prop_id)
+ {
+ case PROP_ID:
+ self->id = g_intern_string (g_value_get_string (value));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+ide_plugin_section_class_init (IdePluginSectionClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->dispose = ide_plugin_section_dispose;
+ object_class->get_property = ide_plugin_section_get_property;
+ object_class->set_property = ide_plugin_section_set_property;
+
+ properties [PROP_ID] =
+ g_param_spec_string ("id", NULL, NULL, NULL,
+ (G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
+
+ properties [PROP_PLUGINS] =
+ g_param_spec_object ("plugins", NULL, NULL,
+ G_TYPE_LIST_MODEL,
+ (G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_properties (object_class, N_PROPS, properties);
+}
+
+static void
+ide_plugin_section_init (IdePluginSection *self)
+{
+}
+
+const char *
+ide_plugin_section_get_id (IdePluginSection *self)
+{
+ g_return_val_if_fail (IDE_IS_PLUGIN_SECTION (self), NULL);
+
+ return self->id;
+}
+
+/**
+ * ide_plugin_section_get_plugins:
+ * @self: a #IdePluginSection
+ *
+ * A #GListModel of #IdePlugin.
+ *
+ * Returns: (transfer none): a #GListModel
+ */
+GListModel *
+ide_plugin_section_get_plugins (IdePluginSection *self)
+{
+ g_return_val_if_fail (IDE_IS_PLUGIN_SECTION (self), NULL);
+
+ if (self->plugins == NULL)
+ {
+ GtkExpression *expression = gtk_property_expression_new (IDE_TYPE_PLUGIN, NULL, "section");
+ GtkStringFilter *filter = gtk_string_filter_new (expression);
+ GtkFilterListModel *model;
+
+ gtk_string_filter_set_search (filter, self->id);
+ gtk_string_filter_set_match_mode (filter, GTK_STRING_FILTER_MATCH_MODE_EXACT);
+ model = gtk_filter_list_model_new (g_object_ref (_ide_plugin_get_all ()), GTK_FILTER (filter));
+
+ self->plugins = G_LIST_MODEL (model);
+ }
+
+ return self->plugins;
+}
+
+/**
+ * _ide_plugin_section_get_all:
+ *
+ * A #GListModel of #IdePluginSection.
+ *
+ * Returns: (transfer none): a #GListModel
+ */
+GListModel *
+_ide_plugin_section_get_all (void)
+{
+ static GListStore *sections;
+ static const char *section_ids[] = {
+ "editing",
+ "tooling",
+ "projects",
+ "history",
+ "platforms",
+ "integration",
+ "other",
+ };
+
+ if (sections == NULL)
+ {
+ sections = g_list_store_new (IDE_TYPE_PLUGIN_SECTION);
+
+ for (guint i = 0; i < G_N_ELEMENTS (section_ids); i++)
+ {
+ g_autoptr(IdePluginSection) section = NULL;
+
+ section = g_object_new (IDE_TYPE_PLUGIN_SECTION,
+ "id", section_ids[i],
+ NULL);
+ g_list_store_append (sections, section);
+ }
+ }
+
+ return G_LIST_MODEL (sections);
+}
diff --git a/src/libide/plugins/ide-plugin-section.h b/src/libide/plugins/ide-plugin-section.h
new file mode 100644
index 000000000..1fbc2e2a8
--- /dev/null
+++ b/src/libide/plugins/ide-plugin-section.h
@@ -0,0 +1,43 @@
+/* ide-plugin-section.h
+ *
+ * Copyright 2022 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
+
+#if !defined (IDE_PLUGINS_INSIDE) && !defined (IDE_PLUGINS_COMPILATION)
+# error "Only <libide-plugins.h> can be included directly."
+#endif
+
+#include <libide-core.h>
+
+#include "ide-plugin.h"
+
+G_BEGIN_DECLS
+
+#define IDE_TYPE_PLUGIN_SECTION (ide_plugin_section_get_type())
+
+IDE_AVAILABLE_IN_ALL
+G_DECLARE_FINAL_TYPE (IdePluginSection, ide_plugin_section, IDE, PLUGIN_SECTION, GObject)
+
+IDE_AVAILABLE_IN_ALL
+const char *ide_plugin_section_get_id (IdePluginSection *self);
+IDE_AVAILABLE_IN_ALL
+GListModel *ide_plugin_section_get_plugins (IdePluginSection *self);
+
+G_END_DECLS
diff --git a/src/libide/plugins/ide-plugin.c b/src/libide/plugins/ide-plugin.c
index ce6bbd81d..c6e076d74 100644
--- a/src/libide/plugins/ide-plugin.c
+++ b/src/libide/plugins/ide-plugin.c
@@ -22,7 +22,10 @@
#include "config.h"
+#include <glib/gi18n.h>
+
#include "ide-plugin.h"
+#include "ide-plugin-private.h"
struct _IdePlugin
{
@@ -32,7 +35,10 @@ struct _IdePlugin
enum {
PROP_0,
+ PROP_CATEGORY,
+ PROP_CATEGORY_ID,
PROP_DESCRIPTION,
+ PROP_ID,
PROP_INFO,
PROP_NAME,
PROP_SECTION,
@@ -42,6 +48,7 @@ enum {
G_DEFINE_FINAL_TYPE (IdePlugin, ide_plugin, G_TYPE_OBJECT)
static GParamSpec *properties [N_PROPS];
+static GHashTable *sections;
static void
ide_plugin_dispose (GObject *object)
@@ -67,6 +74,10 @@ ide_plugin_get_property (GObject *object,
switch (prop_id)
{
+ case PROP_ID:
+ g_value_set_string (value, ide_plugin_get_id (self));
+ break;
+
case PROP_INFO:
g_value_set_boxed (value, self->info);
break;
@@ -75,6 +86,14 @@ ide_plugin_get_property (GObject *object,
g_value_set_string (value, ide_plugin_get_name (self));
break;
+ case PROP_CATEGORY:
+ g_value_set_string (value, ide_plugin_get_category (self));
+ break;
+
+ case PROP_CATEGORY_ID:
+ g_value_set_string (value, ide_plugin_get_category_id (self));
+ break;
+
case PROP_DESCRIPTION:
g_value_set_string (value, ide_plugin_get_description (self));
break;
@@ -121,11 +140,26 @@ ide_plugin_class_init (IdePluginClass *klass)
PEAS_TYPE_PLUGIN_INFO,
(G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
+ properties[PROP_ID] =
+ g_param_spec_string ("id", NULL, NULL,
+ NULL,
+ (G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+
properties[PROP_NAME] =
g_param_spec_string ("name", NULL, NULL,
NULL,
(G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+ properties[PROP_CATEGORY] =
+ g_param_spec_string ("category", NULL, NULL,
+ NULL,
+ (G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+
+ properties[PROP_CATEGORY_ID] =
+ g_param_spec_string ("category-id", NULL, NULL,
+ NULL,
+ (G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+
properties[PROP_DESCRIPTION] =
g_param_spec_string ("description", NULL, NULL,
NULL,
@@ -176,10 +210,156 @@ ide_plugin_get_description (IdePlugin *self)
return peas_plugin_info_get_description (self->info);
}
+static void
+ide_plugin_init_sections (void)
+{
+#define ADD_SECTION(category_id, section) \
+ g_hash_table_insert (sections, (char *)category_id, (char *)section)
+
+ if G_UNLIKELY (sections == NULL)
+ {
+ sections = g_hash_table_new (g_str_hash, g_str_equal);
+ ADD_SECTION ("vcs", "history");
+ ADD_SECTION ("sdks", "platforms");
+ ADD_SECTION ("lsps", "tooling");
+ ADD_SECTION ("devices", "platforms");
+ ADD_SECTION ("diagnostics", "tooling");
+ ADD_SECTION ("buildsystems", "projects");
+ ADD_SECTION ("compilers", "tooling");
+ ADD_SECTION ("debuggers", "projects");
+ ADD_SECTION ("templates", "projects");
+ ADD_SECTION ("editing", "editing");
+ ADD_SECTION ("keybindings", "integration");
+ ADD_SECTION ("search", "history");
+ ADD_SECTION ("web", "integration");
+ ADD_SECTION ("language", "tooling");
+ ADD_SECTION ("desktop", "integration");
+ ADD_SECTION ("other", "other");
+ }
+
+#undef ADD_SECTION
+}
+
const char *
ide_plugin_get_section (IdePlugin *self)
{
+ const char *category_id;
+
+ g_return_val_if_fail (IDE_IS_PLUGIN (self), NULL);
+
+ ide_plugin_init_sections ();
+
+ if (!(category_id = peas_plugin_info_get_external_data (self->info, "Category")))
+ category_id = "other";
+
+ return g_hash_table_lookup (sections, category_id);
+}
+
+const char *
+ide_plugin_get_category_id (IdePlugin *self)
+{
+ const char *category_id;
+
g_return_val_if_fail (IDE_IS_PLUGIN (self), NULL);
- return peas_plugin_info_get_external_data (self->info, "Section");
+ if (!(category_id = peas_plugin_info_get_external_data (self->info, "Category")))
+ category_id = "other";
+
+ return category_id;
+}
+
+const char *
+ide_plugin_get_id (IdePlugin *self)
+{
+ g_return_val_if_fail (IDE_IS_PLUGIN (self), NULL);
+
+ return peas_plugin_info_get_module_name (self->info);
+}
+
+const char *
+ide_plugin_get_category (IdePlugin *self)
+{
+ static GHashTable *titles;
+ const char *category_id;
+
+ g_return_val_if_fail (IDE_IS_PLUGIN (self), NULL);
+
+ if G_UNLIKELY (titles == NULL)
+ {
+ titles = g_hash_table_new (g_str_hash, g_str_equal);
+
+#define ADD_TITLE(category, name) \
+ g_hash_table_insert (titles, (char *)category, (char *)name)
+ ADD_TITLE ("vcs", _("Version Control"));
+ ADD_TITLE ("sdks", _("SDKs"));
+ ADD_TITLE ("lsps", _("Language Servers"));
+ ADD_TITLE ("devices", _("Devices & Simulators"));
+ ADD_TITLE ("diagnostics", _("Diagnostics"));
+ ADD_TITLE ("buildsystems", _("Build Systems"));
+ ADD_TITLE ("compilers", _("Compilers"));
+ ADD_TITLE ("debuggers", _("Debuggers"));
+ ADD_TITLE ("templates", _("Templates"));
+ ADD_TITLE ("editing", _("Editing & Formatting"));
+ ADD_TITLE ("keybindings", _("Keyboard Shortcuts"));
+ ADD_TITLE ("search", _("Search"));
+ ADD_TITLE ("web", _("Web"));
+ ADD_TITLE ("language", _("Language Enablement"));
+ ADD_TITLE ("desktop", _("Desktop Integration"));
+ ADD_TITLE ("other", _("Additional"));
+#undef ADD_TITLE
+ }
+
+ category_id = ide_plugin_get_category_id (self);
+
+ return g_hash_table_lookup (titles, category_id);
+}
+
+static void
+plugin_list_changed_cb (PeasEngine *engine,
+ GParamSpec *pspec,
+ GListStore *store)
+{
+ const GList *plugins;
+
+ g_assert (PEAS_IS_ENGINE (engine));
+ g_assert (G_IS_LIST_STORE (store));
+
+ g_list_store_remove_all (store);
+
+ plugins = peas_engine_get_plugin_list (peas_engine_get_default ());
+
+ for (const GList *iter = plugins; iter; iter = iter->next)
+ {
+ const PeasPluginInfo *plugin_info = iter->data;
+ g_autoptr(IdePlugin) plugin = NULL;
+
+ if (peas_plugin_info_is_hidden (plugin_info))
+ continue;
+
+ plugin = g_object_new (IDE_TYPE_PLUGIN,
+ "info", plugin_info,
+ NULL);
+ g_list_store_append (store, plugin);
+ }
+}
+
+GListModel *
+_ide_plugin_get_all (void)
+{
+ static GListStore *store;
+
+ if (store == NULL)
+ {
+ PeasEngine *engine = peas_engine_get_default ();
+
+ store = g_list_store_new (IDE_TYPE_PLUGIN);
+ g_signal_connect_object (engine,
+ "notify::plugin-list",
+ G_CALLBACK (plugin_list_changed_cb),
+ store,
+ 0);
+ plugin_list_changed_cb (engine, NULL, store);
+ }
+
+ return G_LIST_MODEL (store);
}
diff --git a/src/libide/plugins/ide-plugin.h b/src/libide/plugins/ide-plugin.h
index 6675ce2c8..6d486d5c5 100644
--- a/src/libide/plugins/ide-plugin.h
+++ b/src/libide/plugins/ide-plugin.h
@@ -36,12 +36,18 @@ IDE_AVAILABLE_IN_ALL
G_DECLARE_FINAL_TYPE (IdePlugin, ide_plugin, IDE, PLUGIN, GObject)
IDE_AVAILABLE_IN_ALL
-PeasPluginInfo *ide_plugin_get_info (IdePlugin *self);
+const char *ide_plugin_get_id (IdePlugin *self);
IDE_AVAILABLE_IN_ALL
-const char *ide_plugin_get_name (IdePlugin *self);
+const char *ide_plugin_get_category (IdePlugin *self);
+IDE_AVAILABLE_IN_ALL
+const char *ide_plugin_get_category_id (IdePlugin *self);
IDE_AVAILABLE_IN_ALL
const char *ide_plugin_get_description (IdePlugin *self);
IDE_AVAILABLE_IN_ALL
+PeasPluginInfo *ide_plugin_get_info (IdePlugin *self);
+IDE_AVAILABLE_IN_ALL
+const char *ide_plugin_get_name (IdePlugin *self);
+IDE_AVAILABLE_IN_ALL
const char *ide_plugin_get_section (IdePlugin *self);
G_END_DECLS
diff --git a/src/libide/plugins/libide-plugins.h b/src/libide/plugins/libide-plugins.h
index 3d3bbf2c8..cdebb1710 100644
--- a/src/libide/plugins/libide-plugins.h
+++ b/src/libide/plugins/libide-plugins.h
@@ -28,6 +28,7 @@ G_BEGIN_DECLS
# include "ide-extension-adapter.h"
# include "ide-extension-set-adapter.h"
# include "ide-plugin.h"
+# include "ide-plugin-section.h"
#undef IDE_PLUGINS_INSIDE
G_END_DECLS
diff --git a/src/libide/plugins/meson.build b/src/libide/plugins/meson.build
index 8a4d5b844..e607b54ec 100644
--- a/src/libide/plugins/meson.build
+++ b/src/libide/plugins/meson.build
@@ -9,6 +9,7 @@ libide_plugins_public_headers = [
'ide-extension-adapter.h',
'ide-extension-set-adapter.h',
'ide-plugin.h',
+ 'ide-plugin-section.h',
'libide-plugins.h',
]
@@ -26,6 +27,7 @@ libide_plugins_public_sources = [
'ide-extension-adapter.c',
'ide-extension-set-adapter.c',
'ide-plugin.c',
+ 'ide-plugin-section.c',
]
libide_plugins_private_sources = [
@@ -39,6 +41,8 @@ libide_plugins_private_sources = [
libide_plugins_deps = [
libgio_dep,
libpeas_dep,
+ libgtk_dep,
+
libide_core_dep,
]
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]