From 6b78fdf82263981ec4c5b2417abbb873d927cd00 Mon Sep 17 00:00:00 2001 From: jean-pierre charras Date: Mon, 17 Feb 2020 09:14:18 +0100 Subject: [PATCH] LOCALE_IO: replace the call to setlocale by a call to wxLocale to switch to "C" locale. Previously we call only setlocale( xx, "C" ), but it was not enough on Windows. Now we call wxLocale("C") wxLocale calls setlocale, but also make some others initialization in wxWidgets. It fixes some issues related to comma versus point as fp separator. Especially wxWidgets warnings are no longer thrown, and a one case of incorrect conversion is fixed. However, wxLocale( "C" ) also switches the current translations to English, so loading files can have a slightly different behavior --- common/common.cpp | 43 ++++++++++++++++++++++++++++++------------ include/common.h | 3 ++- pcbnew/zone_filler.cpp | 2 +- 3 files changed, 34 insertions(+), 14 deletions(-) diff --git a/common/common.cpp b/common/common.cpp index a548f9f039..c385bd1914 100644 --- a/common/common.cpp +++ b/common/common.cpp @@ -57,33 +57,46 @@ using KIGFX::COLOR4D; COLOR4D g_GhostColor; +// When reading/writing files, we need to swtich to setlocale( LC_NUMERIC, "C" ). +// Works fine to read/write files with floating point numbers. +// We can call setlocale( LC_NUMERIC, "C" ) of wxLocale( "C", "C", "C", false ) +// wxWidgets discourage a direct call to setlocale +// However, for us, calling wxLocale( "C", "C", "C", false ) has a unwanted effect: +// The I18N translations are no longer active, because the English dixtionary is selected. +// To read files, this is not a major issues, but the resul can differ +// from using setlocale(xx, "C"). +// Previouly, we called setlocale( LC_NUMERIC, "C" ) +// The old code will be removed when calling wxLocale( "C", "C", "C", false ) +// is fully tested, and all issues fixed +#define USE_WXLOCALE 1 /* 0 to call setlocale, 1 to call wxLocale */ + +// On Windows, when using setlocale, a wx alert is generated +// in some cases (reading a bitmap for instance) +// So we disable alerts during the time a file is read or written +#if !USE_WXLOCALE #if defined( _WIN32 ) && defined( DEBUG ) // a wxAssertHandler_t function to filter wxWidgets alert messages when reading/writing a file // when switching the locale to LC_NUMERIC, "C" // It is used in class LOCALE_IO to hide a useless (in kicad) wxWidgets alert message void KiAssertFilter( const wxString &file, int line, - const wxString &func, const wxString &cond, - const wxString &msg) + const wxString &func, const wxString &cond, + const wxString &msg) { if( !msg.Contains( "Decimal separator mismatch" ) ) - wxTheApp->OnAssertFailure( file, line, func, cond, msg ); + wxTheApp->OnAssertFailure( file.c_str(), line, func.c_str(), cond.c_str(), msg.c_str() ); } #endif - +#endif std::atomic LOCALE_IO::m_c_count( 0 ); - - -// Note on Windows, setlocale( LC_NUMERIC, "C" ) works fine to read/write -// files with floating point numbers, but generates a overzealous wx alert -// in some cases (reading a bitmap for instance) -// So we disable alerts during the time a file is read or written - -LOCALE_IO::LOCALE_IO() +LOCALE_IO::LOCALE_IO() : m_wxLocale( nullptr ) { // use thread safe, atomic operation if( m_c_count++ == 0 ) { +#if USE_WXLOCALE + m_wxLocale = new wxLocale( "C", "C", "C", false ); +#else // Store the user locale name, to restore this locale later, in dtor m_user_locale = setlocale( LC_NUMERIC, nullptr ); #if defined( _WIN32 ) && defined( DEBUG ) @@ -92,6 +105,7 @@ LOCALE_IO::LOCALE_IO() #endif // Switch the locale to C locale, to read/write files with fp numbers setlocale( LC_NUMERIC, "C" ); +#endif } } @@ -102,10 +116,15 @@ LOCALE_IO::~LOCALE_IO() if( --m_c_count == 0 ) { // revert to the user locale +#if USE_WXLOCALE + delete m_wxLocale; // Deleting m_wxLocale restored previous locale + m_wxLocale = nullptr; +#else setlocale( LC_NUMERIC, m_user_locale.c_str() ); #if defined( _WIN32 ) && defined( DEBUG ) // Enable wxWidgets alerts wxSetDefaultAssertHandler(); +#endif #endif } } diff --git a/include/common.h b/include/common.h index 8cda70048c..baedb04a60 100644 --- a/include/common.h +++ b/include/common.h @@ -4,7 +4,7 @@ * Copyright (C) 2014-2017 Jean-Pierre Charras, jp.charras at wanadoo.fr * Copyright (C) 2007-2015 SoftPLC Corporation, Dick Hollenbeck * Copyright (C) 2008 Wayne Stambaugh - * Copyright (C) 1992-2018 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 1992-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 @@ -188,6 +188,7 @@ private: // The locale in use before switching to the "C" locale // (the locale can be set by user, and is not always the system locale) std::string m_user_locale; + wxLocale* m_wxLocale; }; /** diff --git a/pcbnew/zone_filler.cpp b/pcbnew/zone_filler.cpp index 63876219fa..6d1b340ed4 100644 --- a/pcbnew/zone_filler.cpp +++ b/pcbnew/zone_filler.cpp @@ -477,7 +477,7 @@ void ZONE_FILLER::buildZoneFeatureHoleList( const ZONE_CONTAINER* aZone, { int gap = zone_clearance; int thermalGap = aZone->GetThermalReliefGap( pad ); - gap = std::max( gap, thermalGap ); + gap = std::max( gap, thermalGap ) + outline_half_thickness; item_boundingbox = pad->GetBoundingBox(); item_boundingbox.Inflate( gap );