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