[gnome-builder] plugins/menu-search: add menu search plugin



commit 01f506a2765d39b632a20609eb303356e0c7846a
Author: Christian Hergert <chergert redhat com>
Date:   Fri Jul 15 22:02:02 2022 -0700

    plugins/menu-search: add menu search plugin
    
    This searches registered GMenu from plugins and the application to find
    menu items which have enough information to display something reasonable.
    
    We require the addition of "description" to make this opt-in rather than
    trying to search everything which might have lots of duplicates or wrong
    actions given the focus.

 src/plugins/menu-search/gbp-menu-search-provider.c | 170 +++++++++++++++++++++
 src/plugins/menu-search/gbp-menu-search-provider.h |  31 ++++
 src/plugins/menu-search/gbp-menu-search-result.c   |  94 ++++++++++++
 src/plugins/menu-search/gbp-menu-search-result.h   |  35 +++++
 src/plugins/menu-search/menu-search-plugin.c       |  37 +++++
 src/plugins/menu-search/menu-search.gresource.xml  |   6 +
 src/plugins/menu-search/menu-search.plugin         |   8 +
 src/plugins/menu-search/meson.build                |  13 ++
 src/plugins/meson.build                            |   1 +
 9 files changed, 395 insertions(+)
---
diff --git a/src/plugins/menu-search/gbp-menu-search-provider.c 
b/src/plugins/menu-search/gbp-menu-search-provider.c
new file mode 100644
index 000000000..a6ab38d4c
--- /dev/null
+++ b/src/plugins/menu-search/gbp-menu-search-provider.c
@@ -0,0 +1,170 @@
+/* gbp-menu-search-provider.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 "gbp-menu-search-provider"
+
+#include "config.h"
+
+#include <libide-gui.h>
+#include <libide-search.h>
+#include <libide-sourceview.h>
+
+#include "ide-application-private.h"
+
+#include "gbp-menu-search-provider.h"
+#include "gbp-menu-search-result.h"
+
+struct _GbpMenuSearchProvider
+{
+  IdeObject parent_instance;
+};
+
+static GIcon *default_gicon;
+
+static void
+populate_from_menu_model (GListStore *store,
+                          GMenuModel *menu,
+                          const char *query)
+{
+  guint n_items;
+
+  g_assert (G_IS_LIST_STORE (store));
+  g_assert (G_IS_MENU_MODEL (menu));
+
+  n_items = g_menu_model_get_n_items (menu);
+
+  for (guint i = 0; i < n_items; i++)
+    {
+      g_autoptr(IdeSearchResult) result = NULL;
+      g_autoptr(GVariant) target = NULL;
+      g_autofree char *label = NULL;
+      g_autofree char *icon_name = NULL;
+      g_autofree char *description = NULL;
+      g_autofree char *action = NULL;
+      guint prio = 0;
+
+      if (!g_menu_model_get_item_attribute (menu, i, "label", "s", &label) ||
+          !g_menu_model_get_item_attribute (menu, i, "action", "s", &action) ||
+          !g_menu_model_get_item_attribute (menu, i, "description", "s", &description))
+        continue;
+
+      if (!gtk_source_completion_fuzzy_match (label, query, &prio) &&
+          !gtk_source_completion_fuzzy_match (description, query, &prio))
+        continue;
+
+      result = g_object_new (GBP_TYPE_MENU_SEARCH_RESULT,
+                             "title", label,
+                             "subtitle", description,
+                             NULL);
+
+      if (g_menu_model_get_item_attribute (menu, i, "verb-icon", "s", &icon_name))
+        {
+          g_autoptr(GIcon) icon = g_themed_icon_new (icon_name);
+          ide_search_result_set_gicon (result, icon);
+        }
+      else
+        {
+          ide_search_result_set_gicon (result, default_gicon);
+        }
+
+      target = g_menu_model_get_item_attribute_value (menu, i, "target", NULL);
+      gbp_menu_search_result_set_action (GBP_MENU_SEARCH_RESULT (result), action, target);
+
+      g_list_store_append (store, result);
+    }
+}
+
+static void
+gbp_menu_search_provider_search_async (IdeSearchProvider   *provider,
+                                       const char          *query,
+                                       guint                max_results,
+                                       GCancellable        *cancellable,
+                                       GAsyncReadyCallback  callback,
+                                       gpointer             user_data)
+{
+  g_autoptr(IdeTask) task = NULL;
+  g_autoptr(GListStore) store = NULL;
+  const char * const *menu_ids;
+  IdeApplication *app;
+
+  IDE_ENTRY;
+
+  g_assert (IDE_IS_MAIN_THREAD ());
+  g_assert (GBP_IS_MENU_SEARCH_PROVIDER (provider));
+  g_assert (query != NULL);
+  g_assert (!cancellable || G_IS_CANCELLABLE (cancellable));
+
+  task = ide_task_new (provider, cancellable, callback, user_data);
+  ide_task_set_source_tag (task, gbp_menu_search_provider_search_async);
+
+  app = IDE_APPLICATION_DEFAULT;
+  menu_ids = ide_menu_manager_get_menu_ids (app->menu_manager);
+  store = g_list_store_new (IDE_TYPE_SEARCH_RESULT);
+
+  for (guint i = 0; menu_ids[i]; i++)
+    {
+      GMenu *menu = ide_menu_manager_get_menu_by_id (app->menu_manager, menu_ids[i]);
+
+      populate_from_menu_model (store, G_MENU_MODEL (menu), query);
+    }
+
+  ide_task_return_pointer (task, g_steal_pointer (&store), g_object_unref);
+
+  IDE_EXIT;
+}
+
+static GListModel *
+gbp_menu_search_provider_search_finish (IdeSearchProvider  *provider,
+                                        GAsyncResult       *result,
+                                        GError            **error)
+{
+  GListModel *ret;
+
+  IDE_ENTRY;
+
+  g_assert (IDE_IS_MAIN_THREAD ());
+  g_assert (GBP_IS_MENU_SEARCH_PROVIDER (provider));
+  g_assert (IDE_IS_TASK (result));
+
+  ret = ide_task_propagate_pointer (IDE_TASK (result), error);
+
+  IDE_RETURN (ret);
+}
+
+static void
+search_provider_iface_init (IdeSearchProviderInterface *iface)
+{
+  iface->search_async = gbp_menu_search_provider_search_async;
+  iface->search_finish = gbp_menu_search_provider_search_finish;
+}
+
+G_DEFINE_FINAL_TYPE_WITH_CODE (GbpMenuSearchProvider, gbp_menu_search_provider, IDE_TYPE_OBJECT,
+                               G_IMPLEMENT_INTERFACE (IDE_TYPE_SEARCH_PROVIDER, search_provider_iface_init))
+
+static void
+gbp_menu_search_provider_class_init (GbpMenuSearchProviderClass *klass)
+{
+  default_gicon = g_themed_icon_new ("preferences-desktop-keyboard-shortcuts-symbolic");
+}
+
+static void
+gbp_menu_search_provider_init (GbpMenuSearchProvider *self)
+{
+}
diff --git a/src/plugins/menu-search/gbp-menu-search-provider.h 
b/src/plugins/menu-search/gbp-menu-search-provider.h
new file mode 100644
index 000000000..0e13dc45a
--- /dev/null
+++ b/src/plugins/menu-search/gbp-menu-search-provider.h
@@ -0,0 +1,31 @@
+/* gbp-menu-search-provider.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 <libide-core.h>
+
+G_BEGIN_DECLS
+
+#define GBP_TYPE_MENU_SEARCH_PROVIDER (gbp_menu_search_provider_get_type())
+
+G_DECLARE_FINAL_TYPE (GbpMenuSearchProvider, gbp_menu_search_provider, GBP, MENU_SEARCH_PROVIDER, IdeObject)
+
+G_END_DECLS
diff --git a/src/plugins/menu-search/gbp-menu-search-result.c 
b/src/plugins/menu-search/gbp-menu-search-result.c
new file mode 100644
index 000000000..5e4485812
--- /dev/null
+++ b/src/plugins/menu-search/gbp-menu-search-result.c
@@ -0,0 +1,94 @@
+/* gbp-menu-search-result.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 "gbp-menu-search-result"
+
+#include "config.h"
+
+#include "gbp-menu-search-result.h"
+
+struct _GbpMenuSearchResult
+{
+  IdeSearchResult  parent_instance;
+  char            *action;
+  GVariant        *target;
+};
+
+G_DEFINE_FINAL_TYPE (GbpMenuSearchResult, gbp_menu_search_result, IDE_TYPE_SEARCH_RESULT)
+
+static void
+gbp_menu_search_result_activate (IdeSearchResult *result,
+                                 GtkWidget       *last_focus)
+{
+  GbpMenuSearchResult *self = (GbpMenuSearchResult *)result;
+
+  IDE_ENTRY;
+
+  g_assert (IDE_IS_MAIN_THREAD ());
+  g_assert (GBP_IS_MENU_SEARCH_RESULT (self));
+  g_assert (GTK_IS_WIDGET (last_focus));
+
+  g_debug ("Activating action \"%s\" starting from %s",
+           self->action,
+           G_OBJECT_TYPE_NAME (last_focus));
+
+  gtk_widget_activate_action_variant (last_focus, self->action, self->target);
+
+  IDE_EXIT;
+}
+
+static void
+gbp_menu_search_result_dispose (GObject *object)
+{
+  GbpMenuSearchResult *self = (GbpMenuSearchResult *)object;
+
+  g_clear_pointer (&self->action, g_free);
+  g_clear_pointer (&self->target, g_variant_unref);
+
+  G_OBJECT_CLASS (gbp_menu_search_result_parent_class)->dispose (object);
+}
+
+static void
+gbp_menu_search_result_class_init (GbpMenuSearchResultClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+  IdeSearchResultClass *search_result_class = IDE_SEARCH_RESULT_CLASS (klass);
+
+  object_class->dispose = gbp_menu_search_result_dispose;
+
+  search_result_class->activate = gbp_menu_search_result_activate;
+}
+
+static void
+gbp_menu_search_result_init (GbpMenuSearchResult *self)
+{
+}
+
+void
+gbp_menu_search_result_set_action (GbpMenuSearchResult *self,
+                                   const char          *action,
+                                   GVariant            *target)
+{
+  g_return_if_fail (GBP_IS_MENU_SEARCH_RESULT (self));
+
+  ide_set_string (&self->action, action);
+  g_clear_pointer (&self->target, g_variant_unref);
+  self->target = target ? g_variant_ref (target) : NULL;
+}
diff --git a/src/plugins/menu-search/gbp-menu-search-result.h 
b/src/plugins/menu-search/gbp-menu-search-result.h
new file mode 100644
index 000000000..a112a16a1
--- /dev/null
+++ b/src/plugins/menu-search/gbp-menu-search-result.h
@@ -0,0 +1,35 @@
+/* gbp-menu-search-result.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 <libide-search.h>
+
+G_BEGIN_DECLS
+
+#define GBP_TYPE_MENU_SEARCH_RESULT (gbp_menu_search_result_get_type())
+
+G_DECLARE_FINAL_TYPE (GbpMenuSearchResult, gbp_menu_search_result, GBP, MENU_SEARCH_RESULT, IdeSearchResult)
+
+void gbp_menu_search_result_set_action (GbpMenuSearchResult *self,
+                                        const char          *action,
+                                        GVariant            *target);
+
+G_END_DECLS
diff --git a/src/plugins/menu-search/menu-search-plugin.c b/src/plugins/menu-search/menu-search-plugin.c
new file mode 100644
index 000000000..5c0b5b364
--- /dev/null
+++ b/src/plugins/menu-search/menu-search-plugin.c
@@ -0,0 +1,37 @@
+/* menu-search-plugin.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 "menu-search-plugin"
+
+#include "config.h"
+
+#include <libpeas/peas.h>
+
+#include <libide-search.h>
+
+#include "gbp-menu-search-provider.h"
+
+void
+_gbp_menu_search_register_types (PeasObjectModule *module)
+{
+  peas_object_module_register_extension_type (module,
+                                              IDE_TYPE_SEARCH_PROVIDER,
+                                              GBP_TYPE_MENU_SEARCH_PROVIDER);
+}
diff --git a/src/plugins/menu-search/menu-search.gresource.xml 
b/src/plugins/menu-search/menu-search.gresource.xml
new file mode 100644
index 000000000..d178a9512
--- /dev/null
+++ b/src/plugins/menu-search/menu-search.gresource.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<gresources>
+  <gresource prefix="/plugins/menu-search">
+    <file>menu-search.plugin</file>
+  </gresource>
+</gresources>
diff --git a/src/plugins/menu-search/menu-search.plugin b/src/plugins/menu-search/menu-search.plugin
new file mode 100644
index 000000000..0ef34abe7
--- /dev/null
+++ b/src/plugins/menu-search/menu-search.plugin
@@ -0,0 +1,8 @@
+[Plugin]
+Authors=Christian Hergert <christian hergert me>
+Builtin=true
+Copyright=Copyright © 2022 Christian Hergert
+Embedded=_gbp_menu_search_register_types
+Hidden=true
+Module=menu-search
+Name=Menu Search
diff --git a/src/plugins/menu-search/meson.build b/src/plugins/menu-search/meson.build
new file mode 100644
index 000000000..1ae42efd9
--- /dev/null
+++ b/src/plugins/menu-search/meson.build
@@ -0,0 +1,13 @@
+plugins_sources += files([
+  'gbp-menu-search-provider.c',
+  'gbp-menu-search-result.c',
+  'menu-search-plugin.c',
+])
+
+plugin_menu_search_resources = gnome.compile_resources(
+  'menu-search-resources',
+  'menu-search.gresource.xml',
+  c_name: 'gbp_menu_search',
+)
+
+plugins_sources += plugin_menu_search_resources
diff --git a/src/plugins/meson.build b/src/plugins/meson.build
index 5a89ee8be..724bb2941 100644
--- a/src/plugins/meson.build
+++ b/src/plugins/meson.build
@@ -87,6 +87,7 @@ subdir('make')
 subdir('make-templates')
 subdir('markdown-preview')
 subdir('maven')
+subdir('menu-search')
 subdir('meson')
 subdir('meson-templates')
 subdir('messages')


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