tdf#133000 writerfilter: apply non-contradictory num-style
This fixes 7.0 regression exposed by tdf#131321's
commit 35fc5ef0a759884b24ed8b83cd05702a0fab64cc
This patch version heavily depends on recent changes,
but could easily be adapted to older ways.
(See previous versions in gerrit.)
Because LO can now find the numbering rule through
the para-style definition, it doesn't bother creating it
as a direct paragraph property anymore.
So that "directness" has to be specified during the import.
This problem manifested itself in two ways.
1.) In SW, the direct numbering was lost and it simply
inherits from the para-style. If numbering is now turned off
in the para-style, then the paragraph loses it too.
2.) Because the numbering was considered to be
defined by the paragraph style, the para-style-indents
had higher priority than the numbering-indents.
When numbering is defined directly on the paragraph,
it has higher priority than the para-style-indents.
Change-Id: I04c3944de8a91d9f253791fbd05d6324a8b7a9da
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/94365
Tested-by: Jenkins
Reviewed-by: Justin Luth <justin_luth@sil.org>
diff --git a/sw/qa/extras/ooxmlexport/data/tdf133000_numStyleFormatting.docx b/sw/qa/extras/ooxmlexport/data/tdf133000_numStyleFormatting.docx
new file mode 100644
index 0000000..567f382
--- /dev/null
+++ b/sw/qa/extras/ooxmlexport/data/tdf133000_numStyleFormatting.docx
Binary files differ
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport14.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport14.cxx
index e57100b..60725f0 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport14.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport14.cxx
@@ -204,6 +204,17 @@ DECLARE_OOXMLEXPORT_TEST(testTdf87569v, "tdf87569_vml.docx")
true, bValue);
}
DECLARE_OOXMLEXPORT_TEST(testTdf133000_numStyleFormatting, "tdf133000_numStyleFormatting.docx")
{
// Paragraph style's LeftMargin should not override numbering's Left Margin
xmlDocUniquePtr pDump = parseLayoutDump();
assertXPathContent(pDump, "/root/page[1]/body/txt[2]", "First line");
const sal_Int32 nLevel1Margin = getXPath(pDump, "//page[1]/body/txt[2]/infos/prtBounds", "left").toInt32();
assertXPathContent(pDump, "/root/page[1]/body/txt[4]", "One sublevel");
const sal_Int32 nLevel2Margin = getXPath(pDump, "//page[1]/body/txt[4]/infos/prtBounds", "left").toInt32();
CPPUNIT_ASSERT( nLevel1Margin < nLevel2Margin );
}
DECLARE_ODFEXPORT_TEST(testArabicZeroNumbering, "arabic-zero-numbering.docx")
{
auto xNumberingRules
diff --git a/writerfilter/source/dmapper/DomainMapper.cxx b/writerfilter/source/dmapper/DomainMapper.cxx
index a092715..5391149 100644
--- a/writerfilter/source/dmapper/DomainMapper.cxx
+++ b/writerfilter/source/dmapper/DomainMapper.cxx
@@ -3506,6 +3506,7 @@ void DomainMapper::lcl_utext(const sal_uInt8 * data_, size_t len)
// to the next paragraph in sw SplitNode and then be applied to
// every following paragraph
xContext->Erase(PROP_NUMBERING_RULES);
static_cast<ParagraphPropertyMap*>(xContext.get())->SetListId(-1);;
xContext->Erase(PROP_NUMBERING_LEVEL);
}
m_pImpl->SetParaSectpr(false);
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
index 4b7b3ccd..3021aec 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
@@ -1372,19 +1372,40 @@ void DomainMapper_Impl::finishParagraph( const PropertyMapPtr& pPropertyMap, con
OSL_ENSURE( pEntry.get(), "no style sheet found" );
const StyleSheetPropertyMap* pStyleSheetProperties = dynamic_cast<const StyleSheetPropertyMap*>(pEntry ? pEntry->pProperties.get() : nullptr);
bool isNumberingViaStyle(false);
bool isNumberingViaRule = pParaContext && pParaContext->GetListId() > -1;
//apply numbering to paragraph if it was set at the style, but only if the paragraph itself
//does not specify the numbering
sal_Int32 nListId = -1;
if ( !bRemove && pStyleSheetProperties && pParaContext && !pParaContext->isSet(PROP_NUMBERING_RULES) )
if ( !bRemove && pStyleSheetProperties && pParaContext )
{
const sal_Int16 nListLevel = pStyleSheetProperties->GetListLevel();
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))
{
pParaContext->Insert( PROP_NUMBERING_STYLE_NAME, uno::makeAny( pList->GetStyleName() ), false);
isNumberingViaStyle = true;
if ( !isNumberingViaRule )
{
isNumberingViaStyle = true;
// Since LO7.0/tdf#131321 fixed the loss of numbering in styles, this OUGHT to be obsolete,
// but now other new/critical LO7.0 code expects it, and perhaps some corner cases still need it as well.
pParaContext->Insert( PROP_NUMBERING_STYLE_NAME, uno::makeAny(pList->GetStyleName()), true );
}
else if ( !pList->isOutlineNumbering(nListLevel) )
{
// After ignoring anything related to the special Outline levels,
// we have direct numbering, as well as paragraph-style numbering.
// Apply the style if it uses the same list as the direct numbering,
// otherwise the directly-applied-to-paragraph status will be lost,
// and the priority of the numbering-style-indents will be lowered. tdf#133000
if ( nListId == pParaContext->GetListId() )
pParaContext->Insert( PROP_NUMBERING_STYLE_NAME, uno::makeAny(pList->GetStyleName()), true );
}
}
if ( isNumberingViaStyle )
{
// Indent properties from the paragraph style have priority
// over the ones from the numbering styles in Word
// but in Writer numbering styles have priority,
@@ -1420,8 +1441,7 @@ void DomainMapper_Impl::finishParagraph( const PropertyMapPtr& pPropertyMap, con
pParaContext->Insert(PROP_PARA_RIGHT_MARGIN, uno::makeAny(nParaRightMargin), /*bOverwrite=*/false);
}
}
if ( pStyleSheetProperties->GetListLevel() >= 0 )
if ( !isNumberingViaRule && pStyleSheetProperties->GetListLevel() >= 0 )
pParaContext->Insert( PROP_NUMBERING_LEVEL, uno::makeAny(pStyleSheetProperties->GetListLevel()), false);
}
@@ -1625,7 +1645,8 @@ void DomainMapper_Impl::finishParagraph( const PropertyMapPtr& pPropertyMap, con
return rValue.Name == "NumberingRules";
});
bool isNumberingViaRule = (itNumberingRules != aProperties.end());
assert( isNumberingViaRule == (itNumberingRules != aProperties.end()) );
isNumberingViaRule = (itNumberingRules != aProperties.end());
if (m_xPreviousParagraph.is() && (isNumberingViaRule || isNumberingViaStyle))
{
// This textnode has numbering. Look up the numbering style name of the current and previous paragraph.
diff --git a/writerfilter/source/dmapper/NumberingManager.hxx b/writerfilter/source/dmapper/NumberingManager.hxx
index f5c2d01..f2f89ec 100644
--- a/writerfilter/source/dmapper/NumberingManager.hxx
+++ b/writerfilter/source/dmapper/NumberingManager.hxx
@@ -166,6 +166,7 @@ public:
const OUString& GetStyleLink() const { return m_sStyleLink; };
const OUString& MapListId(OUString const& rId);
bool isOutlineNumbering( sal_uInt16 nLvl ) { return GetLevel(nLvl) && GetLevel(nLvl)->isOutlineNumbering(); }
};
class ListDef : public AbstractListDef