sw/qa/core/layout/data/floattable-footer.docx |binary
 sw/qa/core/layout/flycnt.cxx                  |   29 ++++++++++++++++++++++++++
 sw/source/core/layout/flycnt.cxx              |   22 ++++++++++---------
 3 files changed, 41 insertions(+), 10 deletions(-)

New commits:
commit 34794e122fb4570376e712a7a356fc41620a46c7
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Thu Mar 2 08:10:02 2023 +0100
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Thu Mar 2 08:08:01 2023 +0000

    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 <vmik...@collabora.com>
    Tested-by: Jenkins

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
Binary files /dev/null and b/sw/qa/core/layout/data/floattable-footer.docx 
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.

Reply via email to