[Libreoffice-commits] core.git: Branch 'libreoffice-5-1' - 3 commits - include/LibreOfficeKit libreofficekit/Library_libreofficekitgtk.mk libreofficekit/qa libreofficekit/source

Pranav Kant pranavk at libreoffice.org
Wed Dec 9 04:18:37 PST 2015


 include/LibreOfficeKit/LibreOfficeKitGtk.h          |   41 +
 libreofficekit/Library_libreofficekitgtk.mk         |    4 
 libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx |   46 --
 libreofficekit/source/gtk/lokdocview.cxx            |  411 ++++++++++++--------
 4 files changed, 321 insertions(+), 181 deletions(-)

New commits:
commit dabfa0ce06f605fd0e8de32774b6385fd6ffbd56
Author: Pranav Kant <pranavk at libreoffice.org>
Date:   Tue Dec 8 23:14:25 2015 +0530

    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 at libreoffice.org>
    Reviewed-by: David Tardon <dtardon at redhat.com>
    (cherry picked from commit 424c09b10d3d6ba6edfed2dcf560d5ce2c950b9d)

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)
commit e7cdd6803485bbe4cfe27f5f466b427823318334
Author: Pranav Kant <pranavk at libreoffice.org>
Date:   Wed Dec 9 10:33:05 2015 +0530

    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 at libreoffice.org>
    Reviewed-by: David Tardon <dtardon at redhat.com>
    (cherry picked from commit 0f64cf72ff3b930e306e937bb18f4cbe55a8026a)

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
commit 0a28049853ce84aa8ef4f871065970c1220ae855
Author: Pranav Kant <pranavk at libreoffice.org>
Date:   Wed Dec 9 01:03:02 2015 +0530

    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 at redhat.com>
    Tested-by: David Tardon <dtardon at redhat.com>
    (cherry picked from commit b3bfc26d0863b074bb990725718f2ab23d05425d)

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);


More information about the Libreoffice-commits mailing list