[gnome-builder] devhelp-search: documentation view needs find support



commit 41abc86e02050b06ad34816e873adb57ce13a6b6
Author: Lucie Charvat <luci charvat gmail com>
Date:   Wed May 24 21:31:41 2017 +0200

    devhelp-search: documentation view needs find support
    
    https://bugzilla.gnome.org/show_bug.cgi?id=742733

 plugins/devhelp/Makefile.am                        |    3 +
 .../devhelp/gbp-devhelp-resources.gresource.xml    |    1 +
 plugins/devhelp/gbp-devhelp-search-private.h       |   48 +++++++
 plugins/devhelp/gbp-devhelp-search.c               |  137 ++++++++++++++++++++
 plugins/devhelp/gbp-devhelp-search.h               |   37 ++++++
 plugins/devhelp/gbp-devhelp-search.ui              |  116 +++++++++++++++++
 plugins/devhelp/gbp-devhelp-view.c                 |   70 ++++++++++-
 plugins/devhelp/gbp-devhelp-view.ui                |   14 +-
 plugins/devhelp/meson.build                        |    3 +
 9 files changed, 420 insertions(+), 9 deletions(-)
---
diff --git a/plugins/devhelp/Makefile.am b/plugins/devhelp/Makefile.am
index 3433569..9ae0d4e 100644
--- a/plugins/devhelp/Makefile.am
+++ b/plugins/devhelp/Makefile.am
@@ -15,6 +15,9 @@ libdevhelp_plugin_la_SOURCES =          \
        gbp-devhelp-panel.c             \
        gbp-devhelp-panel.h             \
        gbp-devhelp-plugin.c            \
+       gbp-devhelp-search.c            \
+       gbp-devhelp-search.h            \
+       gbp-devhelp-search-private.h    \
        gbp-devhelp-view.c              \
        gbp-devhelp-view.h              \
        gbp-devhelp-workbench-addin.c   \
diff --git a/plugins/devhelp/gbp-devhelp-resources.gresource.xml 
b/plugins/devhelp/gbp-devhelp-resources.gresource.xml
index 040ef13..f1aa202 100644
--- a/plugins/devhelp/gbp-devhelp-resources.gresource.xml
+++ b/plugins/devhelp/gbp-devhelp-resources.gresource.xml
@@ -3,5 +3,6 @@
   <gresource prefix="/org/gnome/builder/plugins/devhelp-plugin">
     <file>theme/shared.css</file>
     <file>gbp-devhelp-view.ui</file>
+    <file>gbp-devhelp-search.ui</file>
   </gresource>
 </gresources>
