From e0ffbf106d2a959c7c27d688036c86779ded7bb0 Mon Sep 17 00:00:00 2001 From: Brian Nixon Date: Mon, 3 Apr 2023 11:34:02 +0100 Subject: [PATCH] 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. --- clientgui/BOINCGUIApp.cpp | 24 ++++++++++----- clientgui/BOINCGUIApp.h | 5 +++- clientgui/DlgOptions.cpp | 62 +++++++++++++++++++-------------------- 3 files changed, 51 insertions(+), 40 deletions(-) diff --git a/clientgui/BOINCGUIApp.cpp b/clientgui/BOINCGUIApp.cpp index 43ee88c884..fa0c74f726 100644 --- a/clientgui/BOINCGUIApp.cpp +++ b/clientgui/BOINCGUIApp.cpp @@ -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 diff --git a/clientgui/BOINCGUIApp.h b/clientgui/BOINCGUIApp.h index 3a644fd8ed..30ba9efc25 100644 --- a/clientgui/BOINCGUIApp.h +++ b/clientgui/BOINCGUIApp.h @@ -124,6 +124,7 @@ protected: std::vector 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(); diff --git a/clientgui/DlgOptions.cpp b/clientgui/DlgOptions.cpp index 9e930fa005..f4fec7b207 100644 --- a/clientgui/DlgOptions.cpp +++ b/clientgui/DlgOptions.cpp @@ -624,24 +624,27 @@ bool CDlgOptions::ReadSettings() { // General Tab - const wxLanguageInfo* pLI = wxLocale::FindLanguageInfo(wxGetApp().GetISOLanguageCode()); - if (pLI) { - const std::vector& 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& 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& 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& 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: