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