[gnome-builder/wip/chergert/grep: 15/15] grep: popover searching bits



commit 57ca54d5f9fc5e8dcc29cbfa020e745664220d4f
Author: Christian Hergert <chergert redhat com>
Date:   Tue Oct 30 13:40:02 2018 -0700

    grep: popover searching bits

 po/POTFILES.in                                     |   3 +
 src/plugins/grep/gbp-grep-dialog.ui                | 285 ---------------------
 src/plugins/grep/gbp-grep-editor-addin.c           |   1 -
 src/plugins/grep/gbp-grep-model.c                  |   6 +-
 src/plugins/grep/gbp-grep-panel.c                  |   9 +-
 src/plugins/grep/gbp-grep-plugin.c                 |   4 +
 src/plugins/grep/gbp-grep-popover.c                | 222 ++++++++++++++++
 .../grep/{gbp-grep-dialog.h => gbp-grep-popover.h} |   8 +-
 src/plugins/grep/gbp-grep-popover.ui               |  77 ++++++
 src/plugins/grep/gbp-grep-project-tree-addin.c     | 192 ++++++++++++++
 ...grep-dialog.c => gbp-grep-project-tree-addin.h} |  31 +--
 src/plugins/grep/grep.gresource.xml                |   3 +-
 src/plugins/grep/grep.plugin                       |   2 +-
 src/plugins/grep/gtk/menus.ui                      |  11 +
 src/plugins/grep/meson.build                       |   3 +-
 src/plugins/project-tree/gtk/menus.ui              |   1 +
 16 files changed, 539 insertions(+), 319 deletions(-)
---
diff --git a/po/POTFILES.in b/po/POTFILES.in
index ddd9a9275..a007db4b2 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -195,6 +195,9 @@ src/plugins/gnome-code-assistance/ide-gca-preferences-addin.c
 src/plugins/gnome-code-assistance/ide-gca-service.c
 src/plugins/gnome-code-assistance/org.gnome.builder.gnome-code-assistance.gschema.xml
 src/plugins/gradle/gradle_plugin.py
+src/plugins/grep/gbp-grep-panel.c
+src/plugins/grep/gbp-grep-popover.ui
+src/plugins/grep/gtk/menus.ui
 src/plugins/html-preview/gtk/menus.ui
 src/plugins/html-preview/html_preview.py
 src/plugins/jedi/jedi_plugin.py
diff --git a/src/plugins/grep/gbp-grep-editor-addin.c b/src/plugins/grep/gbp-grep-editor-addin.c
index 887b80237..fac50066f 100644
--- a/src/plugins/grep/gbp-grep-editor-addin.c
+++ b/src/plugins/grep/gbp-grep-editor-addin.c
@@ -22,7 +22,6 @@
 
 #define G_LOG_DOMAIN "gbp-grep-editor-addin"
 
-#include "gbp-grep-dialog.h"
 #include "gbp-grep-editor-addin.h"
 #include "gbp-grep-model.h"
 #include "gbp-grep-panel.h"
