tdf#153613 tdf#146984 writerfilter: split para after anchors
Even though the w:br occurs in the paragraph before the anchors,
the anchors stay on the first page, and don't move to the second page
(unless it is the last paragraph in the section/document,
which is not yet handled.)
make CppunitTest_sw_ooxmlexport18 \
CPPUNIT_TEST_NAME=testTdf153613_textboxAfterPgBreak3
Change-Id: Icfc7e2a5d7657f1eb8f94263a4bfc8dcca7e52de
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/148897
Tested-by: Jenkins
Reviewed-by: Justin Luth <jluth@mail.com>
diff --git a/sw/qa/extras/ooxmlexport/data/tdf153613_textboxAfterPgBreak3.docx b/sw/qa/extras/ooxmlexport/data/tdf153613_textboxAfterPgBreak3.docx
new file mode 100644
index 0000000..a282dea
--- /dev/null
+++ b/sw/qa/extras/ooxmlexport/data/tdf153613_textboxAfterPgBreak3.docx
Binary files differ
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport18.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport18.cxx
index 460f409..c30e555 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport18.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport18.cxx
@@ -217,6 +217,16 @@ DECLARE_OOXMLEXPORT_TEST(testTdf153613_textboxAfterPgBreak2, "tdf153613_textboxA
assertXPathContent(pLayout, "//page[2]/body/txt", "There should be no prior carriage return.");
}
DECLARE_OOXMLEXPORT_TEST(testTdf153613_textboxAfterPgBreak3, "tdf153613_textboxAfterPgBreak3.docx")
{
// All anchored TO-character shapes stay on the first page, before the page break.
CPPUNIT_ASSERT_EQUAL(2, getPages());
CPPUNIT_ASSERT_EQUAL(3, getParagraphs());
const auto& pLayout = parseLayoutDump();
assertXPath(pLayout, "//page[2]//anchored", 0);
}
DECLARE_OOXMLEXPORT_TEST(testTdf153613_sdtAfterPgBreak, "tdf153613_sdtAfterPgBreak.docx")
{
CPPUNIT_ASSERT_EQUAL(2, getPages());
diff --git a/writerfilter/source/dmapper/DomainMapper.cxx b/writerfilter/source/dmapper/DomainMapper.cxx
index c526968..800ae25 100644
--- a/writerfilter/source/dmapper/DomainMapper.cxx
+++ b/writerfilter/source/dmapper/DomainMapper.cxx
@@ -3635,7 +3635,7 @@ void DomainMapper::lcl_startShape(uno::Reference<drawing::XShape> const& xShape)
{
// If there is a deferred page break, handle it now, so that the
// started shape will be on the correct page.
if (m_pImpl->isBreakDeferred(PAGE_BREAK))
if (m_pImpl->isBreakDeferred(PAGE_BREAK) && !m_pImpl->IsBreakDeferredByAnchor())
{
// RTF doesn't properly report IsFirstRun, so in order to prevent regressions
// always split the paragraph for RTF since that is the way it has been done lately.
@@ -3645,6 +3645,9 @@ void DomainMapper::lcl_startShape(uno::Reference<drawing::XShape> const& xShape)
finishParagraph();
lcl_startParagraphGroup();
}
else
m_pImpl->SetIsBreakDeferredByAnchor();
}
m_pImpl->PushShapeContext( xShape );
lcl_startParagraphGroup();
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
index 62dda7d..f33d3c3 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
@@ -1477,6 +1477,7 @@ void DomainMapper_Impl::clearDeferredBreak(BreakType deferredBreakType)
break;
case PAGE_BREAK:
m_bIsPageBreakDeferred = false;
m_bIsBreakDeferredByAnchor = false;
break;
default:
break;
@@ -1488,6 +1489,17 @@ void DomainMapper_Impl::clearDeferredBreaks()
m_nLineBreaksDeferred = 0;
m_bIsColumnBreakDeferred = false;
m_bIsPageBreakDeferred = false;
m_bIsBreakDeferredByAnchor = false;
}
bool DomainMapper_Impl::IsBreakDeferredByAnchor()
{
return m_bIsBreakDeferredByAnchor;
}
void DomainMapper_Impl::SetIsBreakDeferredByAnchor()
{
m_bIsBreakDeferredByAnchor = true;
}
void DomainMapper_Impl::setSdtEndDeferred(bool bSdtEndDeferred)
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.hxx b/writerfilter/source/dmapper/DomainMapper_Impl.hxx
index 234ae94..050a510 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.hxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.hxx
@@ -487,6 +487,7 @@ private:
bool m_bIsColumnBreakDeferred;
bool m_bIsPageBreakDeferred;
sal_Int32 m_nLineBreaksDeferred;
bool m_bIsBreakDeferredByAnchor;
/// If we want to set "sdt end" on the next character context.
bool m_bSdtEndDeferred;
/// If we want to set "paragraph sdt end" on the next paragraph context.
@@ -755,6 +756,8 @@ public:
bool isBreakDeferred( BreakType deferredBreakType );
void clearDeferredBreaks();
void clearDeferredBreak(BreakType deferredBreakType);
bool IsBreakDeferredByAnchor();
void SetIsBreakDeferredByAnchor();
void setSdtEndDeferred(bool bSdtEndDeferred);
bool isSdtEndDeferred() const;