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_luth@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 0000000..7072b47
--- /dev/null
+++ b/sw/qa/extras/ooxmlexport/data/tdf143692_outlineLevelTortureTest.docx
Binary files differ
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport16.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport16.cxx
index d1f0603..10cb7f1 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 ac63dc69..f5731e7 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 9178499..3314ce7 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 986db52..815a261 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 );