tdf#95377 ooxmlimport: treat default style like named styles

The default style was missing out on all of the fixes made
by LN_CT_PPrBase_pStyle. That included right margins, and
numbering styles.

Essentially, this change is just copy and paste from one function
to another. I tried to make all of the logic changes
separately in previous commits. So the adjustments here are simply
to accommodate different variable/function names. So if this
causes any regressions, it ought to just be related to either
applying later on (at finishparagraph instead of
LN_CT_PPrBase_pStyle or because it includes the default style.

One important note regards the preparatory
commit 254c80037a3939c110d5c66fef6c28caf47625e5.
If this commit is reverted, make sure to check that commit
to add a conditional wrappers around GetCurrentNumberingRules().

Change-Id: I9827b2cd1a74a13cf18ada9baa221c5c567a7391
Reviewed-on: https://gerrit.libreoffice.org/48458
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Justin Luth <justin_luth@sil.org>
Reviewed-by: Miklos Vajna <vmiklos@collabora.co.uk>
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport10.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport10.cxx
index 9128303..4451e06 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport10.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport10.cxx
@@ -921,6 +921,14 @@ DECLARE_OOXMLEXPORT_TEST(testTdf95377, "tdf95377.docx")
    CPPUNIT_ASSERT_EQUAL(sal_Int32(-250), getProperty<sal_Int32>(xParagraph, "ParaFirstLineIndent"));
    CPPUNIT_ASSERT_EQUAL(sal_Int32(250), getProperty<sal_Int32>(xParagraph, "ParaLeftMargin"));
    CPPUNIT_ASSERT_EQUAL(beans::PropertyState_DIRECT_VALUE, xParagraph->getPropertyState("ParaFirstLineIndent"));

    //default style has numbering enabled.  Styles inherit numbering unless specifically disabled
    xmlDocPtr pXmlDoc = parseLayoutDump();
    assertXPath(pXmlDoc, "//body/txt/Special", 3);  //first three paragraphs have numbering
    assertXPath(pXmlDoc, "//body/txt[1]/Special", "rText", "a.");
    assertXPath(pXmlDoc, "//body/txt[2]/Special", "rText", "b.");
    assertXPath(pXmlDoc, "//body/txt[3]/Special", "rText", "c.");
    assertXPath(pXmlDoc, "/root/page/body/txt[4]/Special", 0); //last paragraph style disables numbering
}

DECLARE_OOXMLEXPORT_TEST(testTdf95376, "tdf95376.docx")
diff --git a/writerfilter/source/dmapper/DomainMapper.cxx b/writerfilter/source/dmapper/DomainMapper.cxx
index 9acb00f..a573275 100644
--- a/writerfilter/source/dmapper/DomainMapper.cxx
+++ b/writerfilter/source/dmapper/DomainMapper.cxx
@@ -1194,30 +1194,6 @@ static bool ExchangeLeftRight(const PropertyMapPtr& rContext, DomainMapper_Impl&
    return bExchangeLeftRight;
}

/// Check if the style or its parent has a list id, recursively.
static sal_Int32 lcl_getListId(const StyleSheetEntryPtr& rEntry, const StyleSheetTablePtr& rStyleTable)
{
    const StyleSheetPropertyMap* pEntryProperties = dynamic_cast<const StyleSheetPropertyMap*>(rEntry->pProperties.get());
    if (!pEntryProperties)
        return -1;

    sal_Int32 nListId = pEntryProperties->GetListId();
    // The style itself has a list id.
    if (nListId >= 0)
        return nListId;

    // The style has no parent.
    if (rEntry->sBaseStyleIdentifier.isEmpty())
        return -1;

    const StyleSheetEntryPtr pParent = rStyleTable->FindStyleSheetByISTD(rEntry->sBaseStyleIdentifier);
    // No such parent style or loop in the style hierarchy.
    if (!pParent || pParent == rEntry)
        return -1;

    return lcl_getListId(pParent, rStyleTable);
}