diff --git a/src/plugins/grep/gbp-grep-model.c b/src/plugins/grep/gbp-grep-model.c
index d3652807e..dd278d26a 100644
--- a/src/plugins/grep/gbp-grep-model.c
+++ b/src/plugins/grep/gbp-grep-model.c
@@ -1102,13 +1102,17 @@ create_edits_cb (GbpGrepModel *self,
   if (gbp_grep_model_line_parse (&line, row, self->message_regex))
     {
       g_autoptr(IdeFile) file = NULL;
+      g_autoptr(GFile) gfile = NULL;
       IdeContext *context;
       guint lineno;
 
       context = ide_object_get_context (IDE_OBJECT (self));
       g_assert (IDE_IS_CONTEXT (context));
 
-      file = ide_file_new_for_path (context, line.path);
+      gfile = g_file_get_child (self->directory, line.path);
+      g_assert (G_IS_FILE (gfile));
+
+      file = ide_file_new (context, gfile);
       g_assert (IDE_IS_FILE (file));
 
       lineno = line.line ? line.line - 1 : 0;
diff --git a/src/plugins/grep/gbp-grep-panel.c b/src/plugins/grep/gbp-grep-panel.c
index 10e49f16a..a6994dd97 100644
--- a/src/plugins/grep/gbp-grep-panel.c
+++ b/src/plugins/grep/gbp-grep-panel.c
@@ -210,12 +210,17 @@ gbp_grep_panel_row_activated_cb (GbpGrepPanel      *self,
       gtk_tree_model_get_iter (model, &iter, path))
     {
       const GbpGrepModelLine *line = NULL;
+      GFile *directory;
+
+      directory = gbp_grep_model_get_directory (GBP_GREP_MODEL (model));
 
       gbp_grep_model_get_line (GBP_GREP_MODEL (model), &iter, &line);
 
       if G_LIKELY (line != NULL)
         {
           g_autoptr(IdeSourceLocation) location = NULL;
+          g_autoptr(GFile) child = NULL;
+          g_autoptr(IdeFile) ichild = NULL;
           IdePerspective *editor;
           IdeWorkbench *workbench;
           IdeContext *context;
@@ -228,7 +233,9 @@ gbp_grep_panel_row_activated_cb (GbpGrepPanel      *self,
           if (lineno > 0)
             lineno--;
 
-          location = ide_source_location_new_for_path (context, line->path, lineno, 0);
+          child = g_file_get_child (directory, line->path);
+          ichild = ide_file_new (context, child);
+          location = ide_source_location_new (ichild, lineno, 0, 0);
 
           ide_editor_perspective_focus_location (IDE_EDITOR_PERSPECTIVE (editor), location);
         }
diff --git a/src/plugins/grep/gbp-grep-plugin.c b/src/plugins/grep/gbp-grep-plugin.c
index f2a79638e..24b87da6f 100644
--- a/src/plugins/grep/gbp-grep-plugin.c
+++ b/src/plugins/grep/gbp-grep-plugin.c
@@ -22,6 +22,7 @@
 #include <libpeas/peas.h>
 
 #include "gbp-grep-editor-addin.h"
+#include "gbp-grep-project-tree-addin.h"
 
 void
 gbp_grep_register_types (PeasObjectModule *module)
@@ -29,4 +30,7 @@ gbp_grep_register_types (PeasObjectModule *module)
   peas_object_module_register_extension_type (module,
                                               IDE_TYPE_EDITOR_ADDIN,
                                               GBP_TYPE_GREP_EDITOR_ADDIN);
+  peas_object_module_register_extension_type (module,
+                                              IDE_TYPE_PROJECT_TREE_ADDIN,
+                                              GBP_TYPE_GREP_PROJECT_TREE_ADDIN);
 }
diff --git a/src/plugins/grep/gbp-grep-popover.c b/src/plugins/grep/gbp-grep-popover.c
new file mode 100644
index 000000000..a601d5538
--- /dev/null
+++ b/src/plugins/grep/gbp-grep-popover.c
@@ -0,0 +1,222 @@
+/* gbp-grep-popover.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 "gbp-grep-popover"
+
+#include <ide.h>
+
+#include "gbp-grep-model.h"
+#include "gbp-grep-panel.h"
+#include "gbp-grep-popover.h"
+
+struct _GbpGrepPopover
+{
+  GtkPopover parent_instance;
+
+  GFile *file;
+
+  GtkEntry       *entry;
+  GtkButton      *button;
+  GtkCheckButton *regex_button;
+  GtkCheckButton *whole_button;
+  GtkCheckButton *case_button;
+};
+
+enum {
+  PROP_0,
+  PROP_FILE,
+  N_PROPS
+};
+
+G_DEFINE_TYPE (GbpGrepPopover, gbp_grep_popover, GTK_TYPE_POPOVER)
+
+static GParamSpec *properties [N_PROPS];
+
+static void
+gbp_grep_popover_scan_cb (GObject      *object,
+                          GAsyncResult *result,
+                          gpointer      user_data)
+{
+  GbpGrepModel *model = (GbpGrepModel *)object;
+  g_autoptr(GbpGrepPanel) panel = user_data;
+  g_autoptr(GError) error = NULL;
+
+  g_assert (GBP_IS_GREP_MODEL (model));
+  g_assert (G_IS_ASYNC_RESULT (result));
+  g_assert (GBP_IS_GREP_PANEL (panel));
+
+  if (!gbp_grep_model_scan_finish (model, result, &error))
+    ide_widget_warning (GTK_WIDGET (panel), "Failed to find files: %s", error->message);
+  else
+    gbp_grep_panel_set_model (panel, model);
+
+  gtk_widget_grab_focus (GTK_WIDGET (panel));
+}
+
+static void
+gbp_grep_popover_button_clicked_cb (GbpGrepPopover *self,
+                                    GtkButton      *button)
+{
+  g_autoptr(GbpGrepModel) model = NULL;
+  IdePerspective *editor;
+  IdeWorkbench *workbench;
+  IdeContext *context;
+  GtkWidget *panel;
+  GtkWidget *utils;
+  gboolean use_regex;
+  gboolean at_word_boundaries;
+  gboolean case_sensitive;
+
+  g_assert (GBP_IS_GREP_POPOVER (self));
+  g_assert (GTK_IS_BUTTON (button));
+
+  workbench = ide_widget_get_workbench (GTK_WIDGET (self));
+  editor = ide_workbench_get_perspective_by_name (workbench, "editor");
+  utils = ide_editor_perspective_get_utilities (IDE_EDITOR_PERSPECTIVE (editor));
+  context = ide_workbench_get_context (workbench);
+
+  use_regex = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (self->regex_button));
+  at_word_boundaries = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (self->whole_button));
+  case_sensitive = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (self->case_button));
+
+  model = gbp_grep_model_new (context);
+  gbp_grep_model_set_directory (model, self->file);
+  gbp_grep_model_set_use_regex (model, use_regex);
+  gbp_grep_model_set_at_word_boundaries (model, at_word_boundaries);
+  gbp_grep_model_set_case_sensitive (model, case_sensitive);
+  gbp_grep_model_set_query (model, gtk_entry_get_text (self->entry));
+
+  /* TODO: Add recursive toggle */
+  gbp_grep_model_set_recursive (model, TRUE);
+
+  panel = gbp_grep_panel_new ();
+  gtk_container_add (GTK_CONTAINER (utils), panel);
+  gtk_widget_show (panel);
+
+  gbp_grep_model_scan_async (model,
+                             NULL,
+                             gbp_grep_popover_scan_cb,
+                             g_object_ref (panel));
+
+  dzl_dock_item_present (DZL_DOCK_ITEM (panel));
+}
+
+static void
+gbp_grep_popover_entry_activate_cb (GbpGrepPopover *self,
+                                    GtkEntry       *entry)
+{
+  g_assert (GBP_IS_GREP_POPOVER (self));
+  g_assert (GTK_IS_ENTRY (entry));
+
+  gtk_widget_activate (GTK_WIDGET (self->button));
+}
+
+static void
+gbp_grep_popover_finalize (GObject *object)
+{
+  GbpGrepPopover *self = (GbpGrepPopover *)object;
+
+  g_clear_object (&self->file);
+
+  G_OBJECT_CLASS (gbp_grep_popover_parent_class)->finalize (object);
+}
+
+static void
+gbp_grep_popover_get_property (GObject    *object,
+                               guint       prop_id,
+                               GValue     *value,
+                               GParamSpec *pspec)
+{
+  GbpGrepPopover *self = GBP_GREP_POPOVER (object);
+
+  switch (prop_id)
+    {
+    case PROP_FILE:
+      g_value_set_object (value, self->file);
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
+}
+
+static void
+gbp_grep_popover_set_property (GObject      *object,
+                               guint         prop_id,
+                               const GValue *value,
+                               GParamSpec   *pspec)
+{
+  GbpGrepPopover *self = GBP_GREP_POPOVER (object);
+
+  switch (prop_id)
+    {
+    case PROP_FILE:
+      g_set_object (&self->file, g_value_get_object (value));
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
+}
+
+static void
+gbp_grep_popover_class_init (GbpGrepPopoverClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+  object_class->finalize = gbp_grep_popover_finalize;
+  object_class->get_property = gbp_grep_popover_get_property;
+  object_class->set_property = gbp_grep_popover_set_property;
+
+  properties [PROP_FILE] =
+    g_param_spec_object ("file", NULL, NULL,
+                         G_TYPE_FILE,
+                         (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+  g_object_class_install_properties (object_class, N_PROPS, properties);
+
+  gtk_widget_class_set_template_from_resource (widget_class, 
"/org/gnome/builder/plugins/grep/gbp-grep-popover.ui");
+  gtk_widget_class_bind_template_child (widget_class, GbpGrepPopover, button);
+  gtk_widget_class_bind_template_child (widget_class, GbpGrepPopover, entry);
+  gtk_widget_class_bind_template_child (widget_class, GbpGrepPopover, regex_button);
+  gtk_widget_class_bind_template_child (widget_class, GbpGrepPopover, whole_button);
+  gtk_widget_class_bind_template_child (widget_class, GbpGrepPopover, case_button);
+}
+
+static void
+gbp_grep_popover_init (GbpGrepPopover *self)
+{
+  gtk_widget_init_template (GTK_WIDGET (self));
+
+  g_signal_connect_object (self->entry,
+                           "activate",
+                           G_CALLBACK (gbp_grep_popover_entry_activate_cb),
+                           self,
+                           G_CONNECT_SWAPPED);
+
+  g_signal_connect_object (self->button,
+                           "clicked",
+                           G_CALLBACK (gbp_grep_popover_button_clicked_cb),
+                           self,
+                           G_CONNECT_SWAPPED);
+}
diff --git a/src/plugins/grep/gbp-grep-dialog.h b/src/plugins/grep/gbp-grep-popover.h
similarity index 77%
rename from src/plugins/grep/gbp-grep-dialog.h
rename to src/plugins/grep/gbp-grep-popover.h
index 2ce9dfd40..4f569dea1 100644
--- a/src/plugins/grep/gbp-grep-dialog.h
+++ b/src/plugins/grep/gbp-grep-popover.h
@@ -1,6 +1,6 @@
-/* gbp-grep-dialog.h
+/* gbp-grep-popover.h
  *
- * Copyright © 2018 Christian Hergert <chergert redhat com>
+ * 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
@@ -24,8 +24,8 @@
 
 G_BEGIN_DECLS
 
-#define GBP_TYPE_GREP_DIALOG (gbp_grep_dialog_get_type())
+#define GBP_TYPE_GREP_POPOVER (gbp_grep_popover_get_type())
 
-G_DECLARE_FINAL_TYPE (GbpGrepDialog, gbp_grep_dialog, GBP, GREP_DIALOG, GtkDialog)
+G_DECLARE_FINAL_TYPE (GbpGrepPopover, gbp_grep_popover, GBP, GREP_POPOVER, GtkPopover)
 
 G_END_DECLS
diff --git a/src/plugins/grep/gbp-grep-popover.ui b/src/plugins/grep/gbp-grep-popover.ui
new file mode 100644
index 000000000..1027f4630
--- /dev/null
+++ b/src/plugins/grep/gbp-grep-popover.ui
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <template class="GbpGrepPopover" parent="GtkPopover">
+    <property name="border-width">12</property>
+    <child>
+      <object class="GtkBox">
+        <property name="orientation">vertical</property>
+        <property name="spacing">6</property>
+        <property name="visible">true</property>
+        <child>
+          <object class="GtkLabel">
+            <property name="label" translatable="yes">Find in Files</property>
+            <property name="visible">true</property>
+            <property name="xalign">0.0</property>
+            <attributes>
+              <attribute name="weight" value="bold"/>
+            </attributes>
+          </object>
+        </child>
+        <child>
+          <object class="GtkBox">
+            <property name="orientation">horizontal</property>
+            <property name="spacing">6</property>
+            <property name="visible">true</property>
+            <child>
+              <object class="GtkEntry" id="entry">
+                <property name="placeholder-text" translatable="yes">Search for…</property>
+                <property name="width-chars">24</property>
+                <property name="visible">true</property>
+              </object>
+            </child>
+            <child>
+              <object class="GtkButton" id="button">
+                <property name="hexpand">false</property>
+                <property name="halign">end</property>
+                <property name="label" translatable="yes">Find</property>
+                <property name="visible">true</property>
+                <style>
+                  <class name="suggested-action"/>
+                </style>
+              </object>
+            </child>
+          </object>
+        </child>
+        <child>
+          <object class="GtkBox">
+            <property name="margin-top">6</property>
+            <property name="orientation">vertical</property>
+            <property name="visible">true</property>
+            <child>
+              <object class="GtkCheckButton" id="case_button">
+                <property name="label" translatable="yes">Match _case when searching</property>
+                <property name="active">true</property>
+                <property name="use-underline">true</property>
+                <property name="visible">true</property>
+              </object>
+            </child>
+            <child>
+              <object class="GtkCheckButton" id="whole_button">
+                <property name="label" translatable="yes">Match _whole words</property>
+                <property name="use-underline">true</property>
+                <property name="visible">true</property>
+              </object>
+            </child>
+            <child>
+              <object class="GtkCheckButton" id="regex_button">
+                <property name="label" translatable="yes">Allow _regular expressions</property>
+                <property name="use-underline">true</property>
+                <property name="visible">true</property>
+              </object>
+            </child>
+          </object>
+        </child>
+      </object>
+    </child>
+  </template>
+</interface>
diff --git a/src/plugins/grep/gbp-grep-project-tree-addin.c b/src/plugins/grep/gbp-grep-project-tree-addin.c
new file mode 100644
index 000000000..0c1883e0e
--- /dev/null
+++ b/src/plugins/grep/gbp-grep-project-tree-addin.c
@@ -0,0 +1,192 @@
+/* gbp-grep-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 "gbp-grep-project-tree-addin"
+
+#include "gbp-grep-popover.h"
+#include "gbp-grep-project-tree-addin.h"
+
+/* This crosses the plugin boundary, but it is easier for now
+ * until we get some of the project tree stuff moved into a
+ * libide-project library (or similar).
+ */
+#include "../project-tree/gb-project-file.h"
+
+struct _GbpGrepProjectTreeAddin
+{
+  GObject         parent_instance;
+  DzlTree        *tree;
+  DzlTreeBuilder *builder;
+};
+
+static GFile *
+get_file_for_node (DzlTreeNode *node)
+{
+  GObject *item;
+
+  g_return_val_if_fail (!node || DZL_IS_TREE_NODE (node), NULL);
+
+  if (node == NULL)
+    return NULL;
+
+  if (!(item = dzl_tree_node_get_item (node)))
+    return NULL;
+
+  if (GB_IS_PROJECT_FILE (item))
+    return gb_project_file_get_file (GB_PROJECT_FILE (item));
+
+  return NULL;
+}
+
+static void
+popover_closed_cb (GtkPopover *popover)
+{
+  IdeWorkbench *workbench;
+
+  g_assert (GTK_IS_POPOVER (popover));
+
+  /*
+   * Clear focus before destroying popover, or we risk some
+   * re-entrancy issues in libdazzle. Needs safer tracking of
+   * focus widgets as gtk is not clearing pointers in destroy.
+   */
+
+  workbench = ide_widget_get_workbench (GTK_WIDGET (popover));
+  gtk_window_set_focus (GTK_WINDOW (workbench), NULL);
+  gtk_widget_destroy (GTK_WIDGET (popover));
+}
+
+static void
+find_in_files_action (GSimpleAction *action,
+                      GVariant      *param,
+                      gpointer       user_data)
+{
+  GbpGrepProjectTreeAddin *self = user_data;
+  DzlTreeNode *node;
+  GFile *file;
+
+  g_assert (G_IS_SIMPLE_ACTION (action));
+  g_assert (GBP_IS_GREP_PROJECT_TREE_ADDIN (self));
+
+  if ((node = dzl_tree_get_selected (self->tree)) &&
+      (file = get_file_for_node (node)))
+    {
+      GtkPopover *popover;
+
+      popover = g_object_new (GBP_TYPE_GREP_POPOVER,
+                              "file", file,
+                              "position", GTK_POS_RIGHT,
+                              NULL);
+      g_signal_connect_after (popover,
+                              "closed",
+                              G_CALLBACK (popover_closed_cb),
+                              NULL);
+      dzl_tree_node_show_popover (node, popover);
+    }
+}
+
+static void
+on_node_selected_cb (GbpGrepProjectTreeAddin *self,
+                     DzlTreeNode             *node,
+                     DzlTreeBuilder          *builder)
+{
+  GFile *file;
+
+  g_assert (GBP_IS_GREP_PROJECT_TREE_ADDIN (self));
+  g_assert (!node || DZL_IS_TREE_NODE (node));
+  g_assert (DZL_IS_TREE_BUILDER (builder));
+
+  file = get_file_for_node (node);
+
+  dzl_gtk_widget_action_set (GTK_WIDGET (self->tree), "grep", "find-in-files",
+                             "enabled", (file != NULL),
+                             NULL);
+}
+
+static void
+gbp_grep_project_tree_addin_load (IdeProjectTreeAddin *addin,
+                                  DzlTree             *tree)
+{
+  GbpGrepProjectTreeAddin *self = (GbpGrepProjectTreeAddin *)addin;
+  g_autoptr(GActionMap) group = NULL;
+  static GActionEntry actions[] = {
+    { "find-in-files", find_in_files_action },
+  };
+
+  g_assert (GBP_IS_GREP_PROJECT_TREE_ADDIN (self));
+  g_assert (DZL_IS_TREE (tree));
+  g_assert (self->builder == NULL);
+  g_assert (self->tree == NULL);
+
+  self->tree = tree;
+
+  group = G_ACTION_MAP (g_simple_action_group_new ());
+  g_action_map_add_action_entries (group, actions, G_N_ELEMENTS (actions), self);
+  gtk_widget_insert_action_group (GTK_WIDGET (tree), "grep", G_ACTION_GROUP (group));
+
+  self->builder = g_object_ref_sink (dzl_tree_builder_new ());
+  g_signal_connect_object (self->builder,
+                           "node-selected",
+                           G_CALLBACK (on_node_selected_cb),
+                           self,
+                           G_CONNECT_SWAPPED);
+  dzl_tree_add_builder (tree, self->builder);
+}
+
+static void
+gbp_grep_project_tree_addin_unload (IdeProjectTreeAddin *addin,
+                                    DzlTree             *tree)
+{
+  GbpGrepProjectTreeAddin *self = (GbpGrepProjectTreeAddin *)addin;
+
+  g_assert (GBP_IS_GREP_PROJECT_TREE_ADDIN (self));
+  g_assert (DZL_IS_TREE (tree));
+  g_assert (self->builder != NULL);
+  g_assert (self->tree == tree);
+
+  gtk_widget_insert_action_group (GTK_WIDGET (tree), "grep", NULL);
+  dzl_tree_remove_builder (tree, self->builder);
+  g_clear_object (&self->builder);
+
+  self->tree = NULL;
+}
+
+static void
+project_tree_addin_iface_init (IdeProjectTreeAddinInterface *iface)
+{
+  iface->load = gbp_grep_project_tree_addin_load;
+  iface->unload = gbp_grep_project_tree_addin_unload;
+}
+
+G_DEFINE_TYPE_WITH_CODE (GbpGrepProjectTreeAddin, gbp_grep_project_tree_addin, G_TYPE_OBJECT,
+                         G_IMPLEMENT_INTERFACE (IDE_TYPE_PROJECT_TREE_ADDIN,
+                                                project_tree_addin_iface_init))
+
+static void
+gbp_grep_project_tree_addin_class_init (GbpGrepProjectTreeAddinClass *klass)
+{
+}
+
+static void
+gbp_grep_project_tree_addin_init (GbpGrepProjectTreeAddin *self)
+{
+}
diff --git a/src/plugins/grep/gbp-grep-dialog.c b/src/plugins/grep/gbp-grep-project-tree-addin.h
similarity index 52%
rename from src/plugins/grep/gbp-grep-dialog.c
rename to src/plugins/grep/gbp-grep-project-tree-addin.h
index 387b44a9f..19aa66a1a 100644
--- a/src/plugins/grep/gbp-grep-dialog.c
+++ b/src/plugins/grep/gbp-grep-project-tree-addin.h
@@ -1,6 +1,6 @@
-/* gbp-grep-dialog.c
+/* gbp-grep-project-tree-addin.h
  *
- * Copyright © 2018 Christian Hergert <chergert redhat com>
+ * 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
@@ -18,31 +18,14 @@
  * SPDX-License-Identifier: GPL-3.0-or-later
  */
 
-#include "config.h"
-
-#define G_LOG_DOMAIN "gbp-grep-dialog"
+#pragma once
 
 #include <ide.h>
 
-#include "gbp-grep-dialog.h"
-
-struct _GbpGrepDialog
-{
-  GtkDialog parent_instance;
-};
-
-G_DEFINE_TYPE (GbpGrepDialog, gbp_grep_dialog, GTK_TYPE_DIALOG)
+G_BEGIN_DECLS
 
-static void
-gbp_grep_dialog_class_init (GbpGrepDialogClass *klass)
-{
-  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+#define GBP_TYPE_GREP_PROJECT_TREE_ADDIN (gbp_grep_project_tree_addin_get_type())
 
-  gtk_widget_class_set_template_from_resource (widget_class, 
"/org/gnome/builder/plugins/grep/gbp-grep-dialog.ui");
-}
+G_DECLARE_FINAL_TYPE (GbpGrepProjectTreeAddin, gbp_grep_project_tree_addin, GBP, GREP_PROJECT_TREE_ADDIN, 
GObject)
 
-static void
-gbp_grep_dialog_init (GbpGrepDialog *self)
-{
-  gtk_widget_init_template (GTK_WIDGET (self));
-}
+G_END_DECLS
diff --git a/src/plugins/grep/grep.gresource.xml b/src/plugins/grep/grep.gresource.xml
index d0c6cbbb1..ead09764c 100644
--- a/src/plugins/grep/grep.gresource.xml
+++ b/src/plugins/grep/grep.gresource.xml
@@ -4,8 +4,9 @@
     <file>grep.plugin</file>
   </gresource>
   <gresource prefix="/org/gnome/builder/plugins/grep">
-    <file preprocess="xml-stripblanks">gbp-grep-dialog.ui</file>
     <file preprocess="xml-stripblanks">gbp-grep-panel.ui</file>
+    <file preprocess="xml-stripblanks">gbp-grep-popover.ui</file>
+    <file preprocess="xml-stripblanks">gtk/menus.ui</file>
     <file>themes/Adwaita-shared.css</file>
     <file>themes/Adwaita-dark.css</file>
     <file>themes/Adwaita.css</file>
diff --git a/src/plugins/grep/grep.plugin b/src/plugins/grep/grep.plugin
index c68179cca..8812d8ab0 100644
--- a/src/plugins/grep/grep.plugin
+++ b/src/plugins/grep/grep.plugin
@@ -5,5 +5,5 @@ Description=Search across project files
 Authors=Christian Hergert <christian hergert me>
 Copyright=Copyright © 2018 Christian Hergert
 Builtin=true
-Depends=editor
+Depends=editor;project-tree-plugin
 Embedded=gbp_grep_register_types
diff --git a/src/plugins/grep/gtk/menus.ui b/src/plugins/grep/gtk/menus.ui
new file mode 100644
index 000000000..aef127545
--- /dev/null
+++ b/src/plugins/grep/gtk/menus.ui
@@ -0,0 +1,11 @@
+<?xml version="1.0"?>
+<interface>
+  <menu id="gb-project-tree-popup-menu">
+    <section id="gb-project-tree-find-section">
+      <item>
+        <attribute name="label" translatable="yes">Find in Files</attribute>
+        <attribute name="action">grep.find-in-files</attribute>
+      </item>
+    </section>
+  </menu>
+</interface>
diff --git a/src/plugins/grep/meson.build b/src/plugins/grep/meson.build
index 5481a5614..505169dc5 100644
--- a/src/plugins/grep/meson.build
+++ b/src/plugins/grep/meson.build
@@ -7,11 +7,12 @@ grep_resources = gnome.compile_resources(
 )
 
 grep_sources = [
-  'gbp-grep-dialog.c',
   'gbp-grep-editor-addin.c',
   'gbp-grep-model.c',
   'gbp-grep-panel.c',
   'gbp-grep-plugin.c',
+  'gbp-grep-popover.c',
+  'gbp-grep-project-tree-addin.c',
 ]
 
 gnome_builder_plugins_sources += files(grep_sources)
diff --git a/src/plugins/project-tree/gtk/menus.ui b/src/plugins/project-tree/gtk/menus.ui
index ae30ee1c0..903289782 100644
--- a/src/plugins/project-tree/gtk/menus.ui
+++ b/src/plugins/project-tree/gtk/menus.ui
@@ -49,6 +49,7 @@
         <attribute name="action">project-tree.open-in-terminal</attribute>
       </item>
     </section>
+    <section id="gb-project-tree-find-section"/>
     <section id="gb-project-tree-rename-section">
       <item>
         <attribute name="label" translatable="yes">_Rename</attribute>


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