[Libreoffice-commits] core.git: Branch 'feature/tiled-editing' - 4 commits - desktop/source include/LibreOfficeKit include/vcl libreofficekit/source sw/inc sw/source

Miklos Vajna vmiklos at collabora.co.uk
Tue Feb 10 09:41:56 PST 2015


 desktop/source/lib/init.cxx                |   16 ++++
 include/LibreOfficeKit/LibreOfficeKit.h    |   14 +++
 include/LibreOfficeKit/LibreOfficeKit.hxx  |   12 +++
 include/LibreOfficeKit/LibreOfficeKitGtk.h |   12 +++
 include/vcl/ITiledRenderable.hxx           |    7 +
 libreofficekit/source/gtk/lokdocview.c     |  113 ++++++++++++++++++++++-------
 sw/inc/unotxdoc.hxx                        |    2 
 sw/source/uibase/docvw/edtwin.cxx          |   14 +++
 sw/source/uibase/inc/edtwin.hxx            |    2 
 sw/source/uibase/uno/unotxdoc.cxx          |   19 ++++
 10 files changed, 187 insertions(+), 24 deletions(-)

New commits:
commit 0856476bf09a71789ee982d2ce7f592c78ab35b0
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Tue Feb 10 18:40:02 2015 +0100

    lokdocview: reset start/end or middle handle depending on if we have selection
    
    Change-Id: Iee5511a8077e37999865aa83da2dfde1fdd4dbc2

diff --git a/libreofficekit/source/gtk/lokdocview.c b/libreofficekit/source/gtk/lokdocview.c
index a9644b7..61d107c 100644
--- a/libreofficekit/source/gtk/lokdocview.c
+++ b/libreofficekit/source/gtk/lokdocview.c
@@ -604,8 +604,12 @@ static gboolean lok_docview_callback(gpointer pData)
         if (pRectangles == NULL)
         {
             memset(&pDocView->m_aTextSelectionStart, 0, sizeof(pDocView->m_aTextSelectionStart));
+            memset(&pDocView->m_aHandleStartRect, 0, sizeof(pDocView->m_aHandleStartRect));
             memset(&pDocView->m_aTextSelectionEnd, 0, sizeof(pDocView->m_aTextSelectionEnd));
+            memset(&pDocView->m_aHandleEndRect, 0, sizeof(pDocView->m_aHandleEndRect));
         }
+        else
+            memset(&pDocView->m_aHandleMiddleRect, 0, sizeof(pDocView->m_aHandleMiddleRect));
         gtk_widget_queue_draw(GTK_WIDGET(pDocView->pEventBox));
     }
     break;
commit 0d0c0058277484ad185103445ecaa79eeeb32c39
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Tue Feb 10 18:35:00 2015 +0100

    lokdocview: allow dragging the selection start handle, too
    
    Change-Id: Ic5dd96c4ced7c5ea67d4417c73721535302f754b

diff --git a/include/LibreOfficeKit/LibreOfficeKitGtk.h b/include/LibreOfficeKit/LibreOfficeKitGtk.h
index 40ce630..c1a1731 100644
--- a/include/LibreOfficeKit/LibreOfficeKitGtk.h
+++ b/include/LibreOfficeKit/LibreOfficeKitGtk.h
@@ -56,8 +56,15 @@ struct _LOKDocView
     GdkRectangle m_aTextSelectionStart;
     /// Position and size of the selection end.
     GdkRectangle m_aTextSelectionEnd;
+
+    /// @name Start/middle/end handle.
+    ///@{
     /// Bitmap of the text selection start handle.
     cairo_surface_t* m_pHandleStart;
+    /// Rectangle of the text selection start handle, to know if the user clicked on it or not
+    GdkRectangle m_aHandleStartRect;
+    /// If we are in the middle of a drag of the text selection end handle.
+    gboolean m_bInDragStartHandle;
     /// Bitmap of the text selection middle handle.
     cairo_surface_t* m_pHandleMiddle;
     /// Rectangle of the text selection middle handle, to know if the user clicked on it or not
@@ -70,6 +77,7 @@ struct _LOKDocView
     GdkRectangle m_aHandleEndRect;
     /// If we are in the middle of a drag of the text selection end handle.
     gboolean m_bInDragEndHandle;
