+ const wxString langOnly = ExtractLang(locale);
+ if ( !retloc )
+ {
+ // Some C libraries don't like xx_YY form and require xx only
+ retloc = wxSetlocaleTryUTF8(LC_ALL, langOnly);
+ }
+
+#if wxUSE_FONTMAP
+ // some systems (e.g. FreeBSD and HP-UX) don't have xx_YY aliases but
+ // require the full xx_YY.encoding form, so try using UTF-8 because this is
+ // the only thing we can do generically
+ //
+ // TODO: add encodings applicable to each language to the lang DB and try
+ // them all in turn here
+ if ( !retloc )
+ {
+ const wxChar **names =
+ wxFontMapperBase::GetAllEncodingNames(wxFONTENCODING_UTF8);
+ while ( *names )
+ {
+ retloc = wxSetlocale(LC_ALL, locale + wxS('.') + *names++);
+ if ( retloc )
+ break;
+ }
+ }
+#endif // wxUSE_FONTMAP
+
+ if ( !retloc )
+ {
+ // Some C libraries (namely glibc) still use old ISO 639,
+ // so will translate the abbrev for them
+ wxString localeAlt;
+ if ( langOnly == wxS("he") )
+ localeAlt = wxS("iw") + ExtractNotLang(locale);
+ else if ( langOnly == wxS("id") )
+ localeAlt = wxS("in") + ExtractNotLang(locale);
+ else if ( langOnly == wxS("yi") )
+ localeAlt = wxS("ji") + ExtractNotLang(locale);
+ else if ( langOnly == wxS("nb") )
+ localeAlt = wxS("no_NO");
+ else if ( langOnly == wxS("nn") )
+ localeAlt = wxS("no_NY");
+
+ if ( !localeAlt.empty() )
+ {
+ retloc = wxSetlocaleTryUTF8(LC_ALL, localeAlt);
+ if ( !retloc )
+ retloc = wxSetlocaleTryUTF8(LC_ALL, ExtractLang(localeAlt));
+ }
+ }
+
+ if ( !retloc )
+ ret = false;
+
+#ifdef __AIX__
+ // at least in AIX 5.2 libc is buggy and the string returned from
+ // setlocale(LC_ALL) can't be passed back to it because it returns 6
+ // strings (one for each locale category), i.e. for C locale we get back
+ // "C C C C C C"
+ //
+ // this contradicts IBM own docs but this is not of much help, so just work
+ // around it in the crudest possible manner
+ char* p = const_cast<char*>(wxStrchr(retloc, ' '));
+ if ( p )
+ *p = '\0';
+#endif // __AIX__
+
+#elif defined(__WIN32__)
+ const char *retloc = "C";
+ if ( language != wxLANGUAGE_DEFAULT )
+ {
+ if ( info->WinLang == 0 )
+ {
+ wxLogWarning(wxS("Locale '%s' not supported by OS."), name.c_str());
+ // retloc already set to "C"
+ }
+ else // language supported by Windows
+ {
+ // Windows CE doesn't have SetThreadLocale() and there doesn't seem
+ // to be any equivalent
+#ifndef __WXWINCE__
+ const wxUint32 lcid = info->GetLCID();
+
+ // change locale used by Windows functions
+ ::SetThreadLocale(lcid);
+#endif
+
+ // and also call setlocale() to change locale used by the CRT
+ locale = info->GetLocaleName();
+ if ( locale.empty() )
+ {
+ ret = false;
+ }
+ else // have a valid locale
+ {
+ retloc = wxSetlocale(LC_ALL, locale);
+ }
+ }
+ }
+ else // language == wxLANGUAGE_DEFAULT
+ {
+ retloc = wxSetlocale(LC_ALL, wxEmptyString);
+ }
+
+#if wxUSE_UNICODE && (defined(__VISUALC__) || defined(__MINGW32__))
+ // VC++ setlocale() (also used by Mingw) can't set locale to languages that
+ // can only be written using Unicode, therefore wxSetlocale() call fails
+ // for such languages but we don't want to report it as an error -- so that
+ // at least message catalogs can be used.
+ if ( !retloc )
+ {
+ if ( wxGetANSICodePageForLocale(LOCALE_USER_DEFAULT).empty() )
+ {
+ // we set the locale to a Unicode-only language, don't treat the
+ // inability of CRT to use it as an error
+ retloc = "C";
+ }
+ }
+#endif // CRT not handling Unicode-only languages
+
+ if ( !retloc )
+ ret = false;
+#elif defined(__WXMAC__)
+ if (lang == wxLANGUAGE_DEFAULT)
+ locale = wxEmptyString;
+ else
+ locale = info->CanonicalName;
+
+ const char *retloc = wxSetlocale(LC_ALL, locale);
+
+ if ( !retloc )
+ {
+ // Some C libraries don't like xx_YY form and require xx only
+ retloc = wxSetlocale(LC_ALL, ExtractLang(locale));
+ }
+#else
+ wxUnusedVar(flags);
+ return false;
+ #define WX_NO_LOCALE_SUPPORT
+#endif
+
+#ifndef WX_NO_LOCALE_SUPPORT
+ if ( !ret )
+ {
+ wxLogWarning(_("Cannot set locale to language \"%s\"."), name.c_str());
+
+ // continue nevertheless and try to load at least the translations for
+ // this language
+ }
+
+ if ( !DoInit(name, canonical, retloc) )
+ {
+ ret = false;
+ }
+
+ if (IsOk()) // setlocale() succeeded
+ m_language = lang;
+
+ // NB: don't use 'lang' here, 'language'
+ wxTranslations *t = wxTranslations::Get();
+ if ( t )
+ {
+ t->SetLanguage(static_cast<wxLanguage>(language));
+
+ if ( flags & wxLOCALE_LOAD_DEFAULT )
+ t->AddStdCatalog();
+ }
+
+ return ret;
+#endif // !WX_NO_LOCALE_SUPPORT
+}
+
+/*static*/ int wxLocale::GetSystemLanguage()
+{
+ CreateLanguagesDB();
+
+ // init i to avoid compiler warning
+ size_t i = 0,
+ count = ms_languagesDB->GetCount();
+
+#if defined(__UNIX__)
+ // first get the string identifying the language from the environment
+ wxString langFull;
+#ifdef __WXMAC__
+ wxCFRef<CFLocaleRef> userLocaleRef(CFLocaleCopyCurrent());
+
+ // because the locale identifier (kCFLocaleIdentifier) is formatted a little bit differently, eg
+ // az_Cyrl_AZ@calendar=buddhist;currency=JPY we just recreate the base info as expected by wx here
+
+ wxCFStringRef str(wxCFRetain((CFStringRef)CFLocaleGetValue(userLocaleRef, kCFLocaleLanguageCode)));
+ langFull = str.AsString()+"_";
+ str.reset(wxCFRetain((CFStringRef)CFLocaleGetValue(userLocaleRef, kCFLocaleCountryCode)));
+ langFull += str.AsString();
+#else
+ if (!wxGetEnv(wxS("LC_ALL"), &langFull) &&
+ !wxGetEnv(wxS("LC_MESSAGES"), &langFull) &&
+ !wxGetEnv(wxS("LANG"), &langFull))
+ {
+ // no language specified, treat it as English
+ return wxLANGUAGE_ENGLISH_US;
+ }