135360
From cc1e87b14fae9c6fb84ee5c9307ed27945fab289 Mon Sep 17 00:00:00 2001
135360
From: Pranav Kant <pranavk@libreoffice.org>
135360
Date: Wed, 9 Dec 2015 10:33:05 +0530
135360
Subject: [PATCH 368/398] tdf#96318: Add searching API
135360
135360
Clients should now use these APIs to search for text in the
135360
widget, rather than executing UNO commands directly on the
135360
widget. This allows searching for text in the widget in view-only
135360
mode too.
135360
135360
Change-Id: I013b6f96e69a634ec33367394d39c0f645a4994d
135360
Reviewed-on: https://gerrit.libreoffice.org/20488
135360
Tested-by: Jenkins <ci@libreoffice.org>
135360
Reviewed-by: David Tardon <dtardon@redhat.com>
135360
(cherry picked from commit 0f64cf72ff3b930e306e937bb18f4cbe55a8026a)
135360
(cherry picked from commit e7cdd6803485bbe4cfe27f5f466b427823318334)
135360
---
135360
 include/LibreOfficeKit/LibreOfficeKitGtk.h         |  38 ++++++++
135360
 .../qa/gtktiledviewer/gtktiledviewer.cxx           |  46 +++------
135360
 libreofficekit/source/gtk/lokdocview.cxx           | 107 +++++++++++++++++----
135360
 3 files changed, 139 insertions(+), 52 deletions(-)
135360
135360
diff --git a/include/LibreOfficeKit/LibreOfficeKitGtk.h b/include/LibreOfficeKit/LibreOfficeKitGtk.h
135360
index 8b6092c56ef2..b2f17f14b6cb 100644
135360
--- a/include/LibreOfficeKit/LibreOfficeKitGtk.h
135360
+++ b/include/LibreOfficeKit/LibreOfficeKitGtk.h
135360
@@ -195,6 +195,44 @@ void                           lok_doc_view_post_command           (LOKDocView*
135360
                                                                     const gchar* pArguments,
135360
                                                                     gboolean bNotifyWhenFinished);
135360
 
135360
+
135360
+/**
135360
+ * lok_doc_view_find_next:
135360
+ * @pDocView: The #LOKDocView instance
135360
+ * @pText: text to search for
135360
+ * @bHighlightAll: Whether all the matches should be highlighted or not
135360
+ *
135360
+ * Highlights the next matching text in the view. `search-not-found` signal will
135360
+ * be emitted when no search is found
135360
+ */
135360
+void                           lok_doc_view_find_next              (LOKDocView* pDocView,
135360
+                                                                    const gchar* pText,
135360
+                                                                    gboolean bHighlightAll);
135360
+
135360
+/**
135360
+ * lok_doc_view_find_prev:
135360
+ * @pDocView: The #LOKDocView instance
135360
+ * @pText: text to search for
135360
+ * @bHighlightAll: Whether all the matches should be highlighted or not
135360
+ *
135360
+ * Highlights the previous matching text in the view. `search-not-found` signal
135360
+ * will be emitted when no search is found
135360
+ */
135360
+void                           lok_doc_view_find_prev              (LOKDocView* pDocView,
135360
+                                                                    const gchar* pText,
135360
+                                                                    gboolean bHighlightAll);
135360
+
135360
+/**
135360
+ * lok_doc_view_highlight_all:
135360
+ * @pDocView: The #LOKDocView instance
135360
+ * @pText: text to search for
135360
+ *
135360
+ * Highlights all matching texts in the view. `search-not-found` signal
135360
+ * will be emitted when no search is found
135360
+ */
135360
+void                           lok_doc_view_highlight_all          (LOKDocView* pDocView,
135360
+                                                                    const gchar* pText);
135360
+
135360
 /**
135360
  * lok_doc_view_pixel_to_twip:
135360
  * @pDocView: The #LOKDocView instance
135360
diff --git a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx
135360
index e44a92a3f3de..2416e1c6dbcf 100644
135360
--- a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx
135360
+++ b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx
135360
@@ -439,7 +439,11 @@ static void toggleEditing(GtkWidget* pButton, gpointer /*pItem*/)
135360
 static void toggleFindAll(GtkWidget* pButton, gpointer /*pItem*/)
