sw/qa/extras/rtfexport/data/tdf167512.rtf | 11 ++++++++ sw/qa/extras/rtfexport/rtfexport8.cxx | 37 ++++++++++++++++++++++++++++ sw/source/filter/ww8/rtfattributeoutput.cxx | 7 +---- 3 files changed, 50 insertions(+), 5 deletions(-)
New commits: commit 64ce212034953d9f1fc242f7aa04ffabf0d96eea Author: Mike Kaganski <mike.kagan...@collabora.com> AuthorDate: Tue Jul 15 18:50:51 2025 +0500 Commit: Miklos Vajna <vmik...@collabora.com> CommitDate: Wed Jul 16 08:49:34 2025 +0200 tdf#167512: don't avoid resetting paragraphs' properties in fly Commit 5bbc027d5dae3472223538b13933ff821e027737 (cws-vmiklos01.diff: Better RTF export filter, 2010-09-17) introduced RtfAttributeOutput and its StartParagraphProperties, where output of \pard\plain was skipped when in fly. The reason likely was, that at that time, text boxes were output using an "old-style" method, where text box was purely a paragraph-level formatting. This created a problem: list settings weren't reset for following paragraphs, so lists continued incorrectly. Commit d53dd70b15f0e3f7c8a05a93f8fcd70e1147c1f7 (sw: rework RTF export of text frames, 2013-04-12) reimplemented text box export to use a "new-style" frames (using \shp ... \shptxt markup). This made it possible to restore resetting of paragraph properties, without breaking text boxes. This is done here. Change-Id: Idaabece2a658845906463c942aad45a142f87633 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/187920 Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com> Tested-by: Jenkins Reviewed-on: https://gerrit.libreoffice.org/c/core/+/187933 Reviewed-by: Miklos Vajna <vmik...@collabora.com> Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com> diff --git a/sw/qa/extras/rtfexport/data/tdf167512.rtf b/sw/qa/extras/rtfexport/data/tdf167512.rtf new file mode 100644 index 000000000000..476eb388be68 --- /dev/null +++ b/sw/qa/extras/rtfexport/data/tdf167512.rtf @@ -0,0 +1,11 @@ +{ tf1 +{onttbl{0romancharset0prq2 Liberation Serif;}} +{\*\listtable{\list\listtemplateid1{\listlevel\levelnfc23\leveljc0\levelfollow0{\leveltext \'01-}0}\listid1}} +{\listoverridetable{\listoverride\listid1\listoverridecount0\ls1}} +{\shp{\*\shpinst\shpwr1\shpbypara\shpbyignore\shptop0\shpbottom1700\shpbxcolumn\shpbxignore\shpleft1000\shpright4000 +{\shptxt +\pard0 AAA\par +\pard0\ls1 BBB\par +\pard0 CCC\par +}}} +\par } \ No newline at end of file diff --git a/sw/qa/extras/rtfexport/rtfexport8.cxx b/sw/qa/extras/rtfexport/rtfexport8.cxx index e697dab465ce..7862a235292d 100644 --- a/sw/qa/extras/rtfexport/rtfexport8.cxx +++ b/sw/qa/extras/rtfexport/rtfexport8.cxx @@ -735,6 +735,43 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf155835) } } +CPPUNIT_TEST_FIXTURE(Test, testTdf167512) +{ + // Given a document with a text box with a paragraph in a list, followed by a paragraph not + // in a list: + createSwDoc("tdf167512.rtf"); + { + CPPUNIT_ASSERT_EQUAL(1, getShapes()); + auto xTextBox = getShape(1).queryThrow<text::XText>(); + // First paragraph is not in list + auto xParagraph = getParagraphOfText(1, xTextBox, u"AAA"_ustr); + CPPUNIT_ASSERT(getProperty<OUString>(xParagraph, u"ListId"_ustr).isEmpty()); + // Second paragraph is in list (its ListId is not empty) + xParagraph = getParagraphOfText(2, xTextBox, u"BBB"_ustr); + CPPUNIT_ASSERT(!getProperty<OUString>(xParagraph, u"ListId"_ustr).isEmpty()); + // Third paragraph is not in list + xParagraph = getParagraphOfText(3, xTextBox, u"CCC"_ustr); + CPPUNIT_ASSERT(getProperty<OUString>(xParagraph, u"ListId"_ustr).isEmpty()); + } + // Check export + saveAndReload(mpFilter); + { + CPPUNIT_ASSERT_EQUAL(1, getShapes()); + auto xTextBox = getShape(1).queryThrow<text::XText>(); + // First paragraph is not in list + auto xParagraph = getParagraphOfText(1, xTextBox, u"AAA"_ustr); + CPPUNIT_ASSERT(getProperty<OUString>(xParagraph, u"ListId"_ustr).isEmpty()); + // Second paragraph is in list (its ListId is not empty) + xParagraph = getParagraphOfText(2, xTextBox, u"BBB"_ustr); + CPPUNIT_ASSERT(!getProperty<OUString>(xParagraph, u"ListId"_ustr).isEmpty()); + // Third paragraph is not in list + xParagraph = getParagraphOfText(3, xTextBox, u"CCC"_ustr); + // Without the fix, this failed, because on export, the paragraph's properties weren't + // reset to defaults using \pard when starting next paragraph; so the list continued: + CPPUNIT_ASSERT(getProperty<OUString>(xParagraph, u"ListId"_ustr).isEmpty()); + } +} + } // end of anonymous namespace CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/sw/source/filter/ww8/rtfattributeoutput.cxx b/sw/source/filter/ww8/rtfattributeoutput.cxx index bf7d99a628cb..01b92a9876db 100644 --- a/sw/source/filter/ww8/rtfattributeoutput.cxx +++ b/sw/source/filter/ww8/rtfattributeoutput.cxx @@ -383,11 +383,8 @@ void RtfAttributeOutput::SectionBreaks(const SwNode& rNode) void RtfAttributeOutput::StartParagraphProperties() { - OStringBuffer aPar; - if (!m_rExport.GetRTFFlySyntax()) - { - aPar.append(OOO_STRING_SVTOOLS_RTF_PARD OOO_STRING_SVTOOLS_RTF_PLAIN " "); - } + static constexpr std::string_view aPar(OOO_STRING_SVTOOLS_RTF_PARD OOO_STRING_SVTOOLS_RTF_PLAIN + " "); if (!m_bBufferSectionHeaders) m_rExport.Strm().WriteOString(aPar); else