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 {