Related: tdf#158986 sw floattable: fix unexpected page break with sections

Regression from commit c303981cfd95ce1c3881366023d5495ae2edce97
(tdf#156724 sw: layout: fix tables not splitting due to footnotes
differently, 2023-08-24), the floating table in the DOCX version of the
bugdoc went from page 1 to page 2.

It seems what happens is that the first page has 2 section frames, and
we used to directly recalc the last lower of the first section frame,
which triggered a recalc of the second section frame, so the table moved
from page 2 to page 1 once the top of the second section frame was
reduced (so the table could fit on page 1). But this direct recalc was
removed because it caused problems for split tables and footnotes in
tdf#156724.

Fix the problem by conditionally restoring the OptCalc() call in
SwLayAction::FormatLayout(): only do it for the last lower of section
frames, which is enough for the DOCX version of tdf#158986, but it keeps
the old tdf#156724 use-case working (the layout of that bugdoc doesn't
modify with this change).

The RTF version of the bugdoc (which was the originally reported
problem) still needs more work, but that's hopefully not a layout
problem but an RTF import one.

Change-Id: I1134ec3a27aec8ee871b535d81dedf9d27bd6bd5
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/163805
Reviewed-by: Miklos Vajna <[email protected]>
Tested-by: Jenkins
diff --git a/sw/qa/core/layout/data/floattable-in-section.docx b/sw/qa/core/layout/data/floattable-in-section.docx
index a0e9090..9aab264 100644
--- a/sw/qa/core/layout/data/floattable-in-section.docx
+++ b/sw/qa/core/layout/data/floattable-in-section.docx
Binary files differ
diff --git a/sw/qa/core/layout/layact.cxx b/sw/qa/core/layout/layact.cxx
index d432ae5..8923d6b 100644
--- a/sw/qa/core/layout/layact.cxx
+++ b/sw/qa/core/layout/layact.cxx
@@ -86,6 +86,28 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf157096)

    CPPUNIT_ASSERT_EQUAL(1, getPages());
}

CPPUNIT_TEST_FIXTURE(Test, testSplitFlyInSection)
{
    // Given a document with multiple sections, the 2nd section on page 1 has a one-page floating
    // table:
    createSwDoc("floattable-in-section.docx");

    // When laying out that document:
    SwDoc* pDoc = getSwDoc();
    SwRootFrame* pLayout = pDoc->getIDocumentLayoutAccess().GetCurrentLayout();

    // Then make sure the table is on page 1, not on page 2:
    auto pPage1 = pLayout->Lower()->DynCastPageFrame();
    CPPUNIT_ASSERT(pPage1);
    // Without the fix in place, it would have failed, the table was on page 2, not on page 1.
    CPPUNIT_ASSERT(pPage1->GetSortedObjs());
    SwSortedObjs& rPage1Objs = *pPage1->GetSortedObjs();
    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), rPage1Objs.size());
    auto pPage2 = pPage1->GetNext()->DynCastPageFrame();
    CPPUNIT_ASSERT(pPage2);
    CPPUNIT_ASSERT(!pPage2->GetSortedObjs());
}
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/layout/layact.cxx b/sw/source/core/layout/layact.cxx
index 5c910ee..abbca7d 100644
--- a/sw/source/core/layout/layact.cxx
+++ b/sw/source/core/layout/layact.cxx
@@ -1433,7 +1433,11 @@ bool SwLayAction::FormatLayout( OutputDevice *pRenderContext, SwLayoutFrame *pLa
                PopFormatLayout();
            }
        }
        // else: don't calc content frames any more
        else if (pLay->IsSctFrame() && pLow->IsTextFrame() && pLow == pLay->GetLastLower())
        {
            // else: only calc the last text lower of sections
            pLow->OptCalc();
        }

        if ( IsAgain() )
            return false;