sw/qa/core/layout/flycnt.cxx      |   55 ++++++++++++++++++++++++++++++++++++++
 sw/source/core/layout/findfrm.cxx |   15 +++++++++-
 2 files changed, 69 insertions(+), 1 deletion(-)

New commits:
commit 3c3a47e911a7ee4d199fe96bd3003c7d9afa9deb
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Fri Mar 24 08:15:59 2023 +0100
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Fri Mar 24 08:34:20 2023 +0000

    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 <vmik...@collabora.com>
    Tested-by: Jenkins

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

Reply via email to