diff --git a/include/wx/private/uilocale.h b/include/wx/private/uilocale.h index bfa6f318ea..af8e3dcedc 100644 --- a/include/wx/private/uilocale.h +++ b/include/wx/private/uilocale.h @@ -33,8 +33,8 @@ public: // It may return NULL in case of failure. static wxUILocaleImpl* CreateUserDefault(); - // This function exists only for wxLocale compatibility and sets the locale - // corresponding to the given language. + // This function exists only for wxLocale compatibility and creates the + // locale corresponding to the given language. // // The language passed to this function is a valid language, i.e. neither // wxLANGUAGE_UNKNOWN nor wxLANGUAGE_DEFAULT. @@ -42,6 +42,13 @@ public: // It may return NULL in case of failure. static wxUILocaleImpl* CreateForLanguage(const wxLanguageInfo& info); + // Use this locale in the UI. + // + // This is not implemented for all platforms, notably not for Mac where the + // UI locale is determined at application startup, and so this function + // always returns false there. + virtual bool Use() = 0; + // Functions corresponding to wxUILocale ones. virtual wxString GetName() const = 0; virtual wxString GetInfo(wxLocaleInfo index, wxLocaleCategory cat) const = 0; diff --git a/src/common/uilocale.cpp b/src/common/uilocale.cpp index 4843f823e5..0cd095c879 100644 --- a/src/common/uilocale.cpp +++ b/src/common/uilocale.cpp @@ -48,6 +48,7 @@ bool wxUILocale::UseDefault() if ( !impl ) return false; + impl->Use(); ms_current.SetImpl(impl); return true; @@ -60,6 +61,12 @@ bool wxUILocale::UseLanguage(const wxLanguageInfo& info) if ( !impl ) return false; + if ( !impl->Use() ) + { + delete impl; + return false; + } + ms_current.SetImpl(impl); return true; diff --git a/src/msw/uilocale.cpp b/src/msw/uilocale.cpp index fa942fc7b9..be2583eba3 100644 --- a/src/msw/uilocale.cpp +++ b/src/msw/uilocale.cpp @@ -142,7 +142,14 @@ public: explicit wxUILocaleImplLCID(LCID lcid) : m_lcid(lcid) { - wxUseLCID(lcid); + } + + bool Use() wxOVERRIDE + { + wxUseLCID(m_lcid); + + // As long as we use a valid LCID (and we always do), it shouldn't fail. + return true; } wxString GetName() const wxOVERRIDE diff --git a/src/osx/core/uilocale.mm b/src/osx/core/uilocale.mm index 63d21ce6d8..7c9625ec28 100644 --- a/src/osx/core/uilocale.mm +++ b/src/osx/core/uilocale.mm @@ -87,6 +87,7 @@ public: return new wxUILocaleImplCF(cfloc); } + bool Use() wxOVERRIDE; wxString GetName() const wxOVERRIDE; wxString GetInfo(wxLocaleInfo index, wxLocaleCategory cat) const wxOVERRIDE; @@ -102,6 +103,13 @@ private: // implementation // ============================================================================ +bool +wxUILocaleImplCF::Use() +{ + // There is no way to start using a locale other than default. + return false; +} + wxString wxUILocaleImplCF::GetName() const { diff --git a/src/unix/uilocale.cpp b/src/unix/uilocale.cpp index 405f53df89..eccb44594d 100644 --- a/src/unix/uilocale.cpp +++ b/src/unix/uilocale.cpp @@ -43,11 +43,16 @@ class wxUILocaleImplUnix : public wxUILocaleImpl public: // Locale argument may be NULL to not change it at all. explicit wxUILocaleImplUnix(const char* locale); + ~wxUILocaleImplUnix() wxOVERRIDE; + bool Use() wxOVERRIDE; wxString GetName() const wxOVERRIDE; wxString GetInfo(wxLocaleInfo index, wxLocaleCategory cat) const wxOVERRIDE; private: + // This pointer is owned by this class and may be NULL. + char* const m_name; + wxDECLARE_NO_COPY_CLASS(wxUILocaleImplUnix); }; @@ -142,15 +147,54 @@ const char *wxSetlocaleTryAll(int c, const wxString& lc) // ---------------------------------------------------------------------------- wxUILocaleImplUnix::wxUILocaleImplUnix(const char* locale) + : m_name(locale ? strdup(locale) : NULL) { - if ( locale ) - setlocale(LC_ALL, locale); +} + +wxUILocaleImplUnix::~wxUILocaleImplUnix() +{ + free(m_name); +} + +bool +wxUILocaleImplUnix::Use() +{ + if ( !m_name ) + { + // This is the default locale, it is already in use. + return true; + } + + const wxString& shortName = wxString::FromAscii(m_name); + + if ( !wxSetlocaleTryAll(LC_ALL, shortName) ) + { + // Some C libraries (namely glibc) still use old ISO 639, + // so will translate the abbrev for them + wxString localeAlt; + const wxString& langOnly = ExtractLang(shortName); + if ( langOnly == wxS("he") ) + localeAlt = wxS("iw") + ExtractNotLang(shortName); + else if ( langOnly == wxS("id") ) + localeAlt = wxS("in") + ExtractNotLang(shortName); + else if ( langOnly == wxS("yi") ) + localeAlt = wxS("ji") + ExtractNotLang(shortName); + else if ( langOnly == wxS("nb") ) + localeAlt = wxS("no_NO"); + else if ( langOnly == wxS("nn") ) + localeAlt = wxS("no_NY"); + + if ( localeAlt.empty() || !wxSetlocaleTryAll(LC_ALL, localeAlt) ) + return false; + } + + return true; } wxString wxUILocaleImplUnix::GetName() const { - return wxString::FromAscii(setlocale(LC_ALL, NULL)); + return wxString::FromAscii(m_name ? m_name : setlocale(LC_ALL, NULL)); } wxString @@ -217,33 +261,7 @@ wxUILocaleImpl* wxUILocaleImpl::CreateUserDefault() /* static */ wxUILocaleImpl* wxUILocaleImpl::CreateForLanguage(const wxLanguageInfo& info) { - // Set the locale before creating the wxUILocaleImplUnix object in order to - // check if we succeed in doing it. - - const wxString& shortName = info.CanonicalName; - - if ( !wxSetlocaleTryAll(LC_ALL, shortName) ) - { - // Some C libraries (namely glibc) still use old ISO 639, - // so will translate the abbrev for them - wxString localeAlt; - const wxString& langOnly = ExtractLang(shortName); - if ( langOnly == wxS("he") ) - localeAlt = wxS("iw") + ExtractNotLang(shortName); - else if ( langOnly == wxS("id") ) - localeAlt = wxS("in") + ExtractNotLang(shortName); - else if ( langOnly == wxS("yi") ) - localeAlt = wxS("ji") + ExtractNotLang(shortName); - else if ( langOnly == wxS("nb") ) - localeAlt = wxS("no_NO"); - else if ( langOnly == wxS("nn") ) - localeAlt = wxS("no_NY"); - - if ( localeAlt.empty() || !wxSetlocaleTryAll(LC_ALL, localeAlt) ) - return NULL; - } - - return new wxUILocaleImplUnix(NULL); + return new wxUILocaleImplUnix(info.CanonicalName); } #endif // wxUSE_INTL