tdf#94326 doc import: allow direct numbering to cancel outlineStyle

Prior to this, if a Chapter Numbering style was assigned
as the paragraph style, any direct numbering would have
been skipped.

In this unit test, DOC defines WW8Num2 as the
numbering style for the Heading styles.
LO copies this to its special "Outline" style.
So any direct formatting with WW8Num2 must be ignored.
However, any other numbering rules should be allowed,
and that is what this patch does.

Make sure that WW8Num2 can also be applied outside of
the Heading styles. (Unfortunately, the numbering
is probably broken since these are now considered
to be two different lists - unless someone has
connected them in the background some way.)

Change-Id: If29c8bbd096acc0edd6f1fe32cedc054f16460d6
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/114298
Tested-by: Jenkins
Reviewed-by: Justin Luth <justin_luth@sil.org>
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
diff --git a/sw/qa/extras/ww8export/data/tdf94326_notOutlineNumbering.doc b/sw/qa/extras/ww8export/data/tdf94326_notOutlineNumbering.doc
new file mode 100644
index 0000000..2df22e9
--- /dev/null
+++ b/sw/qa/extras/ww8export/data/tdf94326_notOutlineNumbering.doc
Binary files differ
diff --git a/sw/qa/extras/ww8export/ww8export3.cxx b/sw/qa/extras/ww8export/ww8export3.cxx
index e525927..f5ae1ce 100644
--- a/sw/qa/extras/ww8export/ww8export3.cxx
+++ b/sw/qa/extras/ww8export/ww8export3.cxx
@@ -745,6 +745,13 @@ CPPUNIT_TEST_FIXTURE(Test, testRtlGutter)
    verify();
}

DECLARE_WW8EXPORT_TEST(testTdf94326_notOutlineNumbering, "tdf94326_notOutlineNumbering.doc")
{
    // The directly applied numbering list must not be lost.
    uno::Reference<beans::XPropertySet> xPara(getParagraph(2, u"ОБЩИЕ ПОЛОЖЕНИЯ"), uno::UNO_QUERY);
    CPPUNIT_ASSERT_EQUAL(OUString("1."), getProperty<OUString>(xPara, "ListLabelString"));
}

DECLARE_WW8EXPORT_TEST(testTdf120394, "tdf120394.doc")
{
    CPPUNIT_ASSERT_EQUAL(1, getPages());
diff --git a/sw/source/filter/ww8/ww8par.cxx b/sw/source/filter/ww8/ww8par.cxx
index 9466e3a..a2847bc 100644
--- a/sw/source/filter/ww8/ww8par.cxx
+++ b/sw/source/filter/ww8/ww8par.cxx
@@ -4313,6 +4313,7 @@ SwWW8ImplReader::SwWW8ImplReader(sal_uInt8 nVersionPara, SotStorage* pStorage,
    , m_nWantedVersion(nVersionPara)
    , m_nSwNumLevel(0xff)
    , m_nWwNumType(0xff)
    , m_pChosenWW8OutlineStyle(nullptr)
    , m_nListLevel(WW8ListManager::nMaxLevel)
    , m_bNewDoc(bNewDoc)
    , m_bSkipImages(bSkipImages)
@@ -5973,7 +5974,6 @@ void SwWW8ImplReader::SetOutlineStyles()
    // - Populate temporary list of WW8 Built-In Heading Styles for further
    // iteration
    std::vector<SwWW8StyInf*> aWW8BuiltInHeadingStyles;
    const SwNumRule* pChosenWW8ListStyle = nullptr;
    {
        std::map<const SwNumRule*, int> aWW8ListStyleCounts;
        for (SwWW8StyInf & rSI : m_vColl)
@@ -6007,7 +6007,7 @@ void SwWW8ImplReader::SetOutlineStyles()
            if (rEntry.second > nCurrentMaxCount)
            {
                nCurrentMaxCount = rEntry.second;
                pChosenWW8ListStyle = rEntry.first;
                m_pChosenWW8OutlineStyle = rEntry.first;
            }
        }
    }
@@ -6037,11 +6037,11 @@ void SwWW8ImplReader::SetOutlineStyles()
            continue;
        }

        if (pChosenWW8ListStyle != nullptr && pStyleInf->mnWW8OutlineLevel
                                           == pStyleInf->m_nListLevel)
        if (m_pChosenWW8OutlineStyle != nullptr
            && pStyleInf->mnWW8OutlineLevel == pStyleInf->m_nListLevel)
        {
            const SwNumFormat& rRule
                = pChosenWW8ListStyle->Get(pStyleInf->mnWW8OutlineLevel);
                = m_pChosenWW8OutlineStyle->Get(pStyleInf->mnWW8OutlineLevel);
            aOutlineRule.Set(pStyleInf->mnWW8OutlineLevel, rRule);
            bAppliedChangedOutlineStyle = true;
        }
@@ -6051,7 +6051,7 @@ void SwWW8ImplReader::SetOutlineStyles()
            |= nOutlineStyleListLevelOfWW8BuiltInHeadingStyle;

        SwTextFormatColl* pTextFormatColl = static_cast<SwTextFormatColl*>(pStyleInf->m_pFormat);
        if (pStyleInf->GetOutlineNumrule() != pChosenWW8ListStyle
        if (pStyleInf->GetOutlineNumrule() != m_pChosenWW8OutlineStyle
            || (pStyleInf->m_nListLevel < WW8ListManager::nMaxLevel
                && pStyleInf->mnWW8OutlineLevel != pStyleInf->m_nListLevel))
        {
diff --git a/sw/source/filter/ww8/ww8par.hxx b/sw/source/filter/ww8/ww8par.hxx
index ce027e87..8d81b78 100644
--- a/sw/source/filter/ww8/ww8par.hxx
+++ b/sw/source/filter/ww8/ww8par.hxx
@@ -1306,6 +1306,7 @@ private:

    sal_uInt8 m_nSwNumLevel;           // level number for outline / enumeration
    sal_uInt8 m_nWwNumType;            // outline / number / enumeration
    const SwNumRule* m_pChosenWW8OutlineStyle; // copied to the "Outline" Chapter Numbering style
    sal_uInt8 m_nListLevel;

    bool m_bNewDoc;          // new document?
diff --git a/sw/source/filter/ww8/ww8par3.cxx b/sw/source/filter/ww8/ww8par3.cxx
index 0931eb5..f3b8ad5 100644
--- a/sw/source/filter/ww8/ww8par3.cxx
+++ b/sw/source/filter/ww8/ww8par3.cxx
@@ -1785,8 +1785,11 @@ void SwWW8ImplReader::RegisterNumFormatOnTextNode(sal_uInt16 nCurrentLFO,
        return;

    if (bSetAttr && pTextNd->GetNumRule() != pRule
        && pTextNd->GetNumRule() != m_rDoc.GetOutlineNumRule())
        && (pTextNd->GetNumRule() != m_rDoc.GetOutlineNumRule()
            || pRule != m_pChosenWW8OutlineStyle))
    {
        // Now this is either not a part of Chapter Numbering,
        // or else it is using a different numRule than the one copied to Chapter Numbering.
        pTextNd->SetAttr(SwNumRuleItem(pRule->GetName()));
    }
    pTextNd->SetAttrListLevel(nCurrentLevel);