Move platform-specific parts of wxLocale::Init() to wxUILocale

This is tidier than using #ifdefs in the same common file and also
ensures that initializing wxLocale affects wxUILocale too, which will be
important for compatibility when the code elsewhere is modified to use
wxUILocale::GetInfo() instead of wxLocale::GetInfo() in the upcoming
commits.

This commit is best viewed with --color-moved git option.
This commit is contained in:
Vadim Zeitlin
2021-08-14 17:42:29 +01:00
parent d3a1abaab2
commit 37a23e1ab1
9 changed files with 270 additions and 193 deletions

View File

@@ -22,6 +22,8 @@
#include "wx/private/uilocale.h"
#include "wx/unix/private/uilocale.h"
#include "wx/intl.h"
#include <locale.h>
@@ -52,6 +54,67 @@ private:
// implementation
// ============================================================================
// Helper of wxSetlocaleTryAll() below which tries setting the given locale
// with and without UTF-8 suffix. Don't use this one directly.
static const char *wxSetlocaleTryUTF8(int c, const wxString& lc)
{
const char *l = NULL;
// NB: We prefer to set UTF-8 locale if it's possible and only fall back to
// non-UTF-8 locale if it fails, but this is not necessary under the
// supported macOS versions where xx_YY locales are just aliases to
// xx_YY.UTF-8 anyhow.
#if wxUSE_UNICODE && !defined(__WXMAC__)
if ( !lc.empty() )
{
wxString buf(lc);
wxString buf2;
buf2 = buf + wxS(".UTF-8");
l = wxSetlocale(c, buf2);
if ( !l )
{
buf2 = buf + wxS(".utf-8");
l = wxSetlocale(c, buf2);
}
if ( !l )
{
buf2 = buf + wxS(".UTF8");
l = wxSetlocale(c, buf2);
}
if ( !l )
{
buf2 = buf + wxS(".utf8");
l = wxSetlocale(c, buf2);
}
}
// if we can't set UTF-8 locale, try non-UTF-8 one:
if ( !l )
#endif // wxUSE_UNICODE && !__WXMAC__
l = wxSetlocale(c, lc);
return l;
}
// Try setting all possible versions of the given locale, i.e. with and without
// UTF-8 encoding, and with or without the "_territory" part.
const char *wxSetlocaleTryAll(int c, const wxString& lc)
{
const char* l = wxSetlocaleTryUTF8(c, lc);
if ( !l )
{
const wxString& lcOnlyLang = ExtractLang(lc);
if ( lcOnlyLang != lc )
l = wxSetlocaleTryUTF8(c, lcOnlyLang);
}
return l;
}
// ----------------------------------------------------------------------------
// wxUILocale implementation for Unix
// ----------------------------------------------------------------------------
wxUILocaleImplUnix::wxUILocaleImplUnix(const char* locale)
{
if ( locale )
@@ -88,4 +151,36 @@ wxUILocaleImpl* wxUILocaleImpl::CreateUserDefault()
return new wxUILocaleImplUnix("");
}
/* 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);
}
#endif // wxUSE_INTL