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

Reply via email to