sw/qa/extras/rtfimport/data/section-pagebreak.rtf | 15 ++++++ sw/qa/extras/rtfimport/rtfimport.cxx | 48 ++++++++++++++++++++++ writerfilter/source/dmapper/DomainMapper.cxx | 1 writerfilter/source/rtftok/rtfdocumentimpl.cxx | 4 + 4 files changed, 68 insertions(+)
New commits: commit 454e5010aec9953f586fe8af671765358f6cafc4 Author: Michael Stahl <michael.st...@allotropia.de> AuthorDate: Wed Nov 15 18:24:50 2023 +0100 Commit: Michael Stahl <michael.st...@allotropia.de> CommitDate: Thu Nov 16 15:36:03 2023 +0100 tdf#153194 writerfilter: RTF import: testContSectionPageBreak last para For testContSectionPageBreak, Word inserts an additional empty paragraph at the end of the document that was missing in Writer. Ensure markLastSectionGroup() is always called at the end of the document so that the \par that is dispatched in m_bNeedPar case will be inserted and not automatically removed immediately. Also add a test for the same document without \sbknone, which has 4 pages instead of 2. Change-Id: Ib3e4fbdb66df55941e4a487d4b249cd98fe42008 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/159472 Tested-by: Jenkins Reviewed-by: Michael Stahl <michael.st...@allotropia.de> diff --git a/sw/qa/extras/rtfimport/data/section-pagebreak.rtf b/sw/qa/extras/rtfimport/data/section-pagebreak.rtf new file mode 100644 index 000000000000..077cd71e5d48 --- /dev/null +++ b/sw/qa/extras/rtfimport/data/section-pagebreak.rtf @@ -0,0 +1,15 @@ +{\rtf1 \ansi +\fet0 \ftnbj \paperw11905 \paperh16837 \margt2267 \margb1133 \margl1417 \margr1417 + +\sectd +FIRST +\par +\sect +SECOND +\par +\page +\sect +THIRD +\par +\sect +} diff --git a/sw/qa/extras/rtfimport/rtfimport.cxx b/sw/qa/extras/rtfimport/rtfimport.cxx index 3533b7a77f92..d561969f8989 100644 --- a/sw/qa/extras/rtfimport/rtfimport.cxx +++ b/sw/qa/extras/rtfimport/rtfimport.cxx @@ -877,10 +877,58 @@ CPPUNIT_TEST_FIXTURE(Test, testContSectionPageBreak) CPPUNIT_ASSERT_EQUAL(uno::Any(), uno::Reference<beans::XPropertySet>(xParaThird, uno::UNO_QUERY_THROW) ->getPropertyValue("PageDescName")); + // there is an empty paragraph after THIRD + uno::Reference<text::XTextRange> xParaLast = getParagraph(5); + CPPUNIT_ASSERT_EQUAL(OUString(), xParaLast->getString()); + try + { + getParagraph(6); + } + catch (container::NoSuchElementException const&) + { + // does not exist - expected + } CPPUNIT_ASSERT_EQUAL(2, getPages()); } +CPPUNIT_TEST_FIXTURE(Test, testSectionPageBreak) +{ + createSwDoc("section-pagebreak.rtf"); + uno::Reference<text::XTextRange> xParaSecond = getParagraph(2); + CPPUNIT_ASSERT_EQUAL(OUString("SECOND"), xParaSecond->getString()); + CPPUNIT_ASSERT_EQUAL(style::BreakType_NONE, + getProperty<style::BreakType>(xParaSecond, "BreakType")); + CPPUNIT_ASSERT(uno::Any() != getProperty<OUString>(xParaSecond, "PageDescName")); + // actually not sure how many paragraph there should be between + // SECOND and THIRD - important is that the page break is on there + // (could be either 1 or 2; in Word it's a 2-line paragraph with the 1st + // line containing only the page break being ~0 height) + uno::Reference<text::XTextRange> xParaNext = getParagraph(3); + CPPUNIT_ASSERT_EQUAL(OUString(), xParaNext->getString()); + //If PageDescName is not empty, a page break / switch to page style is defined + CPPUNIT_ASSERT_EQUAL(style::BreakType_PAGE_BEFORE, + getProperty<style::BreakType>(xParaNext, "BreakType")); + uno::Reference<text::XTextRange> xParaThird = getParagraph(4); + CPPUNIT_ASSERT_EQUAL(OUString("THIRD"), xParaThird->getString()); + CPPUNIT_ASSERT_EQUAL(style::BreakType_NONE, + getProperty<style::BreakType>(xParaThird, "BreakType")); + CPPUNIT_ASSERT(uno::Any() != getProperty<OUString>(xParaThird, "PageDescName")); + // there is an empty paragraph after THIRD + uno::Reference<text::XTextRange> xParaLast = getParagraph(5); + CPPUNIT_ASSERT_EQUAL(OUString(), xParaLast->getString()); + try + { + getParagraph(6); + } + catch (container::NoSuchElementException const&) + { + // does not exist - expected + } + + CPPUNIT_ASSERT_EQUAL(4, getPages()); +} + CPPUNIT_TEST_FIXTURE(Test, testBackground) { createSwDoc("background.rtf"); diff --git a/writerfilter/source/dmapper/DomainMapper.cxx b/writerfilter/source/dmapper/DomainMapper.cxx index dc863f3f5e8b..8cf91bcf859f 100644 --- a/writerfilter/source/dmapper/DomainMapper.cxx +++ b/writerfilter/source/dmapper/DomainMapper.cxx @@ -4410,6 +4410,7 @@ void DomainMapper::lcl_utext(const sal_uInt8 * data_, size_t len) (!m_pImpl->GetParaChanged() && m_pImpl->GetParaSectpr() && !bSingleParagraphAfterRedline && !bIsColumnBreak + && !m_pImpl->GetIsLastSectionGroup() // testContSectionPageBreak && !m_pImpl->GetParaHadField() && (!m_pImpl->GetIsDummyParaAddedForTableInSectionPage()) && !m_pImpl->GetIsPreviousParagraphFramed() diff --git a/writerfilter/source/rtftok/rtfdocumentimpl.cxx b/writerfilter/source/rtftok/rtfdocumentimpl.cxx index ef504ca900aa..958000e4587a 100644 --- a/writerfilter/source/rtftok/rtfdocumentimpl.cxx +++ b/writerfilter/source/rtftok/rtfdocumentimpl.cxx @@ -3662,6 +3662,10 @@ RTFError RTFDocumentImpl::popState() dispatchSymbol(RTFKeyword::PAR); if (m_bNeedSect) // may be set by dispatchSymbol above! sectBreak(true); + else if (!m_pSuperstream) + { + Mapper().markLastSectionGroup(); // ensure it's set for \par below + } if (m_bNeedPar && !m_pSuperstream) { assert(!m_bNeedSect);