void DomainMapper::sprmWithProps( Sprm& rSprm, const PropertyMapPtr& rContext )
{
    // These SPRM's are not specific to any section, so it's expected that there is no context yet.
@@ -2121,57 +2097,6 @@ void DomainMapper::sprmWithProps( Sprm& rSprm, const PropertyMapPtr& rContext )
        const OUString sConvertedStyleName = pStyleTable->ConvertStyleName( sStringValue, true );
        if (m_pImpl->GetTopContext() && m_pImpl->GetTopContextType() != CONTEXT_SECTION)
            m_pImpl->GetTopContext()->Insert( PROP_PARA_STYLE_NAME, uno::makeAny( sConvertedStyleName ));
        //apply numbering to paragraph if it was set at the style, but only if the paragraph itself
        //does not specify the numbering
        if( !rContext->isSet(PROP_NUMBERING_RULES) ) // !contains
        {
            const StyleSheetEntryPtr pEntry = pStyleTable->FindStyleSheetByISTD(sStringValue);
            OSL_ENSURE( pEntry.get(), "no style sheet found" );
            const StyleSheetPropertyMap* pStyleSheetProperties = dynamic_cast<const StyleSheetPropertyMap*>(pEntry ? pEntry->pProperties.get() : nullptr);

            sal_Int32 nListId = pEntry ? lcl_getListId(pEntry, pStyleTable) : -1;
            if( pStyleSheetProperties && nListId >= 0 )
            {
                if ( !pEntry->bIsChapterNumbering )
                    rContext->Insert( PROP_NUMBERING_STYLE_NAME, uno::makeAny( ListDef::GetStyleName( nListId ) ), false);

                // Indent properties from the paragraph style have priority
                // over the ones from the numbering styles in Word
                // but in Writer numbering styles have priority,
                // so insert directly into the paragraph properties to compensate.
                boost::optional<PropertyMap::Property> oProperty;
                if ( (oProperty = pStyleSheetProperties->getProperty(PROP_PARA_FIRST_LINE_INDENT)) )
                    rContext->Insert(PROP_PARA_FIRST_LINE_INDENT, oProperty->second, /*bOverwrite=*/false);
                if ( (oProperty = pStyleSheetProperties->getProperty(PROP_PARA_LEFT_MARGIN)) )
                    rContext->Insert(PROP_PARA_LEFT_MARGIN, oProperty->second, /*bOverwrite=*/false);

                // We're inheriting properties from a numbering style. Make sure a possible right margin is inherited from the base style.
                sal_Int32 nParaRightMargin = 0;
                if (!pEntry->sBaseStyleIdentifier.isEmpty())
                {
                    const StyleSheetEntryPtr pParent = pStyleTable->FindStyleSheetByISTD(pEntry->sBaseStyleIdentifier);
                    const StyleSheetPropertyMap* pParentProperties = dynamic_cast<const StyleSheetPropertyMap*>(pParent ? pParent->pProperties.get() : nullptr);
                    boost::optional<PropertyMap::Property> pPropMargin;
                    if (pParentProperties && (pPropMargin = pParentProperties->getProperty(PROP_PARA_RIGHT_MARGIN)) )
                        nParaRightMargin = pPropMargin->second.get<sal_Int32>();
                }
                if (nParaRightMargin != 0)
                {
                    // If we're setting the right margin, we should set the first / left margin as well from the numbering style.
                    const sal_Int32 nFirstLineIndent = m_pImpl->getNumberingProperty(nListId, pStyleSheetProperties->GetListLevel(), "FirstLineIndent");
                    const sal_Int32 nParaLeftMargin  = m_pImpl->getNumberingProperty(nListId, pStyleSheetProperties->GetListLevel(), "IndentAt");
                    if (nFirstLineIndent != 0)
                        rContext->Insert(PROP_PARA_FIRST_LINE_INDENT, uno::makeAny(nFirstLineIndent), /*bOverwrite=*/false);
                    if (nParaLeftMargin != 0)
                        rContext->Insert(PROP_PARA_LEFT_MARGIN, uno::makeAny(nParaLeftMargin), /*bOverwrite=*/false);

                    rContext->Insert(PROP_PARA_RIGHT_MARGIN, uno::makeAny(nParaRightMargin), /*bOverwrite=*/false);
                }
            }

            if( pStyleSheetProperties && pStyleSheetProperties->GetListLevel() >= 0 )
                rContext->Insert( PROP_NUMBERING_LEVEL, uno::makeAny(pStyleSheetProperties->GetListLevel()), false);
        }
    }
    break;
    case NS_ooxml::LN_EG_RPrBase_rStyle:
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
index 823fc60..69147cd 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
@@ -1056,6 +1056,30 @@ void DomainMapper_Impl::CheckUnregisteredFrameConversion( )
    }
}

/// Check if the style or its parent has a list id, recursively.
static sal_Int32 lcl_getListId(const StyleSheetEntryPtr& rEntry, const StyleSheetTablePtr& rStyleTable)
{
    const StyleSheetPropertyMap* pEntryProperties = dynamic_cast<const StyleSheetPropertyMap*>(rEntry->pProperties.get());
    if (!pEntryProperties)
        return -1;

    sal_Int32 nListId = pEntryProperties->GetListId();
    // The style itself has a list id.
    if (nListId >= 0)
        return nListId;

    // The style has no parent.
    if (rEntry->sBaseStyleIdentifier.isEmpty())
        return -1;

    const StyleSheetEntryPtr pParent = rStyleTable->FindStyleSheetByISTD(rEntry->sBaseStyleIdentifier);
    // No such parent style or loop in the style hierarchy.
    if (!pParent || pParent == rEntry)
        return -1;

    return lcl_getListId(pParent, rStyleTable);
}

