sw/qa/filter/ww8/ww8.cxx                     |   30 +++++++++++++++++++++++++++
 sw/source/filter/ww8/docxattributeoutput.cxx |   13 +++++++++++
 sw/source/filter/ww8/docxattributeoutput.hxx |    2 -
 sw/source/filter/ww8/docxexport.cxx          |    4 +--
 4 files changed, 46 insertions(+), 3 deletions(-)

New commits:
commit d0ee0c93d6145542d82ba62887f4e5a3691333fe
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Wed May 29 13:34:25 2024 +0200
Commit:     Caolán McNamara <caolan.mcnam...@collabora.com>
CommitDate: Thu May 30 14:08:24 2024 +0200

    tdf#160984 sw continuous endnotes: DOCX: export of <w:endnotePr> pos == 
sectEnd
    
    In case a DOCX file is re-exported to Word and it collected endnotes at
    section end, this setting was lost on save.
    
    The relevant markup seems to be <w:endnotePr> -> <w:pos
    w:val="sectEnd"/>, though that's a per-section setting in Writer, and is
    a per-doc setting in Word.
    
    Fix the problem by doing it similar to
    DocxExport::WriteDocumentBackgroundFill(), which takes the first page
    style in a similar case; here we take the first section format.
    
    This is meant to be good enough for the DOCX editing case, where we know
    all sections have the same endnote position properties anyway.
    
    (cherry picked from commit 566c7017a84e3d573de85a6d986b81d3f59de0fa)
    
    Change-Id: I95508296e31c9be34196bdc0da2177101647abf9
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/168241
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com>
    Reviewed-by: Caolán McNamara <caolan.mcnam...@collabora.com>

diff --git a/sw/qa/filter/ww8/ww8.cxx b/sw/qa/filter/ww8/ww8.cxx
index 4cbbfe5fbf31..070565345a2d 100644
--- a/sw/qa/filter/ww8/ww8.cxx
+++ b/sw/qa/filter/ww8/ww8.cxx
@@ -32,6 +32,7 @@
 #include <tabfrm.hxx>
 #include <cntfrm.hxx>
 #include <colfrm.hxx>
+#include <fmtftntx.hxx>
 
 namespace
 {
@@ -564,6 +565,35 @@ CPPUNIT_TEST_FIXTURE(Test, testNullPointerDereference)
     createSwDoc("null-pointer-dereference.doc");
     CPPUNIT_ASSERT_EQUAL(6, getPages());
 }
+
+CPPUNIT_TEST_FIXTURE(Test, testEndnotesAtSectEnd)
+{
+    // Given a document, endnotes at collected at section end:
+    createSwDoc();
+    SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
+    pWrtShell->SplitNode();
+    pWrtShell->Up(/*bSelect=*/false);
+    pWrtShell->Insert("x");
+    pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/true, 1, 
/*bBasicCall=*/false);
+    SwSectionData aSection(SectionType::Content, 
pWrtShell->GetUniqueSectionName());
+    pWrtShell->StartAction();
+    SfxItemSetFixed<RES_FTN_AT_TXTEND, RES_FRAMEDIR> 
aSet(pWrtShell->GetAttrPool());
+    aSet.Put(SwFormatEndAtTextEnd(FTNEND_ATTXTEND));
+    pWrtShell->InsertSection(aSection, &aSet);
+    pWrtShell->EndAction();
+    pWrtShell->InsertFootnote(OUString(), /*bEndNote=*/true);
+
+    // When saving to DOCX:
+    save("Office Open XML Text");
+
+    // Then make sure the endnote position is section end:
+    xmlDocUniquePtr pXmlDoc = parseExport("word/settings.xml");
+    OUString aPos = getXPath(pXmlDoc, "/w:settings/w:endnotePr/w:pos"_ostr, 
"val"_ostr);
+    // Without the accompanying fix in place, this test would have failed with:
+    // - XPath '/w:settings/w:endnotePr/w:pos' number of nodes is incorrect
+    // i.e. the default position was used: document end.
+    CPPUNIT_ASSERT_EQUAL(OUString("sectEnd"), aPos);
+}
 }
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx 
b/sw/source/filter/ww8/docxattributeoutput.cxx
index 3201321a6328..2f77cf07b06a 100644
--- a/sw/source/filter/ww8/docxattributeoutput.cxx
+++ b/sw/source/filter/ww8/docxattributeoutput.cxx
@@ -127,6 +127,7 @@
 #include <docsh.hxx>
 #include <docary.hxx>
 #include <fmtclbl.hxx>
