sw/qa/extras/layout/data/image-comment.odt |binary sw/qa/extras/layout/layout.cxx | 42 +++++++++++++++++++++++++++++ sw/source/core/text/itrcrsr.cxx | 30 ++++++++++++++++++++ 3 files changed, 71 insertions(+), 1 deletion(-)
New commits: commit af9e212f84ba5148fac09bb44bf1ea6bb2d57983 Author: Miklos Vajna <vmik...@collabora.com> AuthorDate: Thu Aug 1 15:31:10 2019 +0200 Commit: Miklos Vajna <vmik...@collabora.com> CommitDate: Fri Aug 2 09:58:39 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.) (cherry picked from commit 27c46ecf34b32bae1806d3fc0e1684179301feb8) Conflicts: sw/qa/extras/layout/layout.cxx sw/source/core/text/itrcrsr.cxx Change-Id: I6c36ec4344591fdf330a73bcd3cdd6fd0610e339 Reviewed-on: https://gerrit.libreoffice.org/76832 Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com> Reviewed-by: Miklos Vajna <vmik...@collabora.com> 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 7090f76d5360..5548484c3874 100644 --- a/sw/qa/extras/layout/layout.cxx +++ b/sw/qa/extras/layout/layout.cxx @@ -23,6 +23,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/"; @@ -73,6 +78,7 @@ public: void testTdf118719(); void testTdf123651(); void testBtlrCell(); + void testImageComment(); CPPUNIT_TEST_SUITE(SwLayoutWriter); CPPUNIT_TEST(testRedlineFootnotes); @@ -114,6 +120,7 @@ public: CPPUNIT_TEST(testTdf118719); CPPUNIT_TEST(testTdf123651); CPPUNIT_TEST(testBtlrCell); + CPPUNIT_TEST(testImageComment); CPPUNIT_TEST_SUITE_END(); private: @@ -2907,6 +2914,41 @@ void SwLayoutWriter::testBtlrCell() #endif } +void 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_TEST_SUITE_REGISTRATION(SwLayoutWriter); CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/sw/source/core/text/itrcrsr.cxx b/sw/source/core/text/itrcrsr.cxx index 1aa6a311fc6d..7f862bd02921 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->GetPortion()) + { + 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->GetPortion()->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->GetPortion() && 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() ) _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits