sw/qa/extras/rtfexport/data/tdf165564.odt |binary sw/qa/extras/rtfexport/rtfexport8.cxx | 14 ++++++++++++++ sw/source/filter/ww8/attributeoutputbase.hxx | 2 +- sw/source/filter/ww8/docxattributeoutput.cxx | 3 ++- sw/source/filter/ww8/docxattributeoutput.hxx | 2 +- sw/source/filter/ww8/rtfattributeoutput.cxx | 7 ++++--- sw/source/filter/ww8/rtfattributeoutput.hxx | 4 ++-- sw/source/filter/ww8/ww8atr.cxx | 3 ++- sw/source/filter/ww8/ww8attributeoutput.hxx | 2 +- sw/source/writerfilter/dmapper/DomainMapper.cxx | 3 ++- 10 files changed, 29 insertions(+), 11 deletions(-)
New commits: commit 26359db2ad225fa8c6300eec357437ac96305f72 Author: Oliver Specht <oliver.spe...@cib.de> AuthorDate: Tue May 6 08:34:17 2025 +0200 Commit: Miklos Vajna <vmik...@collabora.com> CommitDate: Mon Jul 28 09:35:00 2025 +0200 tdf#165564 RTF:Fix export and import of footnotes/endnotes Removes additional spaces in export and wrong insertions of custom footnote/endnote symbols in import. Change-Id: I2e79e87a5b644b116a87602332e09cde89b64ba5 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/184978 Reviewed-by: Gabor Kelemen <gabor.kelemen.ext...@allotropia.de> Tested-by: Jenkins Reviewed-on: https://gerrit.libreoffice.org/c/core/+/188431 Reviewed-by: Miklos Vajna <vmik...@collabora.com> Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com> diff --git a/sw/qa/extras/rtfexport/data/tdf165564.odt b/sw/qa/extras/rtfexport/data/tdf165564.odt new file mode 100644 index 000000000000..d849e1a115ff Binary files /dev/null and b/sw/qa/extras/rtfexport/data/tdf165564.odt differ diff --git a/sw/qa/extras/rtfexport/rtfexport8.cxx b/sw/qa/extras/rtfexport/rtfexport8.cxx index bb035043c6ce..5580c1f65dae 100644 --- a/sw/qa/extras/rtfexport/rtfexport8.cxx +++ b/sw/qa/extras/rtfexport/rtfexport8.cxx @@ -691,6 +691,20 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf161878) verify(); } +CPPUNIT_TEST_FIXTURE(Test, testTdf165564) +{ + auto verify = [this]() { + auto para1 = getParagraph(1); + CPPUNIT_ASSERT_EQUAL(u"iXEndnote testiiY"_ustr, para1->getString()); + auto para2 = getParagraph(2); + CPPUNIT_ASSERT_EQUAL(u"*1Footnote test2+"_ustr, para2->getString()); + }; + createSwDoc("tdf165564.odt"); + verify(); + saveAndReload(mpFilter); + verify(); +} + CPPUNIT_TEST_FIXTURE(Test, testTdf166620) { createSwDoc(); diff --git a/sw/source/filter/ww8/attributeoutputbase.hxx b/sw/source/filter/ww8/attributeoutputbase.hxx index bdc551245b49..c13e1a0ff5dd 100644 --- a/sw/source/filter/ww8/attributeoutputbase.hxx +++ b/sw/source/filter/ww8/attributeoutputbase.hxx @@ -179,7 +179,7 @@ public: virtual void StartRunProperties() = 0; /// Called after we end outputting the attributes. - virtual void EndRunProperties( const SwRedlineData* pRedlineData ) = 0; + virtual bool EndRunProperties( const SwRedlineData* pRedlineData ) = 0; /// docx requires footnoteRef/endnoteRef tag at the beginning of each of them virtual bool FootnoteEndnoteRefTag() { return false; }; diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx index 67b31e72768d..b5394e5f3b68 100644 --- a/sw/source/filter/ww8/docxattributeoutput.cxx +++ b/sw/source/filter/ww8/docxattributeoutput.cxx @@ -3689,7 +3689,7 @@ void DocxAttributeOutput::WriteCollectedRunProperties() } } -void DocxAttributeOutput::EndRunProperties( const SwRedlineData* pRedlineData ) +bool DocxAttributeOutput::EndRunProperties( const SwRedlineData* pRedlineData ) { // Call the 'Redline' function. This will add redline (change-tracking) information that regards to run properties. // This includes changes like 'Bold', 'Underline', 'Strikethrough' etc. @@ -3728,6 +3728,7 @@ void DocxAttributeOutput::EndRunProperties( const SwRedlineData* pRedlineData ) WritePostponedOLE(); WritePostponedActiveXControl(true); + return false; } void DocxAttributeOutput::GetSdtEndBefore(const SdrObject* pSdrObj) diff --git a/sw/source/filter/ww8/docxattributeoutput.hxx b/sw/source/filter/ww8/docxattributeoutput.hxx index aa8876a0cb31..a0a6e0f24e31 100644 --- a/sw/source/filter/ww8/docxattributeoutput.hxx +++ b/sw/source/filter/ww8/docxattributeoutput.hxx @@ -232,7 +232,7 @@ public: virtual void StartRunProperties() override; /// Called after we end outputting the attributes. - virtual void EndRunProperties( const SwRedlineData* pRedlineData ) override; + virtual bool EndRunProperties( const SwRedlineData* pRedlineData ) override; virtual bool FootnoteEndnoteRefTag() override; diff --git a/sw/source/filter/ww8/rtfattributeoutput.cxx b/sw/source/filter/ww8/rtfattributeoutput.cxx index 4dbf66aac278..a17924a55c65 100644 --- a/sw/source/filter/ww8/rtfattributeoutput.cxx +++ b/sw/source/filter/ww8/rtfattributeoutput.cxx @@ -480,10 +480,11 @@ void RtfAttributeOutput::StartRunProperties() OSL_ENSURE(m_aStyles.getLength() == 0, "m_aStyles is not empty"); } -void RtfAttributeOutput::EndRunProperties(const SwRedlineData* /*pRedlineData*/) +bool RtfAttributeOutput::EndRunProperties(const SwRedlineData* /*pRedlineData*/) { const OString aProperties = MoveCharacterProperties(true); m_aRun->append(aProperties); + return !aProperties.isEmpty(); } OString RtfAttributeOutput::MoveCharacterProperties(bool aAutoWriteRtlLtr) @@ -3112,8 +3113,8 @@ void RtfAttributeOutput::TextFootnote_Impl(const SwFormatFootnote& rFootnote) SAL_INFO("sw.rtf", __func__ << " start"); m_aRun->append("{" OOO_STRING_SVTOOLS_RTF_SUPER " "); - EndRunProperties(nullptr); - m_aRun->append(' '); + if (EndRunProperties(nullptr)) + m_aRun->append(' '); WriteTextFootnoteNumStr(rFootnote); m_aRun->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_FOOTNOTE); if (rFootnote.IsEndNote() || m_rExport.m_rDoc.GetFootnoteInfo().m_ePos == FTNPOS_CHAPTER) diff --git a/sw/source/filter/ww8/rtfattributeoutput.hxx b/sw/source/filter/ww8/rtfattributeoutput.hxx index 0f7fc5c77dc2..924c2f4a781f 100644 --- a/sw/source/filter/ww8/rtfattributeoutput.hxx +++ b/sw/source/filter/ww8/rtfattributeoutput.hxx @@ -82,8 +82,8 @@ public: /// Called before we start outputting the attributes. void StartRunProperties() override; - /// Called after we end outputting the attributes. - void EndRunProperties(const SwRedlineData* pRedlineData) override; + /// Called after we end outputting the attributes, returns true if commands were added. + bool EndRunProperties(const SwRedlineData* pRedlineData) override; /// Output text (inside a run). void RunText(const OUString& rText, rtl_TextEncoding eCharSet = RTL_TEXTENCODING_UTF8, diff --git a/sw/source/filter/ww8/ww8atr.cxx b/sw/source/filter/ww8/ww8atr.cxx index cb80ace499f9..7c836fffdf8e 100644 --- a/sw/source/filter/ww8/ww8atr.cxx +++ b/sw/source/filter/ww8/ww8atr.cxx @@ -1194,7 +1194,7 @@ void WW8AttributeOutput::EndRun( const SwTextNode* /*pNode*/, sal_Int32 nPos, sa } } -void WW8AttributeOutput::EndRunProperties( const SwRedlineData* pRedlineData ) +bool WW8AttributeOutput::EndRunProperties( const SwRedlineData* pRedlineData ) { Redline( pRedlineData ); @@ -1213,6 +1213,7 @@ void WW8AttributeOutput::EndRunProperties( const SwRedlineData* pRedlineData ) m_rWW8Export.m_pO->size(), m_rWW8Export.m_pO->data() ); } m_rWW8Export.m_pO->clear(); + return false; } void WW8AttributeOutput::RunText( const OUString& rText, rtl_TextEncoding eCharSet, const OUString& /*rSymbolFont*/ ) diff --git a/sw/source/filter/ww8/ww8attributeoutput.hxx b/sw/source/filter/ww8/ww8attributeoutput.hxx index 8f32ab9f1d7c..6b019acff24c 100644 --- a/sw/source/filter/ww8/ww8attributeoutput.hxx +++ b/sw/source/filter/ww8/ww8attributeoutput.hxx @@ -64,7 +64,7 @@ public: virtual void StartRunProperties() override; /// After we end outputting the attributes. - virtual void EndRunProperties( const SwRedlineData* pRedlineData ) override; + virtual bool EndRunProperties( const SwRedlineData* pRedlineData ) override; /// Output text. virtual void RunText( const OUString& rText, rtl_TextEncoding eCharSet = RTL_TEXTENCODING_UTF8, const OUString& rSymbolFont = OUString() ) override; diff --git a/sw/source/writerfilter/dmapper/DomainMapper.cxx b/sw/source/writerfilter/dmapper/DomainMapper.cxx index d6f5bab425ea..050991aa2771 100644 --- a/sw/source/writerfilter/dmapper/DomainMapper.cxx +++ b/sw/source/writerfilter/dmapper/DomainMapper.cxx @@ -4654,7 +4654,8 @@ void DomainMapper::lcl_utext(const sal_Unicode *const data_, size_t len) pContext->GetFootnote()->setLabel( sText ); // tdf#141548 don't lose footnote/endnote text of the run with uFtnEdnRef // (i.e. when footnoteRef/endnoteRef is followed by some text in the same run) - m_pImpl->appendTextPortion( sText, pContext ); + if (!IsRTFImport()) + m_pImpl->appendTextPortion( sText, pContext ); } else if (m_pImpl->IsOpenFieldCommand() && !m_pImpl->IsForceGenericFields()) {