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) == "." );