sw/source/core/inc/frmtool.hxx    |    1 +
 sw/source/core/layout/flowfrm.cxx |   20 ++++++++++++++++++++
 sw/source/core/layout/sectfrm.cxx |    3 ++-
 3 files changed, 23 insertions(+), 1 deletion(-)

New commits:
commit 325fe7ab507fd8f2ca17a3db32181edf30169525
Author:     Michael Stahl <michael.st...@allotropia.de>
AuthorDate: Fri May 12 17:45:45 2023 +0200
Commit:     Michael Stahl <michael.st...@allotropia.de>
CommitDate: Tue May 16 20:14:00 2023 +0200

    tdf#155324 sw: layout: try not to MoveFwd onto a page created by page break
    
    There is a ToX that is updated; it has about 4 pages worth of entries.
    
    When the old entries are deleted, 2 of the pages become empty, and since
    commit b9ef71476fd70bc13f50ebe80390e0730d1b7afb these pages are deleted.
    
    While layouting the new entries, these are moved onto the page following
    the ToX, which starts with a page break and contains lots of footnotes.
    
    Now the footnotes reduce the space on the page available for the ToX
    entries, and thus after CalcLayout() there are 5 ToX pages instead of 4.
    
    Then the page numbers are inserted into the entries, and another layout
    action deletes one of the ToX pages; now all the page numbers are too
    large by 1.
    
    Some ideas to fix this:
    1) ignore a footnote when formatting a frame that is before the
       footnote anchor frame; similar to commit
       c79bf7865bff4e88cc201357370d8faeef8e6ad9
    2) invalidate the last content on the page when moving forward the
       footnote container, similar to commit
       eb85de8e6b61fb3fcb6c03ae0145f7fe5478bccf; this doesn't look easy to
       do because as it turns out the footnote container is moved in
       SwLayoutFrame::Cut() 5 function calls inside MoveFwd() while the frame
       on which MoveFwd() is called is still on the page, so would probably
       somehow need to be detected in MoveFwd() itself?
    3) don't move frames forward onto a page that was created by a page
       break - instead create a new frame.
    
    Let's try 3) for now, only in SwFrame::GetNextSctLeaf().
    
    (regression from commit b9ef71476fd70bc13f50ebe80390e0730d1b7afb)
    
    Change-Id: I641f586799a5ddb4e2a6ff8e9de784e422ecc214
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/151711
    Tested-by: Jenkins
    Reviewed-by: Michael Stahl <michael.st...@allotropia.de>

diff --git a/sw/source/core/inc/frmtool.hxx b/sw/source/core/inc/frmtool.hxx
index 7e9d2d3013c5..ffc218b5504e 100644
--- a/sw/source/core/inc/frmtool.hxx
+++ b/sw/source/core/inc/frmtool.hxx
@@ -157,6 +157,7 @@ SwTwips CalcRowRstHeight( SwLayoutFrame *pRow );
 tools::Long CalcHeightWithFlys( const SwFrame *pFrame );
 
 namespace sw {
+    bool HasPageBreakBefore(SwPageFrame const& rPage);
     bool IsRightPageByNumber(SwRootFrame const& rLayout, sal_uInt16 nPageNum);
     class FlyCreationSuppressor
     {
diff --git a/sw/source/core/layout/flowfrm.cxx 
b/sw/source/core/layout/flowfrm.cxx
index c3690e2984cc..402f47f8004e 100644
--- a/sw/source/core/layout/flowfrm.cxx
+++ b/sw/source/core/layout/flowfrm.cxx
@@ -893,6 +893,26 @@ SwLayoutFrame *SwFrame::GetLeaf( MakePageType eMakePage, 
bool bFwd )
     return bFwd ? GetNextLeaf( eMakePage ) : GetPrevLeaf();
 }
 
+namespace sw {
+
+bool HasPageBreakBefore(SwPageFrame const& rPage)
+{
+    SwFrame const* pFlow(rPage.FindFirstBodyContent());
+    if (!pFlow)
+    {
+        return false;
+    }
+    while (pFlow->GetUpper()->IsInTab())
+    {
+        pFlow = pFlow->GetUpper()->FindTabFrame();
+    }
+    return pFlow->GetPageDescItem().GetPageDesc()
+        || pFlow->GetBreakItem().GetBreak() == SvxBreak::PageBefore
+        || pFlow->GetBreakItem().GetBreak() == SvxBreak::PageBoth;
+};
+
+} // namespace sw
+
 bool SwFrame::WrongPageDesc( SwPageFrame* pNew )
 {
     // Now it's getting a bit complicated:
diff --git a/sw/source/core/layout/sectfrm.cxx 
b/sw/source/core/layout/sectfrm.cxx
index bc8930cd4332..1faaae683379 100644
--- a/sw/source/core/layout/sectfrm.cxx
+++ b/sw/source/core/layout/sectfrm.cxx
@@ -1742,7 +1742,8 @@ SwLayoutFrame *SwFrame::GetNextSctLeaf( MakePageType 
eMakePage )
             // case pLayLeaf points to our section's cell's follow, which is
             // fine to be on the same page. New page creation is handled when
             // creating / moving the cell frame.
-            if( WrongPageDesc( pNxtPg ) && !bLayLeafTableAllowed )
+            // It doesn't make sense to move to a page that starts with break?
+            if ((WrongPageDesc(pNxtPg) || HasPageBreakBefore(*pNxtPg)) && 
!bLayLeafTableAllowed)
             {
                 if( bWrongPage )
                     break; // there's a column between me and my right page

Reply via email to