sw/qa/extras/ooxmlexport/data/tdf141966_chapterNumberTortureTest.docx |binary
 sw/qa/extras/ooxmlexport/ooxmlexport16.cxx                            |   19 
+++
 writerfilter/source/dmapper/DomainMapper_Impl.cxx                     |   56 
++++++++--
 writerfilter/source/dmapper/DomainMapper_Impl.hxx                     |    2 
 4 files changed, 71 insertions(+), 6 deletions(-)

New commits:
commit bedd73ea578ad01171536ee90d22249fa221d2d6
Author:     Justin Luth <justin_l...@sil.org>
AuthorDate: Fri Apr 30 13:01:29 2021 +0200
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Thu Jul 8 13:16:06 2021 +0200

    tdf#141964 writerfilter CN: get paragraph and inherited listLevel
    
    Just like numId, listLevel is inherited from parent styles.
    This was totally missing. Even the direct formatting of
    a listLevel value was ignored (although that case would
    be rare, because usually both numId and listLevel are defined
    together).
    
    It seems like the most fundamental basics of our numbering
    import are wrong. EXTREMELY DANGEROUS TERRITORY,
    although this particular change ought to be quite safe.
    
    Change-Id: Ia3cbd941a0a90a932938597e0797ee8e2b0aca6c
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/115257
    Tested-by: Jenkins
    Reviewed-by: Justin Luth <justin_l...@sil.org>
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>

diff --git 
a/sw/qa/extras/ooxmlexport/data/tdf141966_chapterNumberTortureTest.docx 
b/sw/qa/extras/ooxmlexport/data/tdf141966_chapterNumberTortureTest.docx
new file mode 100644
index 000000000000..808a70846617
Binary files /dev/null and 
b/sw/qa/extras/ooxmlexport/data/tdf141966_chapterNumberTortureTest.docx differ
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport16.cxx 
b/sw/qa/extras/ooxmlexport/ooxmlexport16.cxx
index 8ec840b3b479..7ef26bb13b4c 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport16.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport16.cxx
@@ -151,6 +151,25 @@ DECLARE_OOXMLEXPORT_TEST(testTdf141966_chapterNumbering, 
"tdf141966_chapterNumbe
     CPPUNIT_ASSERT_EQUAL(OUString("2nd"), getProperty<OUString>(xPara, 
"ListLabelString"));
 }
 
