summaryrefslogtreecommitdiff
path: root/sw
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.com>2024-05-31 09:00:18 +0200
committerMiklos Vajna <vmiklos@collabora.com>2024-05-31 12:58:00 +0200
commite00479404af5058b982c447e485af995d552e372 (patch)
treef50bdf68cda4dd5ddbe5397104a05d9a64232183 /sw
parent0764a44e185d7b940f442cc054f5f1afd8c5cc64 (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.cxx23
-rw-r--r--sw/qa/writerfilter/dmapper/data/clearing-break-sect-end.docxbin0 -> 12202 bytes
-rw-r--r--sw/source/writerfilter/dmapper/DomainMapper.cxx4
-rw-r--r--sw/source/writerfilter/dmapper/DomainMapper_Impl.cxx5
-rw-r--r--sw/source/writerfilter/dmapper/DomainMapper_Impl.hxx3
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
new file mode 100644
index 000000000000..5052b2dd1649
--- /dev/null
+++ b/sw/qa/writerfilter/dmapper/data/clearing-break-sect-end.docx
Binary files differ
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);