sw/qa/extras/ooxmlexport/data/tdf143692_outlineLevelTortureTest.docx |binary
 sw/qa/extras/ooxmlexport/ooxmlexport16.cxx                           |   34 
++++++++++
 writerfilter/source/dmapper/DomainMapper.cxx                         |   10 +-
 writerfilter/source/dmapper/PropertyMap.hxx                          |    2 
 writerfilter/source/dmapper/StyleSheetTable.cxx                      |   18 
++++-
 5 files changed, 55 insertions(+), 9 deletions(-)

New commits:
commit 2aca75ef2ac84360d13e9000ba3063a7a42b6f6f
Author:     Justin Luth <justin_l...@sil.org>
AuthorDate: Thu Aug 19 15:06:35 2021 +0200
Commit:     Justin Luth <justin_l...@sil.org>
CommitDate: Mon Aug 23 06:30:53 2021 +0200

    tdf#143692 writerfilter: fix outlineLevel import x3
    
    First, illegal values don't mean "use body level".
    It means "inherit the value value from the style".
    So just ignore illegal values.
    
    Secondly, styles without any explicit setting (a -1)
    where being incorrectly specified as "-1 + 1",
    i.e. body level(0) - meaning that inheritance was always lost.
    
    Thirdly, the body level value is necessary in order to cancel inheritance
    from a style. So the style must be able to set a value of 9.
    
    Change-Id: I2161085181527fb321dbcc00636513330dd8ca1a
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/120756
    Tested-by: Jenkins
    Reviewed-by: Justin Luth <justin_l...@sil.org>

diff --git 
a/sw/qa/extras/ooxmlexport/data/tdf143692_outlineLevelTortureTest.docx 
b/sw/qa/extras/ooxmlexport/data/tdf143692_outlineLevelTortureTest.docx
new file mode 100644
index 000000000000..7072b47218d6
Binary files /dev/null and 
b/sw/qa/extras/ooxmlexport/data/tdf143692_outlineLevelTortureTest.docx differ
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport16.cxx 
b/sw/qa/extras/ooxmlexport/ooxmlexport16.cxx
index d1f0603ec884..10cb7f1126ed 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport16.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport16.cxx
@@ -329,6 +329,40 @@ 
DECLARE_OOXMLEXPORT_TEST(testTdf141966_chapterNumberTortureTest, "tdf141966_chap
     CPPUNIT_ASSERT_EQUAL(OUString(""), getProperty<OUString>(xPara, 
"ListLabelString"));
 }
 
+DECLARE_OOXMLEXPORT_TEST(testTdf143692_outlineLevelTortureTest, 
"tdf143692_outlineLevelTortureTest.docx")
+{
+    uno::Reference<beans::XPropertySet> xPara(getParagraph(1, "Head non Toc 
style"), uno::UNO_QUERY);
+    // fixed missing inherit from Heading 1
+    CPPUNIT_ASSERT_EQUAL(sal_Int16(1), getProperty<sal_Int16>(xPara, 
"OutlineLevel"));
+
+    xPara.set(getParagraph(2, "noInheritHeading1"), uno::UNO_QUERY);
+    // fixed body level not cancelling inherited level
+    CPPUNIT_ASSERT_EQUAL(sal_Int16(0), getProperty<sal_Int16>(xPara, 
"OutlineLevel"));
+
+    xPara.set(getParagraph(4, "illegal -3"), uno::UNO_QUERY);
+    // illegal value is ignored, so inherit from Heading 1
+    CPPUNIT_ASSERT_EQUAL(sal_Int16(1), getProperty<sal_Int16>(xPara, 
"OutlineLevel"));
+
+    xPara.set(getParagraph(5, "Heading 1 with invalid direct -2"), 
uno::UNO_QUERY);
+    // fixed illegal does not mean body level, it means inherit from style.
+    CPPUNIT_ASSERT_EQUAL(sal_Int16(1), getProperty<sal_Int16>(xPara, 
"OutlineLevel"));
+
+    xPara.set(getParagraph(7, "InheritCN3"), uno::UNO_QUERY);
+    // fixed Chapter Numbering cancelling inheritance
+    //CPPUNIT_ASSERT_EQUAL(sal_Int16(3), getProperty<sal_Int16>(xPara, 
"OutlineLevel"));
+
+    xPara.set(getParagraph(8, "noInheritCN3"), uno::UNO_QUERY);
+    CPPUNIT_ASSERT_EQUAL(sal_Int16(0), getProperty<sal_Int16>(xPara, 
"OutlineLevel"));
+
+    xPara.set(getParagraph(9, "override6CN3"), uno::UNO_QUERY);
+    // fixed body level not cancelling inherited level
+    CPPUNIT_ASSERT_EQUAL(sal_Int16(6), getProperty<sal_Int16>(xPara, 
"OutlineLevel"));
+
+    xPara.set(getParagraph(10, "illegal 25"), uno::UNO_QUERY);
+    // fixed illegal value is ignored, so inherit from List Level (Chapter 
Numbering)
+    //CPPUNIT_ASSERT_EQUAL(sal_Int16(3), getProperty<sal_Int16>(xPara, 
"OutlineLevel"));
+}
+
 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.cxx 