void DomainMapper_Impl::finishParagraph( const PropertyMapPtr& pPropertyMap )
{
#ifdef DEBUG_WRITERFILTER
@@ -1073,6 +1097,59 @@ void DomainMapper_Impl::finishParagraph( const PropertyMapPtr& pPropertyMap )
    TagLogger::getInstance().attribute("isTextAppend", sal_uInt32(xTextAppend.is()));
#endif

    //apply numbering to paragraph if it was set at the style, but only if the paragraph itself
    //does not specify the numbering
    if( pParaContext && !pParaContext->isSet(PROP_NUMBERING_RULES) )
    {
        const StyleSheetEntryPtr pEntry = GetStyleSheetTable()->FindStyleSheetByISTD( GetCurrentParaStyleId() );
        OSL_ENSURE( pEntry.get(), "no style sheet found" );
        const StyleSheetPropertyMap* pStyleSheetProperties = dynamic_cast<const StyleSheetPropertyMap*>(pEntry ? pEntry->pProperties.get() : nullptr);

        sal_Int32 nListId = pEntry ? lcl_getListId(pEntry, GetStyleSheetTable()) : -1;
        if( pStyleSheetProperties && nListId >= 0 )
        {
            if ( !pEntry->bIsChapterNumbering )
                pParaContext->Insert( PROP_NUMBERING_STYLE_NAME, uno::makeAny( ListDef::GetStyleName( nListId ) ), false);

            // Indent properties from the paragraph style have priority
            // over the ones from the numbering styles in Word
            // but in Writer numbering styles have priority,
            // so insert directly into the paragraph properties to compensate.
            boost::optional<PropertyMap::Property> oProperty;
            if ( (oProperty = pStyleSheetProperties->getProperty(PROP_PARA_FIRST_LINE_INDENT)) )
                pParaContext->Insert(PROP_PARA_FIRST_LINE_INDENT, oProperty->second, /*bOverwrite=*/false);
            if ( (oProperty = pStyleSheetProperties->getProperty(PROP_PARA_LEFT_MARGIN)) )
                pParaContext->Insert(PROP_PARA_LEFT_MARGIN, oProperty->second, /*bOverwrite=*/false);

            // We're inheriting properties from a numbering style. Make sure a possible right margin is inherited from the base style.
            sal_Int32 nParaRightMargin = 0;
            if (!pEntry->sBaseStyleIdentifier.isEmpty())
            {
                const StyleSheetEntryPtr pParent = GetStyleSheetTable()->FindStyleSheetByISTD(pEntry->sBaseStyleIdentifier);
                const StyleSheetPropertyMap* pParentProperties = dynamic_cast<const StyleSheetPropertyMap*>(pParent ? pParent->pProperties.get() : nullptr);
                boost::optional<PropertyMap::Property> pPropMargin;
                if (pParentProperties && (pPropMargin = pParentProperties->getProperty(PROP_PARA_RIGHT_MARGIN)) )
                    nParaRightMargin = pPropMargin->second.get<sal_Int32>();
            }
            if (nParaRightMargin != 0)
            {
                // If we're setting the right margin, we should set the first / left margin as well from the numbering style.
                const sal_Int32 nFirstLineIndent = getNumberingProperty(nListId, pStyleSheetProperties->GetListLevel(), "FirstLineIndent");
                const sal_Int32 nParaLeftMargin  = getNumberingProperty(nListId, pStyleSheetProperties->GetListLevel(), "IndentAt");
                if (nFirstLineIndent != 0)
                    pParaContext->Insert(PROP_PARA_FIRST_LINE_INDENT, uno::makeAny(nFirstLineIndent), /*bOverwrite=*/false);
                if (nParaLeftMargin != 0)
                    pParaContext->Insert(PROP_PARA_LEFT_MARGIN, uno::makeAny(nParaLeftMargin), /*bOverwrite=*/false);

                pParaContext->Insert(PROP_PARA_RIGHT_MARGIN, uno::makeAny(nParaRightMargin), /*bOverwrite=*/false);
            }
        }

        if( pStyleSheetProperties && pStyleSheetProperties->GetListLevel() >= 0 )
            pParaContext->Insert( PROP_NUMBERING_LEVEL, uno::makeAny(pStyleSheetProperties->GetListLevel()), false);
    }


    if (xTextAppend.is() && pParaContext && hasTableManager() && !getTableManager().isIgnore())
    {
        try