Fixed a logical error in substitution of the selected language with

the system language: System language returned by Windows for pt_BR
is pt_PT, and this language was then used incorrectly to select
the dictionary.

Now the selected language is stored into PrusaSlicer.ini and
if a substitution is to be performed to select locales (not the dictionary)
based on the system recommended locales, this substitution is being
done in runtime just before switching the locales.
Fixes PrusaSlicer 2.3.0 - Language Portuguese (Brazilian) dont work #3901

Also hopefully fixed
LANGUAGE environment variable not respected #2970
by calling
wxTranslations::Get()->GetBestTranslation()
on Unix systems as well, which reads the "LANGUAGE" environment.
This commit is contained in:
bubnikv 2020-03-26 14:27:18 +01:00
parent 0054134ff8
commit a1aee69c5a

View file

@ -684,15 +684,16 @@ bool GUI_App::select_language()
// Try to load a new language.
if (index != -1 && (init_selection == -1 || init_selection != index)) {
const wxLanguageInfo *new_language_info = language_infos[index];
if (new_language_info == m_language_info_best || new_language_info == m_language_info_system) {
// The newly selected profile matches user's default profile exactly. That's great.
} else if (m_language_info_best != nullptr && new_language_info->CanonicalName.BeforeFirst('_') == m_language_info_best->CanonicalName.BeforeFirst('_'))
new_language_info = m_language_info_best;
else if (m_language_info_system != nullptr && new_language_info->CanonicalName.BeforeFirst('_') == m_language_info_system->CanonicalName.BeforeFirst('_'))
new_language_info = m_language_info_system;
if (this->load_language(new_language_info->CanonicalName, false)) {
// Save language at application config.
app_config->set("translation_language", m_wxLocale->GetCanonicalName().ToUTF8().data());
// Which language to save as the selected dictionary language?
// 1) Hopefully the language set to wxTranslations by this->load_language(), but that API is weird and we don't want to rely on its
// stability in the future:
// wxTranslations::Get()->GetBestTranslation(SLIC3R_APP_KEY, wxLANGUAGE_ENGLISH);
// 2) Current locale language may not match the dictionary name, see GH issue #3901
// m_wxLocale->GetCanonicalName()
// 3) new_language_info->CanonicalName is a safe bet. It points to a valid dictionary name.
app_config->set("translation_language", new_language_info->CanonicalName.ToUTF8().data());
app_config->save();
return true;
}
@ -721,7 +722,6 @@ bool GUI_App::load_language(wxString language, bool initial)
BOOST_LOG_TRIVIAL(trace) << boost::format("System language detected (user locales and such): %1%") % m_language_info_system->CanonicalName.ToUTF8().data();
}
}
#if defined(__WXMSW__) || defined(__WXOSX__)
{
// Allocating a temporary locale will switch the default wxTranslations to its internal wxTranslations instance.
wxLocale temp_locale;
@ -738,7 +738,6 @@ bool GUI_App::load_language(wxString language, bool initial)
BOOST_LOG_TRIVIAL(trace) << boost::format("Best translation language detected (may be different from user locales): %1%") % m_language_info_best->CanonicalName.ToUTF8().data();
}
}
#endif
}
const wxLanguageInfo *language_info = language.empty() ? nullptr : wxLocale::FindLanguageInfo(language);
@ -754,6 +753,7 @@ bool GUI_App::load_language(wxString language, bool initial)
}
if (language_info == nullptr) {
// PrusaSlicer does not support the Right to Left languages yet.
if (m_language_info_system != nullptr && m_language_info_system->LayoutDirection != wxLayout_RightToLeft)
language_info = m_language_info_system;
if (m_language_info_best != nullptr && m_language_info_best->LayoutDirection != wxLayout_RightToLeft)
@ -772,6 +772,16 @@ bool GUI_App::load_language(wxString language, bool initial)
BOOST_LOG_TRIVIAL(trace) << "Using Czech dictionaries for Slovak language";
}
// Select language for locales. This language may be different from the language of the dictionary.
if (language_info == m_language_info_best || language_info == m_language_info_system) {
// The current language matches user's default profile exactly. That's great.
} else if (m_language_info_best != nullptr && language_info->CanonicalName.BeforeFirst('_') == m_language_info_best->CanonicalName.BeforeFirst('_')) {
// Use whatever the operating system recommends, if it the language code of the dictionary matches the recommended language.
// This allows a Swiss guy to use a German dictionary without forcing him to German locales.
language_info = m_language_info_best;
} else if (m_language_info_system != nullptr && language_info->CanonicalName.BeforeFirst('_') == m_language_info_system->CanonicalName.BeforeFirst('_'))
language_info = m_language_info_system;
if (! wxLocale::IsAvailable(language_info->Language)) {
// Loading the language dictionary failed.
wxString message = "Switching PrusaSlicer to language " + language_info->CanonicalName + " failed.";