diff options
author | Vasily Melenchuk <vasily.melenchuk@cib.de> | 2022-02-09 09:41:51 +0300 |
---|---|---|
committer | Andras Timar <andras.timar@collabora.com> | 2022-02-14 11:00:11 +0100 |
commit | 2a6c3a539ac86c1c7e45bee5c5cc25909c6e8d33 (patch) | |
tree | b3175120fd8b229ce702f6a707d95b9bba7ae45a | |
parent | 5bedec81c5ab0151ab365752b039d482872fa813 (diff) |
tdf#146917: docx import: better support for style with num reset
When paragraph style is disabling numbering defined in parent
style we should apply margin properties (like we already do
in other numbering cases), but we should include only properties
from styles not affected by numbering. In other words, only
styles without w:numId are used.
Unittest was extended to cover different combinations of this
situation.
Change-Id: Ic19e00fcfe16b2357cdfe763b4f969cc63122e89
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/129701
Tested-by: Jenkins
Reviewed-by: Thorsten Behrens <thorsten.behrens@allotropia.de>
(cherry picked from commit 96e1be11540bada172fbdbfbbe3f9b7dc3e58462)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/129827
Reviewed-by: Vasily Melenchuk <vasily.melenchuk@cib.de>
-rw-r--r-- | sw/qa/extras/ooxmlexport/data/tdf132752.docx | bin | 34704 -> 26741 bytes | |||
-rw-r--r-- | sw/qa/extras/ooxmlexport/ooxmlexport16.cxx | 32 | ||||
-rw-r--r-- | writerfilter/source/dmapper/DomainMapper_Impl.cxx | 59 |
3 files changed, 83 insertions, 8 deletions
diff --git a/sw/qa/extras/ooxmlexport/data/tdf132752.docx b/sw/qa/extras/ooxmlexport/data/tdf132752.docx Binary files differindex 57eddc455fca..a94fc498a101 100644 --- a/sw/qa/extras/ooxmlexport/data/tdf132752.docx +++ b/sw/qa/extras/ooxmlexport/data/tdf132752.docx diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport16.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport16.cxx index 1e6938bcecc4..e3eb50c29ea4 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlexport16.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlexport16.cxx @@ -384,9 +384,35 @@ DECLARE_OOXMLEXPORT_TEST(testTdf143692_outlineLevelTortureTest, "tdf143692_outli DECLARE_OOXMLEXPORT_TEST(testTdf132752, "tdf132752.docx") { - CPPUNIT_ASSERT_EQUAL(sal_Int32(1801), getProperty<sal_Int32>(getParagraph(1), "ParaLeftMargin")); - CPPUNIT_ASSERT_EQUAL(sal_Int32(1000), getProperty<sal_Int32>(getParagraph(1), "ParaRightMargin")); - CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty<sal_Int32>(getParagraph(1), "ParaFirstLineIndent")); + uno::Reference<beans::XPropertySet> xPara1(getParagraph(1), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(sal_Int32(1801), getProperty<sal_Int32>(xPara1, "ParaLeftMargin")); + CPPUNIT_ASSERT_EQUAL(sal_Int32(1000), getProperty<sal_Int32>(xPara1, "ParaRightMargin")); + CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty<sal_Int32>(xPara1, "ParaFirstLineIndent")); + + uno::Reference<beans::XPropertySet> xPara2(getParagraph(2), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(sal_Int32(1801), getProperty<sal_Int32>(xPara2, "ParaLeftMargin")); + CPPUNIT_ASSERT_EQUAL(sal_Int32(1000), getProperty<sal_Int32>(xPara2, "ParaRightMargin")); + CPPUNIT_ASSERT_EQUAL(sal_Int32(-630), getProperty<sal_Int32>(xPara2, "ParaFirstLineIndent")); + + uno::Reference<beans::XPropertySet> xPara3(getParagraph(3), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty<sal_Int32>(xPara3, "ParaLeftMargin")); + CPPUNIT_ASSERT_EQUAL(sal_Int32(5891), getProperty<sal_Int32>(xPara3, "ParaRightMargin")); + CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty<sal_Int32>(xPara3, "ParaFirstLineIndent")); + + uno::Reference<beans::XPropertySet> xPara4(getParagraph(4), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(sal_Int32(1801), getProperty<sal_Int32>(xPara4, "ParaLeftMargin")); + CPPUNIT_ASSERT_EQUAL(sal_Int32(1000), getProperty<sal_Int32>(xPara4, "ParaRightMargin")); + CPPUNIT_ASSERT_EQUAL(sal_Int32(4157), getProperty<sal_Int32>(xPara4, "ParaFirstLineIndent")); + + uno::Reference<beans::XPropertySet> xPara5(getParagraph(5), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(sal_Int32(1801), getProperty<sal_Int32>(xPara5, "ParaLeftMargin")); + CPPUNIT_ASSERT_EQUAL(sal_Int32(1000), getProperty<sal_Int32>(xPara5, "ParaRightMargin")); + CPPUNIT_ASSERT_EQUAL(sal_Int32(-630), getProperty<sal_Int32>(xPara5, "ParaFirstLineIndent")); + + uno::Reference<beans::XPropertySet> xPara6(getParagraph(6), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(sal_Int32(3565), getProperty<sal_Int32>(xPara6, "ParaLeftMargin")); + CPPUNIT_ASSERT_EQUAL(sal_Int32(2764), getProperty<sal_Int32>(xPara6, "ParaRightMargin")); + CPPUNIT_ASSERT_EQUAL(sal_Int32(-2394), getProperty<sal_Int32>(xPara6, "ParaFirstLineIndent")); } DECLARE_OOXMLEXPORT_TEST(testGutterLeft, "gutter-left.docx") diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx b/writerfilter/source/dmapper/DomainMapper_Impl.cxx index 4b0f3f6c4e75..13f1fb9056b9 100644 --- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx +++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx @@ -183,6 +183,45 @@ static void lcl_handleTextField( const uno::Reference< beans::XPropertySet >& rx } } +/** + Very similar to DomainMapper_Impl::GetPropertyFromStyleSheet + It is focused on paragraph properties search in current & parent stylesheet entries. + But it will not take into account propeties with listid: these are "list paragraph styles" and + not used in some cases. +*/ +static uno::Any lcl_GetPropertyFromParaStyleSheetNoNum(PropertyIds eId, StyleSheetEntryPtr pEntry, const StyleSheetTablePtr& rStyleSheet) +{ + while (pEntry) + { + if (pEntry->pProperties) + { + std::optional<PropertyMap::Property> aProperty = + pEntry->pProperties->getProperty(eId); + if (aProperty) + { + if (pEntry->pProperties->GetListId()) + // It is a paragraph style with list. Paragraph list styles are not taken into account + return uno::Any(); + else + return aProperty->second; + } + } + //search until the property is set or no parent is available + StyleSheetEntryPtr pNewEntry; + if (!pEntry->sBaseStyleIdentifier.isEmpty()) + pNewEntry = rStyleSheet->FindStyleSheetByISTD(pEntry->sBaseStyleIdentifier); + + SAL_WARN_IF(pEntry == pNewEntry, "writerfilter.dmapper", "circular loop in style hierarchy?"); + + if (pEntry == pNewEntry) //fdo#49587 + break; + + pEntry = pNewEntry; + } + return uno::Any(); +} + + namespace { struct FieldConversion @@ -1771,11 +1810,21 @@ void DomainMapper_Impl::finishParagraph( const PropertyMapPtr& pPropertyMap, con if (nListId == 0 && !pList) { - // Seems situation with listid=0 and missing list definition is used by DOCX - // to remove numbering defined previously. But some default numbering attributes - // are still applied. This is first line indent, probably something more? - if (!pParaContext->isSet(PROP_PARA_FIRST_LINE_INDENT)) - pParaContext->Insert(PROP_PARA_FIRST_LINE_INDENT, uno::makeAny(sal_Int16(0)), false); + // listid = 0 and no list definition is used in DOCX to stop numbering + // defined somewhere in parent styles + // And here we should explicitly set left margin and first-line margin. + // They can be taken from referred style, but not from styles with listid! + uno::Any aProp = lcl_GetPropertyFromParaStyleSheetNoNum(PROP_PARA_FIRST_LINE_INDENT, pEntry, m_pStyleSheetTable); + if (aProp.hasValue()) + pParaContext->Insert(PROP_PARA_FIRST_LINE_INDENT, aProp, false); + else + pParaContext->Insert(PROP_PARA_FIRST_LINE_INDENT, uno::makeAny(sal_uInt32(0)), false); + + aProp = lcl_GetPropertyFromParaStyleSheetNoNum(PROP_PARA_LEFT_MARGIN, pEntry, m_pStyleSheetTable); + if (aProp.hasValue()) + pParaContext->Insert(PROP_PARA_LEFT_MARGIN, aProp, false); + else + pParaContext->Insert(PROP_PARA_LEFT_MARGIN, uno::makeAny(sal_uInt32(0)), false); } } |