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 566c7017a84e3d573de85a6d986b81d3f59de0fa
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Wed May 29 13:34:25 2024 +0200
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Wed May 29 20:10:50 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.
    
    Change-Id: I95508296e31c9be34196bdc0da2177101647abf9
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/168187
    Tested-by: Jenkins
    Reviewed-by: Miklos Vajna <vmik...@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 1532ecf72c81..971f27df0314 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>
@@ -8780,6 +8781,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 b1da698c3dec..063cb02bbc69 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 adff5738da45..622cc7b0fe6e 100644
--- a/sw/source/filter/ww8/docxexport.cxx
+++ b/sw/source/filter/ww8/docxexport.cxx
@@ -1226,11 +1226,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