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);
             }

Reply via email to