b/writerfilter/source/dmapper/DomainMapper.cxx
index ac63dc699fd2..f5731e735cbe 100644
--- a/writerfilter/source/dmapper/DomainMapper.cxx
+++ b/writerfilter/source/dmapper/DomainMapper.cxx
@@ -1556,17 +1556,19 @@ void DomainMapper::sprmWithProps( Sprm& rSprm, const 
PropertyMapPtr& rContext )
         break;
     case NS_ooxml::LN_CT_PPrBase_outlineLvl:
         {
-            sal_Int16 nLvl = static_cast< sal_Int16 >( nIntValue );
+            if (nIntValue < WW_OUTLINE_MIN || nIntValue > WW_OUTLINE_MAX)
+                break; // invalid value is ignored by MS Word
+
             if( IsStyleSheetImport() )
             {
-
                 StyleSheetPropertyMap* pStyleSheetPropertyMap = dynamic_cast< 
StyleSheetPropertyMap* >( rContext.get() );
                 if (pStyleSheetPropertyMap)
-                    pStyleSheetPropertyMap->SetOutlineLevel( nLvl );
+                    pStyleSheetPropertyMap->SetOutlineLevel(nIntValue);
             }
             else
             {
-                nLvl = nLvl >= WW_OUTLINE_MIN && nLvl < WW_OUTLINE_MAX? nLvl+1 
: 0; //0 means no outline level set on
+                // convert MS body level (9) to LO body level (0) and 
equivalent outline levels
+                sal_Int16 nLvl = nIntValue == WW_OUTLINE_MAX ? 0 : nIntValue + 
1;
                 rContext->Insert(PROP_OUTLINE_LEVEL, uno::makeAny ( nLvl ));
             }
         }
diff --git a/writerfilter/source/dmapper/PropertyMap.hxx 
b/writerfilter/source/dmapper/PropertyMap.hxx
index 917849957ce0..3314ce7451ae 100644
--- a/writerfilter/source/dmapper/PropertyMap.hxx
+++ b/writerfilter/source/dmapper/PropertyMap.hxx
@@ -541,7 +541,7 @@ public:
     void      SetListLevel( sal_Int16 nLevel ) { mnListLevel = nLevel; }
 
     sal_Int16 GetOutlineLevel() const             { return mnOutlineLevel; }
-    void      SetOutlineLevel( sal_Int16 nLevel ) { if ( nLevel < 
WW_OUTLINE_MAX ) mnOutlineLevel = nLevel; }
+    void SetOutlineLevel(sal_Int16 nLevel) { if (nLevel <= WW_OUTLINE_MAX) 
mnOutlineLevel = nLevel; }
 };
 
 class ParagraphPropertyMap
diff --git a/writerfilter/source/dmapper/StyleSheetTable.cxx 
b/writerfilter/source/dmapper/StyleSheetTable.cxx
index 986db5244771..815a261ac092 100644
--- a/writerfilter/source/dmapper/StyleSheetTable.cxx
+++ b/writerfilter/source/dmapper/StyleSheetTable.cxx
@@ -1104,10 +1104,20 @@ void StyleSheetTable::ApplyStyleSheets( const 
FontTablePtr& rFontTable )
 
                         if ( pStyleSheetProperties )
                         {
-                            beans::PropertyValue aLvlVal( getPropertyName( 
PROP_OUTLINE_LEVEL ), 0,
-                                    uno::makeAny( sal_Int16( 
pStyleSheetProperties->GetOutlineLevel( ) + 1 ) ),
-                                    beans::PropertyState_DIRECT_VALUE );
-                            aPropValues.push_back(aLvlVal);
+                            sal_Int16 nLvl = 
pStyleSheetProperties->GetOutlineLevel();
+                            // convert MS body Level (9) to LO body level (0) 
and equivalent outline levels
+                            if (nLvl != -1)
+                            {
+                                if (nLvl == WW_OUTLINE_MAX)
+                                    nLvl = 0;
+                                else
+                                    ++nLvl;
+
+                                beans::PropertyValue 
aLvlVal(getPropertyName(PROP_OUTLINE_LEVEL), 0,
+                                                             
uno::makeAny(nLvl),
+                                                             
beans::PropertyState_DIRECT_VALUE);
+                                aPropValues.push_back(aLvlVal);
+                            }
                         }
 
                         uno::Reference< beans::XPropertyState >xState( xStyle, 
uno::UNO_QUERY_THROW );

Reply via email to