From 32316af106cbddb2334498bb0d3887bbfd085786 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Mon, 30 Aug 2021 21:02:00 +0200 Subject: [PATCH] Add wxUILocale::IsSupported() This function can now be implemented relatively straightforwardly (although it does require an extra check under Mac), so add it, as it can be generally useful and we're also going to need it for our own tests in the upcoming commit. --- include/wx/uilocale.h | 4 ++++ interface/wx/uilocale.h | 11 +++++++++++ src/common/uilocale.cpp | 5 +++++ src/osx/core/uilocale.mm | 13 +++++++++++-- tests/intl/intltest.cpp | 7 +++++++ 5 files changed, 38 insertions(+), 2 deletions(-) diff --git a/include/wx/uilocale.h b/include/wx/uilocale.h index 216619068b..77b9d82abd 100644 --- a/include/wx/uilocale.h +++ b/include/wx/uilocale.h @@ -48,6 +48,10 @@ public: // Create the object corresponding to the given locale. explicit wxUILocale(const wxLocaleIdent& localeId); + // Check if the locale is actually supported by the current system: if it's + // not supported, the other functions will behave as for the "C" locale. + bool IsSupported() const; + // Get the platform-dependent name of the current locale. wxString GetName() const; diff --git a/interface/wx/uilocale.h b/interface/wx/uilocale.h index 3f722722d9..65d24ec01e 100644 --- a/interface/wx/uilocale.h +++ b/interface/wx/uilocale.h @@ -156,6 +156,17 @@ public: */ wxString GetInfo(wxLocaleInfo index, wxLocaleCategory cat = wxLOCALE_CAT_DEFAULT) const; + + /** + Return true if locale is supported on the current system. + + If this function returns @a false, the other functions of this class, + such as GetInfo() and CompareStrings(), behave as in "C" locale, i.e. + it's still safe to call them, but their results don't reflect the rules + for the locale in question, but just use the default (i.e. US English) + conventions. + */ + bool IsSupported() const; }; /** diff --git a/src/common/uilocale.cpp b/src/common/uilocale.cpp index ef360fb42e..6bf54e6710 100644 --- a/src/common/uilocale.cpp +++ b/src/common/uilocale.cpp @@ -116,6 +116,11 @@ void wxUILocale::SetImpl(wxUILocaleImpl* impl) m_impl = impl; } +bool wxUILocale::IsSupported() const +{ + return m_impl != NULL; +} + wxString wxUILocale::GetName() const { if ( !m_impl ) diff --git a/src/osx/core/uilocale.mm b/src/osx/core/uilocale.mm index 501ffa0b6e..e70d72050c 100644 --- a/src/osx/core/uilocale.mm +++ b/src/osx/core/uilocale.mm @@ -80,8 +80,17 @@ public: static wxUILocaleImplCF* Create(const wxLocaleIdent& locId) { - CFLocaleRef cfloc = CFLocaleCreate(kCFAllocatorDefault, - wxCFStringRef(locId.GetName())); + // Surprisingly, CFLocaleCreate() always succeeds, even for completely + // invalid strings, so we need to check if the name is actually in the + // list of the supported locales ourselves. + static wxCFRef + all = CFLocaleCopyAvailableLocaleIdentifiers(); + + wxCFStringRef cfName(locId.GetName()); + if ( !CFArrayContainsValue(all, CFRangeMake(0, CFArrayGetCount(all)), cfName) ) + return NULL; + + CFLocaleRef cfloc = CFLocaleCreate(kCFAllocatorDefault, cfName); if ( !cfloc ) return NULL; diff --git a/tests/intl/intltest.cpp b/tests/intl/intltest.cpp index 4400834a59..350965643e 100644 --- a/tests/intl/intltest.cpp +++ b/tests/intl/intltest.cpp @@ -240,6 +240,13 @@ TEST_CASE("wxLocale::Default", "[locale]") #endif // wxUSE_UNICODE +TEST_CASE("wxUILocale::IsSupported", "[uilocale]") +{ + CHECK( wxUILocale("en").IsSupported() ); + CHECK( wxUILocale(wxLocaleIdent("fr").Region("FR")).IsSupported() ); + CHECK( !wxUILocale("bloordyblop").IsSupported() ); +} + TEST_CASE("wxUILocale::GetInfo", "[uilocale]") { CHECK( wxUILocale("en").GetInfo(wxLOCALE_DECIMAL_POINT) == "." );