tdf#143692 writerfilter CN: reapply lost OutlineLevel
The paragraph styles had already set their numbering-related
properties before numbering.xml choses some styles
to be assigned as Chapter Numbering. Part of this CN process
in SW is to clear the inheriting styles of any inherited
numbering properties (numId, listLevel, outlineLevel).
So, we need to re-address outline levels after
numbering has been imported, and fix up anything
that has been cleared.
[P.S. No need to do the same thing for listLevel yet,
b/c LO does not support listLevel on paragraph styles in general.]
Change-Id: Idfb4d150b94558b069dbb1a87c764460396b34d6
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/120757
Tested-by: Jenkins
Reviewed-by: Justin Luth <justin_luth@sil.org>
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport16.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport16.cxx
index 10cb7f1..e2f68bc 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport16.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport16.cxx
@@ -349,7 +349,7 @@ DECLARE_OOXMLEXPORT_TEST(testTdf143692_outlineLevelTortureTest, "tdf143692_outli
xPara.set(getParagraph(7, "InheritCN3"), uno::UNO_QUERY);
// fixed Chapter Numbering cancelling inheritance
//CPPUNIT_ASSERT_EQUAL(sal_Int16(3), getProperty<sal_Int16>(xPara, "OutlineLevel"));
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"));
@@ -360,7 +360,7 @@ DECLARE_OOXMLEXPORT_TEST(testTdf143692_outlineLevelTortureTest, "tdf143692_outli
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"));
CPPUNIT_ASSERT_EQUAL(sal_Int16(3), getProperty<sal_Int16>(xPara, "OutlineLevel"));
}
DECLARE_OOXMLEXPORT_TEST(testTdf132752, "tdf132752.docx")
diff --git a/writerfilter/source/dmapper/NumberingManager.cxx b/writerfilter/source/dmapper/NumberingManager.cxx
index b0f1102..9e2072b 100644
--- a/writerfilter/source/dmapper/NumberingManager.cxx
+++ b/writerfilter/source/dmapper/NumberingManager.cxx
@@ -610,6 +610,7 @@ void ListDef::CreateNumberingRules( DomainMapper& rDMapper,
xOutlines->getChapterNumberingRules( );
StyleSheetEntryPtr pParaStyle = pAbsLevel->GetParaStyle( );
pParaStyle->bAssignedAsChapterNumbering = true;
aLvlProps.push_back(comphelper::makePropertyValue(getPropertyName(PROP_HEADING_STYLE_NAME), pParaStyle->sConvertedStyleName));
xOutlineRules->replaceByIndex(nLevel, uno::makeAny(comphelper::containerToSequence(aLvlProps)));
@@ -1206,6 +1207,7 @@ void ListsManager::CreateNumberingRules( )
{
rList->CreateNumberingRules(m_rDMapper, m_xFactory, nChosenAsChapterNumberingId);
}
m_rDMapper.GetStyleSheetTable()->ReApplyInheritedOutlineLevelFromChapterNumbering();
m_rDMapper.GetStyleSheetTable()->ApplyNumberingStyleNameToParaStyles();
}
diff --git a/writerfilter/source/dmapper/StyleSheetTable.cxx b/writerfilter/source/dmapper/StyleSheetTable.cxx
index 815a261..11f0fdd 100644
--- a/writerfilter/source/dmapper/StyleSheetTable.cxx
+++ b/writerfilter/source/dmapper/StyleSheetTable.cxx
@@ -55,6 +55,7 @@ namespace writerfilter::dmapper
StyleSheetEntry::StyleSheetEntry() :
sStyleIdentifierD()
,bIsDefaultStyle(false)
,bAssignedAsChapterNumbering(false)
,bInvalidHeight(false)
,bHasUPE(false)
,nStyleTypeCode(STYLE_TYPE_UNKNOWN)
@@ -940,6 +941,59 @@ void StyleSheetTable::ApplyNumberingStyleNameToParaStyles()
}
}
/* Counteract the destructive tendencies of LibreOffice's Chapter Numbering
*
* Any assignment to Chapter Numbering will erase the numbering-like properties of inherited styles.
* So go through the list of styles and any that inherit from a Chapter Numbering style
* should have the Outline Level reapplied.
*/
void StyleSheetTable::ReApplyInheritedOutlineLevelFromChapterNumbering()
{
try
{
uno::Reference< style::XStyleFamiliesSupplier > xStylesSupplier(m_pImpl->m_xTextDocument, uno::UNO_QUERY_THROW);
uno::Reference< lang::XMultiServiceFactory > xDocFactory(m_pImpl->m_xTextDocument, uno::UNO_QUERY_THROW);
uno::Reference< container::XNameAccess > xStyleFamilies = xStylesSupplier->getStyleFamilies();
uno::Reference<container::XNameContainer> xParaStyles;
xStyleFamilies->getByName(getPropertyName(PROP_PARAGRAPH_STYLES)) >>= xParaStyles;
if (!xParaStyles.is())
return;
for (auto& pEntry : m_pImpl->m_aStyleSheetEntries)
{
if (pEntry->nStyleTypeCode != STYLE_TYPE_PARA || pEntry->sBaseStyleIdentifier.isEmpty())
continue;
sal_Int16 nOutlineLevel = pEntry->pProperties->GetOutlineLevel();
if (nOutlineLevel != -1)
continue;
StyleSheetEntryPtr pParent = FindStyleSheetByISTD(pEntry->sBaseStyleIdentifier);
if (!pParent || !pParent->bAssignedAsChapterNumbering)
continue;
nOutlineLevel = pParent->pProperties->GetOutlineLevel();
assert(nOutlineLevel >= WW_OUTLINE_MIN && nOutlineLevel < WW_OUTLINE_MAX);
// convert MS level to LO equivalent outline level
++nOutlineLevel;
uno::Reference< style::XStyle > xStyle;
xParaStyles->getByName(pEntry->sConvertedStyleName) >>= xStyle;
if ( !xStyle.is() )
break;
uno::Reference<beans::XPropertySet> xPropertySet( xStyle, uno::UNO_QUERY_THROW );
xPropertySet->setPropertyValue(getPropertyName(PROP_OUTLINE_LEVEL), uno::makeAny(nOutlineLevel));
}
}
catch( const uno::Exception& )
{
DBG_UNHANDLED_EXCEPTION("writerfilter", "Failed applying outlineLevel to Paragraph styles");
}
}
void StyleSheetTable::ApplyStyleSheets( const FontTablePtr& rFontTable )
{
try
diff --git a/writerfilter/source/dmapper/StyleSheetTable.hxx b/writerfilter/source/dmapper/StyleSheetTable.hxx
index 081d5ef..b0dd24f 100644
--- a/writerfilter/source/dmapper/StyleSheetTable.hxx
+++ b/writerfilter/source/dmapper/StyleSheetTable.hxx
@@ -52,6 +52,7 @@ class StyleSheetEntry : public virtual SvRefBase
public:
OUString sStyleIdentifierD; // WW8 name
bool bIsDefaultStyle;
bool bAssignedAsChapterNumbering;
bool bInvalidHeight;
bool bHasUPE; //universal property expansion
StyleType nStyleTypeCode; //sgc
@@ -88,6 +89,7 @@ public:
StyleSheetTable(DomainMapper& rDMapper, css::uno::Reference<css::text::XTextDocument> const& xTextDocument, bool bIsNewDoc);
virtual ~StyleSheetTable() override;
void ReApplyInheritedOutlineLevelFromChapterNumbering();
void ApplyNumberingStyleNameToParaStyles();
void ApplyStyleSheets( const FontTablePtr& rFontTable );
StyleSheetEntryPtr FindStyleSheetByISTD(const OUString& sIndex);