+    ///@}
 };
 
 struct _LOKDocViewClass
diff --git a/libreofficekit/source/gtk/lokdocview.c b/libreofficekit/source/gtk/lokdocview.c
index c18ccc0..a9644b7 100644
--- a/libreofficekit/source/gtk/lokdocview.c
+++ b/libreofficekit/source/gtk/lokdocview.c
@@ -67,20 +67,24 @@ void lcl_getDragPoint(GdkRectangle* pHandle, GdkEventButton* pEvent, GdkPoint* p
 
 gboolean lcl_signalMotion(GtkWidget* pEventBox, GdkEventButton* pEvent, LOKDocView* pDocView)
 {
+    GdkPoint aPoint;
+
     (void)pEventBox;
     if (pDocView->m_bInDragMiddleHandle)
     {
-        GdkPoint aPoint;
-
         g_info("lcl_signalMotion: dragging the middle handle");
         lcl_getDragPoint(&pDocView->m_aHandleMiddleRect, pEvent, &aPoint);
         pDocView->pDocument->pClass->postMouseEvent(pDocView->pDocument, LOK_MOUSEEVENT_MOUSEBUTTONDOWN, pixelToTwip(aPoint.x), pixelToTwip(aPoint.y), 1);
         pDocView->pDocument->pClass->postMouseEvent(pDocView->pDocument, LOK_MOUSEEVENT_MOUSEBUTTONUP, pixelToTwip(aPoint.x), pixelToTwip(aPoint.y), 1);
     }
+    else if (pDocView->m_bInDragStartHandle)
+    {
+        g_info("lcl_signalMotion: dragging the start handle");
+        lcl_getDragPoint(&pDocView->m_aHandleStartRect, pEvent, &aPoint);
+        pDocView->pDocument->pClass->setTextSelection(pDocView->pDocument, LOK_SETTEXTSELECTION_START, pixelToTwip(aPoint.x), pixelToTwip(aPoint.y));
+    }
     else if (pDocView->m_bInDragEndHandle)
     {
-        GdkPoint aPoint;
-
         g_info("lcl_signalMotion: dragging the end handle");
         lcl_getDragPoint(&pDocView->m_aHandleEndRect, pEvent, &aPoint);
         pDocView->pDocument->pClass->setTextSelection(pDocView->pDocument, LOK_SETTEXTSELECTION_END, pixelToTwip(aPoint.x), pixelToTwip(aPoint.y));
@@ -94,17 +98,26 @@ gboolean lcl_signalButton(GtkWidget* pEventBox, GdkEventButton* pEvent, LOKDocVi
     g_info("lcl_signalButton: %d, %d (in twips: %d, %d)", (int)pEvent->x, (int)pEvent->y, (int)pixelToTwip(pEvent->x), (int)pixelToTwip(pEvent->y));
     (void) pEventBox;
 
-    if (pDocView->m_bInDragMiddleHandle && pEvent->type == GDK_BUTTON_RELEASE)
-    {
-        g_info("lcl_signalButton: end of drag middle handle");
-        pDocView->m_bInDragMiddleHandle = FALSE;
-        return FALSE;
-    }
-    else if (pDocView->m_bInDragEndHandle && pEvent->type == GDK_BUTTON_RELEASE)
+    if (pEvent->type == GDK_BUTTON_RELEASE)
     {
-        g_info("lcl_signalButton: end of drag end handle");
-        pDocView->m_bInDragEndHandle = FALSE;
-        return FALSE;
+        if (pDocView->m_bInDragStartHandle)
+        {
+            g_info("lcl_signalButton: end of drag start handle");
+            pDocView->m_bInDragStartHandle = FALSE;
+            return FALSE;
+        }
+        else if (pDocView->m_bInDragMiddleHandle)
+        {
+            g_info("lcl_signalButton: end of drag middle handle");
+            pDocView->m_bInDragMiddleHandle = FALSE;
+            return FALSE;
+        }
+        else if (pDocView->m_bInDragEndHandle)
+        {
+            g_info("lcl_signalButton: end of drag end handle");
+            pDocView->m_bInDragEndHandle = FALSE;
+            return FALSE;
+        }
     }
 
     if (pDocView->m_bEdit)
@@ -114,17 +127,26 @@ gboolean lcl_signalButton(GtkWidget* pEventBox, GdkEventButton* pEvent, LOKDocVi
         aClick.y = pEvent->y;
         aClick.width = 1;
         aClick.height = 1;
-        if (gdk_rectangle_intersect(&aClick, &pDocView->m_aHandleMiddleRect, NULL) && pEvent->type == GDK_BUTTON_PRESS)
-        {
-            g_info("lcl_signalButton: start of drag middle handle");
-            pDocView->m_bInDragMiddleHandle = TRUE;
-            return FALSE;
-        }
-        else if (gdk_rectangle_intersect(&aClick, &pDocView->m_aHandleEndRect, NULL) && pEvent->type == GDK_BUTTON_PRESS)
+        if (pEvent->type == GDK_BUTTON_PRESS)
         {
-            g_info("lcl_signalButton: start of drag end handle");
-            pDocView->m_bInDragEndHandle = TRUE;
-            return FALSE;
+            if (gdk_rectangle_intersect(&aClick, &pDocView->m_aHandleStartRect, NULL))
+            {
+                g_info("lcl_signalButton: start of drag start handle");
+                pDocView->m_bInDragStartHandle = TRUE;
+                return FALSE;
+            }
+            else if (gdk_rectangle_intersect(&aClick, &pDocView->m_aHandleMiddleRect, NULL))
+            {
+                g_info("lcl_signalButton: start of drag middle handle");
+                pDocView->m_bInDragMiddleHandle = TRUE;
+                return FALSE;
+            }
+            else if (gdk_rectangle_intersect(&aClick, &pDocView->m_aHandleEndRect, NULL))
+            {
+                g_info("lcl_signalButton: start of drag end handle");
+                pDocView->m_bInDragEndHandle = TRUE;
+                return FALSE;
+            }
         }
     }
 
@@ -219,11 +241,15 @@ static void lok_docview_init( LOKDocView* pDocView )
     pDocView->m_pTextSelectionRectangles = NULL;
     memset(&pDocView->m_aTextSelectionStart, 0, sizeof(pDocView->m_aTextSelectionStart));
     memset(&pDocView->m_aTextSelectionEnd, 0, sizeof(pDocView->m_aTextSelectionEnd));
+
+    // Start/middle/end handle.
     pDocView->m_pHandleStart = NULL;
+    memset(&pDocView->m_aHandleStartRect, 0, sizeof(pDocView->m_aHandleStartRect));
+    pDocView->m_bInDragStartHandle = FALSE;
     pDocView->m_pHandleMiddle = NULL;
-    pDocView->m_pHandleEnd = NULL;
     memset(&pDocView->m_aHandleMiddleRect, 0, sizeof(pDocView->m_aHandleMiddleRect));
     pDocView->m_bInDragMiddleHandle = FALSE;
+    pDocView->m_pHandleEnd = NULL;
     memset(&pDocView->m_aHandleEndRect, 0, sizeof(pDocView->m_aHandleEndRect));
     pDocView->m_bInDragEndHandle = FALSE;
 
@@ -360,7 +386,7 @@ static gboolean renderOverlay(GtkWidget* pWidget, GdkEventExpose* pEvent, gpoint
             // Have a start position: we need a start handle.
             if (!pDocView->m_pHandleStart)
                 pDocView->m_pHandleStart = cairo_image_surface_create_from_png(CURSOR_HANDLE_DIR "handle_start.png");
-            lcl_renderHandle(pCairo, &pDocView->m_aTextSelectionStart, pDocView->m_pHandleStart, NULL);
+            lcl_renderHandle(pCairo, &pDocView->m_aTextSelectionStart, pDocView->m_pHandleStart, &pDocView->m_aHandleStartRect);
         }
         if (!lcl_isEmptyRectangle(&pDocView->m_aTextSelectionEnd))
         {
commit dc5d60598adc7d80354e538d749bfce2a856643d
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Tue Feb 10 18:19:32 2015 +0100

    lokdocview: allow dragging the selection end handle
    
    Change-Id: I977e93657c52a66f10762293835ead28451b5406

diff --git a/include/LibreOfficeKit/LibreOfficeKitGtk.h b/include/LibreOfficeKit/LibreOfficeKitGtk.h
index 95288cd..40ce630 100644
--- a/include/LibreOfficeKit/LibreOfficeKitGtk.h
+++ b/include/LibreOfficeKit/LibreOfficeKitGtk.h
@@ -66,6 +66,10 @@ struct _LOKDocView
     gboolean m_bInDragMiddleHandle;
     /// Bitmap of the text selection end handle.
     cairo_surface_t* m_pHandleEnd;
+    /// Rectangle of the text selection end handle, to know if the user clicked on it or not
+    GdkRectangle m_aHandleEndRect;
+    /// If we are in the middle of a drag of the text selection end handle.
+    gboolean m_bInDragEndHandle;
 };
 
 struct _LOKDocViewClass
diff --git a/libreofficekit/source/gtk/lokdocview.c b/libreofficekit/source/gtk/lokdocview.c
index 0fa3e11..c18ccc0 100644
--- a/libreofficekit/source/gtk/lokdocview.c
+++ b/libreofficekit/source/gtk/lokdocview.c
@@ -42,28 +42,49 @@ void lcl_onDestroy( LOKDocView* pDocView, gpointer pData )
     pDocView->pDocument = NULL;
 }
 
+/**
+ * The user drags the handle, which is below the cursor, but wants to move the
+ * cursor accordingly.
+ *
+ * @param pHandle the rectangle of the handle
+ * @param pEvent the motion event
+ * @param pPoint the computed point (output parameter)
+ */
+void lcl_getDragPoint(GdkRectangle* pHandle, GdkEventButton* pEvent, GdkPoint* pPoint)
+{
+    GdkPoint aCursor, aHandle;
+
+    // Center of the cursor rectangle: we know that it's above the handle.
+    aCursor.x = pHandle->x + pHandle->width / 2;
+    aCursor.y = pHandle->y - pHandle->height / 2;
+    // Center of the handle rectangle.
+    aHandle.x = pHandle->x + pHandle->width / 2;
+    aHandle.y = pHandle->y + pHandle->height / 2;
+    // Our target is the original cursor position + the dragged offset.
+    pPoint->x = aCursor.x + (pEvent->x - aHandle.x);
+    pPoint->y = aCursor.y + (pEvent->y - aHandle.y);
+}
+
 gboolean lcl_signalMotion(GtkWidget* pEventBox, GdkEventButton* pEvent, LOKDocView* pDocView)
 {
     (void)pEventBox;
     if (pDocView->m_bInDragMiddleHandle)
     {
-        // The user drags the handle, which is below the cursor, but wants to move the cursor accordingly.
-        GdkPoint aCursor, aHandle, aPoint;
+        GdkPoint aPoint;
 
         g_info("lcl_signalMotion: dragging the middle handle");
-        // Center of the cursor rectangle: we know that it's above the handle.
-        aCursor.x = pDocView->m_aHandleMiddleRect.x + pDocView->m_aHandleMiddleRect.width / 2;
-        aCursor.y = pDocView->m_aHandleMiddleRect.y - pDocView->m_aHandleMiddleRect.height / 2;
-        // Center of the handle rectangle.
-        aHandle.x = pDocView->m_aHandleMiddleRect.x + pDocView->m_aHandleMiddleRect.width / 2;
-        aHandle.y = pDocView->m_aHandleMiddleRect.y + pDocView->m_aHandleMiddleRect.height / 2;
-        // Our target is the original cursor position + the dragged offset.
-        aPoint.x = aCursor.x + (pEvent->x - aHandle.x);
-        aPoint.y = aCursor.y + (pEvent->y - aHandle.y);
-
+        lcl_getDragPoint(&pDocView->m_aHandleMiddleRect, pEvent, &aPoint);
         pDocView->pDocument->pClass->postMouseEvent(pDocView->pDocument, LOK_MOUSEEVENT_MOUSEBUTTONDOWN, pixelToTwip(aPoint.x), pixelToTwip(aPoint.y), 1);
         pDocView->pDocument->pClass->postMouseEvent(pDocView->pDocument, LOK_MOUSEEVENT_MOUSEBUTTONUP, pixelToTwip(aPoint.x), pixelToTwip(aPoint.y), 1);
     }
+    else if (pDocView->m_bInDragEndHandle)
+    {
+        GdkPoint aPoint;
+
+        g_info("lcl_signalMotion: dragging the end handle");
+        lcl_getDragPoint(&pDocView->m_aHandleEndRect, pEvent, &aPoint);
+        pDocView->pDocument->pClass->setTextSelection(pDocView->pDocument, LOK_SETTEXTSELECTION_END, pixelToTwip(aPoint.x), pixelToTwip(aPoint.y));
+    }
     return FALSE;
 }
 
@@ -79,6 +100,12 @@ gboolean lcl_signalButton(GtkWidget* pEventBox, GdkEventButton* pEvent, LOKDocVi
         pDocView->m_bInDragMiddleHandle = FALSE;
         return FALSE;
     }
+    else if (pDocView->m_bInDragEndHandle && pEvent->type == GDK_BUTTON_RELEASE)
+    {
+        g_info("lcl_signalButton: end of drag end handle");
+        pDocView->m_bInDragEndHandle = FALSE;
+        return FALSE;
+    }
 
     if (pDocView->m_bEdit)
     {
@@ -93,6 +120,12 @@ gboolean lcl_signalButton(GtkWidget* pEventBox, GdkEventButton* pEvent, LOKDocVi
             pDocView->m_bInDragMiddleHandle = TRUE;
             return FALSE;
         }
+        else if (gdk_rectangle_intersect(&aClick, &pDocView->m_aHandleEndRect, NULL) && pEvent->type == GDK_BUTTON_PRESS)
+        {
+            g_info("lcl_signalButton: start of drag end handle");
+            pDocView->m_bInDragEndHandle = TRUE;
+            return FALSE;
+        }
     }
 
     lok_docview_set_edit(pDocView, TRUE);
@@ -191,6 +224,8 @@ static void lok_docview_init( LOKDocView* pDocView )
     pDocView->m_pHandleEnd = NULL;
     memset(&pDocView->m_aHandleMiddleRect, 0, sizeof(pDocView->m_aHandleMiddleRect));
     pDocView->m_bInDragMiddleHandle = FALSE;
+    memset(&pDocView->m_aHandleEndRect, 0, sizeof(pDocView->m_aHandleEndRect));
+    pDocView->m_bInDragEndHandle = FALSE;
 
     gtk_signal_connect( GTK_OBJECT(pDocView), "destroy",
                         GTK_SIGNAL_FUNC(lcl_onDestroy), NULL );
@@ -332,7 +367,7 @@ static gboolean renderOverlay(GtkWidget* pWidget, GdkEventExpose* pEvent, gpoint
             // Have a start position: we need an end handle.
             if (!pDocView->m_pHandleEnd)
                 pDocView->m_pHandleEnd = cairo_image_surface_create_from_png(CURSOR_HANDLE_DIR "handle_end.png");
-            lcl_renderHandle(pCairo, &pDocView->m_aTextSelectionEnd, pDocView->m_pHandleEnd, NULL);
+            lcl_renderHandle(pCairo, &pDocView->m_aTextSelectionEnd, pDocView->m_pHandleEnd, &pDocView->m_aHandleEndRect);
         }
     }
 
commit e4b6ffe5136b5aa9da7ff7dbb65ef36914c3ee17
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Tue Feb 10 17:43:18 2015 +0100

    LOK: add lok::Document::setTextSelection()
    
    What's interesting about this is that it allows adjusting the position
    of both the point and mark of the selection, while the normal UI only
    allows adjusting the point.
    
    Change-Id: If61f57c68c28c67fec252f2b666a706f52dd8d26

diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index 7577e3a..ffb00f8 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -207,6 +207,10 @@ static void doc_postMouseEvent (LibreOfficeKitDocument* pThis,
                                 int nX,
                                 int nY,
                                 int nCount);
+static void doc_setTextSelection (LibreOfficeKitDocument* pThis,
+                                  int nType,
+                                  int nX,
+                                  int nY);
 
 struct LibLODocument_Impl : public _LibreOfficeKitDocument
 {
@@ -235,6 +239,7 @@ struct LibLODocument_Impl : public _LibreOfficeKitDocument
             m_pDocumentClass->initializeForRendering = doc_initializeForRendering;
             m_pDocumentClass->registerCallback = doc_registerCallback;
             m_pDocumentClass->postMouseEvent = doc_postMouseEvent;
+            m_pDocumentClass->setTextSelection = doc_setTextSelection;
 
             gDocumentClass = m_pDocumentClass;
         }
@@ -672,6 +677,17 @@ static void doc_postMouseEvent(LibreOfficeKitDocument* pThis, int nType, int nX,
     pDoc->postMouseEvent(nType, nX, nY, nCount);
 }
 
+static void doc_setTextSelection(LibreOfficeKitDocument* pThis, int nType, int nX, int nY)
+{
+    ITiledRenderable* pDoc = getTiledRenderable(pThis);
+    if (!pDoc)
+    {
+        gImpl->maLastExceptionMsg = "Document doesn't support tiled rendering";
+        return;
+    }
+
+    pDoc->setTextSelection(nType, nX, nY);
+}
 
 static char* lo_getError (LibreOfficeKit *pThis)
 {
diff --git a/include/LibreOfficeKit/LibreOfficeKit.h b/include/LibreOfficeKit/LibreOfficeKit.h
index 2044795..eccf19b 100644
--- a/include/LibreOfficeKit/LibreOfficeKit.h
+++ b/include/LibreOfficeKit/LibreOfficeKit.h
@@ -117,6 +117,15 @@ typedef enum
 }
 LibreOfficeKitMouseEventType;
 
+typedef enum
+{
+    /// The start of selection is to be adjusted.
+    LOK_SETTEXTSELECTION_START,
+    /// The end of selection is to be adjusted.
+    LOK_SETTEXTSELECTION_END
+}
+LibreOfficeKitSetTextSelectionType;
+
 typedef void (*LibreOfficeKitCallback)(int nType, const char* pPayload, void* pData);
 #endif // LOK_USE_UNSTABLE_API
 
@@ -204,6 +213,11 @@ struct _LibreOfficeKitDocumentClass
                          int nX,
                          int nY,
                          int nCount);
+  /// @see lok::Document::setTextSelection
+  void (*setTextSelection)(LibreOfficeKitDocument* pThis,
+                         int nType,
+                         int nX,
+                         int nY);
 #endif // LOK_USE_UNSTABLE_API
 };
 