135360
 {
135360
     TiledWindow& rWindow = lcl_getTiledWindow(pButton);
135360
+    GtkEntry* pEntry = GTK_ENTRY(rWindow.m_pFindbarEntry);
135360
+    const char* pText = gtk_entry_get_text(pEntry);
135360
+
135360
     rWindow.m_bFindAll = !rWindow.m_bFindAll;
135360
+    lok_doc_view_highlight_all(LOK_DOC_VIEW(rWindow.m_pDocView), pText);
135360
 }
135360
 
135360
 /// Toggle the visibility of the findbar.
135360
@@ -597,48 +601,24 @@ static void doPaste(GtkWidget* pButton, gpointer /*pItem*/)
135360
         pDocument->pClass->paste(pDocument, "text/plain;charset=utf-8", pText, strlen(pText));
135360
 }
135360
 
135360
-/// Searches for the next or previous text of TiledWindow::m_pFindbarEntry.
135360
-static void doSearch(GtkWidget* pButton, bool bBackwards)
135360
+/// Click handler for the search next button.
135360
+static void signalSearchNext(GtkWidget* pButton, gpointer /*pItem*/)
135360
 {
135360
     TiledWindow& rWindow = lcl_getTiledWindow(pButton);
135360
     GtkEntry* pEntry = GTK_ENTRY(rWindow.m_pFindbarEntry);
135360
     const char* pText = gtk_entry_get_text(pEntry);
135360
-    boost::property_tree::ptree aTree;
135360
-    aTree.put(boost::property_tree::ptree::path_type("SearchItem.SearchString/type", '/'), "string");
135360
-    aTree.put(boost::property_tree::ptree::path_type("SearchItem.SearchString/value", '/'), pText);
135360
-    aTree.put(boost::property_tree::ptree::path_type("SearchItem.Backward/type", '/'), "boolean");
135360
-    aTree.put(boost::property_tree::ptree::path_type("SearchItem.Backward/value", '/'), bBackwards);
135360
-    if (rWindow.m_bFindAll)
135360
-    {
135360
-        aTree.put(boost::property_tree::ptree::path_type("SearchItem.Command/type", '/'), "unsigned short");
135360
-        // SvxSearchCmd::FIND_ALL
135360
-        aTree.put(boost::property_tree::ptree::path_type("SearchItem.Command/value", '/'), "1");
135360
-    }
135360
-
135360
-    LOKDocView* pLOKDocView = LOK_DOC_VIEW(rWindow.m_pDocView);
135360
-    GdkRectangle aArea;
135360
-    getVisibleAreaTwips(rWindow.m_pDocView, &aArea);
135360
-    aTree.put(boost::property_tree::ptree::path_type("SearchItem.SearchStartPointX/type", '/'), "long");
135360
-    aTree.put(boost::property_tree::ptree::path_type("SearchItem.SearchStartPointX/value", '/'), aArea.x);
135360
-    aTree.put(boost::property_tree::ptree::path_type("SearchItem.SearchStartPointY/type", '/'), "long");
135360
-    aTree.put(boost::property_tree::ptree::path_type("SearchItem.SearchStartPointY/value", '/'), aArea.y);
135360
-
135360
-    std::stringstream aStream;
135360
-    boost::property_tree::write_json(aStream, aTree);
135360
 
135360
-    lok_doc_view_post_command(pLOKDocView, ".uno:ExecuteSearch", aStream.str().c_str(), false);
135360
-}
135360
-
135360
-/// Click handler for the search next button.
135360
-static void signalSearchNext(GtkWidget* pButton, gpointer /*pItem*/)
135360
-{
135360
-    doSearch(pButton, /*bBackwards=*/false);
135360
+    lok_doc_view_find_next(LOK_DOC_VIEW(rWindow.m_pDocView), pText, rWindow.m_bFindAll);
135360
 }
135360
 
135360
 /// Click handler for the search previous button.
135360
 static void signalSearchPrev(GtkWidget* pButton, gpointer /*pItem*/)
135360
 {
135360
-    doSearch(pButton, /*bBackwards=*/true);
135360
+    TiledWindow& rWindow = lcl_getTiledWindow(pButton);
135360
+    GtkEntry* pEntry = GTK_ENTRY(rWindow.m_pFindbarEntry);
135360
+    const char* pText = gtk_entry_get_text(pEntry);
135360
+
135360
+    lok_doc_view_find_prev(LOK_DOC_VIEW(rWindow.m_pDocView), pText, rWindow.m_bFindAll);
135360
 }
