tdf#146257: sw: better handling for list numbering = NONE

Previously during refactoring were lost some corner cases with
some level having disabled numbering. In this case LO should
strip useless delimiters up to next level.

For example, if second level has disabled numbering, third level
should look like "1.1", but not "1..1".

Change-Id: I259a16b456f51bc76d5c8360974d0acadfc36776
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/127517
Tested-by: Jenkins
Reviewed-by: Vasily Melenchuk <vasily.melenchuk@cib.de>
(cherry picked from commit bf2b46aa15665dde63ceff4e7686b99b3990354f)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/127569
Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
diff --git a/sw/qa/extras/odfimport/data/tdf146257.odt b/sw/qa/extras/odfimport/data/tdf146257.odt
new file mode 100644
index 0000000..2431fc0
--- /dev/null
+++ b/sw/qa/extras/odfimport/data/tdf146257.odt
Binary files differ
diff --git a/sw/qa/extras/odfimport/odfimport.cxx b/sw/qa/extras/odfimport/odfimport.cxx
index 9d02003..fa79c71 100644
--- a/sw/qa/extras/odfimport/odfimport.cxx
+++ b/sw/qa/extras/odfimport/odfimport.cxx
@@ -1296,5 +1296,37 @@ CPPUNIT_TEST_FIXTURE(Test, testPageAnchorZIndexSecondPage)
        sal_Int32(3), getProperty<sal_Int32>(getShapeByName(u"Shape2"), "ZOrder"));
}

CPPUNIT_TEST_FIXTURE(Test, testTdf146257)
{
    load(mpTestDocumentPath, "tdf146257.odt");

    // First list should contain no labels
    {
        uno::Reference<beans::XPropertySet> xPara(getParagraph(2), uno::UNO_QUERY);
        CPPUNIT_ASSERT_EQUAL(OUString(""), getProperty<OUString>(xPara, "ListLabelString"));
    }
    {
        uno::Reference<beans::XPropertySet> xPara(getParagraph(3), uno::UNO_QUERY);
        CPPUNIT_ASSERT_EQUAL(OUString(""), getProperty<OUString>(xPara, "ListLabelString"));
    }
    {
        uno::Reference<beans::XPropertySet> xPara(getParagraph(4), uno::UNO_QUERY);
        CPPUNIT_ASSERT_EQUAL(OUString(""), getProperty<OUString>(xPara, "ListLabelString"));
    }
    // For second list ensure second level empty and thord level should not contain extra dots
    {
        uno::Reference<beans::XPropertySet> xPara(getParagraph(6), uno::UNO_QUERY);
        CPPUNIT_ASSERT_EQUAL(OUString("1"), getProperty<OUString>(xPara, "ListLabelString"));
    }
    {
        uno::Reference<beans::XPropertySet> xPara(getParagraph(7), uno::UNO_QUERY);
        CPPUNIT_ASSERT_EQUAL(OUString(""), getProperty<OUString>(xPara, "ListLabelString"));
    }
    {
        uno::Reference<beans::XPropertySet> xPara(getParagraph(8), uno::UNO_QUERY);
        CPPUNIT_ASSERT_EQUAL(OUString("1.1"), getProperty<OUString>(xPara, "ListLabelString"));
    }
}

CPPUNIT_PLUGIN_IMPLEMENT();
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/doc/number.cxx b/sw/source/core/doc/number.cxx
index acb142b..93a5c14 100644
--- a/sw/source/core/doc/number.cxx
+++ b/sw/source/core/doc/number.cxx
@@ -670,6 +670,21 @@ OUString SwNumRule::MakeNumString( const SwNumberTree::tNumberVector & rNumVecto

    const SwNumFormat& rMyNFormat = Get( o3tl::narrowing<sal_uInt16>(nLevel) );

    if (rMyNFormat.GetNumberingType() == SVX_NUM_NUMBER_NONE)
    {
        if (!rMyNFormat.HasListFormat())
            return OUString();

        // If numbering is disabled for this level we should emit just prefix/suffix
        // Remove everything between first %1% and last %n% (including markers)
        OUString sLevelFormat = rMyNFormat.GetListFormat(bInclStrings);
        sal_Int32 nFirstPosition = sLevelFormat.indexOf("%");
        sal_Int32 nLastPosition = sLevelFormat.lastIndexOf("%");
        if (nFirstPosition >= 0 && nLastPosition >= nFirstPosition)
            sLevelFormat = sLevelFormat.replaceAt(nFirstPosition, nLastPosition - nFirstPosition + 1, u"");
        return sLevelFormat;
    }

    css::lang::Locale aLocale( LanguageTag::convertToLocale(nLang));

    if (rMyNFormat.HasListFormat())
@@ -681,9 +696,19 @@ OUString SwNumRule::MakeNumString( const SwNumberTree::tNumberVector & rNumVecto
        for (SwNumberTree::tNumberVector::size_type i=0; i <= nLevel; ++i)
        {
            OUString sReplacement;
            if (rMyNFormat.GetNumberingType() == SVX_NUM_NUMBER_NONE)
            const SwNumFormat& rNFormat = Get(i);
            if (rNFormat.GetNumberingType() == SVX_NUM_NUMBER_NONE)
            {
                // Numbering disabled - replacement is empty
                // And we should skip all level string content until next level marker:
                // so %1%.%2%.%3% with second level as NONE will result 1.1, not 1..1
                OUString sFind("%" + OUString::number(i + 1) + "%");
                sal_Int32 nPositionToken = sLevelFormat.indexOf(sFind);
                sal_Int32 nPositionNextToken = sLevelFormat.indexOf('%', nPositionToken + sFind.getLength());
                if (nPositionToken > 0 && nPositionNextToken >= nPositionToken)
                {
                    sLevelFormat = sLevelFormat.replaceAt(nPositionToken, nPositionNextToken - nPositionToken, u"");
                }
            }
            else if (rNumVector[i])
            {