+DECLARE_OOXMLEXPORT_TEST(testTdf141966_chapterNumberTortureTest, 
"tdf141966_chapterNumberTortureTest.docx")
+{
+    // There is no point in identifying what the wrong values where in this 
test,
+    //because EVERYTHING was wrong, and MANY different fixes are required to 
solve the problems.
+    uno::Reference<beans::XPropertySet> xPara(getParagraph(1, "No numId in 
style or paragraph"), uno::UNO_QUERY);
+    CPPUNIT_ASSERT_EQUAL(OUString(""), getProperty<OUString>(xPara, 
"ListLabelString"));
+
+    xPara.set(getParagraph(2, "Paragraph cancels numbering(0)"), 
uno::UNO_QUERY);
+    CPPUNIT_ASSERT_EQUAL(OUString(""), getProperty<OUString>(xPara, 
"ListLabelString"));
+
+    xPara.set(getParagraph(3, "First numbered line"), uno::UNO_QUERY);
+    CPPUNIT_ASSERT_EQUAL(OUString("1st.i.a.1.I"), getProperty<OUString>(xPara, 
"ListLabelString"));
+
+    xPara.set(getParagraph(7, "inheritOnly: inherit outlineLvl and listLvl."), 
uno::UNO_QUERY);
+    // 2nd.iii in MS Word 2003.  2nd.ii in MS Word 2010/2016 where para5 is 
not numbered. Why not?
+    CPPUNIT_ASSERT_EQUAL(OUString("2nd.iii"), getProperty<OUString>(xPara, 
"ListLabelString"));
+    CPPUNIT_ASSERT_EQUAL(sal_Int16(1), getProperty<sal_Int16>(xPara, 
"NumberingLevel")); // Level 2
+}
+
 DECLARE_OOXMLEXPORT_TEST(testTdf132752, "tdf132752.docx")
 {
     CPPUNIT_ASSERT_EQUAL(sal_Int32(1801), 
getProperty<sal_Int32>(getParagraph(1), "ParaLeftMargin"));
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx 
b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
index 25390cc20024..74550ec80245 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
@@ -1447,6 +1447,45 @@ static sal_Int32 lcl_getListId(const StyleSheetEntryPtr& 
rEntry, const StyleShee
     return lcl_getListId(pParent, rStyleTable, rNumberingFromBaseStyle);
 }
 
+/// Return the paragraph's list level (from styles, unless pParacontext is 
provided).
+/// -1 indicates the level is not set anywhere. [In that case, with a numId, 
use 0 (level 1)]
+///  9 indicates that numbering should be at body level (aka disabled) - 
rarely used by MSWord.
+///  0-8 are the nine valid numbering levels.
+sal_Int16 DomainMapper_Impl::GetListLevel(const StyleSheetEntryPtr& pEntry,
+                                  const PropertyMapPtr& pParaContext)
+{
+    sal_Int16 nListLevel = -1;
+    if (pParaContext)
+    {
+        GetAnyProperty(PROP_NUMBERING_LEVEL, pParaContext) >>= nListLevel;
+        if (nListLevel != -1)
+            return nListLevel;
+    }
+
+    if (!pEntry)
+        return -1;
+
+    const StyleSheetPropertyMap* pEntryProperties = dynamic_cast<const 
StyleSheetPropertyMap*>(pEntry->pProperties.get());
+    if (!pEntryProperties)
+        return -1;
+
+    nListLevel = pEntryProperties->GetListLevel();
+    // The style itself has a list level.
+    if (nListLevel >= 0)
+        return nListLevel;
+
+    // The style has no parent.
+    if (pEntry->sBaseStyleIdentifier.isEmpty())
+        return -1;
+
+    const StyleSheetEntryPtr pParent = 
GetStyleSheetTable()->FindStyleSheetByISTD(pEntry->sBaseStyleIdentifier);
+    // No such parent style or loop in the style hierarchy.
+    if (!pParent || pParent == pEntry)
+        return -1;
+
+    return GetListLevel(pParent);
+}
+
 void DomainMapper_Impl::finishParagraph( const PropertyMapPtr& pPropertyMap, 
const bool bRemove, const bool bNoNumbering )
 {
     if (m_bDiscardHeaderFooter)
@@ -1499,14 +1538,19 @@ void DomainMapper_Impl::finishParagraph( const 
PropertyMapPtr& pPropertyMap, con
     sal_Int32 nListId = -1;
     if ( !bRemove && pStyleSheetProperties && pParaContext )
     {
+        bool bNumberingFromBaseStyle = false;
+        nListId = lcl_getListId(pEntry, GetStyleSheetTable(), 
bNumberingFromBaseStyle);
+
         //apply numbering level/style to paragraph if it was set at the style, 
but only if the paragraph itself
         //does not specify the numbering
-        const sal_Int16 nListLevel = pStyleSheetProperties->GetListLevel();
+        sal_Int16 nListLevel = GetListLevel(pEntry, pParaContext);
+        // Undefined listLevel with a valid numId is treated as a first level 
numbering.
+        if (nListLevel == -1 && nListId > 0)
+            nListLevel = 0;
+
         if ( !bNoNumbering && !isNumberingViaRule && nListLevel >= 0 )
             pParaContext->Insert( PROP_NUMBERING_LEVEL, 
uno::makeAny(nListLevel), false );
 
-        bool bNumberingFromBaseStyle = false;
-        nListId = pEntry ? lcl_getListId(pEntry, GetStyleSheetTable(), 
bNumberingFromBaseStyle) : -1;
         auto const pList(GetListTable()->GetList(nListId));
         if (pList && nListId >= 0 && 
!pParaContext->isSet(PROP_NUMBERING_STYLE_NAME))
         {
@@ -2094,7 +2138,7 @@ void DomainMapper_Impl::finishParagraph( const 
PropertyMapPtr& pPropertyMap, con
                                 xParaProps->setPropertyValue("ParaLeftMargin", 
aMargin);
                             else if (isNumberingViaStyle)
                             {
-                                const sal_Int32 nParaLeftMargin = 
getNumberingProperty(nListId, pStyleSheetProperties->GetListLevel(), 
"IndentAt");
+                                const sal_Int32 nParaLeftMargin = 
getNumberingProperty(nListId, GetListLevel(pEntry, pPropertyMap), "IndentAt");
                                 if (nParaLeftMargin != 0)
                                     
xParaProps->setPropertyValue("ParaLeftMargin", uno::makeAny(nParaLeftMargin));
                             }
@@ -2112,7 +2156,7 @@ void DomainMapper_Impl::finishParagraph( const 
PropertyMapPtr& pPropertyMap, con
                                 
xParaProps->setPropertyValue("ParaFirstLineIndent", aMargin);
                             else if (isNumberingViaStyle)
                             {
-                                const sal_Int32 nFirstLineIndent = 
getNumberingProperty(nListId, pStyleSheetProperties->GetListLevel(), 
"FirstLineIndent");
+                                const sal_Int32 nFirstLineIndent = 
getNumberingProperty(nListId, GetListLevel(pEntry, pPropertyMap), 
"FirstLineIndent");
                                 if (nFirstLineIndent != 0)
                                     
xParaProps->setPropertyValue("ParaFirstLineIndent", 
uno::makeAny(nFirstLineIndent));
                             }
@@ -7579,7 +7623,7 @@ uno::Reference<container::XIndexAccess> 
DomainMapper_Impl::GetCurrentNumberingRu
         if (nListId < 0)
             return xRet;
         if (pListLevel)
-            *pListLevel = pStyleSheetProperties->GetListLevel();
+            *pListLevel = GetListLevel(pEntry, 
GetTopContextOfType(CONTEXT_PARAGRAPH));
 
         // So we are in a paragraph style and it has numbering. Look up the 
relevant numbering rules.
         auto const pList(GetListTable()->GetList(nListId));
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.hxx 
b/writerfilter/source/dmapper/DomainMapper_Impl.hxx
index c89e24cd4329..88b3eb7d8332 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.hxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.hxx
@@ -1031,6 +1031,8 @@ public:
     /// If the current paragraph has a numbering style associated, this method 
returns its numbering rules
     css::uno::Reference<css::container::XIndexAccess> 
GetCurrentNumberingRules(sal_Int32* pListLevel);
 
+    sal_Int16 GetListLevel(const StyleSheetEntryPtr& pEntry, const 
PropertyMapPtr& pParaContext = nullptr);
+
     /**
      Used for attributes/sprms which cannot be evaluated immediately (e.g. 
they depend
      on another one that comes in the same CONTEXT_CHARACTER). The property 
will be processed
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to