From c8269210a206d2e0e4524b2b7678161ead5d4c8d Mon Sep 17 00:00:00 2001 From: Alexander Koshelev Date: Fri, 27 Aug 2021 17:54:02 +0300 Subject: [PATCH] Add wxUILocale::CompareStrings() function This function allows comparing strings using the sort order of the specified locale, represented by the new wxLocaleIdent class. It is implemented using CompareStringEx()[1] under MSW and NSString::compare:options:range:locale:[2] under macOS, generic implementation for the other platforms is upcoming. [1]: https://docs.microsoft.com/en-us/windows/win32/api/stringapiset/nf-stringapiset-comparestringex [2]: https://developer.apple.com/documentation/foundation/nsstring/1414561-compare?language=objc --- include/wx/localedefs.h | 57 +++++++++++++++++++++ include/wx/uilocale.h | 4 ++ interface/wx/uilocale.h | 108 +++++++++++++++++++++++++++++++++++++++ src/msw/uilocale.cpp | 92 +++++++++++++++++++++++++++++++++ src/osx/core/uilocale.mm | 62 ++++++++++++++++++++++ src/unix/uilocale.cpp | 20 ++++++++ 6 files changed, 343 insertions(+) diff --git a/include/wx/localedefs.h b/include/wx/localedefs.h index d5b43b2eff..686cb2ae98 100644 --- a/include/wx/localedefs.h +++ b/include/wx/localedefs.h @@ -108,6 +108,63 @@ struct WXDLLIMPEXP_BASE wxLanguageInfo const char* TrySetLocale() const; }; +// ---------------------------------------------------------------------------- +// wxLocaleIdent: allows to fully identify a locale under all platforms +// ---------------------------------------------------------------------------- + +class WXDLLIMPEXP_BASE wxLocaleIdent +{ +public: + // Leave language empty + wxLocaleIdent() { } + + // Construct name from language + wxLocaleIdent(const wxString& language) : m_language(language) { } + + // Set language + wxLocaleIdent& Language(const wxString& language) + { + m_language = language; + return *this; + } + + // Set region + wxLocaleIdent& Region(const wxString& region) + { + m_region = region; + return *this; + } + + // Set script + wxLocaleIdent& Script(const wxString& script) + { + m_script = script; + return *this; + } + + // Set modifier + wxLocaleIdent& Modifier(const wxString& modifier) + { + m_modifier = modifier; + return *this; + } + + // Construct platform dependent name + wxString GetName() const; + + // Empty language represents user's default language + bool IsDefault() const + { + return m_language.empty(); + } + +private: + wxString m_language; + wxString m_region; + wxString m_script; + wxString m_modifier; +}; + #endif // wxUSE_INTL #endif // _WX_LOCALEDEFS_H_ diff --git a/include/wx/uilocale.h b/include/wx/uilocale.h index acae223190..4481aae4c1 100644 --- a/include/wx/uilocale.h +++ b/include/wx/uilocale.h @@ -45,6 +45,10 @@ public: wxString GetInfo(wxLocaleInfo index, wxLocaleCategory cat = wxLOCALE_CAT_DEFAULT) const; + // Compares two strings, for a locale specified by wxLocaleIdent. + static int CompareStrings(const wxString& lhs, const wxString& rhs, + const wxLocaleIdent& localeId = wxLocaleIdent()); + // Note that this class is not supposed to be used polymorphically, hence // its dtor is not virtual. ~wxUILocale(); diff --git a/interface/wx/uilocale.h b/interface/wx/uilocale.h index de6bcc7550..3beecc6ce1 100644 --- a/interface/wx/uilocale.h +++ b/interface/wx/uilocale.h @@ -80,6 +80,24 @@ public: */ static const wxUILocale& GetCurrent(); + /** + Compares two strings using comparison rules of the given locale. + + @param lhs + First comparing string. + @param rhs + Second comparing string. + @param localeId + Represents platform dependent language name. + @see wxLocaleIdent for details. + @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()); + /** Get the platform-dependent name of the current locale. @@ -119,3 +137,93 @@ public: @since 3.1.6 */ wxString wxGetUIDateFormat(); + +/** + Allows to construct the full locale identifier in a portable way. + + Parts of the locale not supported by the current platform (e.g. modifier under non-Unix platforms) are ignored. + The remaining parts are used to construct a string uniquely identifying the locale in a platform-specific name. + + Usage example: + @code + auto loc = wxLocaleIdent("fr").Region("BE").Modifier("euro"); + #if defined(__WINDOWS__) || defined(__WXOSX__) + wxASSERT( loc.GetName() == "fr_BE" ); + #elif defined(__UNIX__) + wxASSERT( loc.GetName() == "fr_BE@euro" ); + #endif + @endcode + @since 3.1.6 +*/ +class wxLocaleIdent +{ +public: + /** + This is the default constructor and it leaves language empty. + */ + wxLocaleIdent(); + + /** + Constructor with language. + + @param language + ISO 639 language code. + See Language() for more detailed info. + */ + wxLocaleIdent(const wxString& language); + + /** + Set language. + Return reference to @this for method chaining. + + @param language + It is a lowercase ISO 639 language code. + The codes from ISO 639-1 are used when available. + Otherwise, codes from ISO 639-2/T are used. + */ + wxLocaleIdent& Language(const wxString& language); + + /** + Set region. + Return reference to @this for method chaining. + + @param region + It specifies an uppercase ISO 3166-1 country/region identifier. + */ + wxLocaleIdent& Region(const wxString& region); + + /** + Set script. + Return reference to @this for method chaining. + + @param script + It is an initial-uppercase ISO 15924 script code. + */ + wxLocaleIdent& Script(const wxString& script); + + /** + Set modifier. + Return reference to @this for method chaining. + + @param modifier + Modifier is defined by ISO/IEC 15897. + It is a semi-colon separated list of identifiers, or name=value pairs. + */ + wxLocaleIdent& Modifier(const wxString& modifier); + + /** + Construct platform dependent name. + Format: + Windows: -