Optionally use case-insensitive comparison in CompareStrings()

Harmonize Mac and MSW versions by using case-sensitive comparison in
both of them by default, but allowing to use a flag to use
case-insensitive comparison instead.
This commit is contained in:
Vadim Zeitlin
2021-08-28 21:13:22 +01:00
parent 5f8483b49d
commit e27497774a
5 changed files with 62 additions and 14 deletions

View File

@@ -19,6 +19,13 @@
class wxUILocaleImpl;
// Flags for wxUILocale::CompareStrings().
enum
{
wxCompare_CaseSensitive = 0,
wxCompare_CaseInsensitive = 1
};
// ----------------------------------------------------------------------------
// wxUILocale allows to use the default UI locale and get information about it
// ----------------------------------------------------------------------------
@@ -47,7 +54,8 @@ public:
// Compares two strings, for a locale specified by wxLocaleIdent.
static int CompareStrings(const wxString& lhs, const wxString& rhs,
const wxLocaleIdent& localeId = wxLocaleIdent());
const wxLocaleIdent& localeId = wxLocaleIdent(),
int flags = wxCompare_CaseSensitive);
// Note that this class is not supposed to be used polymorphically, hence
// its dtor is not virtual.

View File

@@ -7,6 +7,20 @@
// Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////////
/**
Flags for wxUILocale::CompareStrings() function.
@since 3.1.6
*/
enum
{
/// Compare strings case-sensitively, this is the default.
wxCompare_CaseSensitive = 0,
/// Ignore strings case when comparing.
wxCompare_CaseInsensitive = 1
};
/**
Query and modify locale used for the UI by the current platform.
@@ -90,13 +104,17 @@ public:
@param localeId
Represents platform dependent language name.
@see wxLocaleIdent for details.
@param flags
Can be used to specify whether to compare strings case-sensitively
(default) or not, by specifying ::wxCompare_CaseInsensitive.
@return
-1 if lhs less than rhs.
0 if lhs equal to rhs.
1 if lhs greater than rhs.
*/
static int CompareStrings(const wxString& lhs, const wxString& rhs,
const wxLocaleIdent& localeId = wxLocaleIdent());
const wxLocaleIdent& localeId = wxLocaleIdent(),
int flags = wxCompare_CaseSensitive);
/**
Get the platform-dependent name of the current locale.

View File

@@ -205,12 +205,21 @@ wxUILocaleImpl* wxUILocaleImpl::CreateForLanguage(const wxLanguageInfo& info)
}
/* static */
int wxUILocale::CompareStrings(const wxString& lhs, const wxString& rhs, const wxLocaleIdent& localeId)
int
wxUILocale::CompareStrings(const wxString& lhs,
const wxString& rhs,
const wxLocaleIdent& localeId,
int flags)
{
DWORD dwFlags = 0;
if ( flags & wxCompare_CaseInsensitive )
dwFlags |= NORM_IGNORECASE;
int ret = wxMSWCompareStringEx(
localeId.IsDefault() ? LOCALE_NAME_USER_DEFAULT
: static_cast<LPCWSTR>(localeId.GetName().wc_str()),
0, // Maybe we need LINGUISTIC_IGNORECASE here
dwFlags,
static_cast<LPCWSTR>(lhs.wc_str()), -1,
static_cast<LPCWSTR>(rhs.wc_str()), -1,
NULL, // [out] version information -- not needed

View File

@@ -133,7 +133,11 @@ wxUILocaleImpl* wxUILocaleImpl::CreateForLanguage(const wxLanguageInfo& info)
}
/* static */
int wxUILocale::CompareStrings(const wxString& lhs, const wxString& rhs, const wxLocaleIdent& localeId)
int
wxUILocale::CompareStrings(const wxString& lhs,
const wxString& rhs,
const wxLocaleIdent& localeId,
int flags)
{
NSString *ns_lhs = [NSString stringWithCString:lhs.ToStdString(wxConvUTF8).c_str()
encoding:NSUTF8StringEncoding];
@@ -141,7 +145,10 @@ int wxUILocale::CompareStrings(const wxString& lhs, const wxString& rhs, const w
encoding:NSUTF8StringEncoding];
NSString *ns_locale_id = [NSString stringWithCString:localeId.GetName().ToStdString(wxConvUTF8).c_str()
encoding:NSUTF8StringEncoding];
NSInteger options = NSCaseInsensitiveSearch; // Maybe also NSDiacriticInsensitiveSearch?
NSInteger options = 0;
if ( flags & wxCompare_CaseInsensitive )
options |= NSCaseInsensitiveSearch;
NSLocale *locale = [[NSLocale alloc] initWithLocaleIdentifier:ns_locale_id];
NSComparisonResult ret = [ns_lhs compare:ns_rhs

View File

@@ -253,6 +253,9 @@ TEST_CASE("wxUILocale::GetInfo", "[.][uilocale]")
CHECK( loc.GetInfo(wxLOCALE_DECIMAL_POINT) == "." );
}
// Just a small helper to make the test below shorter.
static inline wxString u8(const char* s) { return wxString::FromUTF8(s); }
TEST_CASE("wxUILocale::CompareStrings", "[uilocale]")
{
SECTION("English")
@@ -269,9 +272,11 @@ TEST_CASE("wxUILocale::CompareStrings", "[uilocale]")
CHECK( wxUILocale::CompareStrings("", "a", l) == -1 );
// And for case handling.
CHECK( wxUILocale::CompareStrings("a", "A", l) == 0 );
CHECK( wxUILocale::CompareStrings("b", "A", l) == 1 );
CHECK( wxUILocale::CompareStrings("B", "a", l) == 1 );
CHECK( wxUILocale::CompareStrings("a", "A", l) == -1 );
CHECK( wxUILocale::CompareStrings("a", "A", l,
wxCompare_CaseInsensitive) == 0 );
CHECK( wxUILocale::CompareStrings("b", "A", l) == 1 );
CHECK( wxUILocale::CompareStrings("B", "a", l) == 1 );
}
SECTION("German")
@@ -280,9 +285,10 @@ TEST_CASE("wxUILocale::CompareStrings", "[uilocale]")
// This is more interesting and shows that CompareStrings() uses German
// dictionary rules (DIN 5007-1 variant 1).
CHECK( wxUILocale::CompareStrings(L"a", L"ä", l) == -1 );
CHECK( wxUILocale::CompareStrings(L"ä", "ae", l) == -1 );
CHECK( wxUILocale::CompareStrings(L"ß", "ss", l) == 0 );
CHECK( wxUILocale::CompareStrings("a", u8("ä"), l) == -1 );
CHECK( wxUILocale::CompareStrings(u8("ä"), "ae", l) == -1 );
CHECK( wxUILocale::CompareStrings(u8("ß"), "ss", l,
wxCompare_CaseInsensitive) == 0 );
}
SECTION("Swedish")
@@ -290,8 +296,8 @@ TEST_CASE("wxUILocale::CompareStrings", "[uilocale]")
const wxLocaleIdent l("sv");
// And this shows that sort order really depends on the language.
CHECK( wxUILocale::CompareStrings(L"ä", "ae", l) == 1 );
CHECK( wxUILocale::CompareStrings(L"ö", "z" , l) == 1 );
CHECK( wxUILocale::CompareStrings(u8("ä"), "ae", l) == 1 );
CHECK( wxUILocale::CompareStrings(u8("ö"), "z" , l) == 1 );
}
}