diff --git a/include/LibreOfficeKit/LibreOfficeKit.hxx b/include/LibreOfficeKit/LibreOfficeKit.hxx
index 8448fcd..ef365ce 100644
--- a/include/LibreOfficeKit/LibreOfficeKit.hxx
+++ b/include/LibreOfficeKit/LibreOfficeKit.hxx
@@ -117,6 +117,18 @@ public:
     {
         mpDoc->pClass->postMouseEvent(mpDoc, nType, nX, nY, nCount);
     }
+
+    /**
+     * Sets the start or end of a text selection.
+     *
+     * @param nType @see LibreOfficeKitSetTextSelectionType
+     * @param nX horizontal position in document coordinates
+     * @param nY vertical position in document coordinates
+     */
+    inline void setTextSelection(int nType, int nX, int nY)
+    {
+        mpDoc->pClass->setTextSelection(mpDoc, nType, nX, nY);
+    }
 #endif // LOK_USE_UNSTABLE_API
 };
 
diff --git a/include/vcl/ITiledRenderable.hxx b/include/vcl/ITiledRenderable.hxx
index 9edd7a1..d5b3e80 100644
--- a/include/vcl/ITiledRenderable.hxx
+++ b/include/vcl/ITiledRenderable.hxx
@@ -107,6 +107,13 @@ public:
      * @see lok::Document::postMouseEvent().
      */
     virtual void postMouseEvent(int /*nType*/, int /*nX*/, int /*nY*/, int /*nCount*/) { }
