Show an error message when switching to a language that isn't installed

Also, ensure that the language names are not translated in the menus
and messages, since they are already translated in the code.

Fixes https://gitlab.com/kicad/code/kicad/issues/5324
This commit is contained in:
Ian McInerney 2020-09-01 23:41:06 +01:00
parent 84fb024b9d
commit 8bdf25d3e2
6 changed files with 131 additions and 39 deletions

View File

@ -36,6 +36,7 @@
#include <settings/app_settings.h>
#include <settings/common_settings.h>
#include <settings/settings_manager.h>
#include <pgm_base.h>
#include <project/project_local_settings.h>
#include <tool/action_manager.h>
#include <tool/action_menu.h>
@ -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

View File

@ -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 <dick@softplc.com>
* 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 <config.h>
#include <id.h>
#include <settings/settings_manager.h>
#include <logging.h>
#include <wx/stdpaths.h>
#include <wx/debug.h>
@ -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

View File

@ -36,9 +36,7 @@
#include <tool/action_menu.h>
#include <tool/conditional_menu.h>
#include <bitmaps.h>
// Contained inside pgm_base.cpp
extern LANGUAGE_DESCR LanguagesList[];
#include <pgm_base.h>
/**
* Function AddMenuLanguageList

View File

@ -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;
}

45
include/logging.h Normal file
View File

@ -0,0 +1,45 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2020 Ian McInerney <ian.s.mcinerney at ieee dot org>
* 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 <wx/log.h>
/**
* 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 );
}
};

View File

@ -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.
* <p>
* The files are in kicad/internat/xx or kicad/internat/xx_XX and are named kicad.mo
* </p>
* @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