sw/qa/extras/layout/data/tox-update-wrong-pages.odt |binary sw/qa/extras/layout/layout.cxx | 34 ++++++++++++++++++++ sw/source/core/inc/frmtool.hxx | 1 sw/source/core/layout/flowfrm.cxx | 20 +++++++++++ sw/source/core/layout/sectfrm.cxx | 3 + 5 files changed, 57 insertions(+), 1 deletion(-)
New commits: commit 425a252c3cc5e5a79a533965026dd4af6b8df739 Author: Michael Stahl <michael.st...@allotropia.de> AuthorDate: Fri May 12 17:45:45 2023 +0200 Commit: Thorsten Behrens <thorsten.behr...@allotropia.de> CommitDate: Tue Jun 27 11:28:49 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) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/151711 Tested-by: Jenkins Reviewed-by: Michael Stahl <michael.st...@allotropia.de> (cherry picked from commit 325fe7ab507fd8f2ca17a3db32181edf30169525) tdf#155324 sw: add unit test Reviewed-on: https://gerrit.libreoffice.org/c/core/+/151876 Tested-by: Jenkins Reviewed-by: Michael Stahl <michael.st...@allotropia.de> (cherry picked from commit 247738a9afeeb2f0644fa0307b7023fe115fae83) Change-Id: I641f586799a5ddb4e2a6ff8e9de784e422ecc214 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/151889 Tested-by: Jenkins Reviewed-by: Thorsten Behrens <thorsten.behr...@allotropia.de> diff --git a/sw/qa/extras/layout/data/tox-update-wrong-pages.odt b/sw/qa/extras/layout/data/tox-update-wrong-pages.odt new file mode 100644 index 000000000000..40ceb7ac4bd2 Binary files /dev/null and b/sw/qa/extras/layout/data/tox-update-wrong-pages.odt differ diff --git a/sw/qa/extras/layout/layout.cxx b/sw/qa/extras/layout/layout.cxx index b4101e9f033e..59db7359bafe 100644 --- a/sw/qa/extras/layout/layout.cxx +++ b/sw/qa/extras/layout/layout.cxx @@ -5092,6 +5092,40 @@ CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testTdf54465_ColumnsWithFootnoteDoNotOccupy assertXPath(pXmlDoc, "/root/page", 1); } +CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testTdf155324) +{ + createSwDoc("tox-update-wrong-pages.odt"); + + dispatchCommand(mxComponent, ".uno:UpdateAllIndexes", {}); + + xmlDocUniquePtr pXmlDoc = parseLayoutDump(); + + // the problem was that the first entry was on page 7, 2nd on page 9 etc. + assertXPath(pXmlDoc, + "/root/page[1]/body/section[2]/txt[1]/SwParaPortion/SwLineLayout/SwLinePortion[1]", + "portion", "Foo"); + assertXPath(pXmlDoc, + "/root/page[1]/body/section[2]/txt[1]/SwParaPortion/SwLineLayout/SwLinePortion[2]", + "portion", "5"); + assertXPath(pXmlDoc, + "/root/page[1]/body/section[2]/txt[2]/SwParaPortion/SwLineLayout/SwLinePortion[1]", + "portion", "bar"); + assertXPath(pXmlDoc, + "/root/page[1]/body/section[2]/txt[2]/SwParaPortion/SwLineLayout/SwLinePortion[2]", + "portion", "7"); + assertXPath(pXmlDoc, + "/root/page[1]/body/section[2]/txt[3]/SwParaPortion/SwLineLayout/SwLinePortion[1]", + "portion", "Three"); + assertXPath(pXmlDoc, + "/root/page[1]/body/section[2]/txt[3]/SwParaPortion/SwLineLayout/SwLinePortion[2]", + "portion", "7"); + + // check first content page has the footnotes + assertXPath(pXmlDoc, "/root/page[5]/body/txt[1]/SwParaPortion/SwLineLayout", "portion", "Foo"); + assertXPath(pXmlDoc, "/root/page[4]/ftncont", 0); + assertXPath(pXmlDoc, "/root/page[5]/ftncont/ftn", 5); +} + CPPUNIT_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/core/inc/frmtool.hxx b/sw/source/core/inc/frmtool.hxx index 0aaa4d2c05c3..5cabab690b61 100644 --- a/sw/source/core/inc/frmtool.hxx +++ b/sw/source/core/inc/frmtool.hxx @@ -158,6 +158,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 370ad84b88ff..1b9ecf1cf03c 100644 --- a/sw/source/core/layout/flowfrm.cxx +++ b/sw/source/core/layout/flowfrm.cxx @@ -880,6 +880,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 b9249de5c340..b6890aec917b 100644 --- a/sw/source/core/layout/sectfrm.cxx +++ b/sw/source/core/layout/sectfrm.cxx @@ -1756,7 +1756,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