tdf#122589 rtfexport: no duplicate section at document start
If the document starts with a real section, then RTF export should
not write out \sect before the first paragraph, because there already
is an implicit section. Otherwise on import it is treated as an
empty paragraph.
The reason this problem doesn't multiply on each round-trip
is that the import process puts a PageBreak on the first
paragraph, and so it follows a different code path.
The ODT file does not contain a PageBreak on the first paragraph.
Change-Id: I8f2d48c932587aaf162e8f7352adf12ec15645f0
Reviewed-on: https://gerrit.libreoffice.org/66017
Tested-by: Jenkins
Reviewed-by: Justin Luth <justin_luth@sil.org>
(cherry picked from commit 5b19be032c51e0f7489b29c2c98e484587ed0865)
Reviewed-on: https://gerrit.libreoffice.org/66195
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
diff --git a/sw/qa/extras/rtfexport/data/tdf122589_firstSection.odt b/sw/qa/extras/rtfexport/data/tdf122589_firstSection.odt
new file mode 100644
index 0000000..751517c
--- /dev/null
+++ b/sw/qa/extras/rtfexport/data/tdf122589_firstSection.odt
Binary files differ
diff --git a/sw/qa/extras/rtfexport/rtfexport3.cxx b/sw/qa/extras/rtfexport/rtfexport3.cxx
index 3a5105f..e1ca5c9 100644
--- a/sw/qa/extras/rtfexport/rtfexport3.cxx
+++ b/sw/qa/extras/rtfexport/rtfexport3.cxx
@@ -11,6 +11,7 @@
#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
#include <com/sun/star/style/PageStyleLayout.hpp>
#include <com/sun/star/text/WritingMode2.hpp>
#include <com/sun/star/text/XFootnote.hpp>
#include <com/sun/star/text/XFootnotesSupplier.hpp>
#include <com/sun/star/text/XPageCursor.hpp>
@@ -77,6 +78,17 @@ DECLARE_RTFEXPORT_TEST(testTdf116436_tableBackground, "tdf116436_tableBackground
CPPUNIT_ASSERT_EQUAL(sal_Int32(0xFFFBCC), getProperty<sal_Int32>(xCell, "BackColor"));
}
DECLARE_RTFEXPORT_TEST(testTdf122589_firstSection, "tdf122589_firstSection.odt")
{
uno::Reference<beans::XPropertySet> xPageStyle(getStyles("PageStyles")->getByName("Standard"),
uno::UNO_QUERY);
uno::Reference<text::XTextRange> xHeaderText
= getProperty<uno::Reference<text::XTextRange>>(xPageStyle, "HeaderText");
CPPUNIT_ASSERT_EQUAL(OUString("My header"), xHeaderText->getString());
CPPUNIT_ASSERT_EQUAL_MESSAGE("# of paragraphs", 2, getParagraphs());
}
DECLARE_RTFEXPORT_TEST(testTdf104035, "tdf104035.rtf")
{
auto aTabStops = getProperty<uno::Sequence<style::TabStop>>(getParagraph(1), "ParaTabStops");
diff --git a/sw/source/filter/ww8/rtfattributeoutput.cxx b/sw/source/filter/ww8/rtfattributeoutput.cxx
index 62adfc6..0d06d47 100644
--- a/sw/source/filter/ww8/rtfattributeoutput.cxx
+++ b/sw/source/filter/ww8/rtfattributeoutput.cxx
@@ -243,6 +243,9 @@ void RtfAttributeOutput::RTLAndCJKState(bool bIsRTL, sal_uInt16 nScript)
void RtfAttributeOutput::StartParagraph(ww8::WW8TableNodeInfo::Pointer_t pTextNodeInfo)
{
if (m_bIsBeforeFirstParagraph && m_rExport.m_nTextTyp != TXT_HDFT)
m_bIsBeforeFirstParagraph = false;
// Output table/table row/table cell starts if needed
if (pTextNodeInfo)
{
@@ -1180,6 +1183,9 @@ void RtfAttributeOutput::SectionBreak(sal_uInt8 nC, const WW8_SepInfo* pSectionI
void RtfAttributeOutput::StartSection()
{
if (m_bIsBeforeFirstParagraph)
return;
m_aSectionBreaks.append(OOO_STRING_SVTOOLS_RTF_SECT OOO_STRING_SVTOOLS_RTF_SECTD);
if (!m_bBufferSectionBreaks)
m_rExport.Strm().WriteCharPtr(m_aSectionBreaks.makeStringAndClear().getStr());
@@ -3604,6 +3610,7 @@ RtfAttributeOutput::RtfAttributeOutput(RtfExport& rExport)
, m_bLastTable(true)
, m_bWroteCellInfo(false)
, m_bTableRowEnded(false)
, m_bIsBeforeFirstParagraph(true)
, m_bSingleEmptyRun(false)
, m_bInRun(false)
, m_pFlyFrameSize(nullptr)
diff --git a/sw/source/filter/ww8/rtfattributeoutput.hxx b/sw/source/filter/ww8/rtfattributeoutput.hxx
index 13c54e3..aab5b08 100644
--- a/sw/source/filter/ww8/rtfattributeoutput.hxx
+++ b/sw/source/filter/ww8/rtfattributeoutput.hxx
@@ -584,6 +584,8 @@ private:
/// Number of cells from the table definition, by depth.
std::map<sal_uInt32, sal_uInt32> m_aCells;
bool m_bIsBeforeFirstParagraph;
/// If we're in a paragraph that has a single empty run only.
bool m_bSingleEmptyRun;