tdf#153964 writerfilter: column break split should inherit most properties
When a column break or page break split occurs,
the split off paragraph should keep (most of) the properties
of the original paragraph. This already happened for page breaks.
Exceptions are first line indents, and numbering
if there was a run to apply them to already.
This commit:
-tells lcl_startParagraph when column breaks are m_bIsParaSplit,
resulting in the paragraph properties being copied over
-clears the para properties that shouldn't apply twice.
[Top Margin was more complicated and handled separately.]
make CppunitTest_sw_ooxmlexport18 \
CPPUNIT_TEST_NAME=testTdf153964_firstIndentAfterBreak14
make CppunitTest_sw_ooxmlexport18 \
CPPUNIT_TEST_NAME=testTdf153964_numberingAfterBreak14
Change-Id: I5ecd25da831894536044c6dbffbb0a262f8b6828
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/148452
Tested-by: Jenkins
Reviewed-by: Justin Luth <jluth@mail.com>
diff --git a/sw/qa/extras/ooxmlexport/data/tdf153964_firstIndentAfterBreak14.docx b/sw/qa/extras/ooxmlexport/data/tdf153964_firstIndentAfterBreak14.docx
new file mode 100644
index 0000000..696c4b4
--- /dev/null
+++ b/sw/qa/extras/ooxmlexport/data/tdf153964_firstIndentAfterBreak14.docx
Binary files differ
diff --git a/sw/qa/extras/ooxmlexport/data/tdf153964_numberingAfterBreak14.docx b/sw/qa/extras/ooxmlexport/data/tdf153964_numberingAfterBreak14.docx
new file mode 100644
index 0000000..a94a3c9
--- /dev/null
+++ b/sw/qa/extras/ooxmlexport/data/tdf153964_numberingAfterBreak14.docx
Binary files differ
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport18.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport18.cxx
index 1e87210..770ea9a 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport18.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport18.cxx
@@ -216,7 +216,7 @@ DECLARE_OOXMLEXPORT_TEST(testTdf153964_topMarginAfterBreak14, "tdf153964_topMarg
// The top margin was applied to paragraph 3, so it shouldn't apply here
xPara.set(getParagraph(4, u"column break1"), uno::UNO_QUERY);
CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty<sal_Int32>(xPara, "ParaTopMargin"));
//CPPUNIT_ASSERT_EQUAL(Color(0xfbe4d5), getProperty<Color>(xPara, "ParaBackColor"));
CPPUNIT_ASSERT_EQUAL(Color(0xfbe4d5), getProperty<Color>(xPara, "ParaBackColor"));
xPara.set(getParagraph(5, u"60 pt followed by page break"), uno::UNO_QUERY);
CPPUNIT_ASSERT_EQUAL(sal_Int32(2117), getProperty<sal_Int32>(xPara, "ParaTopMargin"));
@@ -240,7 +240,7 @@ DECLARE_OOXMLEXPORT_TEST(testTdf153964_topMarginAfterBreak14, "tdf153964_topMarg
// The top margin was not applied before the column break, so with compat14 it should apply here
xPara.set(getParagraph(10, u""), uno::UNO_QUERY); // after column break
CPPUNIT_ASSERT_EQUAL(sal_Int32(2117), getProperty<sal_Int32>(xPara, "ParaTopMargin"));
//CPPUNIT_ASSERT_EQUAL(Color(0xfff2cc), getProperty<Color>(xPara, "ParaBackColor"));
CPPUNIT_ASSERT_EQUAL(Color(0xfff2cc), getProperty<Color>(xPara, "ParaBackColor"));
// In an odd twist, the w:br was actually at the end of the previous w:p, so in that case
// we ignore the top margin definition this time.
@@ -262,7 +262,7 @@ DECLARE_OOXMLEXPORT_TEST(testTdf153964_topMarginAfterBreak15, "tdf153964_topMarg
// The top margin was applied to paragraph 3, so it shouldn't apply here
xPara.set(getParagraph(4, u"column break1"), uno::UNO_QUERY);
CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty<sal_Int32>(xPara, "ParaTopMargin"));
//CPPUNIT_ASSERT_EQUAL(Color(0xfbe4d5), getProperty<Color>(xPara, "ParaBackColor"));
CPPUNIT_ASSERT_EQUAL(Color(0xfbe4d5), getProperty<Color>(xPara, "ParaBackColor"));
xPara.set(getParagraph(5, u"60 pt followed by page break"), uno::UNO_QUERY);
CPPUNIT_ASSERT_EQUAL(sal_Int32(2117), getProperty<sal_Int32>(xPara, "ParaTopMargin"));
@@ -285,13 +285,47 @@ DECLARE_OOXMLEXPORT_TEST(testTdf153964_topMarginAfterBreak15, "tdf153964_topMarg
// The top margin was not applied to paragraph 9, and with compat15 it shouldn't apply here.
xPara.set(getParagraph(10, u""), uno::UNO_QUERY); // after column break
CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty<sal_Int32>(xPara, "ParaTopMargin"));
//CPPUNIT_ASSERT_EQUAL(Color(0xfff2cc), getProperty<Color>(xPara, "ParaBackColor"));
CPPUNIT_ASSERT_EQUAL(Color(0xfff2cc), getProperty<Color>(xPara, "ParaBackColor"));
// The top margin was not applied to paragraph 11, and with compat15 it shouldn't apply here.
xPara.set(getParagraph(12, u""), uno::UNO_QUERY); // after page break
CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty<sal_Int32>(xPara, "ParaTopMargin"));
}
DECLARE_OOXMLEXPORT_TEST(testTdf153964_numberingAfterBreak14, "tdf153964_numberingAfterBreak14.docx")
{
//Numbering should only apply once in a split paragraph.
uno::Reference<beans::XPropertySet> xPara(getParagraph(2, "How numbering affected by a column break?"), uno::UNO_QUERY);
//CPPUNIT_ASSERT_EQUAL(OUString("1."), getProperty<OUString>(xPara, "ListLabelString"));
xPara.set(getParagraph(3, "How is numbering affected by a page break?"), uno::UNO_QUERY);
//CPPUNIT_ASSERT_EQUAL(OUString("2."), getProperty<OUString>(xPara, "ListLabelString"));
xPara.set(getParagraph(4, "x"), uno::UNO_QUERY);
//CPPUNIT_ASSERT_EQUAL(OUString("3."), getProperty<OUString>(xPara, "ListLabelString"));
xPara.set(getParagraph(5, "column break"), uno::UNO_QUERY);
CPPUNIT_ASSERT_EQUAL(OUString(""), getProperty<OUString>(xPara, "ListLabelString"));
xPara.set(getParagraph(6, "y"), uno::UNO_QUERY);
//CPPUNIT_ASSERT_EQUAL(OUString("3."), getProperty<OUString>(xPara, "ListLabelString"));
xPara.set(getParagraph(7, "page break"), uno::UNO_QUERY);
CPPUNIT_ASSERT_EQUAL(OUString(""), getProperty<OUString>(xPara, "ListLabelString"));
}
DECLARE_OOXMLEXPORT_TEST(testTdf153964_firstIndentAfterBreak14, "tdf153964_firstIndentAfterBreak14.docx")
{
//First line indents should only apply once in a split paragraph.
uno::Reference<beans::XPropertySet> xPara(getParagraph(2, "How is first line indent affected by a column break?"), uno::UNO_QUERY);
CPPUNIT_ASSERT_EQUAL(sal_Int32(2000), getProperty<sal_Int32>(xPara, "ParaFirstLineIndent"));
xPara.set(getParagraph(3, "How is first line indent affected by a page break?"), uno::UNO_QUERY);
CPPUNIT_ASSERT_EQUAL(sal_Int32(2000), getProperty<sal_Int32>(xPara, "ParaFirstLineIndent"));
xPara.set(getParagraph(4, "x"), uno::UNO_QUERY);
CPPUNIT_ASSERT_EQUAL(sal_Int32(2000), getProperty<sal_Int32>(xPara, "ParaFirstLineIndent"));
xPara.set(getParagraph(5, "column break"), uno::UNO_QUERY);
CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty<sal_Int32>(xPara, "ParaFirstLineIndent"));
xPara.set(getParagraph(6, "y"), uno::UNO_QUERY);
CPPUNIT_ASSERT_EQUAL(sal_Int32(2000), getProperty<sal_Int32>(xPara, "ParaFirstLineIndent"));
xPara.set(getParagraph(7, "page break"), uno::UNO_QUERY);
CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty<sal_Int32>(xPara, "ParaFirstLineIndent"));
}
CPPUNIT_TEST_FIXTURE(Test, testTdf149551_mongolianVert)
{
// Given a docx document with a shape with vert="mongolianVert".
diff --git a/writerfilter/source/dmapper/DomainMapper.cxx b/writerfilter/source/dmapper/DomainMapper.cxx
index e712007..b7e94ff50e 100644
--- a/writerfilter/source/dmapper/DomainMapper.cxx
+++ b/writerfilter/source/dmapper/DomainMapper.cxx
@@ -1124,6 +1124,7 @@ void DomainMapper::lcl_attribute(Id nName, Value & val)
if (m_pImpl->GetIsFirstParagraphInSection() || !m_pImpl->IsFirstRun())
{
mbIsSplitPara = true;
m_pImpl->m_bIsSplitPara = true;
finishParagraph();
lcl_startParagraphGroup();
}
@@ -4164,6 +4165,7 @@ void DomainMapper::lcl_utext(const sal_uInt8 * data_, size_t len)
if ( m_pImpl->GetIsFirstParagraphInSection() || !m_pImpl->IsFirstRun() )
{
mbIsSplitPara = true;
m_pImpl->m_bIsSplitPara = true;
finishParagraph();
lcl_startParagraphGroup();
}
@@ -4263,6 +4265,7 @@ void DomainMapper::lcl_utext(const sal_uInt8 * data_, size_t len)
if (m_pImpl->GetIsFirstParagraphInSection() || !m_pImpl->IsFirstRun() || mbWasShapeInPara)
{
mbIsSplitPara = true;
m_pImpl->m_bIsSplitPara = true;
finishParagraph();
lcl_startParagraphGroup();
}
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
index 7e8dd6b..68f2511 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
@@ -1096,6 +1096,21 @@ void DomainMapper_Impl::PushProperties(ContextType eId)
}
if(eId == CONTEXT_PARAGRAPH && m_bIsSplitPara)
{
// Some paragraph properties only apply at the beginning of the paragraph - apply only once.
if (!m_bIsFirstRun)
{
auto pParaContext = static_cast<ParagraphPropertyMap*>(GetTopContextOfType(eId).get());
pParaContext->props().SetListId(-1);
pParaContext->Erase(PROP_NUMBERING_RULES); // only true with column, not page break
pParaContext->Erase(PROP_NUMBERING_LEVEL);
pParaContext->Erase(PROP_NUMBERING_TYPE);
pParaContext->Erase(PROP_START_WITH);
pParaContext->Insert(PROP_PARA_TOP_MARGIN, uno::Any(sal_uInt32(0)));
pParaContext->Erase(PROP_PARA_TOP_MARGIN_BEFORE_AUTO_SPACING);
pParaContext->Insert(PROP_PARA_FIRST_LINE_INDENT, uno::Any(sal_uInt32(0)));
}
m_aPropertyStacks[eId].push( GetTopContextOfType(eId));
m_bIsSplitPara = false;
}