+
+    /**
+     * Sets the start or end of a text selection.
+     *
+     * @see lok::Document::setTextSelection().
+     */
+    virtual void setTextSelection(int /*nType*/, int /*nX*/, int /*nY*/) { }
 };
 
 } // namespace vcl
diff --git a/sw/inc/unotxdoc.hxx b/sw/inc/unotxdoc.hxx
index 894a127..6ffa02f 100644
--- a/sw/inc/unotxdoc.hxx
+++ b/sw/inc/unotxdoc.hxx
@@ -415,6 +415,8 @@ public:
     virtual void registerCallback(LibreOfficeKitCallback pCallback, void* pData) SAL_OVERRIDE;
     /// @see vcl::ITiledRenderable::postMouseEvent().
     virtual void postMouseEvent(int nType, int nX, int nY, int nCount) SAL_OVERRIDE;
+    /// @see vcl::ITiledRenderable::setTextSelection().
+    virtual void setTextSelection(int nType, int nX, int nY) SAL_OVERRIDE;
 
     void                        Invalidate();
     void                        Reactivate(SwDocShell* pNewDocShell);
diff --git a/sw/source/uibase/docvw/edtwin.cxx b/sw/source/uibase/docvw/edtwin.cxx
index 6666249..bb59217 100644
--- a/sw/source/uibase/docvw/edtwin.cxx
+++ b/sw/source/uibase/docvw/edtwin.cxx
@@ -6256,4 +6256,18 @@ void SwEditWin::LogicMouseButtonUp(const MouseEvent& rMouseEvent)
     MouseButtonUp(rMouseEvent);
 }
 
