tdf#123990 sc condformat: case insensitive begins/ends/contains

This is how Excel handles these.

At first I was afraid that this would upset LibreOffice users,
but then I realized that equals already is case insensitive,
so this change ought to be more consistent, and thus there should
be fewer outcrys.

Change-Id: Ia3de78d5888672ba8b774866d41ecd65293397c1
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/140484
Tested-by: Jenkins
Reviewed-by: Justin Luth <jluth@mail.com>
diff --git a/include/unotools/collatorwrapper.hxx b/include/unotools/collatorwrapper.hxx
index 595d9cc..1552a7c 100644
--- a/include/unotools/collatorwrapper.hxx
+++ b/include/unotools/collatorwrapper.hxx
@@ -45,6 +45,9 @@ class UNOTOOLS_DLLPUBLIC CollatorWrapper
        compareString (
                const OUString& s1, const OUString& s2) const;

        sal_Int32 compareSubstring (const OUString& s1, sal_Int32 off1, sal_Int32 len1,
                                    const OUString& s2, sal_Int32 off2, sal_Int32 len2) const;

        css::uno::Sequence< OUString >
        listCollatorAlgorithms (
                const css::lang::Locale& rLocale) const;
diff --git a/sc/qa/unit/ucalc_condformat.cxx b/sc/qa/unit/ucalc_condformat.cxx
index 652ca8b..35a8a02 100644
--- a/sc/qa/unit/ucalc_condformat.cxx
+++ b/sc/qa/unit/ucalc_condformat.cxx
@@ -818,7 +818,8 @@ void TestCondformat::testCondFormatEndsWithStr()
{
    m_pDoc->InsertTab(0, "Test");

    ScConditionEntry aEntry(ScConditionMode::EndsWith, "\"TestString\"", "", *m_pDoc, ScAddress(),
    // case insnsitive matching
    ScConditionEntry aEntry(ScConditionMode::EndsWith, "\"teststring\"", "", *m_pDoc, ScAddress(),
            "", "", formula::FormulaGrammar::GRAM_DEFAULT, formula::FormulaGrammar::GRAM_DEFAULT);

    svl::SharedStringPool& rStringPool = m_pDoc->GetSharedStringPool();
diff --git a/sc/source/core/data/conditio.cxx b/sc/source/core/data/conditio.cxx
index 46e51cf..834c4a7 100644
--- a/sc/source/core/data/conditio.cxx
+++ b/sc/source/core/data/conditio.cxx
@@ -1175,14 +1175,34 @@ bool ScConditionEntry::IsValidStr( const OUString& rArg, const ScAddress& rPos )
                bValid = !bValid;
        break;
        case ScConditionMode::BeginsWith:
            bValid = rArg.startsWith(aUpVal1);
        break;
        {
            const sal_Int32 nLen = aUpVal1.getLength();
            if (!nLen || nLen > rArg.getLength())
                bValid = false;
            else
            {
                bValid = (ScGlobal::GetCollator().compareSubstring(rArg, 0, nLen,
                                                                   aUpVal1, 0, nLen) == 0);
            }
        }
       break;
        case ScConditionMode::EndsWith:
            bValid = rArg.endsWith(aUpVal1);
        {
            sal_Int32 nStart = rArg.getLength();
            const sal_Int32 nLen = aUpVal1.getLength();
            if (!nLen || nLen > nStart)
                bValid = false;
            else
            {
                nStart = nStart - nLen;
                bValid = (ScGlobal::GetCollator().compareSubstring(rArg, nStart, nLen,
                                                                   aUpVal1, 0, nLen) == 0);
            }
        }
        break;
        case ScConditionMode::ContainsText:
        case ScConditionMode::NotContainsText:
            bValid = rArg.indexOf(aUpVal1) != -1;
            bValid = rArg.toAsciiLowerCase().indexOf(aUpVal1.toAsciiLowerCase()) != -1;
            if(eOp == ScConditionMode::NotContainsText)
                bValid = !bValid;
        break;
diff --git a/unotools/source/i18n/collatorwrapper.cxx b/unotools/source/i18n/collatorwrapper.cxx
index 4da1398e..ce85de1 100644
--- a/unotools/source/i18n/collatorwrapper.cxx
+++ b/unotools/source/i18n/collatorwrapper.cxx
@@ -46,6 +46,23 @@ CollatorWrapper::compareString (const OUString& s1, const OUString& s2) const
    return 0;
}

sal_Int32
CollatorWrapper::compareSubstring (const OUString& s1, sal_Int32 off1, sal_Int32 len1,
                                   const OUString& s2, sal_Int32 off2, sal_Int32 len2) const
{
    try
    {
        if (mxInternationalCollator.is())
            return mxInternationalCollator->compareSubstring (s1, off1, len1, s2, off2, len2);
    }
    catch (const uno::RuntimeException&)
    {
        SAL_WARN( "unotools.i18n","CollatorWrapper: compareSubstring failed");
    }

    return 0;
}

uno::Sequence< OUString >
CollatorWrapper::listCollatorAlgorithms (const lang::Locale& rLocale) const
{