diff --git a/plugins/devhelp/gbp-devhelp-search-private.h b/plugins/devhelp/gbp-devhelp-search-private.h
new file mode 100644
index 0000000..b565cf2
--- /dev/null
+++ b/plugins/devhelp/gbp-devhelp-search-private.h
@@ -0,0 +1,48 @@
+/* gbp-devhelp-view-private.h
+ *
+ * Copyright (C) 2017 Lucie Charvat <luci charvat gmail 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/>.
+ */
+
+#ifndef GBP_DEVHELP_SEARCH_PRIVATE_H
+#define GBP_DEVHELP_SEARCH_PRIVATE_H
+
+#include <gd-tagged-entry.h>
+#include <ide.h>
+
+G_BEGIN_DECLS
+
+struct _GbpDevhelpSearch
+{
+  GtkBin                parent_instance;
+
+  WebKitWebView        *web_view;
+  WebKitFindController *web_controller;
+
+  GtkRevealer          *search_revealer;
+
+  GdTaggedEntry        *search_entry;
+
+  GtkButton            *search_prev_button;
+  GtkButton            *search_next_button;
+  GtkButton            *close_button;
+
+  GtkClipboard         *clipboard;
+  gchar                *selected_text;
+};
+
+G_END_DECLS
+
+#endif /* GBP_DEVHELP_SEARCH_PRIVATE_H */
diff --git a/plugins/devhelp/gbp-devhelp-search.c b/plugins/devhelp/gbp-devhelp-search.c
new file mode 100644
index 0000000..5d5e16d
--- /dev/null
+++ b/plugins/devhelp/gbp-devhelp-search.c
@@ -0,0 +1,137 @@
+/* gbp-devhelp-search.c
+ *
+ * Copyright (C) 2017 Lucie Charvat <luci charvat gmail 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 "gbp-devhelp-search"
+#define MAX_SEARCH 100
+
+#include <fcntl.h>
+#include <glib/gi18n.h>
+#include <ide.h>
+#include <webkit2/webkit2.h>
+
+#include "gbp-devhelp-search.h"
+#include "gbp-devhelp-search-private.h"
+
+G_DEFINE_TYPE (GbpDevhelpSearch, gbp_devhelp_search, GTK_TYPE_BIN)
+
+static void
+close_clicked_cb (GtkButton        *button,
+                  GbpDevhelpSearch *self)
+{
+  g_assert (GBP_IS_DEVHELP_SEARCH (self));
+
+  webkit_find_controller_search_finish (self->web_controller);
+  gtk_revealer_set_reveal_child (self->search_revealer, FALSE);
+}
+
+static void
+search_button_clicked_cb (GtkButton        *button,
+                          GbpDevhelpSearch *self)
+{
+  g_assert (GBP_IS_DEVHELP_SEARCH (self));
+
+  if (button == self->search_prev_button)
+    webkit_find_controller_search_previous (self->web_controller);
+  else
+    webkit_find_controller_search_next (self->web_controller);
+}
+
+static void
+search_text_changed_cb (GdTaggedEntry    *search_entry,
+                        GbpDevhelpSearch *self)
+{
+  const char *search_text;
+
+  g_assert (GBP_IS_DEVHELP_SEARCH (self));
+
+  search_text = gtk_entry_get_text (GTK_ENTRY (self->search_entry));
+  webkit_find_controller_search (self->web_controller,
+                                search_text,
+                                WEBKIT_FIND_OPTIONS_BACKWARDS
+                                | WEBKIT_FIND_OPTIONS_WRAP_AROUND
+                                | WEBKIT_FIND_OPTIONS_CASE_INSENSITIVE,
+                                MAX_SEARCH);
+}
+
+static void
+search_revealer_cb (GtkRevealer      *search_revealer,
+                    GParamSpec       *pspec G_GNUC_UNUSED,
+                    GbpDevhelpSearch *self)
+{
+  g_assert (GBP_IS_DEVHELP_SEARCH (self));
+
+  if (gtk_revealer_get_child_revealed (search_revealer))
+    {
+      g_free (self->selected_text);
+      self->selected_text = gtk_clipboard_wait_for_text (self->clipboard);
+      if (self->selected_text != NULL)
+        gtk_entry_set_text (GTK_ENTRY (self->search_entry), self->selected_text);
+
+      gtk_widget_grab_focus (GTK_WIDGET (self->search_entry));
+    }
+  else
+    gtk_revealer_set_reveal_child (self->search_revealer, FALSE);
+}
+
+static void
+gbp_devhelp_search_class_init (GbpDevhelpSearchClass *klass)
+{
+  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+  gtk_widget_class_set_template_from_resource (widget_class, 
"/org/gnome/builder/plugins/devhelp-plugin/gbp-devhelp-search.ui");
+
+  gtk_widget_class_bind_template_child (widget_class, GbpDevhelpSearch, search_prev_button);
+  gtk_widget_class_bind_template_child (widget_class, GbpDevhelpSearch, search_next_button);
+  gtk_widget_class_bind_template_child (widget_class, GbpDevhelpSearch, close_button);
+  gtk_widget_class_bind_template_child (widget_class, GbpDevhelpSearch, search_entry);
+  gtk_widget_class_bind_template_child (widget_class, GbpDevhelpSearch, search_revealer);
+
+  g_type_ensure (GD_TYPE_TAGGED_ENTRY);
+}
+
+static void
+gbp_devhelp_search_init (GbpDevhelpSearch *self)
+{
+
+  gtk_widget_init_template (GTK_WIDGET (self));
+
+  g_signal_connect (self->search_prev_button, "clicked", G_CALLBACK (search_button_clicked_cb), self);
+  g_signal_connect (self->search_next_button, "clicked", G_CALLBACK (search_button_clicked_cb), self);
+  g_signal_connect (self->close_button, "clicked", G_CALLBACK (close_clicked_cb), self);
+  g_signal_connect (self->search_entry, "search-changed", G_CALLBACK (search_text_changed_cb), self);
+  g_signal_connect (self->search_revealer, "notify::child-revealed", G_CALLBACK (search_revealer_cb), self);
+}
+
+void
+gbp_devhelp_search_set_devhelp (GbpDevhelpSearch     *self,
+                                WebKitFindController *web_controller,
+                                GtkClipboard         *clipboard)
+{
+  g_assert (GBP_IS_DEVHELP_SEARCH (self));
+
+  self->clipboard = clipboard;
+  self->web_controller = web_controller;
+}
+
+GtkRevealer *
+gbp_devhelp_search_get_revealer (GbpDevhelpSearch *self)
+{
+  g_return_val_if_fail (GBP_IS_DEVHELP_SEARCH (self), NULL);
+
+  return self->search_revealer;
+}
diff --git a/plugins/devhelp/gbp-devhelp-search.h b/plugins/devhelp/gbp-devhelp-search.h
new file mode 100644
index 0000000..245f1a8
--- /dev/null
+++ b/plugins/devhelp/gbp-devhelp-search.h
@@ -0,0 +1,37 @@
+/* gbp-devhelp-view.h
+ *
+ * Copyright (C) 2017 Lucie Charvat <luci charvat gmail 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/>.
+ */
+
+#ifndef GBP_DEVHELP_SEARCH_H
+#define GBP_DEVHELP_SEARCH_H
+
+#include <ide.h>
+
+G_BEGIN_DECLS
+
+#define GBP_TYPE_DEVHELP_SEARCH (gbp_devhelp_search_get_type())
+
+G_DECLARE_FINAL_TYPE (GbpDevhelpSearch, gbp_devhelp_search, GBP, DEVHELP_SEARCH, GtkBin)
+
+void         gbp_devhelp_search_set_devhelp     (GbpDevhelpSearch     *self,
+                                                 WebKitFindController *web_controller,
+                                                 GtkClipboard         *clipboard);
+GtkRevealer *gbp_devhelp_search_get_revealer    (GbpDevhelpSearch     *self);
+
+G_END_DECLS
+
+#endif /* GBP_DEVHELP_SEARCH_H */
diff --git a/plugins/devhelp/gbp-devhelp-search.ui b/plugins/devhelp/gbp-devhelp-search.ui
new file mode 100644
index 0000000..96793ae
--- /dev/null
+++ b/plugins/devhelp/gbp-devhelp-search.ui
@@ -0,0 +1,116 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <object class="GtkRevealer" id="search_revealer">
+    <property name="halign">end</property>
+    <property name="valign">start</property>
+    <property name="visible">true</property>
+    <child>
+      <object class="GtkFrame">
+        <property name="visible">true</property>
+        <property name="margin-end">12</property>
+        <style>
+          <class name="gb-search-frame"/>
+        </style>
+        <child>
+          <object class="GtkGrid">
+            <property name="visible">true</property>
+            <property name="can_focus">false</property>
+            <property name="row_spacing">8</property>
+            <property name="column_spacing">8</property>
+            <child>
+              <object class="GdTaggedEntry" id="search_entry">
+                <property name="visible">true</property>
+                <property name="can_focus">true</property>
+                <property name="width-chars">20</property>
+                <property name="max-width-chars">30</property>
+                <property name="primary_icon_name">edit-find-symbolic</property>
+                <property name="primary_icon_activatable">false</property>
+                <property name="primary_icon_sensitive">false</property>
+              </object>
+              <packing>
+                <property name="left_attach">0</property>
+                <property name="top_attach">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkBox">
+                <property name="homogeneous">true</property>
+                <property name="visible">true</property>
+                <property name="can_focus">false</property>
+                <property name="valign">center</property>
+                <style>
+                  <class name="linked"/>
+                </style>
+                <child>
+                  <object class="GtkButton" id="search_prev_button">
+                    <property name="visible">true</property>
+                    <property name="can_focus">false</property>
+                    <property name="receives_default">true</property>
+                    <child>
+                      <object class="GtkImage">
+                        <property name="visible">true</property>
+                        <property name="can_focus">false</property>
+                        <property name="icon_name">go-up-symbolic</property>
+                        <property name="icon_size">1</property>
+                      </object>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="expand">false</property>
+                    <property name="fill">true</property>
+                    <property name="position">0</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkButton" id="search_next_button">
+                    <property name="visible">true</property>
+                    <property name="can_focus">false</property>
+                    <property name="receives_default">true</property>
+                    <child>
+                      <object class="GtkImage">
+                        <property name="visible">true</property>
+                        <property name="can_focus">false</property>
+                        <property name="icon_name">go-down-symbolic</property>
+                        <property name="icon_size">1</property>
+                      </object>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="expand">false</property>
+                    <property name="fill">true</property>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+              </object>
+              <packing>
+                <property name="left_attach">1</property>
+                <property name="top_attach">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkButton" id="close_button">
+                <property name="visible">true</property>
+                <property name="halign">center</property>
+                <property name="valign">center</property>
+                <property name="focus_on_click">false</property>
+                <style>
+                  <class name="close"/>
+                </style>
+                <child>
+                  <object class="GtkImage">
+                    <property name="visible">true</property>
+                    <property name="icon_name">window-close-symbolic</property>
+                  </object>
+                </child>
+              </object>
+              <packing>
+                <property name="left_attach">3</property>
+                <property name="top_attach">0</property>
+              </packing>
+            </child>
+          </object>
+        </child>
+      </object>
+    </child>
+  </object>
+</interface>
diff --git a/plugins/devhelp/gbp-devhelp-view.c b/plugins/devhelp/gbp-devhelp-view.c
index 7bc2e0a..f9f1b55 100644
--- a/plugins/devhelp/gbp-devhelp-view.c
+++ b/plugins/devhelp/gbp-devhelp-view.c
@@ -21,12 +21,20 @@
 #include <webkit2/webkit2.h>
 
 #include "gbp-devhelp-view.h"