+void SwEditWin::SetCursorLogicPosition(bool bPoint, const Point& rPosition)
+{
+    // Not an SwWrtShell, as that would make SwCrsrShell::GetCrsr() inaccessible.
+    SwEditShell& rShell = m_rView.GetWrtShell();
+    SwMvContext aMvContext(&rShell);
+    // If the mark is to be updated, then exchange the point and mark before
+    // and after, as we can't easily set the mark.
+    if (!bPoint)
+        rShell.GetCrsr()->Exchange();
+    rShell.SetCrsr(rPosition);
+    if (!bPoint)
+        rShell.GetCrsr()->Exchange();
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/inc/edtwin.hxx b/sw/source/uibase/inc/edtwin.hxx
index 5557321..9af9446 100644
--- a/sw/source/uibase/inc/edtwin.hxx
+++ b/sw/source/uibase/inc/edtwin.hxx
@@ -305,6 +305,8 @@ public:
     void LogicMouseButtonDown(const MouseEvent& rMouseEvent);
     /// Same as MouseButtonUp(), but coordinates are in logic unit.
     void LogicMouseButtonUp(const MouseEvent& rMouseEvent);
+    /// Allows adjusting the point or mark of the selection to a document coordinate.
+    void SetCursorLogicPosition(bool bPoint, const Point& rPosition);
 };
 
 #endif
