include/unotools/collatorwrapper.hxx     |    3 +++
 sc/qa/unit/ucalc_condformat.cxx          |    3 ++-
 sc/source/core/data/conditio.cxx         |   28 ++++++++++++++++++++++++----
 unotools/source/i18n/collatorwrapper.cxx |   17 +++++++++++++++++
 4 files changed, 46 insertions(+), 5 deletions(-)

New commits:
commit 3bfed17b047422a8c4e98ab80001f3158afb227e
Author:     Justin Luth <justin.l...@collabora.com>
AuthorDate: Fri Sep 23 07:41:23 2022 -0400
Commit:     Justin Luth <jl...@mail.com>
CommitDate: Fri Sep 23 17:38:15 2022 +0200

    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 <jl...@mail.com>

diff --git a/include/unotools/collatorwrapper.hxx 
b/include/unotools/collatorwrapper.hxx
index 595d9ccf4f41..1552a7ce9b36 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 652ca8b059c6..35a8a02b0802 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 46e51cf9f297..834c4a78f5e8 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 4da1398e0636..ce85de11df7e 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
 {

Reply via email to