135360
 
135360
 /// Handles the key-press-event of the search entry widget.
135360
@@ -651,7 +631,7 @@ static gboolean signalFindbar(GtkWidget* pWidget, GdkEventKey* pEvent, gpointer
135360
         case GDK_KEY_Return:
135360
         {
135360
             // Search forward.
135360
-            doSearch(pWidget, /*bBackwards=*/false);
135360
+            signalSearchNext(pWidget, nullptr);
135360
             return TRUE;
135360
         }
135360
         case GDK_KEY_Escape:
135360
diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx
135360
index 5e985d4a8c2f..424d80eabcf9 100644
135360
--- a/libreofficekit/source/gtk/lokdocview.cxx
135360
+++ b/libreofficekit/source/gtk/lokdocview.cxx
135360
@@ -306,6 +306,67 @@ callbackTypeToString (int nType)
135360
     return nullptr;
135360
 }
135360
 
135360
+static void
135360
+LOKPostCommand (LOKDocView* pDocView,
135360
+                const gchar* pCommand,
135360
+                const gchar* pArguments,
135360
+                gboolean bNotifyWhenFinished)
135360
+{
135360
+    LOKDocViewPrivate& priv = getPrivate(pDocView);
135360
+    GTask* task = g_task_new(pDocView, nullptr, nullptr, nullptr);
135360
+    LOEvent* pLOEvent = new LOEvent(LOK_POST_COMMAND);
135360
+    GError* error = nullptr;
135360
+    pLOEvent->m_pCommand = pCommand;
135360
+    pLOEvent->m_pArguments  = g_strdup(pArguments);
135360
+    pLOEvent->m_bNotifyWhenFinished = bNotifyWhenFinished;
135360
+
135360
+    g_task_set_task_data(task, pLOEvent, LOEvent::destroy);
135360
+    g_thread_pool_push(priv->lokThreadPool, g_object_ref(task), &error);
135360
+    if (error != nullptr)
135360
+    {
135360
+        g_warning("Unable to call LOK_POST_COMMAND: %s", error->message);
135360
+        g_clear_error(&error);
135360
+    }
135360
+    g_object_unref(task);
135360
+}
135360
+
135360
+static void
135360
+doSearch(LOKDocView* pDocView, const char* pText, bool bBackwards, bool highlightAll)
135360
+{
135360
+    LOKDocViewPrivate& priv = getPrivate(pDocView);
135360
+    boost::property_tree::ptree aTree;
135360
+    GtkWidget* drawingWidget = GTK_WIDGET(pDocView);
135360
+    GdkWindow* drawingWindow = gtk_widget_get_window(drawingWidget);
135360
+    cairo_region_t* cairoVisRegion = gdk_window_get_visible_region(drawingWindow);
135360
+    cairo_rectangle_int_t cairoVisRect;
135360
+    int x, y;
135360
+
135360
+    cairo_region_get_rectangle(cairoVisRegion, 0, &cairoVisRect);
135360
+    x = pixelToTwip (cairoVisRect.x, priv->m_fZoom);
135360
+    y = pixelToTwip (cairoVisRect.y, priv->m_fZoom);
135360
+    
135360
+    aTree.put(boost::property_tree::ptree::path_type("SearchItem.SearchString/type", '/'), "string");
135360
+    aTree.put(boost::property_tree::ptree::path_type("SearchItem.SearchString/value", '/'), pText);
135360
+    aTree.put(boost::property_tree::ptree::path_type("SearchItem.Backward/type", '/'), "boolean");
135360
+    aTree.put(boost::property_tree::ptree::path_type("SearchItem.Backward/value", '/'), bBackwards);
135360
+    if (highlightAll)
135360
+    {
135360
+        aTree.put(boost::property_tree::ptree::path_type("SearchItem.Command/type", '/'), "unsigned short");
135360
+        // SvxSearchCmd::FIND_ALL
135360
+        aTree.put(boost::property_tree::ptree::path_type("SearchItem.Command/value", '/'), "1");
135360
+    }
135360
+
135360
+    aTree.put(boost::property_tree::ptree::path_type("SearchItem.SearchStartPointX/type", '/'), "long");
135360
+    aTree.put(boost::property_tree::ptree::path_type("SearchItem.SearchStartPointX/value", '/'), x);
135360
+    aTree.put(boost::property_tree::ptree::path_type("SearchItem.SearchStartPointY/type", '/'), "long");
135360
+    aTree.put(boost::property_tree::ptree::path_type("SearchItem.SearchStartPointY/value", '/'), y);
135360
+
135360
+    std::stringstream aStream;
135360
+    boost::property_tree::write_json(aStream, aTree);
135360
+
135360
+    LOKPostCommand (pDocView, ".uno:ExecuteSearch", aStream.str().c_str(), false);
135360
+}
135360
+
135360
 static bool
