diff options
author | Miklos Vajna <vmiklos@collabora.com> | 2023-03-24 08:15:59 +0100 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.com> | 2023-03-24 08:34:20 +0000 |
commit | 3c3a47e911a7ee4d199fe96bd3003c7d9afa9deb (patch) | |
tree | 7ff3017d714cda14d735afa84b87f7400f4f5d53 /sw | |
parent | fa5c01e67775c01b302fc08033a0eb78d3b87489 (diff) |
sw floattable: fix up/down cursor travel at fly boundary
Pressing the "down" key in the middle of the last line of the A1 cell on
page 1 went to the end of the paragraph instead of going to the A2 cell
on page 2.
The problem was that fly frames don't have a "next" pointer to the
follow fly frame, so the cursor travel code thought there is no follow
frame to jump to.
Fix the problem similar to how explicitly chained frames do this in
lcl_FindLayoutFrame().
While at it, also fix the the "up" direction.
Change-Id: I8dd0c2d011300520b126abf3ca8d17722ab5ff92
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/149476
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
Tested-by: Jenkins
Diffstat (limited to 'sw')
-rw-r--r-- | sw/qa/core/layout/flycnt.cxx | 55 | ||||
-rw-r--r-- | sw/source/core/layout/findfrm.cxx | 15 |
2 files changed, 69 insertions, 1 deletions
diff --git a/sw/qa/core/layout/flycnt.cxx b/sw/qa/core/layout/flycnt.cxx index b9ab0ac116cb..daa9764325f5 100644 --- a/sw/qa/core/layout/flycnt.cxx +++ b/sw/qa/core/layout/flycnt.cxx @@ -25,6 +25,7 @@ #include <frmmgr.hxx> #include <frameformats.hxx> #include <cellfrm.hxx> +#include <ndtxt.hxx> namespace { @@ -543,6 +544,60 @@ CPPUNIT_TEST_FIXTURE(Test, testSplitFlyFollowHorizontalPosition) // master fly. CPPUNIT_ASSERT_EQUAL(nPage1FlyLeft, nPage2FlyLeft); } + +CPPUNIT_TEST_FIXTURE(Test, testCursorTraversal) +{ + // Given a document with a multi-page floating table: + createSwDoc(); + SwDoc* pDoc = getSwDoc(); + SwPageDesc aStandard(pDoc->GetPageDesc(0)); + SwFormatFrameSize aPageSize(aStandard.GetMaster().GetFrameSize()); + // 5cm for the page height, 2cm are the top and bottom margins, so 1cm remains for the body + // frame: + aPageSize.SetHeight(2834); + aStandard.GetMaster().SetFormatAttr(aPageSize); + pDoc->ChgPageDesc(0, aStandard); + // Insert a table: + SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell(); + SwInsertTableOptions aTableOptions(SwInsertTableFlags::DefaultBorder, 0); + pWrtShell->InsertTable(aTableOptions, /*nRows=*/2, /*nCols=*/1); + pWrtShell->MoveTable(GotoPrevTable, fnTableStart); + pWrtShell->GoPrevCell(); + pWrtShell->Insert("A1"); + pWrtShell->GoNextCell(); + pWrtShell->Insert("A2"); + // Select cell: + pWrtShell->SelAll(); + // Select table: + pWrtShell->SelAll(); + // Wrap the table in a text frame: + SwFlyFrameAttrMgr aMgr(true, pWrtShell, Frmmgr_Type::TEXT, nullptr); + pWrtShell->StartAllAction(); + aMgr.InsertFlyFrame(RndStdIds::FLY_AT_PARA, aMgr.GetPos(), aMgr.GetSize()); + pWrtShell->EndAllAction(); + // Allow the text frame to split: + pWrtShell->StartAllAction(); + SwFrameFormats& rFlys = *pDoc->GetSpzFrameFormats(); + SwFrameFormat* pFly = rFlys[0]; + SwAttrSet aSet(pFly->GetAttrSet()); + aSet.Put(SwFormatFlySplit(true)); + pDoc->SetAttr(aSet, *pFly); + pWrtShell->EndAllAction(); + + // When going from A1 to A2: + pWrtShell->GotoTable("Table1"); + SwTextNode* pTextNode = pWrtShell->GetCursor()->GetPointNode().GetTextNode(); + CPPUNIT_ASSERT_EQUAL(OUString("A1"), pTextNode->GetText()); + pWrtShell->Down(/*bSelect=*/false); + + // Then make sure we get to A2 and don't stay in A1: + pTextNode = pWrtShell->GetCursor()->GetPointNode().GetTextNode(); + // Without the accompanying fix in place, this test would have failed with: + // - Expected: A2 + // - Actual : A1 + // i.e. the cursor didn't get from A1 to A2. + CPPUNIT_ASSERT_EQUAL(OUString("A2"), pTextNode->GetText()); +} } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/core/layout/findfrm.cxx b/sw/source/core/layout/findfrm.cxx index 0e425e0a1eb5..3e2c26a8bbf9 100644 --- a/sw/source/core/layout/findfrm.cxx +++ b/sw/source/core/layout/findfrm.cxx @@ -41,6 +41,7 @@ #include <sal/log.hxx> #include <IDocumentSettingAccess.hxx> #include <formatflysplit.hxx> +#include <flyfrms.hxx> /// Searches the first ContentFrame in BodyText below the page. @@ -308,7 +309,19 @@ static const SwFrame* lcl_FindLayoutFrame( const SwFrame* pFrame, bool bNext ) { const SwFrame* pRet = nullptr; if ( pFrame->IsFlyFrame() ) - pRet = bNext ? static_cast<const SwFlyFrame*>(pFrame)->GetNextLink() : static_cast<const SwFlyFrame*>(pFrame)->GetPrevLink(); + { + auto pFlyFrame = static_cast<const SwFlyFrame*>(pFrame); + if (pFlyFrame->IsFlySplitAllowed()) + { + // This is a flow frame, look up the follow/precede. + auto pFlyAtContent = static_cast<const SwFlyAtContentFrame*>(pFlyFrame); + pRet = bNext ? pFlyAtContent->GetFollow() : pFlyAtContent->GetPrecede(); + } + else + { + pRet = bNext ? pFlyFrame->GetNextLink() : pFlyFrame->GetPrevLink(); + } + } else pRet = bNext ? pFrame->GetNext() : pFrame->GetPrev(); |