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 90ce84a5dd371c804af19e97896a5e19a3ebf8ca Author: Oliver Specht <oliver.spe...@cib.de> AuthorDate: Tue May 6 08:34:17 2025 +0200 Commit: Gabor Kelemen <gabor.kelemen.ext...@allotropia.de> CommitDate: Thu May 8 11:38:05 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 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 69717e0c5db2..17091665be20 100644 --- a/sw/qa/extras/rtfexport/rtfexport8.cxx +++ b/sw/qa/extras/rtfexport/rtfexport8.cxx @@ -634,6 +634,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(); +} + } // end of anonymous namespace CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/sw/source/filter/ww8/attributeoutputbase.hxx b/sw/source/filter/ww8/attributeoutputbase.hxx index 36027ee65ef7..66978890435b 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 98ea7864824d..899d6fdbf5dc 100644 --- a/sw/source/filter/ww8/docxattributeoutput.cxx +++ b/sw/source/filter/ww8/docxattributeoutput.cxx @@ -3692,7 +3692,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. @@ -3731,6 +3731,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 a66ac7ed49f7..85ec8a4cff1b 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 f55efb729c73..646aabde12f2 100644 --- a/sw/source/filter/ww8/rtfattributeoutput.cxx +++ b/sw/source/filter/ww8/rtfattributeoutput.cxx @@ -446,10 +446,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) @@ -3082,8 +3083,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 165223487da2..f743d44f147e 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 20f2f2542c32..a7818623f5d1 100644 --- a/sw/source/filter/ww8/ww8atr.cxx +++ b/sw/source/filter/ww8/ww8atr.cxx @@ -1193,7 +1193,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 ); @@ -1212,6 +1212,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 cad132763226..232d9be56bcf 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 ad32fb4fe2ef..a1018b9c65c1 100644 --- a/sw/source/writerfilter/dmapper/DomainMapper.cxx +++ b/sw/source/writerfilter/dmapper/DomainMapper.cxx @@ -4704,7 +4704,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()) {