135360
 isEmptyRectangle(const GdkRectangle& rRectangle)
135360
 {
135360
@@ -1768,10 +1829,7 @@ lokThreadFunc(gpointer data, gpointer /*user_data*/)
135360
         openDocumentInThread(task);
135360
         break;
135360
     case LOK_POST_COMMAND:
135360
-        if (priv->m_bEdit)
135360
-            postCommandInThread(task);
135360
-        else
135360
-            g_info ("LOK_POST_COMMAND: ignoring commands in view-only mode");
135360
+        postCommandInThread(task);
135360
         break;
135360
     case LOK_SET_EDIT:
135360
         setEditInThread(task);
135360
@@ -2573,7 +2631,6 @@ lok_doc_view_get_edit (LOKDocView* pDocView)
135360
     return priv->m_bEdit;
135360
 }
135360
 
135360
-
135360
 SAL_DLLPUBLIC_EXPORT void
135360
 lok_doc_view_post_command (LOKDocView* pDocView,
135360
                            const gchar* pCommand,
135360
@@ -2581,21 +2638,33 @@ lok_doc_view_post_command (LOKDocView* pDocView,
135360
                            gboolean bNotifyWhenFinished)
135360
 {
135360
     LOKDocViewPrivate& priv = getPrivate(pDocView);
135360
-    GTask* task = g_task_new(pDocView, nullptr, nullptr, nullptr);
135360
-    LOEvent* pLOEvent = new LOEvent(LOK_POST_COMMAND);
135360
-    GError* error = nullptr;
135360
-    pLOEvent->m_pCommand = pCommand;
135360
-    pLOEvent->m_pArguments  = g_strdup(pArguments);
135360
-    pLOEvent->m_bNotifyWhenFinished = bNotifyWhenFinished;
135360
+    if (priv->m_bEdit)
135360
+        LOKPostCommand(pDocView, pCommand, pArguments, bNotifyWhenFinished);
135360
+    else
135360
+        g_info ("LOK_POST_COMMAND: ignoring commands in view-only mode");
135360
+}
135360
 
135360
-    g_task_set_task_data(task, pLOEvent, LOEvent::destroy);
135360
-    g_thread_pool_push(priv->lokThreadPool, g_object_ref(task), &error);
135360
-    if (error != nullptr)
135360
-    {
135360
-        g_warning("Unable to call LOK_POST_COMMAND: %s", error->message);
135360
-        g_clear_error(&error);
135360
-    }
135360
-    g_object_unref(task);
135360
+SAL_DLLPUBLIC_EXPORT void
135360
+lok_doc_view_find_prev (LOKDocView* pDocView,
135360
+                        const gchar* pText,
135360
+                        gboolean bHighlightAll)
135360
+{
135360
+    doSearch(pDocView, pText, true, bHighlightAll);
135360
+}
135360
+
135360
+SAL_DLLPUBLIC_EXPORT void
135360
+lok_doc_view_find_next (LOKDocView* pDocView,
135360
+                        const gchar* pText,
135360
+                        gboolean bHighlightAll)
135360
+{
135360
+    doSearch(pDocView, pText, false, bHighlightAll);
135360
+}
135360
+
135360
+SAL_DLLPUBLIC_EXPORT void
135360
+lok_doc_view_highlight_all (LOKDocView* pDocView,
135360
+                            const gchar* pText)
135360
+{
135360
+    doSearch(pDocView, pText, false, true);
135360
 }
135360
 
135360
 SAL_DLLPUBLIC_EXPORT float
135360
-- 
135360
2.12.0
135360