diff options
author | Miklos Vajna <vmiklos@collabora.com> | 2023-03-02 08:10:02 +0100 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.com> | 2023-03-02 08:08:01 +0000 |
commit | 34794e122fb4570376e712a7a356fc41620a46c7 (patch) | |
tree | 55427225bb116c8bb18c4ccf325da8536df530a9 | |
parent | 53ad80f72fb1067b975be5ff597f869f05ac97f6 (diff) |
sw floattable: don't leave body in SwFrame::GetNextFlyLeaf()
- assert IsFlySplitAllowed() in SwFrame::GetNextFlyLeaf(), since the
only caller is SwFrame::GetLeaf(), and it only checks this
- extend the conditions where we reject a candidate, make sure that a
master fly anchored in the body can't have a follow fly anchored in a
footer
- with this, the bugdoc is now of 2 pages, but still the position of the
follow is incorrect
Change-Id: Ibb02fe9cf741eecd60103179abcb44cee14e924d
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/148082
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
Tested-by: Jenkins
-rw-r--r-- | sw/qa/core/layout/data/floattable-footer.docx | bin | 0 -> 31684 bytes | |||
-rw-r--r-- | sw/qa/core/layout/flycnt.cxx | 29 | ||||
-rw-r--r-- | sw/source/core/layout/flycnt.cxx | 22 |
3 files changed, 41 insertions, 10 deletions
diff --git a/sw/qa/core/layout/data/floattable-footer.docx b/sw/qa/core/layout/data/floattable-footer.docx Binary files differnew file mode 100644 index 000000000000..52cc73b17dfb --- /dev/null +++ b/sw/qa/core/layout/data/floattable-footer.docx diff --git a/sw/qa/core/layout/flycnt.cxx b/sw/qa/core/layout/flycnt.cxx index 12ec5785b4f3..10a84856da0a 100644 --- a/sw/qa/core/layout/flycnt.cxx +++ b/sw/qa/core/layout/flycnt.cxx @@ -312,6 +312,35 @@ CPPUNIT_TEST_FIXTURE(Test, testSplitFlyEnable) // Without the accompanying fix in place, this test would have failed, there was no 2nd page. CPPUNIT_ASSERT(pPage2); } + +CPPUNIT_TEST_FIXTURE(Test, testSplitFlyFooter) +{ + // Given a document with a floattable, table split on 2 pages with headers/footers: + std::shared_ptr<comphelper::ConfigurationChanges> pChanges( + comphelper::ConfigurationChanges::create()); + officecfg::Office::Writer::Filter::Import::DOCX::ImportFloatingTableAsSplitFly::set(true, + pChanges); + pChanges->commit(); + comphelper::ScopeGuard g([pChanges] { + officecfg::Office::Writer::Filter::Import::DOCX::ImportFloatingTableAsSplitFly::set( + false, pChanges); + pChanges->commit(); + }); + createSwDoc("floattable-footer.docx"); + + // When laying out that document: + calcLayout(); + + // Then make sure that the table is split to 2 pages: + SwDoc* pDoc = getSwDoc(); + SwRootFrame* pLayout = pDoc->getIDocumentLayoutAccess().GetCurrentLayout(); + auto pPage1 = dynamic_cast<SwPageFrame*>(pLayout->Lower()); + CPPUNIT_ASSERT(pPage1); + // Second page: + auto pPage2 = dynamic_cast<SwPageFrame*>(pPage1->GetNext()); + // Without the accompanying fix in place, this test would have failed, there was no 2nd page. + CPPUNIT_ASSERT(pPage2); +} } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/core/layout/flycnt.cxx b/sw/source/core/layout/flycnt.cxx index f96669c537d0..2a979563d7ba 100644 --- a/sw/source/core/layout/flycnt.cxx +++ b/sw/source/core/layout/flycnt.cxx @@ -1551,7 +1551,10 @@ SwLayoutFrame *SwFrame::GetNextFlyLeaf( MakePageType eMakePage ) { auto pFly = dynamic_cast<SwFlyAtContentFrame*>(FindFlyFrame()); assert(pFly && "GetNextFlyLeaf: missing fly frame"); + assert(pFly->IsFlySplitAllowed() && "GetNextFlyLeaf: fly split not allowed"); + SwTextFrame* pFlyAnchor = pFly->FindAnchorCharFrame(); + bool bBody = pFlyAnchor && pFlyAnchor->IsInDocBody(); SwLayoutFrame *pLayLeaf = nullptr; // Look up the first candidate. if (IsTabFrame()) @@ -1570,16 +1573,16 @@ SwLayoutFrame *SwFrame::GetNextFlyLeaf( MakePageType eMakePage ) { if (pLayLeaf) { - // If we have a candidate, make sure that it's a child of our follow. - if (pFly->IsFlySplitAllowed()) + // If we're anchored in a body frame, the candidate has to be in a body frame as well. + bool bLeftBody = bBody && !pLayLeaf->IsInDocBody(); + // If the candiate is in a fly, make sure that the candidate is a child of our follow. + bool bLeftFly = pLayLeaf->IsInFly() && pLayLeaf->FindFlyFrame() != pFly->GetFollow(); + if (bLeftBody || bLeftFly) { - if (pFly->GetFollow() != pLayLeaf->FindFlyFrame()) - { - // It's not in our follow, reject. - pOldLayLeaf = pLayLeaf; - pLayLeaf = pLayLeaf->GetNextLayoutLeaf(); - continue; - } + // The above conditions are not held, reject. + pOldLayLeaf = pLayLeaf; + pLayLeaf = pLayLeaf->GetNextLayoutLeaf(); + continue; } } else @@ -1601,7 +1604,6 @@ SwLayoutFrame *SwFrame::GetNextFlyLeaf( MakePageType eMakePage ) { SwFlyAtContentFrame* pNew = nullptr; // Find the anchor frame to split. - SwTextFrame* pFlyAnchor = pFly->FindAnchorCharFrame(); if (pFlyAnchor) { // Split the anchor at char 0: all the content goes to the follow of the anchor. |