diff --git a/common/eda_base_frame.cpp b/common/eda_base_frame.cpp index 5f5d52cd5b..b8bdfeb559 100644 --- a/common/eda_base_frame.cpp +++ b/common/eda_base_frame.cpp @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -343,9 +344,6 @@ void EDA_BASE_FRAME::HandleUpdateUIEvent( wxUpdateUIEvent& aEvent, EDA_BASE_FRAM } -// Contained inside pgm_base.cpp -extern LANGUAGE_DESCR LanguagesList[]; - void EDA_BASE_FRAME::setupUIConditions() { // Setup the conditions to check a language menu item diff --git a/common/kiway.cpp b/common/kiway.cpp index 820f7050f7..f567ae8c88 100644 --- a/common/kiway.cpp +++ b/common/kiway.cpp @@ -2,7 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2014 SoftPLC Corporation, Dick Hollenbeck - * Copyright (C) 2014-2017 KiCad Developers, see CHANGELOG.TXT for contributors. + * Copyright (C) 2014-2020 KiCad Developers, see CHANGELOG.TXT for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -439,8 +440,39 @@ void KIWAY::ExpressMail( FRAME_T aDestination, MAIL_T aCommand, std::string& aPa void KIWAY::SetLanguage( int aLanguage ) { - Pgm().SetLanguageIdentifier( aLanguage ); - Pgm().SetLanguage(); + wxString errMsg; + bool ret = false; + + { + // Only allow the traces to be logged by wx. We use our own system to log when the + // OS doesn't support the language, so we want to hide the wx error. + WX_LOG_TRACE_ONLY logtraceOnly; + Pgm().SetLanguageIdentifier( aLanguage ); + ret = Pgm().SetLanguage( errMsg ); + } + + if( !ret ) + { + wxString lang; + + for( unsigned ii = 0; LanguagesList[ii].m_KI_Lang_Identifier != 0; ii++ ) + { + if( aLanguage == LanguagesList[ii].m_KI_Lang_Identifier ) + { + if( LanguagesList[ii].m_DoNotTranslate ) + lang = LanguagesList[ii].m_Lang_Label; + else + lang = wxGetTranslation( LanguagesList[ii].m_Lang_Label ); + + break; + } + } + + DisplayErrorMessage( nullptr, + wxString::Format( _( "Unable to switch language to %s" ), lang ), + errMsg ); + return; + } #if 1 // This is a risky hack that goes away if we allow the language to be diff --git a/common/languages_menu.cpp b/common/languages_menu.cpp index 0cc8be557e..2bd3dafae1 100644 --- a/common/languages_menu.cpp +++ b/common/languages_menu.cpp @@ -36,9 +36,7 @@ #include #include #include - -// Contained inside pgm_base.cpp -extern LANGUAGE_DESCR LanguagesList[]; +#include /** * Function AddMenuLanguageList diff --git a/common/pgm_base.cpp b/common/pgm_base.cpp index 0cb754f460..251e94f048 100644 --- a/common/pgm_base.cpp +++ b/common/pgm_base.cpp @@ -72,23 +72,23 @@ LANGUAGE_DESCR LanguagesList[] = { { wxLANGUAGE_DEFAULT, ID_LANGUAGE_DEFAULT, _( "Default" ), false }, { wxLANGUAGE_ENGLISH, ID_LANGUAGE_ENGLISH, wxT( "English" ), true }, - { wxLANGUAGE_FRENCH, ID_LANGUAGE_FRENCH, wxT( "Français" ), false }, - { wxLANGUAGE_SPANISH, ID_LANGUAGE_SPANISH, wxT( "Español" ), false }, - { wxLANGUAGE_PORTUGUESE, ID_LANGUAGE_PORTUGUESE, wxT( "Português" ),false }, - { wxLANGUAGE_ITALIAN, ID_LANGUAGE_ITALIAN, wxT( "Italiano" ), false }, - { wxLANGUAGE_GERMAN, ID_LANGUAGE_GERMAN, wxT( "Deutsch" ), false }, - { wxLANGUAGE_GREEK, ID_LANGUAGE_GREEK, wxT( "Ελληνικά" ), false }, - { wxLANGUAGE_HUNGARIAN, ID_LANGUAGE_HUNGARIAN, wxT( "Magyar" ), false }, - { wxLANGUAGE_POLISH, ID_LANGUAGE_POLISH, wxT( "Polski" ), false }, - { wxLANGUAGE_CZECH, ID_LANGUAGE_CZECH, wxT( "Čeština" ), false }, - { wxLANGUAGE_RUSSIAN, ID_LANGUAGE_RUSSIAN, wxT( "Русский" ), false }, + { wxLANGUAGE_FRENCH, ID_LANGUAGE_FRENCH, wxT( "Français" ), true }, + { wxLANGUAGE_SPANISH, ID_LANGUAGE_SPANISH, wxT( "Español" ), true }, + { wxLANGUAGE_PORTUGUESE, ID_LANGUAGE_PORTUGUESE, wxT( "Português" ),true }, + { wxLANGUAGE_ITALIAN, ID_LANGUAGE_ITALIAN, wxT( "Italiano" ), true }, + { wxLANGUAGE_GERMAN, ID_LANGUAGE_GERMAN, wxT( "Deutsch" ), true }, + { wxLANGUAGE_GREEK, ID_LANGUAGE_GREEK, wxT( "Ελληνικά" ), true }, + { wxLANGUAGE_HUNGARIAN, ID_LANGUAGE_HUNGARIAN, wxT( "Magyar" ), true }, + { wxLANGUAGE_POLISH, ID_LANGUAGE_POLISH, wxT( "Polski" ), true }, + { wxLANGUAGE_CZECH, ID_LANGUAGE_CZECH, wxT( "Čeština" ), true }, + { wxLANGUAGE_RUSSIAN, ID_LANGUAGE_RUSSIAN, wxT( "Русский" ), true }, { wxLANGUAGE_CHINESE_SIMPLIFIED, ID_LANGUAGE_CHINESE_SIMPLIFIED, - wxT( "简体中文" ), false }, + wxT( "简体中文" ), true }, { wxLANGUAGE_CHINESE_TRADITIONAL, ID_LANGUAGE_CHINESE_TRADITIONAL, wxT( "繁體中文" ), false }, - { wxLANGUAGE_CATALAN, ID_LANGUAGE_CATALAN, wxT( "Català" ), false }, - { wxLANGUAGE_JAPANESE, ID_LANGUAGE_JAPANESE, wxT( "日本語" ), false }, - { wxLANGUAGE_LITHUANIAN, ID_LANGUAGE_LITHUANIAN, wxT( "Lietuvių" ), false }, + { wxLANGUAGE_CATALAN, ID_LANGUAGE_CATALAN, wxT( "Català" ), true }, + { wxLANGUAGE_JAPANESE, ID_LANGUAGE_JAPANESE, wxT( "日本語" ), true }, + { wxLANGUAGE_LITHUANIAN, ID_LANGUAGE_LITHUANIAN, wxT( "Lietuvių" ), true }, { 0, 0, "", false } // Sentinel }; #undef _ @@ -434,7 +434,8 @@ bool PGM_BASE::InitPgm() // Init user language *before* calling loadCommonSettings, because // env vars could be incorrectly initialized on Linux // (if the value contains some non ASCII7 chars, the env var is not initialized) - SetLanguage( true ); + wxString tmp; + SetLanguage( tmp, true ); loadCommonSettings(); @@ -559,10 +560,8 @@ COMMON_SETTINGS* PGM_BASE::GetCommonSettings() const } -bool PGM_BASE::SetLanguage( bool first_time ) +bool PGM_BASE::SetLanguage( wxString& aErrMsg, bool first_time ) { - bool retv = true; - if( first_time ) { setLanguageId( wxLANGUAGE_DEFAULT ); @@ -596,7 +595,9 @@ bool PGM_BASE::SetLanguage( bool first_time ) m_locale = new wxLocale; m_locale->Init(); - retv = false; + + aErrMsg = _( "This language is not supported by the operating system." ); + return false; } else if( !first_time ) { @@ -636,18 +637,32 @@ bool PGM_BASE::SetLanguage( bool first_time ) double result; msg.ToDouble( &result ); + // string to double encode/decode does not work! Bug detected: + // Disable floating point localization: if( result != dtst ) - // string to double encode/decode does not work! Bug detected: - // Disable floating point localization: setlocale( LC_NUMERIC, "C" ); + // Try adding the dictionary if it is not currently loaded if( !m_locale->IsLoaded( dictionaryName ) ) m_locale->AddCatalog( dictionaryName ); - if( !retv ) - return retv; + // Verify the dictionary was loaded properly + if( !m_locale->IsLoaded( dictionaryName ) ) + { + wxLogTrace( traceLocale, "Unable to load dictionary %s.mo in %s", + GetChars( dictionaryName ), GetChars( m_locale->GetName() ) ); - return m_locale->IsOk(); + setLanguageId( wxLANGUAGE_DEFAULT ); + delete m_locale; + + m_locale = new wxLocale; + m_locale->Init(); + + aErrMsg = _( "The KiCad language file for this language is not installed." ); + return false; + } + + return true; } diff --git a/include/logging.h b/include/logging.h new file mode 100644 index 0000000000..509c5a7860 --- /dev/null +++ b/include/logging.h @@ -0,0 +1,45 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2020 Ian McInerney + * Copyright (C) 2020 KiCad Developers, see AUTHORS.TXT for contributors. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include + +/** + * A logger class that filters out all log messages that are not generated by wxLogTrace + * and ignores them, while passing the trace messages onwards. + */ +class WX_LOG_TRACE_ONLY : public wxLogInterposerTemp +{ +public: + WX_LOG_TRACE_ONLY() : wxLogInterposerTemp() + { + } + +protected: + void DoLogRecord( wxLogLevel aLevel, const wxString& aMsg, const wxLogRecordInfo& aInfo ) override + { + // Only forward the message if it is a trace message + if( aLevel == wxLOG_Trace ) + wxLogInterposerTemp::DoLogRecord( aLevel, aMsg, aInfo ); + } +}; diff --git a/include/pgm_base.h b/include/pgm_base.h index f098d160cd..7b6d2a770f 100644 --- a/include/pgm_base.h +++ b/include/pgm_base.h @@ -52,7 +52,7 @@ class SETTINGS_MANAGER; * The locale translation is automatic. * The selection of languages is mainly for maintainer's convenience * To add a support to a new translation: - * add a new item to s_Languages[]. + * add a new item to LanguagesList[]. */ struct LANGUAGE_DESCR { @@ -69,6 +69,10 @@ struct LANGUAGE_DESCR bool m_DoNotTranslate; }; +/** + * An array containing all the languages that KiCad supports. + */ +extern LANGUAGE_DESCR LanguagesList[]; // inter program module calling #define VTBL_ENTRY virtual @@ -224,16 +228,16 @@ public: VTBL_ENTRY void ForceSystemPdfBrowser( bool aFlg ) { m_use_system_pdf_browser = aFlg; } /** - * Function SetLanguage * sets the dictionary file name for internationalization. *

* The files are in kicad/internat/xx or kicad/internat/xx_XX and are named kicad.mo *

- * @param first_time must be set to true the first time this funct is - * called, false otherwise - * @return true if the language can be set (i.e. if the locale is available) + * @param aErrMsg is the string to return the error message it + * @param first_time must be set to true the first time this function is + * called, false otherwise + * @return false if there was an error setting the language */ - VTBL_ENTRY bool SetLanguage( bool first_time = false ); + VTBL_ENTRY bool SetLanguage( wxString& aErrMsg, bool first_time = false ); /** * Function SetLanguageIdentifier