diff options
author | Miklos Vajna <vmiklos@collabora.com> | 2024-05-31 09:00:18 +0200 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.com> | 2024-05-31 12:58:00 +0200 |
commit | e00479404af5058b982c447e485af995d552e372 (patch) | |
tree | f50bdf68cda4dd5ddbe5397104a05d9a64232183 /sw | |
parent | 0764a44e185d7b940f442cc054f5f1afd8c5cc64 (diff) |
tdf#161318 sw clearing break: fix this at section end
Regression from commit 19bca24486315cc35f873486e6a2dd18394d0614
(tdf#126287: docx import: use defered linebreak, 2022-02-07), the bugdoc
has a single paragraph in the first section, containing a clearing
break, which is lost. This leads to overlapping text as the text is
shifted up.
Seems the intention was to avoid a line break at the very end of the
document, as that can lead to an empty page with "next page" section
breaks, with non-clearing line breaks.
Fix the problem by only doing this for non-clearing line breaks: that
keeps the old use-case working, but the new, clearing line break then
shifts down the text, so no text overlap happens.
Switching from appendTextPortion() to HandleLineBreak() helps because
HandleLineBreak() does exactly appendTextPortion("\n") in the
non-clearing case, but knows about the stream stack's line break clear
status.
Change-Id: I38868eeeac55e20e86b668e9baf7e0d6a4976608
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/168278
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
Tested-by: Jenkins
Diffstat (limited to 'sw')
-rw-r--r-- | sw/qa/writerfilter/dmapper/DomainMapper_Impl.cxx | 23 | ||||
-rw-r--r-- | sw/qa/writerfilter/dmapper/data/clearing-break-sect-end.docx | bin | 0 -> 12202 bytes | |||
-rw-r--r-- | sw/source/writerfilter/dmapper/DomainMapper.cxx | 4 | ||||
-rw-r--r-- | sw/source/writerfilter/dmapper/DomainMapper_Impl.cxx | 5 | ||||
-rw-r--r-- | sw/source/writerfilter/dmapper/DomainMapper_Impl.hxx | 3 |
5 files changed, 33 insertions, 2 deletions
diff --git a/sw/qa/writerfilter/dmapper/DomainMapper_Impl.cxx b/sw/qa/writerfilter/dmapper/DomainMapper_Impl.cxx index 825e615fb574..963db22c4c28 100644 --- a/sw/qa/writerfilter/dmapper/DomainMapper_Impl.cxx +++ b/sw/qa/writerfilter/dmapper/DomainMapper_Impl.cxx @@ -411,6 +411,29 @@ CPPUNIT_TEST_FIXTURE(Test, testRedlinedShapeThenSdt) CPPUNIT_ASSERT_EQUAL(u"ContentControl"_ustr, xPortion->getPropertyValue("TextPortionType").get<OUString>()); } + +CPPUNIT_TEST_FIXTURE(Test, testClearingBreakSectEnd) +{ + // Given a file with a single-paragraph section, ends with a clearing break: + // When importing that document: + loadFromFile(u"clearing-break-sect-end.docx"); + + // Then make sure the clearing break is not lost before a cont sect break: + uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY); + uno::Reference<container::XEnumerationAccess> xParaEnumAccess(xTextDocument->getText(), + uno::UNO_QUERY); + uno::Reference<container::XEnumeration> xParaEnum = xParaEnumAccess->createEnumeration(); + uno::Reference<container::XEnumerationAccess> xPortionEnumAccess(xParaEnum->nextElement(), + uno::UNO_QUERY); + uno::Reference<container::XEnumeration> xPortionEnum = xPortionEnumAccess->createEnumeration(); + uno::Reference<beans::XPropertySet> xPortion(xPortionEnum->nextElement(), uno::UNO_QUERY); + // Without the accompanying fix in place, this test would have failed with: + // - Expected: LineBreak + // - Actual : Text + // i.e. the clearing break at sect end was lost, leading to text overlap. + CPPUNIT_ASSERT_EQUAL(u"LineBreak"_ustr, + xPortion->getPropertyValue("TextPortionType").get<OUString>()); +} } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/qa/writerfilter/dmapper/data/clearing-break-sect-end.docx b/sw/qa/writerfilter/dmapper/data/clearing-break-sect-end.docx Binary files differnew file mode 100644 index 000000000000..5052b2dd1649 --- /dev/null +++ b/sw/qa/writerfilter/dmapper/data/clearing-break-sect-end.docx diff --git a/sw/source/writerfilter/dmapper/DomainMapper.cxx b/sw/source/writerfilter/dmapper/DomainMapper.cxx index 9144acaf79f7..72f88fc2a1a3 100644 --- a/sw/source/writerfilter/dmapper/DomainMapper.cxx +++ b/sw/source/writerfilter/dmapper/DomainMapper.cxx @@ -4347,13 +4347,13 @@ void DomainMapper::lcl_utext(const sal_Unicode *const data_, size_t len) else if (len == 1 && sText[0] == '\r') { // Clear "last" one linebreak at end of section - if (m_pImpl->GetIsLastParagraphInSection() && m_pImpl->isBreakDeferred(LINE_BREAK)) + if (m_pImpl->GetIsLastParagraphInSection() && m_pImpl->isBreakDeferred(LINE_BREAK) && !m_pImpl->HasLineBreakClear()) m_pImpl->clearDeferredBreak(LINE_BREAK); // And emit all other linebreaks while (m_pImpl->isBreakDeferred(LINE_BREAK)) { m_pImpl->clearDeferredBreak(LINE_BREAK); - m_pImpl->appendTextPortion(u"\n"_ustr, m_pImpl->GetTopContext()); + m_pImpl->HandleLineBreak(m_pImpl->GetTopContext()); } } else if (len == 1 && sText[0] == '\t' ) diff --git a/sw/source/writerfilter/dmapper/DomainMapper_Impl.cxx b/sw/source/writerfilter/dmapper/DomainMapper_Impl.cxx index 7ce54f5ace36..32d26b03d5bb 100644 --- a/sw/source/writerfilter/dmapper/DomainMapper_Impl.cxx +++ b/sw/source/writerfilter/dmapper/DomainMapper_Impl.cxx @@ -5176,6 +5176,11 @@ void DomainMapper_Impl::HandleLineBreakClear(sal_Int32 nClear) } } +bool DomainMapper_Impl::HasLineBreakClear() const +{ + return m_StreamStateStack.top().oLineBreakClear.has_value(); +} + void DomainMapper_Impl::HandleLineBreak(const PropertyMapPtr& pPropertyMap) { if (!m_StreamStateStack.top().oLineBreakClear.has_value()) diff --git a/sw/source/writerfilter/dmapper/DomainMapper_Impl.hxx b/sw/source/writerfilter/dmapper/DomainMapper_Impl.hxx index d54b42e719dd..7962facc5252 100644 --- a/sw/source/writerfilter/dmapper/DomainMapper_Impl.hxx +++ b/sw/source/writerfilter/dmapper/DomainMapper_Impl.hxx @@ -1234,6 +1234,9 @@ public: /// Handles <w:br w:clear="...">. void HandleLineBreakClear(sal_Int32 nClear); + /// Checks if we have a pending <w:br w:clear="...">. + bool HasLineBreakClear() const; + /// Handles <w:br>. void HandleLineBreak(const PropertyMapPtr& pPropertyMap); |