add more LOKDevView related fixes

f41
David Tardon 9 years ago
parent 75b36407c9
commit 9a1935211b

@ -0,0 +1,406 @@
From 0a28049853ce84aa8ef4f871065970c1220ae855 Mon Sep 17 00:00:00 2001
From: Pranav Kant <pranavk@libreoffice.org>
Date: Wed, 9 Dec 2015 01:03:02 +0530
Subject: [PATCH 1/3] tdf#96316: Decouple view-only/editable modes
- Move text selection and graphic selection tasks into functions
- Merge GDK_BUTTON_PRESS, GDK_BUTTON_RELEASE conditional code
- Do not change to 'move' cursor in view-only mode
- Ignore LOK_POST_COMMAND, LOK_SET_GRAPHIC_SELECTION in view-only
As a consequence this commit also allows dragging handles during text
selection in view-only mode which was earlier not possible.
Change-Id: Iffb668d5447dd646a1e40237dee8d8d3fa3314b6
Reviewed-on: https://gerrit.libreoffice.org/20487
Reviewed-by: David Tardon <dtardon@redhat.com>
Tested-by: David Tardon <dtardon@redhat.com>
(cherry picked from commit b3bfc26d0863b074bb990725718f2ab23d05425d)
---
libreofficekit/source/gtk/lokdocview.cxx | 312 ++++++++++++++++++-------------
1 file changed, 180 insertions(+), 132 deletions(-)
diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx
index c808752..cbdac71 100644
--- a/libreofficekit/source/gtk/lokdocview.cxx
+++ b/libreofficekit/source/gtk/lokdocview.cxx
@@ -312,6 +312,153 @@ isEmptyRectangle(const GdkRectangle& rRectangle)
return rRectangle.x == 0 && rRectangle.y == 0 && rRectangle.width == 0 && rRectangle.height == 0;
}
+/// if handled, returns TRUE else FALSE
+static bool
+handleTextSelectionOnButtonPress(GdkRectangle& aClick, LOKDocView* pDocView) {
+ LOKDocViewPrivate& priv = getPrivate(pDocView);
+
+ if (gdk_rectangle_intersect(&aClick, &priv->m_aHandleStartRect, nullptr))
+ {
+ g_info("LOKDocView_Impl::signalButton: start of drag start handle");
+ priv->m_bInDragStartHandle = true;
+ return TRUE;
+ }
+ else if (gdk_rectangle_intersect(&aClick, &priv->m_aHandleMiddleRect, nullptr))
+ {
+ g_info("LOKDocView_Impl::signalButton: start of drag middle handle");
+ priv->m_bInDragMiddleHandle = true;
+ return TRUE;
+ }
+ else if (gdk_rectangle_intersect(&aClick, &priv->m_aHandleEndRect, nullptr))
+ {
+ g_info("LOKDocView_Impl::signalButton: start of drag end handle");
+ priv->m_bInDragEndHandle = true;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/// if handled, returns TRUE else FALSE
+static bool
+handleGraphicSelectionOnButtonPress(GdkRectangle& aClick, LOKDocView* pDocView) {
+ LOKDocViewPrivate& priv = getPrivate(pDocView);
+ GError* error = nullptr;
+
+ for (int i = 0; i < GRAPHIC_HANDLE_COUNT; ++i)
+ {
+ if (gdk_rectangle_intersect(&aClick, &priv->m_aGraphicHandleRects[i], nullptr))
+ {
+ g_info("LOKDocView_Impl::signalButton: start of drag graphic handle #%d", i);
+ priv->m_bInDragGraphicHandles[i] = true;
+
+ GTask* task = g_task_new(pDocView, nullptr, nullptr, nullptr);
+ LOEvent* pLOEvent = new LOEvent(LOK_SET_GRAPHIC_SELECTION);
+ pLOEvent->m_nSetGraphicSelectionType = LOK_SETGRAPHICSELECTION_START;
+ pLOEvent->m_nSetGraphicSelectionX = pixelToTwip(priv->m_aGraphicHandleRects[i].x + priv->m_aGraphicHandleRects[i].width / 2, priv->m_fZoom);
+ pLOEvent->m_nSetGraphicSelectionY = pixelToTwip(priv->m_aGraphicHandleRects[i].y + priv->m_aGraphicHandleRects[i].height / 2, priv->m_fZoom);
+ g_task_set_task_data(task, pLOEvent, LOEvent::destroy);
+
+ g_thread_pool_push(priv->lokThreadPool, g_object_ref(task), &error);
+ if (error != nullptr)
+ {
+ g_warning("Unable to call LOK_SET_GRAPHIC_SELECTION: %s", error->message);
+ g_clear_error(&error);
+ }
+ g_object_unref(task);
+
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+/// if handled, returns TRUE else FALSE
+static bool
+handleTextSelectionOnButtonRelease(LOKDocView* pDocView) {
+ LOKDocViewPrivate& priv = getPrivate(pDocView);
+
+ if (priv->m_bInDragStartHandle)
+ {
+ g_info("LOKDocView_Impl::signalButton: end of drag start handle");
+ priv->m_bInDragStartHandle = false;
+ return TRUE;
+ }
+ else if (priv->m_bInDragMiddleHandle)
+ {
+ g_info("LOKDocView_Impl::signalButton: end of drag middle handle");
+ priv->m_bInDragMiddleHandle = false;
+ return TRUE;
+ }
+ else if (priv->m_bInDragEndHandle)
+ {
+ g_info("LOKDocView_Impl::signalButton: end of drag end handle");
+ priv->m_bInDragEndHandle = false;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/// if handled, returns TRUE else FALSE
+static bool
+handleGraphicSelectionOnButtonRelease(LOKDocView* pDocView, GdkEventButton* pEvent) {
+ LOKDocViewPrivate& priv = getPrivate(pDocView);
+ GError* error = nullptr;
+
+ for (int i = 0; i < GRAPHIC_HANDLE_COUNT; ++i)
+ {
+ if (priv->m_bInDragGraphicHandles[i])
+ {
+ g_info("LOKDocView_Impl::signalButton: end of drag graphic handle #%d", i);
+ priv->m_bInDragGraphicHandles[i] = false;
+
+ GTask* task = g_task_new(pDocView, nullptr, nullptr, nullptr);
+ LOEvent* pLOEvent = new LOEvent(LOK_SET_GRAPHIC_SELECTION);
+ pLOEvent->m_nSetGraphicSelectionType = LOK_SETGRAPHICSELECTION_END;
+ pLOEvent->m_nSetGraphicSelectionX = pixelToTwip(pEvent->x, priv->m_fZoom);
+ pLOEvent->m_nSetGraphicSelectionY = pixelToTwip(pEvent->y, priv->m_fZoom);
+ g_task_set_task_data(task, pLOEvent, LOEvent::destroy);
+
+ g_thread_pool_push(priv->lokThreadPool, g_object_ref(task), &error);
+ if (error != nullptr)
+ {
+ g_warning("Unable to call LOK_SET_GRAPHIC_SELECTION: %s", error->message);
+ g_clear_error(&error);
+ }
+ g_object_unref(task);
+
+ return TRUE;
+ }
+ }
+
+ if (priv->m_bInDragGraphicSelection)
+ {
+ g_info("LOKDocView_Impl::signalButton: end of drag graphic selection");
+ priv->m_bInDragGraphicSelection = false;
+
+ GTask* task = g_task_new(pDocView, nullptr, nullptr, nullptr);
+ LOEvent* pLOEvent = new LOEvent(LOK_SET_GRAPHIC_SELECTION);
+ pLOEvent->m_nSetGraphicSelectionType = LOK_SETGRAPHICSELECTION_END;
+ pLOEvent->m_nSetGraphicSelectionX = pixelToTwip(pEvent->x, priv->m_fZoom);
+ pLOEvent->m_nSetGraphicSelectionY = pixelToTwip(pEvent->y, priv->m_fZoom);
+ g_task_set_task_data(task, pLOEvent, LOEvent::destroy);
+
+ g_thread_pool_push(priv->lokThreadPool, g_object_ref(task), &error);
+ if (error != nullptr)
+ {
+ g_warning("Unable to call LOK_SET_GRAPHIC_SELECTION: %s", error->message);
+ g_clear_error(&error);
+ }
+ g_object_unref(task);
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
static void
postKeyEventInThread(gpointer data)
{
@@ -747,11 +894,17 @@ callback (gpointer pData)
break;
case LOK_CALLBACK_MOUSE_POINTER:
{
- // The gtk docs claim that most css cursors should be supported, however
- // on my system at least this is not true and many cursors are unsupported.
- // In this case pCursor = null, which results in the default cursor being set.
- GdkCursor* pCursor = gdk_cursor_new_from_name(gtk_widget_get_display(GTK_WIDGET(pDocView)), pCallback->m_aPayload.c_str());
- gdk_window_set_cursor(gtk_widget_get_window(GTK_WIDGET(pDocView)), pCursor);
+ // We do not want the cursor to get changed in view-only mode
+ if (priv->m_bEdit)
+ {
+ // The gtk docs claim that most css cursors should be supported, however
+ // on my system at least this is not true and many cursors are unsupported.
+ // In this case pCursor = null, which results in the default cursor
+ // being set.
+ GdkCursor* pCursor = gdk_cursor_new_from_name(gtk_widget_get_display(GTK_WIDGET(pDocView)),
+ pCallback->m_aPayload.c_str());
+ gdk_window_set_cursor(gtk_widget_get_window(GTK_WIDGET(pDocView)), pCursor);
+ }
}
break;
case LOK_CALLBACK_GRAPHIC_SELECTION:
@@ -1176,140 +1329,21 @@ lok_doc_view_signal_button(GtkWidget* pWidget, GdkEventButton* pEvent)
(int)pixelToTwip(pEvent->y, priv->m_fZoom));
gtk_widget_grab_focus(GTK_WIDGET(pDocView));
- if (pEvent->type == GDK_BUTTON_RELEASE)
+ switch (pEvent->type)
{
- if (priv->m_bInDragStartHandle)
- {
- g_info("LOKDocView_Impl::signalButton: end of drag start handle");
- priv->m_bInDragStartHandle = false;
- return FALSE;
- }
- else if (priv->m_bInDragMiddleHandle)
- {
- g_info("LOKDocView_Impl::signalButton: end of drag middle handle");
- priv->m_bInDragMiddleHandle = false;
- return FALSE;
- }
- else if (priv->m_bInDragEndHandle)
- {
- g_info("LOKDocView_Impl::signalButton: end of drag end handle");
- priv->m_bInDragEndHandle = false;
- return FALSE;
- }
-
- for (int i = 0; i < GRAPHIC_HANDLE_COUNT; ++i)
- {
- if (priv->m_bInDragGraphicHandles[i])
- {
- g_info("LOKDocView_Impl::signalButton: end of drag graphic handle #%d", i);
- priv->m_bInDragGraphicHandles[i] = false;
-
- GTask* task = g_task_new(pDocView, nullptr, nullptr, nullptr);
- LOEvent* pLOEvent = new LOEvent(LOK_SET_GRAPHIC_SELECTION);
- pLOEvent->m_nSetGraphicSelectionType = LOK_SETGRAPHICSELECTION_END;
- pLOEvent->m_nSetGraphicSelectionX = pixelToTwip(pEvent->x, priv->m_fZoom);
- pLOEvent->m_nSetGraphicSelectionY = pixelToTwip(pEvent->y, priv->m_fZoom);
- g_task_set_task_data(task, pLOEvent, LOEvent::destroy);
-
- g_thread_pool_push(priv->lokThreadPool, g_object_ref(task), &error);
- if (error != nullptr)
- {
- g_warning("Unable to call LOK_SET_GRAPHIC_SELECTION: %s", error->message);
- g_clear_error(&error);
- }
- g_object_unref(task);
-
- return FALSE;
- }
- }
-
- if (priv->m_bInDragGraphicSelection)
- {
- g_info("LOKDocView_Impl::signalButton: end of drag graphic selection");
- priv->m_bInDragGraphicSelection = false;
-
- GTask* task = g_task_new(pDocView, nullptr, nullptr, nullptr);
- LOEvent* pLOEvent = new LOEvent(LOK_SET_GRAPHIC_SELECTION);
- pLOEvent->m_nSetGraphicSelectionType = LOK_SETGRAPHICSELECTION_END;
- pLOEvent->m_nSetGraphicSelectionX = pixelToTwip(pEvent->x, priv->m_fZoom);
- pLOEvent->m_nSetGraphicSelectionY = pixelToTwip(pEvent->y, priv->m_fZoom);
- g_task_set_task_data(task, pLOEvent, LOEvent::destroy);
-
- g_thread_pool_push(priv->lokThreadPool, g_object_ref(task), &error);
- if (error != nullptr)
- {
- g_warning("Unable to call LOK_SET_GRAPHIC_SELECTION: %s", error->message);
- g_clear_error(&error);
- }
- g_object_unref(task);
-
- return FALSE;
- }
- }
-
- if (priv->m_bEdit)
+ case GDK_BUTTON_PRESS:
{
GdkRectangle aClick;
aClick.x = pEvent->x;
aClick.y = pEvent->y;
aClick.width = 1;
aClick.height = 1;
- if (pEvent->type == GDK_BUTTON_PRESS)
- {
- if (gdk_rectangle_intersect(&aClick, &priv->m_aHandleStartRect, nullptr))
- {
- g_info("LOKDocView_Impl::signalButton: start of drag start handle");
- priv->m_bInDragStartHandle = true;
- return FALSE;
- }
- else if (gdk_rectangle_intersect(&aClick, &priv->m_aHandleMiddleRect, nullptr))
- {
- g_info("LOKDocView_Impl::signalButton: start of drag middle handle");
- priv->m_bInDragMiddleHandle = true;
- return FALSE;
- }
- else if (gdk_rectangle_intersect(&aClick, &priv->m_aHandleEndRect, nullptr))
- {
- g_info("LOKDocView_Impl::signalButton: start of drag end handle");
- priv->m_bInDragEndHandle = true;
- return FALSE;
- }
- for (int i = 0; i < GRAPHIC_HANDLE_COUNT; ++i)
- {
- if (gdk_rectangle_intersect(&aClick, &priv->m_aGraphicHandleRects[i], nullptr))
- {
- g_info("LOKDocView_Impl::signalButton: start of drag graphic handle #%d", i);
- priv->m_bInDragGraphicHandles[i] = true;
-
- GTask* task = g_task_new(pDocView, nullptr, nullptr, nullptr);
- LOEvent* pLOEvent = new LOEvent(LOK_SET_GRAPHIC_SELECTION);
- pLOEvent->m_nSetGraphicSelectionType = LOK_SETGRAPHICSELECTION_START;
- pLOEvent->m_nSetGraphicSelectionX = pixelToTwip(priv->m_aGraphicHandleRects[i].x + priv->m_aGraphicHandleRects[i].width / 2, priv->m_fZoom);
- pLOEvent->m_nSetGraphicSelectionY = pixelToTwip(priv->m_aGraphicHandleRects[i].y + priv->m_aGraphicHandleRects[i].height / 2, priv->m_fZoom);
- g_task_set_task_data(task, pLOEvent, LOEvent::destroy);
-
- g_thread_pool_push(priv->lokThreadPool, g_object_ref(task), &error);
- if (error != nullptr)
- {
- g_warning("Unable to call LOK_SET_GRAPHIC_SELECTION: %s", error->message);
- g_clear_error(&error);
- }
- g_object_unref(task);
-
- return FALSE;
- }
- }
- }
- }
-
- if (!priv->m_bEdit)
- lok_doc_view_set_edit(pDocView, TRUE);
+ if (handleTextSelectionOnButtonPress(aClick, pDocView))
+ return FALSE;
+ if (handleGraphicSelectionOnButtonPress(aClick, pDocView))
+ return FALSE;
- switch (pEvent->type)
- {
- case GDK_BUTTON_PRESS:
- {
int nCount = 1;
if ((pEvent->time - priv->m_nLastButtonPressTime) < 250)
nCount++;
@@ -1347,6 +1381,11 @@ lok_doc_view_signal_button(GtkWidget* pWidget, GdkEventButton* pEvent)
}
case GDK_BUTTON_RELEASE:
{
+ if (handleTextSelectionOnButtonRelease(pDocView))
+ return FALSE;
+ if (handleGraphicSelectionOnButtonRelease(pDocView, pEvent))
+ return FALSE;
+
int nCount = 1;
if ((pEvent->time - priv->m_nLastButtonReleaseTime) < 250)
nCount++;
@@ -1722,6 +1761,8 @@ lokThreadFunc(gpointer data, gpointer /*user_data*/)
{
GTask* task = G_TASK(data);
LOEvent* pLOEvent = static_cast<LOEvent*>(g_task_get_task_data(task));
+ LOKDocView* pDocView = LOK_DOC_VIEW(g_task_get_source_object(task));
+ LOKDocViewPrivate& priv = getPrivate(pDocView);
switch (pLOEvent->m_nType)
{
@@ -1729,7 +1770,10 @@ lokThreadFunc(gpointer data, gpointer /*user_data*/)
openDocumentInThread(task);
break;
case LOK_POST_COMMAND:
- postCommandInThread(task);
+ if (priv->m_bEdit)
+ postCommandInThread(task);
+ else
+ g_info ("LOK_POST_COMMAND: ignoring commands in view-only mode");
break;
case LOK_SET_EDIT:
setEditInThread(task);
@@ -1741,6 +1785,7 @@ lokThreadFunc(gpointer data, gpointer /*user_data*/)
setPartmodeInThread(task);
break;
case LOK_POST_KEY:
+ // view-only/editable mode already checked during signal key signal emission
postKeyEventInThread(task);
break;
case LOK_PAINT_TILE:
@@ -1750,7 +1795,10 @@ lokThreadFunc(gpointer data, gpointer /*user_data*/)
postMouseEventInThread(task);
break;
case LOK_SET_GRAPHIC_SELECTION:
- setGraphicSelectionInThread(task);
+ if (priv->m_bEdit)
+ setGraphicSelectionInThread(task);
+ else
+ g_info ("LOK_SET_GRAPHIC_SELECTION: skipping graphical operation in view-only mode");
break;
case LOK_SET_CLIENT_ZOOM:
setClientZoomInThread(task);
--
2.5.0

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

@ -0,0 +1,64 @@
From dabfa0ce06f605fd0e8de32774b6385fd6ffbd56 Mon Sep 17 00:00:00 2001
From: Pranav Kant <pranavk@libreoffice.org>
Date: Tue, 8 Dec 2015 23:14:25 +0530
Subject: [PATCH 3/3] lokdocview: Set a 'default' path for LOK init
When passed NULL to lok_doc_view_new, use the default path :
$libdir/libreoffice/program as LOK install path
Change-Id: I1e033c407184b29b1509cfb8c416b514591d67ce
Reviewed-on: https://gerrit.libreoffice.org/20476
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: David Tardon <dtardon@redhat.com>
(cherry picked from commit 424c09b10d3d6ba6edfed2dcf560d5ce2c950b9d)
---
include/LibreOfficeKit/LibreOfficeKitGtk.h | 3 ++-
libreofficekit/Library_libreofficekitgtk.mk | 4 ++++
libreofficekit/source/gtk/lokdocview.cxx | 2 +-
3 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/include/LibreOfficeKit/LibreOfficeKitGtk.h b/include/LibreOfficeKit/LibreOfficeKitGtk.h
index b2f17f1..1b03e46 100644
--- a/include/LibreOfficeKit/LibreOfficeKitGtk.h
+++ b/include/LibreOfficeKit/LibreOfficeKitGtk.h
@@ -42,7 +42,8 @@ GType lok_doc_view_get_type (void) G_GNUC
/**
* lok_doc_view_new:
- * @pPath: LibreOffice install path.
+ * @pPath: (nullable): LibreOffice install path. Pass null to set it to default
+ * path which in most cases would be $libdir/libreoffice/program
* @cancellable: The cancellable object that you can use to cancel this
* operation.
* @error: The error that will be set if the object fails to initialize.
diff --git a/libreofficekit/Library_libreofficekitgtk.mk b/libreofficekit/Library_libreofficekitgtk.mk
index 3eba939..fc62e72 100644
--- a/libreofficekit/Library_libreofficekitgtk.mk
+++ b/libreofficekit/Library_libreofficekitgtk.mk
@@ -28,6 +28,10 @@ $(eval $(call gb_Library_add_libs,libreofficekitgtk,\
$(GTK3_LIBS) \
))
+$(eval $(call gb_Library_add_defs,libreofficekitgtk,\
+ -DLOK_PATH="\"$(LIBDIR)/libreoffice/$(LIBO_LIB_FOLDER)\"" \
+))
+
ifeq ($(OS),$(filter LINUX %BSD SOLARIS, $(OS)))
$(eval $(call gb_Library_add_libs,libreofficekitgtk,\
$(DLOPEN_LIBS) -lm \
diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx
index 488abc0..f734baa 100644
--- a/libreofficekit/source/gtk/lokdocview.cxx
+++ b/libreofficekit/source/gtk/lokdocview.cxx
@@ -2387,7 +2387,7 @@ static void lok_doc_view_class_init (LOKDocViewClass* pClass)
SAL_DLLPUBLIC_EXPORT GtkWidget*
lok_doc_view_new (const gchar* pPath, GCancellable *cancellable, GError **error)
{
- return GTK_WIDGET (g_initable_new (LOK_TYPE_DOC_VIEW, cancellable, error, "lopath", pPath, NULL));
+ return GTK_WIDGET (g_initable_new (LOK_TYPE_DOC_VIEW, cancellable, error, "lopath", pPath == NULL ? LOK_PATH : pPath, NULL));
}
SAL_DLLPUBLIC_EXPORT GtkWidget* lok_doc_view_new_from_widget(LOKDocView* pOldLOKDocView)
--
2.5.0

@ -327,6 +327,9 @@ Patch20: 0001-update-the-appstream-files-to-most-recent-version-of.patch
Patch21: 0001-tdf-96243-don-t-crash-if-LibO-install.-wasn-t-found.patch Patch21: 0001-tdf-96243-don-t-crash-if-LibO-install.-wasn-t-found.patch
Patch22: 0001-tdf-96246-Make-pRenderingArguments-nullable.patch Patch22: 0001-tdf-96246-Make-pRenderingArguments-nullable.patch
Patch23: 0001-tdf-96250-desktop-empty-str-is-the-same-as-0-str-in-.patch Patch23: 0001-tdf-96250-desktop-empty-str-is-the-same-as-0-str-in-.patch
Patch24: 0001-tdf-96316-Decouple-view-only-editable-modes.patch
Patch25: 0002-tdf-96318-Add-searching-API.patch
Patch26: 0003-lokdocview-Set-a-default-path-for-LOK-init.patch
%define instdir %{_libdir} %define instdir %{_libdir}
%define baseinstdir %{instdir}/libreoffice %define baseinstdir %{instdir}/libreoffice

Loading…
Cancel
Save