Add "(Automatic Detection)" as a language option

New config option "BOINC Manager/UseDefaultLocale" (Boolean)

Also remove the logic that tried to match regional locale variations to
translation base languages, because it had the unacceptable side-effect
of losing region-specific locale settings like date formats.
This commit is contained in:
Brian Nixon 2023-04-03 11:34:02 +01:00
parent 992892b430
commit e0ffbf106d
3 changed files with 51 additions and 40 deletions

View File

@ -101,6 +101,7 @@ bool CBOINCGUIApp::OnInit() {
m_iRPCPortArg = GUI_RPC_PORT;
m_strBOINCArguments = wxEmptyString;
m_strISOLanguageCode = wxEmptyString;
m_bUseDefaultLocale = true;
m_bGUIVisible = true;
m_bDebugSkins = false;
m_bMultipleInstancesOK = false;
@ -119,7 +120,7 @@ bool CBOINCGUIApp::OnInit() {
m_bNeedRunDaemon = true;
// Initialize local variables
int iDesiredLanguageCode = 0;
int iDesiredLanguageCode = wxLANGUAGE_DEFAULT;
bool bOpenEventLog = false;
wxString strDesiredSkinName = wxEmptyString;
#ifdef SANDBOX
@ -196,6 +197,10 @@ bool CBOINCGUIApp::OnInit() {
#endif
m_pConfig->Read(wxT("DisableAutoStart"), &m_iBOINCMGRDisableAutoStart, 0L);
m_pConfig->Read(wxT("LanguageISO"), &m_strISOLanguageCode, wxT(""));
bool bUseDefaultLocaleDefault =
// Migration: assume a selected language code that matches the system default means "auto select"
m_strISOLanguageCode == wxLocale::GetLanguageInfo(wxLANGUAGE_DEFAULT)->CanonicalName;
m_pConfig->Read(wxT("UseDefaultLocale"), &m_bUseDefaultLocale, bUseDefaultLocaleDefault);
m_pConfig->Read(wxT("GUISelection"), &m_iGUISelected, BOINC_SIMPLEGUI);
m_pConfig->Read(wxT("EventLogOpen"), &bOpenEventLog);
m_pConfig->Read(wxT("RunDaemon"), &m_bRunDaemon, 1L);
@ -265,15 +270,11 @@ bool CBOINCGUIApp::OnInit() {
wxASSERT(m_pLocale);
//
if (!m_strISOLanguageCode.IsEmpty()) {
if (!m_bUseDefaultLocale && !m_strISOLanguageCode.IsEmpty()) {
const wxLanguageInfo* pLI = wxLocale::FindLanguageInfo(m_strISOLanguageCode);
if (pLI) {
iDesiredLanguageCode = pLI->Language;
} else {
iDesiredLanguageCode = wxLANGUAGE_DEFAULT;
}
} else {
iDesiredLanguageCode = wxLANGUAGE_DEFAULT;
}
m_pLocale->Init(iDesiredLanguageCode);
if (iDesiredLanguageCode == wxLANGUAGE_DEFAULT) {
@ -603,6 +604,7 @@ void CBOINCGUIApp::SaveState() {
m_pConfig->Write(wxT("Skin"), m_pSkinManager->GetSelectedSkin());
}
m_pConfig->Write(wxT("LanguageISO"), m_strISOLanguageCode);
m_pConfig->Write(wxT("UseDefaultLocale"), m_bUseDefaultLocale);
m_pConfig->Write(wxT("AutomaticallyShutdownClient"), m_iShutdownCoreClient);
m_pConfig->Write(wxT("DisplayShutdownClientDialog"), m_iDisplayExitDialog);
m_pConfig->Write(wxT("DisplayShutdownConnectedClientDialog"), m_iDisplayShutdownConnectedClientDialog);
@ -912,7 +914,15 @@ void CBOINCGUIApp::InitSupportedLanguages() {
}
// Synthesize labels to be used in the options dialog
m_astrLanguages.reserve(langs.size() + 1); // +1 for the entry for "English"
m_astrLanguages.reserve(2 + langs.size()); // +2 for the entries for "Auto" and "English"
// CDlgOptions depends on "Auto" being the first item in the list
wxString strAutoEnglish = wxT("(Automatic Detection)");
wxString strAutoTranslated = wxGetTranslation(strAutoEnglish);
wxString lblAuto = strAutoTranslated;
if (strAutoTranslated != strAutoEnglish) {
lblAuto += wxT(" ") + strAutoEnglish;
}
m_astrLanguages.push_back(GUI_SUPPORTED_LANG({wxLANGUAGE_DEFAULT, lblAuto}));
// English is a special case:
// - it's guaranteed to be available because it's compiled in
// - the label is unique because "English (English)" would look silly

View File

@ -124,6 +124,7 @@ protected:
std::vector<GUI_SUPPORTED_LANG> m_astrLanguages;
wxString m_strISOLanguageCode;
bool m_bUseDefaultLocale;
int m_bSafeMessageBoxDisplayed;
@ -194,7 +195,9 @@ public:
wxString GetISOLanguageCode() { return m_strISOLanguageCode; }
void SetISOLanguageCode(wxString strISOLanguageCode)
{ m_strISOLanguageCode = strISOLanguageCode; }
bool UseDefaultLocale() const { return m_bUseDefaultLocale; }
void SetUseDefaultLocale(bool b) { m_bUseDefaultLocale = b; }
void SetEventLogWasActive(bool wasActive) { m_bEventLogWasActive = wasActive; }
void DisplayEventLog(bool bShowWindow = true);
void OnEventLogClose();

View File

@ -624,24 +624,27 @@ bool CDlgOptions::ReadSettings() {
// General Tab
const wxLanguageInfo* pLI = wxLocale::FindLanguageInfo(wxGetApp().GetISOLanguageCode());
if (pLI) {
const std::vector<GUI_SUPPORTED_LANG>& langs = wxGetApp().GetSupportedLanguages();
auto finder = [pLI](const GUI_SUPPORTED_LANG& item) {
// Previous auto-detection might have set preference to e.g. "de_CH"
// But now selected language will appear as just "de"
// Make sure we find a match in that case
return item.Language == pLI->Language ||
wxLocale::GetLanguageInfo(item.Language)->CanonicalName
== pLI->CanonicalName.BeforeFirst('_');
};
const auto foundit = std::find_if(langs.begin(), langs.end(), finder);
if (foundit != langs.end()) {
int selLangIdx = foundit - langs.begin();
m_LanguageSelectionCtrl->SetSelection(selLangIdx);
} // else (probably) the user had previously selected a language for which
// no translation is available. In that case, we don't forcibly change
// their stored preference. They'll still see the UI in English.
if (wxGetApp().UseDefaultLocale()) {
// CBOINCGUIApp::InitSupportedLanguages() ensures "Auto" is the first item in the list
m_LanguageSelectionCtrl->SetSelection(0);
} else {
const wxLanguageInfo* pLI = wxLocale::FindLanguageInfo(wxGetApp().GetISOLanguageCode());
if (pLI) {
const std::vector<GUI_SUPPORTED_LANG>& langs = wxGetApp().GetSupportedLanguages();
auto finder = [pLI](const GUI_SUPPORTED_LANG& item) {
return item.Language == pLI->Language;
};
const auto foundit = std::find_if(langs.begin(), langs.end(), finder);
if (foundit != langs.end()) {
int selLangIdx = foundit - langs.begin();
m_LanguageSelectionCtrl->SetSelection(selLangIdx);
} // else (probably) the user had previously selected a language for which no
// translation is available, or a regional variation that isn't the system default.
// In those cases, we don't forcibly change their stored preference.
// The language drop-down will have no selection, which looks a bit odd;
// and if they subsequently select one of the available languages,
// the previous setting (including any regional variation) will be lost.
}
}
m_ReminderFrequencyCtrl->Append(_("always"));
@ -746,21 +749,15 @@ bool CDlgOptions::SaveSettings() {
// General Tab
wxString oldLangCode = wxGetApp().GetISOLanguageCode();
wxString newLangCode = oldLangCode;
const std::vector<GUI_SUPPORTED_LANG>& langs = wxGetApp().GetSupportedLanguages();
int selLangIdx = m_LanguageSelectionCtrl->GetSelection();
if (selLangIdx >= 0 && selLangIdx < langs.size()) {
const GUI_SUPPORTED_LANG& selLang = langs[selLangIdx];
const wxLanguageInfo* pLI = wxLocale::GetLanguageInfo(selLang.Language);
if (pLI) {
// Previous auto-detection might have set preference to e.g. "de_CH"
// But now selected language will appear as just "de"
// Make sure we don't consider that a change
bool isSelLangEquivalentToUserPref =
pLI->CanonicalName == oldLangCode ||
oldLangCode.StartsWith(pLI->CanonicalName+wxT("_"));
if (!isSelLangEquivalentToUserPref) {
newLangCode = pLI->CanonicalName;
}
if (selLangIdx == 0) {
// CBOINCGUIApp::InitSupportedLanguages() ensures "Auto" is the first item in the list
newLangCode = wxLocale::GetLanguageInfo(wxLANGUAGE_DEFAULT)->CanonicalName;
} else if (selLangIdx > 0) {
const std::vector<GUI_SUPPORTED_LANG>& langs = wxGetApp().GetSupportedLanguages();
if (selLangIdx < langs.size()) {
const GUI_SUPPORTED_LANG& selLang = langs[selLangIdx];
newLangCode = wxLocale::GetLanguageInfo(selLang.Language)->CanonicalName;
}
}
if (newLangCode != oldLangCode) {
@ -790,6 +787,7 @@ bool CDlgOptions::SaveSettings() {
}
wxGetApp().SetISOLanguageCode(newLangCode);
wxGetApp().SetUseDefaultLocale(selLangIdx == 0);
switch(m_ReminderFrequencyCtrl->GetSelection()) {
case 0: