[Libreoffice-commits] core.git: sw/qa sw/source

Miklos Vajna (via logerrit) logerrit at kemper.freedesktop.org
Thu Aug 1 16:38:13 UTC 2019


 sw/qa/extras/layout/data/image-comment.odt |binary
 sw/qa/extras/layout/layout.cxx             |   40 +++++++++++++++++++++++++++++
 sw/source/core/text/itrcrsr.cxx            |   30 +++++++++++++++++++++
 3 files changed, 69 insertions(+), 1 deletion(-)

New commits:
commit 27c46ecf34b32bae1806d3fc0e1684179301feb8
Author:     Miklos Vajna <vmiklos at collabora.com>
AuthorDate: Thu Aug 1 15:31:10 2019 +0200
Commit:     Miklos Vajna <vmiklos at collabora.com>
CommitDate: Thu Aug 1 18:37:25 2019 +0200

    sw comments on frames: improve doc coordinates -> doc model pos conversion
    
    In case an as-char image at the end of a paragraph was commented and the
    user clicked past the end of the paragraph, we defaulted to extending
    that comment, rather appending content. (The cursor was placed between
    the as-char image and the comment anchor, not past the comment anchor.)
    
    This doesn't seem to be useful, probably the expectation is that if the
    user clicks before the comment anchor then we extend the comment range,
    and if the click is after the comment anchor, then we don't. In both
    cases we used to *select* the comment anchor, so typing a character
    deleted the comment instead.
    
    This commit is a step in the direction of never selecting the comment
    anchor: now if you click past the comment anchor, then we place the
    cursor after the comment anchor.
    
    (But clicking before the comment anchor results in unchanged behavior
    for now.)
    
    Change-Id: I6c36ec4344591fdf330a73bcd3cdd6fd0610e339
    Reviewed-on: https://gerrit.libreoffice.org/76803
    Reviewed-by: Miklos Vajna <vmiklos at collabora.com>
    Tested-by: Jenkins

diff --git a/sw/qa/extras/layout/data/image-comment.odt b/sw/qa/extras/layout/data/image-comment.odt
new file mode 100644
index 000000000000..d861d3a9aa03
Binary files /dev/null and b/sw/qa/extras/layout/data/image-comment.odt differ
diff --git a/sw/qa/extras/layout/layout.cxx b/sw/qa/extras/layout/layout.cxx
index 2f69230849e1..1de7bba9d926 100644
--- a/sw/qa/extras/layout/layout.cxx
+++ b/sw/qa/extras/layout/layout.cxx
@@ -25,6 +25,11 @@
 #include <edtwin.hxx>
 #include <view.hxx>
 #include <txtfrm.hxx>
+#include <pagefrm.hxx>
+#include <bodyfrm.hxx>
+#include <sortedobjs.hxx>
+#include <anchoredobject.hxx>
+#include <ndtxt.hxx>
 
 static char const DATA_DIRECTORY[] = "/sw/qa/extras/layout/data/";
 
@@ -2978,6 +2983,41 @@ CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testTabOverMargin)
     assertXPath(pXmlDoc, "/root/page/body/txt[2]/LineBreak", 1);
 }
 
+CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testImageComment)
+{
+    // Load a document that has "aaa" in it, then a commented image (4th char is the as-char image,
+    // 5th char is the comment anchor).
+    SwDoc* pDoc = createDoc("image-comment.odt");
+    SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
+
+    // Look up a layout position which is on the right of the image.
+    SwRootFrame* pRoot = pWrtShell->GetLayout();
+    CPPUNIT_ASSERT(pRoot->GetLower()->IsPageFrame());
+    SwPageFrame* pPage = static_cast<SwPageFrame*>(pRoot->GetLower());
+    CPPUNIT_ASSERT(pPage->GetLower()->IsBodyFrame());
+    SwBodyFrame* pBody = static_cast<SwBodyFrame*>(pPage->GetLower());
+    CPPUNIT_ASSERT(pBody->GetLower()->IsTextFrame());
+    SwTextFrame* pTextFrame = static_cast<SwTextFrame*>(pBody->GetLower());
+    CPPUNIT_ASSERT(pTextFrame->GetDrawObjs());
+    SwSortedObjs& rDrawObjs = *pTextFrame->GetDrawObjs();
+    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), rDrawObjs.size());
+    SwAnchoredObject* pDrawObj = rDrawObjs[0];
+    const SwRect& rDrawObjRect = pDrawObj->GetObjRect();
+    Point aPoint = rDrawObjRect.Center();
+    aPoint.setX(aPoint.getX() + rDrawObjRect.Width() / 2);
+
+    // Ask for the doc model pos of this layout point.
+    SwPosition aPosition(*pTextFrame->GetTextNodeForFirstText());
+    pTextFrame->GetCursorOfst(&aPosition, aPoint);
+
+    // Without the accompanying fix in place, this test would have failed with:
+    // - Expected: 5
+    // - Actual  : 4
+    // i.e. the cursor got positioned between the image and its comment, so typing extended the
+    // comment, instead of adding content after the commented image.
+    CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(5), aPosition.nContent.GetIndex());
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/text/itrcrsr.cxx b/sw/source/core/text/itrcrsr.cxx
index 84effe8b49c1..cc5b21cd0b0e 100644
--- a/sw/source/core/text/itrcrsr.cxx
+++ b/sw/source/core/text/itrcrsr.cxx
@@ -1254,6 +1254,27 @@ void SwTextCursor::GetCharRect( SwRect* pOrig, TextFrameIndex const nOfst,
     }
 }
 
+/**
+ * Determines if SwTextCursor::GetCursorOfst() should consider the next portion when calculating the
+ * doc model position from a Point.
+ */
+static bool ConsiderNextPortionForCursorOffset(SwLinePortion* pPor, sal_uInt16 nWidth30, sal_uInt16 nX)
+{
+    if (!pPor->GetNextPortion())
+    {
+        return false;
+    }
+
+    // If we're poast the target position, stop the iteration in general.
+    // Exception: don't stop the iteration between as-char fly portions and their comments.
+    if (nWidth30 >= nX && (!pPor->IsFlyCntPortion() || !pPor->GetNextPortion()->IsPostItsPortion()))
+    {
+        return false;
+    }
+
+    return !pPor->IsBreakPortion();
+}
+
 // Return: Offset in String
 TextFrameIndex SwTextCursor::GetCursorOfst( SwPosition *pPos, const Point &rPoint,
                                     bool bChgNode, SwCursorMoveState* pCMS ) const
@@ -1341,7 +1362,7 @@ TextFrameIndex SwTextCursor::GetCursorOfst( SwPosition *pPos, const Point &rPoin
                      30 :
                      nWidth;
 
-    while( pPor->GetNextPortion() && nWidth30 < nX && !pPor->IsBreakPortion() )
+    while (ConsiderNextPortionForCursorOffset(pPor, nWidth30, nX))
     {
         nX = nX - nWidth;
         nCurrStart = nCurrStart + pPor->GetLen();
@@ -1512,7 +1533,14 @@ TextFrameIndex SwTextCursor::GetCursorOfst( SwPosition *pPos, const Point &rPoin
         {
             if ( pPor->IsPostItsPortion() || pPor->IsBreakPortion() ||
                  pPor->InToxRefGrp() )
+            {
+                if (pPor->IsPostItsPortion())
+                {
+                    // Offset would be nCurrStart + nLength below, do the same for post-it portions.
+                    nCurrStart += pPor->GetLen();
+                }
                 return nCurrStart;
+            }
             if ( pPor->InFieldGrp() )
             {
                 if( bRightOver && !static_cast<SwFieldPortion*>(pPor)->HasFollow() )


More information about the Libreoffice-commits mailing list