+#include "gbp-devhelp-search.h"
 
 struct _GbpDevhelpView
 {
-  IdeLayoutView  parent_instance;
-  WebKitWebView *web_view1;
-};
+  IdeLayoutView         parent_instance;
+
+  WebKitWebView        *web_view1;
+  WebKitFindController *web_controller;
+  GtkClipboard         *clipboard;
+
+  GtkOverlay           *devhelp_overlay;
+  GtkRevealer          *search_revealer;
+  GbpDevhelpSearch     *search;
+ };
 
 enum {
   PROP_0,
@@ -34,9 +42,15 @@ enum {
   LAST_PROP
 };
 
+enum {
+  SEARCH_REVEAL,
+  LAST_SIGNAL
+};
+
 G_DEFINE_TYPE (GbpDevhelpView, gbp_devhelp_view, IDE_TYPE_LAYOUT_VIEW)
 
 static GParamSpec *properties [LAST_PROP];
+static guint signals [LAST_SIGNAL];
 
 void
 gbp_devhelp_view_set_uri (GbpDevhelpView *self,
@@ -110,6 +124,25 @@ gbp_devhelp_view_set_property (GObject      *object,
 }
 
 static void
+gbp_devhelp_search_reveal (GbpDevhelpView *self)
+{
+  g_assert (GBP_IS_DEVHELP_VIEW (self));
+
+  webkit_web_view_can_execute_editing_command (self->web_view1, WEBKIT_EDITING_COMMAND_COPY, NULL, NULL, 
NULL);
+  gtk_revealer_set_reveal_child (self->search_revealer, TRUE);
+}
+
+static void
+gbp_devhelp_focus_in_event (GbpDevhelpView *self,
+                            GdkEvent       *event)
+{
+  g_assert (GBP_IS_DEVHELP_VIEW (self));
+
+  webkit_find_controller_search_finish (self->web_controller);
+  gtk_revealer_set_reveal_child (self->search_revealer, FALSE);
+}
+
+static void
 gbp_devhelp_view_class_init (GbpDevhelpViewClass *klass)
 {
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
@@ -128,10 +161,24 @@ gbp_devhelp_view_class_init (GbpDevhelpViewClass *klass)
                          NULL,
                          (G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS));
 
+  signals [SEARCH_REVEAL] =
+    g_signal_new_class_handler ("search-reveal",
+                                G_TYPE_FROM_CLASS (klass),
+                                G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+                                G_CALLBACK (gbp_devhelp_search_reveal),
+                                NULL, NULL, NULL,
+                                G_TYPE_NONE, 0);
+
+  gtk_binding_entry_add_signal (gtk_binding_set_by_class (klass),
+                                GDK_KEY_f,
+                                GDK_CONTROL_MASK,
+                                "search-reveal", 0);
+
   g_object_class_install_properties (object_class, LAST_PROP, properties);
 
   gtk_widget_class_set_template_from_resource (widget_class, 
"/org/gnome/builder/plugins/devhelp-plugin/gbp-devhelp-view.ui");
   gtk_widget_class_bind_template_child (widget_class, GbpDevhelpView, web_view1);
+  gtk_widget_class_bind_template_child (widget_class, GbpDevhelpView, devhelp_overlay);
 
   g_type_ensure (WEBKIT_TYPE_WEB_VIEW);
 }
@@ -141,9 +188,26 @@ gbp_devhelp_view_init (GbpDevhelpView *self)
 {
   gtk_widget_init_template (GTK_WIDGET (self));
 
+  self->search = g_object_new (GBP_TYPE_DEVHELP_SEARCH, NULL);
+  self->search_revealer = gbp_devhelp_search_get_revealer (self->search);
+  self->clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
+  self->web_controller = webkit_web_view_get_find_controller (self->web_view1);
+
+  gtk_overlay_add_overlay (self->devhelp_overlay,
+                           GTK_WIDGET (self->search_revealer));
+
+  gbp_devhelp_search_set_devhelp (self->search,
+                                  self->web_controller,
+                                  self->clipboard);
+
   g_signal_connect_object (self->web_view1,
                            "notify::title",
                            G_CALLBACK (gbp_devhelp_view_notify_title),
                            self,
                            G_CONNECT_SWAPPED);
+  g_signal_connect_object (self->web_view1,
+                          "focus-in-event",
+                           G_CALLBACK (gbp_devhelp_focus_in_event),
+                           self,
+                           G_CONNECT_SWAPPED);
 }
diff --git a/plugins/devhelp/gbp-devhelp-view.ui b/plugins/devhelp/gbp-devhelp-view.ui
index be1b7df..fdd8ad7 100644
--- a/plugins/devhelp/gbp-devhelp-view.ui
+++ b/plugins/devhelp/gbp-devhelp-view.ui
@@ -8,14 +8,16 @@
         <property name="orientation">vertical</property>
         <property name="visible">true</property>
         <child>
-          <object class="WebKitWebView" id="web_view1">
-            <property name="visible">true</property>
+          <object class="GtkOverlay" id="devhelp_overlay">
             <property name="expand">true</property>
+            <property name="visible">true</property>
+            <child>
+              <object class="WebKitWebView" id="web_view1">
+                <property name="visible">true</property>
+                <property name="expand">true</property>
+              </object>
+            </child>
           </object>
-          <packing>
-          <property name="resize">true</property>
-          <property name="shrink">false</property>
-          </packing>
         </child>
       </object>
     </child>
diff --git a/plugins/devhelp/meson.build b/plugins/devhelp/meson.build
index 71b6673..7f2fbd3 100644
--- a/plugins/devhelp/meson.build
+++ b/plugins/devhelp/meson.build
@@ -12,6 +12,9 @@ devhelp_sources = [
   'gbp-devhelp-panel.c',
   'gbp-devhelp-panel.h',
   'gbp-devhelp-plugin.c',
+  'gbp-devhelp-search.c',
+  'gbp-devhelp-search.h',
+  'gbp-devhelp-search-private.h',
   'gbp-devhelp-view.c',
   'gbp-devhelp-view.h',
   'gbp-devhelp-workbench-addin.c',


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