tdf#131321 writerfilter: ApplyNumberingStyleNameToParaStyles()
Prior to this commit, numbering on paragraph styles
was lost on import. This didn't affect layout at all,
but it did affect user editing.
DOCX: export already was fine, just import was missing.
RTF: export is explicitly ignored for non-paragraphs,
(ParaNumRule_Impl), so I am ignoring RTF, since
this fix is meaningless unless both import and
export are working.
This is a bit tricky because styles.xml is loaded before
numbering.xml, so the names are not known until after
numbering.xml has finished. So this helper function runs
at the end of the numbering.xml import process.
Several existing unit tests nicely confirmed a few things.
-tdf95377.docx: numId 0 overrides an inherited numbering
-chtoutline.docx proves that outlineLevel styles are exempt.
-fdo61343.docx actually has nothing in numbering.xml,
so it is possible to have a numbering with no name.
Of course, it is a really messed up document, too...
Change-Id: I270a581f08704c2595d861ce5c5b546f9d6ba6b6
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/92058
Tested-by: Jenkins
Reviewed-by: Justin Luth <justin_luth@sil.org>
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport10.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport10.cxx
index 09a232a..3e0d375 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport10.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport10.cxx
@@ -1022,6 +1022,10 @@ DECLARE_OOXMLEXPORT_TEST(testTdf95376, "tdf95376.docx")
// did not have priority over indentation-from-paragraph-style, due to a
// filter workaround that's not correct here.
CPPUNIT_ASSERT_EQUAL(beans::PropertyState_DEFAULT_VALUE, xParagraph->getPropertyState("ParaFirstLineIndent"));
//tdf#131321 - paragraph styles lost their numbering. Bullet+space inherits WWNum1 from Bullet
uno::Reference<beans::XPropertySet> xStyle(getStyles("ParagraphStyles")->getByName("Bullet+space"), uno::UNO_QUERY);
CPPUNIT_ASSERT(!(getProperty<OUString>(xStyle, "NumberingStyleName")).isEmpty());
}
DECLARE_OOXMLEXPORT_TEST(testTdf92124, "tdf92124.docx")
diff --git a/writerfilter/source/dmapper/DomainMapper.cxx b/writerfilter/source/dmapper/DomainMapper.cxx
index 6eb00b1..12fa4f2 100644
--- a/writerfilter/source/dmapper/DomainMapper.cxx
+++ b/writerfilter/source/dmapper/DomainMapper.cxx
@@ -3903,6 +3903,11 @@ bool DomainMapper::IsInTable() const
return m_pImpl->hasTableManager() && m_pImpl->getTableManager().isInCell();
}
OUString DomainMapper::GetListStyleName(sal_Int32 nListId) const
{
return m_pImpl->GetListStyleName( nListId );
}
bool DomainMapper::IsStyleSheetImport() const
{
return m_pImpl->IsStyleSheetImport();
diff --git a/writerfilter/source/dmapper/DomainMapper.hxx b/writerfilter/source/dmapper/DomainMapper.hxx
index 0fbd2ea..6fdb44e 100644
--- a/writerfilter/source/dmapper/DomainMapper.hxx
+++ b/writerfilter/source/dmapper/DomainMapper.hxx
@@ -95,6 +95,7 @@ public:
void PushListProperties( const ::tools::SvRef<PropertyMap>& pListProperties );
void PopListProperties();
OUString GetListStyleName(sal_Int32 nListId) const;
bool IsOOXMLImport() const;
bool IsRTFImport() const;
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
index 98e9e77..6428155 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
@@ -914,6 +914,12 @@ uno::Any DomainMapper_Impl::GetAnyProperty(PropertyIds eId, const PropertyMapPtr
return GetPropertyFromParaStyleSheet(eId);
}
OUString DomainMapper_Impl::GetListStyleName(sal_Int32 nListId)
{
auto const pList(GetListTable()->GetList( nListId ));
return pList ? pList->GetStyleName() : OUString();
}
ListsManager::Pointer const & DomainMapper_Impl::GetListTable()
{
if(!m_pListTable)
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.hxx b/writerfilter/source/dmapper/DomainMapper_Impl.hxx
index e6654a1..c96a68b 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.hxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.hxx
@@ -718,6 +718,7 @@ public:
m_pStyleSheetTable = new StyleSheetTable( m_rDMapper, m_xTextDocument, m_bIsNewDoc );
return m_pStyleSheetTable;
}
OUString GetListStyleName(sal_Int32 nListId);
ListsManager::Pointer const & GetListTable();
ThemeTablePtr const & GetThemeTable()
{
diff --git a/writerfilter/source/dmapper/NumberingManager.cxx b/writerfilter/source/dmapper/NumberingManager.cxx
index 93ba485..e0922b4 100644
--- a/writerfilter/source/dmapper/NumberingManager.cxx
+++ b/writerfilter/source/dmapper/NumberingManager.cxx
@@ -1221,6 +1221,7 @@ void ListsManager::CreateNumberingRules( )
{
rList->CreateNumberingRules( m_rDMapper, m_xFactory );
}
m_rDMapper.GetStyleSheetTable()->ApplyNumberingStyleNameToParaStyles();
}
}
diff --git a/writerfilter/source/dmapper/StyleSheetTable.cxx b/writerfilter/source/dmapper/StyleSheetTable.cxx
index 864149a..f0524e7 100644
--- a/writerfilter/source/dmapper/StyleSheetTable.cxx
+++ b/writerfilter/source/dmapper/StyleSheetTable.cxx
@@ -887,6 +887,48 @@ uno::Sequence< OUString > PropValVector::getNames()
return comphelper::containerToSequence(aRet);
}
void StyleSheetTable::ApplyNumberingStyleNameToParaStyles()
{
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 )
{
StyleSheetPropertyMap* pStyleSheetProperties = nullptr;
if ( pEntry->nStyleTypeCode == STYLE_TYPE_PARA && (pStyleSheetProperties = dynamic_cast<StyleSheetPropertyMap*>(pEntry->pProperties.get())) )
{
// ListId 0 means turn off numbering - to cancel inheritance - so make sure that can be set.
// Ignore the special "chapter numbering" outline styles as they are handled internally.
if ( pStyleSheetProperties->GetListId() > -1 && pStyleSheetProperties->GetOutlineLevel() == -1 )
{
uno::Reference< style::XStyle > xStyle;
xParaStyles->getByName( ConvertStyleName(pEntry->sStyleName) ) >>= xStyle;
if ( !xStyle.is() )
break;
uno::Reference<beans::XPropertySet> xPropertySet( xStyle, uno::UNO_QUERY_THROW );
const OUString sNumberingStyleName = m_pImpl->m_rDMapper.GetListStyleName( pStyleSheetProperties->GetListId() );
if ( !sNumberingStyleName.isEmpty() || !pStyleSheetProperties->GetListId() )
xPropertySet->setPropertyValue( getPropertyName(PROP_NUMBERING_STYLE_NAME), uno::makeAny(sNumberingStyleName) );
}
}
}
}
catch( const uno::Exception& )
{
DBG_UNHANDLED_EXCEPTION("writerfilter", "Failed applying numbering style name 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 c192449..a206230 100644
--- a/writerfilter/source/dmapper/StyleSheetTable.hxx
+++ b/writerfilter/source/dmapper/StyleSheetTable.hxx
@@ -92,6 +92,7 @@ public:
StyleSheetTable(DomainMapper& rDMapper, css::uno::Reference<css::text::XTextDocument> const& xTextDocument, bool bIsNewDoc);
virtual ~StyleSheetTable() override;
void ApplyNumberingStyleNameToParaStyles();
void ApplyStyleSheets( const FontTablePtr& rFontTable );
StyleSheetEntryPtr FindStyleSheetByISTD(const OUString& sIndex);
StyleSheetEntryPtr FindStyleSheetByConvertedStyleName(const OUString& rIndex);