diff --git a/sw/source/uibase/uno/unotxdoc.cxx b/sw/source/uibase/uno/unotxdoc.cxx
index 70abbac..3a98cd9 100644
--- a/sw/source/uibase/uno/unotxdoc.cxx
+++ b/sw/source/uibase/uno/unotxdoc.cxx
@@ -3194,6 +3194,25 @@ void SwXTextDocument::postMouseEvent(int nType, int nX, int nY, int nCount)
     }
 }
 
+void SwXTextDocument::setTextSelection(int nType, int nX, int nY)
+{
+    SolarMutexGuard aGuard;
+
+    SwEditWin& rEditWin = pDocShell->GetView()->GetEditWin();
+    switch (nType)
+    {
+    case LOK_SETTEXTSELECTION_START:
+        rEditWin.SetCursorLogicPosition(/*bPoint=*/false, Point(nX, nY));
+        break;
+    case LOK_SETTEXTSELECTION_END:
+        rEditWin.SetCursorLogicPosition(/*bPoint=*/true, Point(nX, nY));
+        break;
+    default:
+        assert(false);
+        break;
+    }
+}
+
 void * SAL_CALL SwXTextDocument::operator new( size_t t) throw()
 {
     return SwXTextDocumentBaseClass::operator new(t);


More information about the Libreoffice-commits mailing list