sw/qa/core/text/data/floattable-heading-split-footer.docx |binary sw/qa/core/text/widorp.cxx | 23 ++++++++++++++ sw/source/core/text/widorp.cxx | 8 ++++ 3 files changed, 30 insertions(+), 1 deletion(-)
New commits: commit 36a9c3dfc80e0f30ef17684cb2427daa286daf90 Author: Miklos Vajna <vmik...@collabora.com> AuthorDate: Thu Jul 17 09:39:56 2025 +0200 Commit: Xisco Fauli <xiscofa...@libreoffice.org> CommitDate: Thu Aug 7 13:55:45 2025 +0200 Related: tdf#167222 sw floattable: fix split of fly and its 'keep' anchor text Open the bugdoc, the floating table is at the bottom of page 2 in Word, but it's at the top of page 3 in Writer. This is similar to commit b8009818d619bff16d19a0f589a733f78a46ec0b (tdf#167222 sw floattable: allow split of fly and its keep-together anchor text, 2025-07-14), but here an SwTextFrameBreak instance is created, IsBreakNow() is invoked multiple times: so by the time the first IsBreakNow() runs, m_bKeep is false, but later it gets turned on. Fix the problem by adapting SwTextFrameBreak::IsBreakNow() to be consistent with its ctor, which already turns off m_bKeep for split fly anchors. This makes sense, because otherwise it can happen that first IsBreakNow() is invoked with a text frame where the format is in progress and we're not yet ready to split, but later we could split, but we don't even try due to the changed m_bKeep flag. Change-Id: I5d122e60c7693614e6e4c1b90e83f622be18fb72 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/187989 Reviewed-by: Miklos Vajna <vmik...@collabora.com> Tested-by: Jenkins Signed-off-by: Xisco Fauli <xiscofa...@libreoffice.org> Reviewed-on: https://gerrit.libreoffice.org/c/core/+/188693 diff --git a/sw/qa/core/text/data/floattable-heading-split-footer.docx b/sw/qa/core/text/data/floattable-heading-split-footer.docx new file mode 100644 index 000000000000..f8c532a03853 Binary files /dev/null and b/sw/qa/core/text/data/floattable-heading-split-footer.docx differ diff --git a/sw/qa/core/text/widorp.cxx b/sw/qa/core/text/widorp.cxx index 7dd48bc9b879..06d5939a7628 100644 --- a/sw/qa/core/text/widorp.cxx +++ b/sw/qa/core/text/widorp.cxx @@ -82,6 +82,29 @@ CPPUNIT_TEST_FIXTURE(Test, testFloattableHeadingSplit) SwTextFrame* pPage2Para1 = pBody2->ContainsContent()->DynCastTextFrame(); CPPUNIT_ASSERT_EQUAL(u"page 2"_ustr, pPage2Para1->GetText()); } + +CPPUNIT_TEST_FIXTURE(Test, testFloattableHeadingSplitFooter) +{ + // Given a document which ends with a floating table and a heading paragraph: + // When loading that document & laying it out: + createSwDoc("floattable-heading-split-footer.docx"); + + // Then make sure that the floating table is on page 2 and the last heading is on page 3: + SwDocShell* pDocShell = getSwDocShell(); + SwDoc* pDoc = pDocShell->GetDoc(); + SwRootFrame* pLayout = pDoc->getIDocumentLayoutAccess().GetCurrentLayout(); + auto pPage1 = pLayout->Lower()->DynCastPageFrame(); + auto pPage2 = pPage1->GetNext()->DynCastPageFrame(); + // Without the accompanying fix in place, this test would have failed, the floating table went + // to page 3, not to page 2. + CPPUNIT_ASSERT(pPage2->GetSortedObjs()); + // Make sure that page 3 has no floating table and has the heading on the correct page. + auto pPage3 = pPage2->GetNext()->DynCastPageFrame(); + CPPUNIT_ASSERT(!pPage3->GetSortedObjs()); + SwLayoutFrame* pBody3 = pPage3->FindBodyCont(); + SwTextFrame* pPage3Para1 = pBody3->ContainsContent()->DynCastTextFrame(); + CPPUNIT_ASSERT_EQUAL(u"page 3"_ustr, pPage3Para1->GetText()); +} } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/core/text/widorp.cxx b/sw/source/core/text/widorp.cxx index fae0ab37c314..e5b02485ca50 100644 --- a/sw/source/core/text/widorp.cxx +++ b/sw/source/core/text/widorp.cxx @@ -260,7 +260,13 @@ bool SwTextFrameBreak::IsBreakNow( SwTextMargin &rLine ) if( ( bFirstLine && m_pFrame->GetIndPrev() ) || ( rLine.GetLineNr() <= rLine.GetDropLines() ) ) { - m_bKeep = true; + bool bSplitFly = !m_bKeep && m_pFrame->HasSplitFlyDrawObjs(); + // The SwTextFrameBreak ctor already turns off m_bKeep for split fly anchors, don't + // change that decision here. + if (!bSplitFly) + { + m_bKeep = true; + } m_bBreak = false; } else if(bFirstLine && m_pFrame->IsInFootnote() && !m_pFrame->FindFootnoteFrame()->GetPrev())