+#include <fmtftntx.hxx>
 #include <IDocumentSettingAccess.hxx>
 #include <IDocumentRedlineAccess.hxx>
 #include <grfatr.hxx>
@@ -8786,6 +8787,18 @@ void DocxAttributeOutput::WriteFootnoteEndnotePr( 
::sax_fastparser::FSHelperPtr
     const SwEndNoteInfo& info, int listtag )
 {
     fs->startElementNS(XML_w, tag);
+
+    SwSectionFormats& rSections = m_rExport.m_rDoc.GetSections();
+    if (!rSections.empty())
+    {
+        SwSectionFormat* pFormat = rSections[0];
+        bool bEndnAtEnd = pFormat->GetEndAtTextEnd().IsAtEnd();
+        if (bEndnAtEnd)
+        {
+            fs->singleElementNS(XML_w, XML_pos, FSNS(XML_w, XML_val), 
"sectEnd");
+        }
+    }
+
     OString aCustomFormat;
     OString fmt = lcl_ConvertNumberingType(info.m_aFormat.GetNumberingType(), 
nullptr, aCustomFormat);
     if (!fmt.isEmpty() && aCustomFormat.isEmpty())
diff --git a/sw/source/filter/ww8/docxattributeoutput.hxx 
b/sw/source/filter/ww8/docxattributeoutput.hxx
index 10f39debc2a0..b23f5b98ee7e 100644
--- a/sw/source/filter/ww8/docxattributeoutput.hxx
+++ b/sw/source/filter/ww8/docxattributeoutput.hxx
@@ -1109,7 +1109,7 @@ public:
     void FootnotesEndnotes( bool bFootnotes );
 
     /// writes the footnotePr/endnotePr (depending on tag) section
-    static void WriteFootnoteEndnotePr( ::sax_fastparser::FSHelperPtr const & 
fs, int tag, const SwEndNoteInfo& info, int listtag );
+    void WriteFootnoteEndnotePr( ::sax_fastparser::FSHelperPtr const & fs, int 
tag, const SwEndNoteInfo& info, int listtag );
 
     bool HasPostitFields() const;
     enum class hasProperties { no, yes };
diff --git a/sw/source/filter/ww8/docxexport.cxx 
b/sw/source/filter/ww8/docxexport.cxx
index e84bbc48eb20..c02703184fc1 100644
--- a/sw/source/filter/ww8/docxexport.cxx
+++ b/sw/source/filter/ww8/docxexport.cxx
@@ -1220,11 +1220,11 @@ void DocxExport::WriteSettings()
 
     // Has Footnotes
     if( m_pAttrOutput->HasFootnotes())
-        DocxAttributeOutput::WriteFootnoteEndnotePr( pFS, XML_footnotePr, 
m_rDoc.GetFootnoteInfo(), XML_footnote );
+        m_pAttrOutput->WriteFootnoteEndnotePr( pFS, XML_footnotePr, 
m_rDoc.GetFootnoteInfo(), XML_footnote );
 
     // Has Endnotes
     if( m_pAttrOutput->HasEndnotes())
-        DocxAttributeOutput::WriteFootnoteEndnotePr( pFS, XML_endnotePr, 
m_rDoc.GetEndNoteInfo(), XML_endnote );
+        m_pAttrOutput->WriteFootnoteEndnotePr( pFS, XML_endnotePr, 
m_rDoc.GetEndNoteInfo(), XML_endnote );
 
     // Has themeFontLang information
     uno::Reference< beans::XPropertySet > xPropSet( pDocShell->GetBaseModel(), 
uno::UNO_QUERY_THROW );

Reply via email to