From 829f181ccd4e2fda21cf493dc331b4a2112e1c87 Mon Sep 17 00:00:00 2001 From: Lauri Nurmi Date: Sun, 23 Sep 2018 16:18:16 +0300 Subject: [PATCH] Get preferred UI languages from the LANGUAGE variable on *nix Obey the LANGUAGE environment variable (if set), which is GNU gettext's primary way of determining language preference. Apparently ignored by wx until now, even though wx attempts to be a reimplementation of GNU gettext. The LANGUAGE variable may contain a list of preferred languages, so use that list to find the best translation. GNU gettext has supported multiple preferred languages since forever (at least 15 years), and therefore it is odd that this wasn't already implemented in 01f953efb211daf5275cbb10aa3dd000eeed6d48. Instead, it was implied that Unix does not support such. (Even if GNU is not Unix, nothing stops a wxWidgets app supporting such nevertheless.) Closes https://github.com/wxWidgets/wxWidgets/pull/948 --- src/common/translation.cpp | 50 +++++++++++++++++++++++++++++++++++--- 1 file changed, 47 insertions(+), 3 deletions(-) diff --git a/src/common/translation.cpp b/src/common/translation.cpp index b092eaa9f9..bf92ed2942 100644 --- a/src/common/translation.cpp +++ b/src/common/translation.cpp @@ -248,9 +248,53 @@ wxString GetPreferredUILanguage(const wxArrayString& available) #else -// On Unix, there's just one language=locale setting, so we should always -// use that. -#define GetPreferredUILanguage GetPreferredUILanguageFallback +// When the preferred UI language is determined, the LANGUAGE environment +// variable is the primary source of preference. +// http://www.gnu.org/software/gettext/manual/html_node/Locale-Environment-Variables.html +// +// The LANGUAGE variable may contain a colon separated list of language +// codes in the order of preference. +// http://www.gnu.org/software/gettext/manual/html_node/The-LANGUAGE-variable.html +wxString GetPreferredUILanguage(const wxArrayString& available) +{ + wxString languageFromEnv; + wxArrayString preferred; + if ( wxGetEnv("LANGUAGE", &languageFromEnv) ) + { + wxStringTokenizer tknzr(languageFromEnv, ":"); + while ( tknzr.HasMoreTokens() ) + { + const wxString tok = tknzr.GetNextToken(); + if ( const wxLanguageInfo *li = wxLocale::FindLanguageInfo(tok) ) + { + preferred.push_back(li->CanonicalName); + } + } + if ( preferred.empty() ) + { + wxLogTrace(TRACE_I18N, " - LANGUAGE was set, but it didn't contain any languages recognized by the system"); + } + } + + LogTraceArray(" - preferred languages from environment", preferred); + for ( wxArrayString::const_iterator j = preferred.begin(); + j != preferred.end(); + ++j ) + { + wxString lang(*j); + if ( available.Index(lang) != wxNOT_FOUND ) + return lang; + size_t pos = lang.find('_'); + if ( pos != wxString::npos ) + { + lang = lang.substr(0, pos); + if ( available.Index(lang) != wxNOT_FOUND ) + return lang; + } + } + + return GetPreferredUILanguageFallback(available); +} #endif