sw/qa/core/layout/data/floattable-anchor-keep-with-next.docx |binary
 sw/qa/core/layout/flycnt.cxx                                 |   25 +++++++++++
 sw/source/core/layout/flowfrm.cxx                            |   11 ++++
 3 files changed, 36 insertions(+)

New commits:
commit 920e76f15b78398de62002e30002f4f8e0fee7c1
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Fri Jun 2 11:02:46 2023 +0200
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Fri Jun 2 12:04:48 2023 +0200

    sw floattable: ignore keep-with-next for anchors of non-last split flys
    
    The bugdoc has a floating table that could split between page 1 and page
    2, but we used to put the entire table to page 2.
    
    What happens is that the anchor of the floating table had <w:keepNext>,
    which means the layout tried to keep the paragraph on a single page, and
    also with the next paragraph (but in this case there is no next
    paragraph, it's the last one in the document).
    
    Fix the problem ignoring the "keep with next" request, in case the
    paragraph is an anchor for a split floating table; unless we're the last
    anchor in the chain.
    
    This is probably consistent with the intent that "keep with next" is
    meant to control the anchor text and not the anchored floating tables.
    
    Change-Id: I387a2db5f5db013da7055686ae6b9d032b467266
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/152525
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>
    Tested-by: Jenkins

diff --git a/sw/qa/core/layout/data/floattable-anchor-keep-with-next.docx 
b/sw/qa/core/layout/data/floattable-anchor-keep-with-next.docx
new file mode 100644
index 000000000000..a0930900d884
Binary files /dev/null and 
b/sw/qa/core/layout/data/floattable-anchor-keep-with-next.docx differ
diff --git a/sw/qa/core/layout/flycnt.cxx b/sw/qa/core/layout/flycnt.cxx
index efc29670c244..5ed28f38aa5a 100644
--- a/sw/qa/core/layout/flycnt.cxx
+++ b/sw/qa/core/layout/flycnt.cxx
@@ -921,6 +921,31 @@ CPPUNIT_TEST_FIXTURE(Test, testSplitFlyNextLeafInSection)
     // Then this never returned, the loop in SwFrame::GetNextFlyLeaf() never 
finished.
     calcLayout();
 }
+
+CPPUNIT_TEST_FIXTURE(Test, testSplitFlyAnchorKeepWithNext)
+{
+    // Given a document with 2 pages, a split floating table on both pages:
+    createSwDoc("floattable-anchor-keep-with-next.docx");
+
+    // When calculating the layout:
+    calcLayout();
+
+    // Then make sure the pages have the expected amount of anchored objects:
+    SwDoc* pDoc = getSwDoc();
+    SwRootFrame* pLayout = pDoc->getIDocumentLayoutAccess().GetCurrentLayout();
+    auto pPage1 = dynamic_cast<SwPageFrame*>(pLayout->Lower());
+    CPPUNIT_ASSERT(pPage1);
+    // Without the accompanying fix in place, this test would have failed, 
page 1 had no floating
+    // table, it was entirely on page 2.
+    CPPUNIT_ASSERT(pPage1->GetSortedObjs());
+    const SwSortedObjs& rPage1Objs = *pPage1->GetSortedObjs();
+    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), rPage1Objs.size());
+    auto pPage2 = dynamic_cast<SwPageFrame*>(pPage1->GetNext());
+    CPPUNIT_ASSERT(pPage2);
+    CPPUNIT_ASSERT(pPage2->GetSortedObjs());
+    const SwSortedObjs& rPage2Objs = *pPage2->GetSortedObjs();
+    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), rPage2Objs.size());
+}
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/layout/flowfrm.cxx 
b/sw/source/core/layout/flowfrm.cxx
index cb47267f1195..41b6b8fff953 100644
--- a/sw/source/core/layout/flowfrm.cxx
+++ b/sw/source/core/layout/flowfrm.cxx
@@ -248,6 +248,17 @@ bool SwFlowFrame::IsKeep(SvxFormatKeepItem const& rKeep,
                     ( !m_rThis.IsInTab() || m_rThis.IsTabFrame() ) &&
                     rKeep.GetValue() && !IsNextContentFullPage(m_rThis));
 
+    if (bKeep && m_rThis.IsTextFrame())
+    {
+        auto& rTextFrame = static_cast<SwTextFrame&>(m_rThis);
+        if (rTextFrame.HasNonLastSplitFlyDrawObj())
+        {
+            // Allow split for the non-last anchors of a split fly, even if 
rKeep.GetValue() is
+            // true.
+            bKeep = false;
+        }
+    }
+
     OSL_ENSURE( !bCheckIfLastRowShouldKeep || m_rThis.IsTabFrame(),
             "IsKeep with bCheckIfLastRowShouldKeep should only be used for 
tabfrms" );
 

Reply via email to