sw/qa/core/layout/data/inline-endnote-and-section.odt |binary sw/qa/core/layout/ftnfrm.cxx | 18 ++++++++++++++++++ sw/source/core/layout/ftnfrm.cxx | 16 +++++++++++++++- 3 files changed, 33 insertions(+), 1 deletion(-)
New commits: commit a8216967ebe242c379b7df1267836c4ec5a566a4 Author: Miklos Vajna <vmik...@collabora.com> AuthorDate: Wed May 15 13:25:13 2024 +0200 Commit: Caolán McNamara <caolan.mcnam...@collabora.com> CommitDate: Thu May 16 16:02:17 2024 +0200 tdf#161083 sw continuous endnotes: fix layout with a section at doc end Open the bugdoc, notice warnings like: warn:legacy.osl:15059:15059:sw/source/core/layout/wsfrm.cxx:910: Frame tree is inconsistent. Which means we try to insert the new section frame under body frame, but the insert point is behind a frame which is not a direct child of the body frame. This went wrong in commit 6885dcd7ec7b82a946d8344bfc27a3e88eecc44a (tdf#160984 sw continuous endnotes: switch to a section-based layout, 2024-05-14), where I didn't consider the case of having a continuous section break at the Word doc end, which maps to a section frame before the section frame of the endnotes in Writer. Fix the problem by walking up the parent chain till we find the last direct child of the body frame, which is typically not required, except when having one or more (nested) section frames at the end of the document. Interestingly tdf#143456 had the same problem, which was the bugdoc to trigger the revert of the old continuous endnotes code for DOCX in eeda1b35a6e87d5349545464da33d997c52f15e3 (Revert "tdf#58521 DOCX import: enable ContinuousEndnotes compat flag", 2021-08-10). (cherry picked from commit 82dd81a9d2049ac95535880fc67c1867f90e1427) Change-Id: I664672b91087217008a42120e8201c39e2a0a423 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167728 Reviewed-by: Caolán McNamara <caolan.mcnam...@collabora.com> Tested-by: Caolán McNamara <caolan.mcnam...@collabora.com> Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com> diff --git a/sw/qa/core/layout/data/inline-endnote-and-section.odt b/sw/qa/core/layout/data/inline-endnote-and-section.odt new file mode 100644 index 000000000000..4518904f6009 Binary files /dev/null and b/sw/qa/core/layout/data/inline-endnote-and-section.odt differ diff --git a/sw/qa/core/layout/ftnfrm.cxx b/sw/qa/core/layout/ftnfrm.cxx index 71fd3fd67150..1cf31809e5a7 100644 --- a/sw/qa/core/layout/ftnfrm.cxx +++ b/sw/qa/core/layout/ftnfrm.cxx @@ -84,4 +84,22 @@ CPPUNIT_TEST_FIXTURE(Test, testInlineEndnoteAndFootnote) CPPUNIT_ASSERT_LESS(nFootnoteTop, nEndnoteTop); } +CPPUNIT_TEST_FIXTURE(Test, testInlineEndnoteAndSection) +{ + // Given a document ending with a section, ContinuousEndnotes is true: + createSwDoc("inline-endnote-and-section.odt"); + + // When laying out that document: + xmlDocUniquePtr pXmlDoc = parseLayoutDump(); + + // Then make sure the endnote section is after the section at the end of the document, not + // inside it: + int nToplevelSections = countXPathNodes(pXmlDoc, "/root/page/body/section"_ostr); + // Without the accompanying fix in place, this test would have failed with: + // - Expected: 2 + // - Actual : 1 + // and we even crashed on shutdown. + CPPUNIT_ASSERT_EQUAL(2, nToplevelSections); +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/core/layout/ftnfrm.cxx b/sw/source/core/layout/ftnfrm.cxx index 4be87ee57ccd..61a8385d51fc 100644 --- a/sw/source/core/layout/ftnfrm.cxx +++ b/sw/source/core/layout/ftnfrm.cxx @@ -1560,7 +1560,21 @@ void SwFootnoteBossFrame::AppendFootnote( SwContentFrame *pRef, SwTextFootnote * { SwSection* pSwSection = pDoc->GetEndNoteInfo().GetSwSection(*pDoc); pEndnoteSection = new SwSectionFrame(*pSwSection, pPage); - pEndnoteSection->InsertBehind(pPage->FindBodyCont(), pPage->FindLastBodyContent()); + SwLayoutFrame* pParent = pPage->FindBodyCont(); + SwFrame* pBefore = pPage->FindLastBodyContent(); + while (pBefore) + { + // Check if the last content frame is directly under the body frame or there is + // something in-between, e.g. a section frame. + if (pBefore->GetUpper() == pParent) + { + break; + } + + // If so, insert behind the parent of the content frame, not inside the parent. + pBefore = pBefore->GetUpper(); + } + pEndnoteSection->InsertBehind(pParent, pBefore); pEndnoteSection->Init(); pEndnoteSection->SetEndNoteSection(true); }