summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.com>2023-03-02 08:10:02 +0100
committerMiklos Vajna <vmiklos@collabora.com>2023-03-02 08:08:01 +0000
commit34794e122fb4570376e712a7a356fc41620a46c7 (patch)
tree55427225bb116c8bb18c4ccf325da8536df530a9
parent53ad80f72fb1067b975be5ff597f869f05ac97f6 (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.docxbin0 -> 31684 bytes
-rw-r--r--sw/qa/core/layout/flycnt.cxx29
-rw-r--r--sw/source/core/layout/flycnt.cxx22
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
new file mode 100644
index 000000000000..52cc73b17dfb
--- /dev/null
+++ b/sw/qa/core/layout/data/floattable-footer.docx
Binary files differ
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.