sw/qa/extras/rtfexport/data/tdf165564.odt |binary sw/qa/extras/rtfexport/rtfexport8.cxx | 15 +++++++++++++++ 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, 30 insertions(+), 11 deletions(-)
New commits: commit 74eae2899cee3b8720ccd86fdedf3fccecdf8035 Author: Oliver Specht <oliver.spe...@cib.de> AuthorDate: Tue May 6 08:34:17 2025 +0200 Commit: Thorsten Behrens <thorsten.behr...@allotropia.de> CommitDate: Thu May 8 17:18:39 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/+/184979 Reviewed-by: Thorsten Behrens <thorsten.behr...@allotropia.de> Tested-by: Thorsten Behrens <thorsten.behr...@allotropia.de> 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 0538ac71ea28..6a2638e2c436 100644 --- a/sw/qa/extras/rtfexport/rtfexport8.cxx +++ b/sw/qa/extras/rtfexport/rtfexport8.cxx @@ -609,6 +609,21 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf161878) saveAndReload(mpFilter); 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 a6845c56b633..8634b08b3e01 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 5c16d48b2dff..268d20c2ad11 100644 --- a/sw/source/filter/ww8/docxattributeoutput.cxx +++ b/sw/source/filter/ww8/docxattributeoutput.cxx @@ -3609,7 +3609,7 @@ void DocxAttributeOutput::WriteCollectedRunProperties() m_aTextEffectsGrabBag.clear(); } -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. @@ -3648,6 +3648,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 d9cddce059c7..8ac2d3cabb73 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 08b5d80a5d7d..6d307647a4fc 100644 --- a/sw/source/filter/ww8/rtfattributeoutput.cxx +++ b/sw/source/filter/ww8/rtfattributeoutput.cxx @@ -441,10 +441,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) @@ -3073,8 +3074,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 8ba84bed6055..37f2bd8f7ffc 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 a9ec2d1983c5..f48d0da0e4c6 100644 --- a/sw/source/filter/ww8/ww8atr.cxx +++ b/sw/source/filter/ww8/ww8atr.cxx @@ -1184,7 +1184,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 ); @@ -1203,6 +1203,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 a103cc4c11ce..70c34c28a92c 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 4a06df0bbb18..cadde4f8a57d 100644 --- a/sw/source/writerfilter/dmapper/DomainMapper.cxx +++ b/sw/source/writerfilter/dmapper/DomainMapper.cxx @@ -4637,7 +4637,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()) {