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 82dd81a9d2049ac95535880fc67c1867f90e1427 Author: Miklos Vajna <vmik...@collabora.com> AuthorDate: Wed May 15 13:25:13 2024 +0200 Commit: Miklos Vajna <vmik...@collabora.com> CommitDate: Wed May 15 16:54:05 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). Change-Id: I664672b91087217008a42120e8201c39e2a0a423 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167691 Tested-by: Jenkins Reviewed-by: Miklos Vajna <vmik...@collabora.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 e03519ed3040..b7851a131e44 100644 --- a/sw/source/core/layout/ftnfrm.cxx +++ b/sw/source/core/layout/ftnfrm.cxx @@ -1585,7 +1585,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); }