KiCad PCB EDA Suite
Loading...
Searching...
No Matches
pgm_base.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright (C) 2004-2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
5 * Copyright (C) 2008 Wayne Stambaugh <[email protected]>
6 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <https://www.gnu.org/licenses/>.
20 */
21
28
29#include <wx/html/htmlwin.h>
30#include <wx/fs_zip.h>
31#include <wx/dir.h>
32#include <wx/filename.h>
33#include <wx/msgdlg.h>
34#include <wx/propgrid/propgrid.h>
35#include <wx/snglinst.h>
36#include <wx/stdpaths.h>
37#include <wx/sysopt.h>
38#include <wx/filedlg.h>
39#include <wx/ffile.h>
40#include <wx/tooltip.h>
41
42#include <advanced_config.h>
44#include <api/api_server.h>
45#include <api/python_manager.h>
46#include <app_monitor.h>
48#include <bitmaps.h>
49#include <build_version.h>
50#include <common.h>
51#include <confirm.h>
52#include <core/arraydim.h>
53#include <id.h>
55#include <kiplatform/policy.h>
57#include <macros.h>
59#include <paths.h>
60#include <pgm_base.h>
62#include <policy_keys.h>
65#include <string_utils.h>
66#include <systemdirsappend.h>
67#include <thread_pool.h>
68#include <trace_helpers.h>
69
70#include <widgets/kistatusbar.h>
71#include <widgets/wx_splash.h>
72
73#ifdef _MSC_VER
74#include <winrt/base.h>
75#endif
85#undef _
86#define _(s) s
88{
89 { wxLANGUAGE_DEFAULT, ID_LANGUAGE_DEFAULT, _( "Default" ), false },
90 { wxLANGUAGE_ARABIC, ID_LANGUAGE_ARABIC, wxT( "العربية" ), true },
91 { wxLANGUAGE_FARSI, ID_LANGUAGE_FARSI, wxT( "فارسی" ), true },
92 { wxLANGUAGE_INDONESIAN, ID_LANGUAGE_INDONESIAN, wxT( "Bahasa Indonesia" ), true },
93 { wxLANGUAGE_BULGARIAN, ID_LANGUAGE_BULGARIAN, wxT( "Български" ), true },
94 { wxLANGUAGE_CATALAN, ID_LANGUAGE_CATALAN, wxT( "Català" ), true },
95 { wxLANGUAGE_CZECH, ID_LANGUAGE_CZECH, wxT( "Čeština" ), true },
96 { wxLANGUAGE_DANISH, ID_LANGUAGE_DANISH, wxT( "Dansk" ), true },
97 { wxLANGUAGE_GERMAN, ID_LANGUAGE_GERMAN, wxT( "Deutsch" ), true },
98 { wxLANGUAGE_GREEK, ID_LANGUAGE_GREEK, wxT( "Ελληνικά" ), true },
99 { wxLANGUAGE_ESTONIAN, ID_LANGUAGE_ESTONIAN, wxT( "Eesti" ), true },
100 { wxLANGUAGE_ENGLISH, ID_LANGUAGE_ENGLISH, wxT( "English" ), true },
101 { wxLANGUAGE_SPANISH, ID_LANGUAGE_SPANISH, wxT( "Español" ), true },
102 { wxLANGUAGE_SPANISH_MEXICAN, ID_LANGUAGE_SPANISH_MEXICAN,
103 wxT( "Español (Latinoamericano)" ), true },
104 { wxLANGUAGE_FRENCH, ID_LANGUAGE_FRENCH, wxT( "Français" ), true },
105 { wxLANGUAGE_HEBREW, ID_LANGUAGE_HEBREW, wxT( "עברית" ), true },
106 { wxLANGUAGE_HINDI, ID_LANGUAGE_HINDI, wxT( "हिन्दी" ), true },
107 { wxLANGUAGE_CROATIAN, ID_LANGUAGE_CROATIAN, wxT( "Hrvatski" ), true },
108 { wxLANGUAGE_KOREAN, ID_LANGUAGE_KOREAN, wxT( "한국어"), true },
109 { wxLANGUAGE_ITALIAN, ID_LANGUAGE_ITALIAN, wxT( "Italiano" ), true },
110 { wxLANGUAGE_LAOTHIAN, ID_LANGUAGE_LAOTHIAN, wxT( "ພາສາລາວ" ), true },
111 { wxLANGUAGE_LATVIAN, ID_LANGUAGE_LATVIAN, wxT( "Latviešu" ), true },
112 { wxLANGUAGE_LITHUANIAN, ID_LANGUAGE_LITHUANIAN, wxT( "Lietuvių" ), true },
113 { wxLANGUAGE_HUNGARIAN, ID_LANGUAGE_HUNGARIAN, wxT( "Magyar" ), true },
114 { wxLANGUAGE_DUTCH, ID_LANGUAGE_DUTCH, wxT( "Nederlands" ), true },
115 { wxLANGUAGE_NORWEGIAN_BOKMAL, ID_LANGUAGE_NORWEGIAN_BOKMAL, wxT( "Norsk Bokmål" ), true },
116 { wxLANGUAGE_JAPANESE, ID_LANGUAGE_JAPANESE, wxT( "日本語" ), true },
117 { wxLANGUAGE_GEORGIAN, ID_LANGUAGE_GEORGIAN, wxT( "ქართული" ), true },
118 { wxLANGUAGE_THAI, ID_LANGUAGE_THAI, wxT( "ภาษาไทย" ), true },
119 { wxLANGUAGE_POLISH, ID_LANGUAGE_POLISH, wxT( "Polski" ), true },
120 { wxLANGUAGE_PORTUGUESE, ID_LANGUAGE_PORTUGUESE, wxT( "Português" ),true },
121 { wxLANGUAGE_PORTUGUESE_BRAZILIAN, ID_LANGUAGE_PORTUGUESE_BRAZILIAN,
122 wxT( "Português (Brasil)" ), true },
123 { wxLANGUAGE_ROMANIAN, ID_LANGUAGE_ROMANIAN, wxT( "Română" ), true },
124 { wxLANGUAGE_RUSSIAN, ID_LANGUAGE_RUSSIAN, wxT( "Русский" ), true },
125 { wxLANGUAGE_SERBIAN, ID_LANGUAGE_SERBIAN, wxT( "Српски" ), true },
126 { wxLANGUAGE_SLOVAK, ID_LANGUAGE_SLOVAK, wxT( "Slovenčina" ), true },
127 { wxLANGUAGE_SLOVENIAN, ID_LANGUAGE_SLOVENIAN, wxT( "Slovenščina" ), true },
128 { wxLANGUAGE_FINNISH, ID_LANGUAGE_FINNISH, wxT( "Suomi" ), true },
129 { wxLANGUAGE_SWEDISH, ID_LANGUAGE_SWEDISH, wxT( "Svenska" ), true },
130 { wxLANGUAGE_VIETNAMESE, ID_LANGUAGE_VIETNAMESE, wxT( "Tiếng Việt" ), true },
131 { wxLANGUAGE_TAMIL, ID_LANGUAGE_TAMIL, wxT( "தமிழ்" ), true },
132 { wxLANGUAGE_TELUGU, ID_LANGUAGE_TELUGU, wxT( "తెలుగు" ), true },
133 { wxLANGUAGE_TURKISH, ID_LANGUAGE_TURKISH, wxT( "Türkçe" ), true },
134 { wxLANGUAGE_UKRAINIAN, ID_LANGUAGE_UKRAINIAN, wxT( "Українська" ), true },
135 { wxLANGUAGE_CHINESE_SIMPLIFIED, ID_LANGUAGE_CHINESE_SIMPLIFIED,
136 wxT( "简体中文" ), true },
137 { wxLANGUAGE_CHINESE_TRADITIONAL, ID_LANGUAGE_CHINESE_TRADITIONAL,
138 wxT( "繁體中文" ), true },
139 { 0, 0, "", false } // Sentinel
140};
141#undef _
142#define _(s) wxGetTranslation((s))
143
144
146{
147 return *m_singleton.m_ThreadPool;
148}
149
150
152{
153 m_locale = nullptr;
154 m_Printing = false;
155 m_Quitting = false;
156 m_argcUtf8 = 0;
157 m_argvUtf8 = nullptr;
158 m_splash = nullptr;
160
161 setLanguageId( wxLANGUAGE_DEFAULT );
162
163 ForceSystemPdfBrowser( false );
164}
165
166
168{
169 HideSplash();
170 Destroy();
171
172 for( int n = 0; n < m_argcUtf8; n++ )
173 {
174 free( m_argvUtf8[n] );
175 }
176
177 delete[] m_argvUtf8;
178
179 delete m_locale;
180 m_locale = nullptr;
181}
182
183
185{
187
189
190 m_pgm_checker.reset();
191
192#ifdef _MSC_VER
193 winrt::uninit_apartment();
194#endif
195
196 // Shut down the thread pool explicitly here, before static destruction begins.
197 // On macOS, if the thread pool destructor runs during static destruction
198 // (via __cxa_finalize_ranges), the condition variables may be in an invalid state,
199 // causing a crash. By destroying the thread pool here, we ensure it's cleaned up
200 // while the C++ runtime is still in a valid state.
201 m_singleton.Shutdown();
202}
203
204
206{
207 wxASSERT( wxTheApp );
208 return *wxTheApp;
209}
210
211
212void PGM_BASE::SetTextEditor( const wxString& aFileName )
213{
214 m_text_editor = aFileName;
216}
217
218
219const wxString& PGM_BASE::GetTextEditor( bool aCanShowFileChooser )
220{
221 wxString editorname = m_text_editor;
222
223 if( !editorname )
224 {
225 if( !wxGetEnv( wxT( "EDITOR" ), &editorname ) )
226 {
227 // If there is no EDITOR variable set, try the desktop default
228#ifdef __WXMAC__
229 editorname = wxT( "/usr/bin/open -e" );
230#elif __WXX11__
231 editorname = wxT( "/usr/bin/xdg-open" );
232#endif
233 }
234 }
235
236 // If we still don't have an editor name show a dialog asking the user to select one
237 if( !editorname && aCanShowFileChooser )
238 {
239 DisplayInfoMessage( nullptr, _( "No default editor found, you must choose one." ) );
240
241 editorname = AskUserForPreferredEditor();
242 }
243
244 // If we finally have a new editor name request it to be copied to m_text_editor and
245 // saved to the preferences file.
246 if( !editorname.IsEmpty() )
247 SetTextEditor( editorname );
248
249 // m_text_editor already has the same value that editorname, or empty if no editor was
250 // found/chosen.
251 return m_text_editor;
252}
253
254
255const wxString PGM_BASE::AskUserForPreferredEditor( const wxString& aDefaultEditor )
256{
257 // Create a mask representing the executable files in the current platform
258#ifdef __WINDOWS__
259 wxString mask( _( "Executable file" ) + wxT( " (*.exe)|*.exe" ) );
260#else
261 wxString mask( _( "Executable file" ) + wxT( " (*)|*" ) );
262#endif
263
264 // Extract the path, name and extension from the default editor (even if the editor's
265 // name was empty, this method will succeed and return empty strings).
266 wxString path, name, ext;
267 wxFileName::SplitPath( aDefaultEditor, &path, &name, &ext );
268
269 // Show the modal editor and return the file chosen (may be empty if the user cancels
270 // the dialog).
271 return wxFileSelector( _( "Select Preferred Editor" ), path, name, wxT( "." ) + ext,
272 mask, wxFD_OPEN | wxFD_FILE_MUST_EXIST, nullptr );
273}
274
275
277{
278 const wxArrayString& argArray = App().argv.GetArguments();
279 m_argcUtf8 = argArray.size();
280
281 m_argvUtf8 = new char*[m_argcUtf8 + 1];
282 for( int n = 0; n < m_argcUtf8; n++ )
283 {
284 m_argvUtf8[n] = wxStrdup( argArray[n].ToUTF8() );
285 }
286
287 m_argvUtf8[m_argcUtf8] = NULL; // null terminator at end of argv
288}
289
290
292{
293 // Disabling until we change to load each DSO at startup rather than lazy-load when needed.
294 // Note that once the splash screen is re-enabled, there are some remaining bugs to fix:
295 // Any wxWidgets error dialogs that appear during startup are hidden by the splash screen,
296 // so we either need to prevent these from happening (probably not feasible) or else change
297 // the error-handling path to make sure errors go on top of the splash.
298#if 0
299 if( m_splash )
300 return;
301
302 m_splash = new WX_SPLASH( KiBitmap( BITMAPS::splash ), wxSPLASH_CENTRE_ON_SCREEN, 0,
303 NULL, -1, wxDefaultPosition, wxDefaultSize,
304 wxBORDER_NONE | wxSTAY_ON_TOP );
305 wxYield();
306#endif
307}
308
309
311{
312 if( !m_splash )
313 return;
314
315 m_splash->Close( true );
316 m_splash->Destroy();
317 m_splash = nullptr;
318}
319
320
321wxString PGM_BASE::DesktopAppIdForProgram( const wxString& aPgmName )
322{
323#if defined( __WXGTK__ ) && defined( KICAD_DESKTOP_APP_NAME )
324 // The prefix varies by build (regular, Flatpak, Nightly) and is supplied by CMake. The main
325 // manager keeps the bare app name; the other GUI apps are prefixed.
326 if( aPgmName == wxT( "kicad" ) )
327 return wxT( KICAD_DESKTOP_APP_NAME );
328
329 if( aPgmName == wxT( "eeschema" ) || aPgmName == wxT( "pcbnew" )
330 || aPgmName == wxT( "gerbview" ) || aPgmName == wxT( "bitmap2component" )
331 || aPgmName == wxT( "pcb_calculator" ) )
332 {
333 // pcb_calculator installs as pcbcalculator to satisfy freedesktop naming rules.
334 wxString appName = aPgmName == wxT( "pcb_calculator" ) ? wxT( "pcbcalculator" ) : aPgmName;
335 return wxString( wxT( KICAD_DESKTOP_APP_PREFIX ) ) + wxT( "." ) + appName;
336 }
337#endif
338
339 return wxEmptyString;
340}
341
342
343bool PGM_BASE::InitPgm( bool aHeadless, bool aIsUnitTest )
344{
345#if defined( __WXMAC__ )
346 // Set the application locale to the system default
347 wxLogNull noLog;
348 wxLocale loc;
349 loc.Init();
350#endif
351
352 // Just make sure we init precreate any folders early for later code
353 // In particular, the user cache path is the most likely to be hit by startup code
355
357
359
360 // Initialize the singleton instance
361 m_singleton.Init();
362
363 wxString pgm_name;
364
366 if( App().argc == 0 )
367 pgm_name = wxT( "kicad" );
368 else
369 pgm_name = wxFileName( App().argv[0] ).GetName().Lower();
370
371 APP_MONITOR::SENTRY::Instance()->AddTag( "kicad.app", pgm_name );
372
373 wxInitAllImageHandlers();
374
375#if !wxCHECK_VERSION( 3, 3, 0 )
376 // Without this the wxPropertyGridManager segfaults on Windows.
377 if( !wxPGGlobalVars )
378 wxPGInitResourceModule();
379#endif
380
381#ifndef __WINDOWS__
382 if( wxString( wxGetenv( "HOME" ) ).IsEmpty() )
383 {
384 DisplayErrorMessage( nullptr, _( "Environment variable HOME is empty. "
385 "Unable to continue." ) );
386 return false;
387 }
388#endif
389
390 // Ensure the instance checker directory exists
391 // It should be globally writable because it is shared between all users on Linux, and so on a
392 // multi-user machine, other need to be able to access it to check for the lock files or make
393 // their own lock files.
394 wxString instanceCheckerDir = PATHS::GetInstanceCheckerPath();
395 PATHS::EnsurePathExists( instanceCheckerDir );
396 wxChmod( instanceCheckerDir,
397 wxPOSIX_USER_READ | wxPOSIX_USER_WRITE | wxPOSIX_USER_EXECUTE |
398 wxPOSIX_GROUP_READ | wxPOSIX_GROUP_WRITE | wxPOSIX_GROUP_EXECUTE |
399 wxPOSIX_OTHERS_READ | wxPOSIX_OTHERS_WRITE | wxPOSIX_OTHERS_EXECUTE );
400
401 wxString instanceCheckerName = wxString::Format( wxS( "%s-%s" ), pgm_name,
403
404 m_pgm_checker = std::make_unique<wxSingleInstanceChecker>();
405 m_pgm_checker->Create( instanceCheckerName, instanceCheckerDir );
406
407 // Init KiCad environment
408 // the environment variable KICAD (if exists) gives the kicad path:
409 // something like set KICAD=d:\kicad
410 bool isDefined = wxGetEnv( wxT( "KICAD" ), &m_kicad_env );
411
412 if( isDefined ) // ensure m_kicad_env ends by "/"
413 {
415
416 if( !m_kicad_env.IsEmpty() && m_kicad_env.Last() != '/' )
418 }
419
420 // Init parameters for configuration
421 App().SetVendorName( wxT( "KiCad" ) );
422 App().SetAppName( pgm_name );
423
425
426#if defined( __WXGTK__ ) && defined( KICAD_DESKTOP_APP_NAME )
427 // On wx >= 3.3.1 wxGTK feeds the class name to gdk_wayland_window_set_application_id(),
428 // which lets Wayland compositors resolve the correct window icon and launch feedback. The
429 // X11 WM_CLASS is applied per window in EDA_BASE_FRAME instead, because wxGTK derives it
430 // from the (human-facing) app display name and would otherwise not match the launcher.
431 if( !m_desktopAppId.IsEmpty() )
432 App().SetClassName( m_desktopAppId );
433#endif
434
435 // Analyze the command line & initialize the binary path
436 wxString tmp;
438 SetDefaultLanguage( tmp );
439
440#ifdef _MSC_VER
441 if( !wxGetEnv( "FONTCONFIG_PATH", NULL ) )
442 {
443 // We need to set this because the internal fontconfig logic
444 // seems to search relative to the dll rather the other logic it
445 // has to look for the /etc folder above the dll
446 // Also don't set it because we need it in QA cli tests to be set by ctest
447 wxSetEnv( "FONTCONFIG_PATH", PATHS::GetWindowsFontConfigDir() );
448 }
449#endif
450
451#ifdef _MSC_VER
452 winrt::init_apartment(winrt::apartment_type::single_threaded);
453#endif
454
455 m_settings_manager = std::make_unique<SETTINGS_MANAGER>();
456 m_library_manager = std::make_unique<LIBRARY_MANAGER>();
457 m_background_jobs_monitor = std::make_unique<BACKGROUND_JOBS_MONITOR>();
458 m_notifications_manager = std::make_unique<NOTIFICATIONS_MANAGER>();
459
460 m_plugin_manager = std::make_unique<API_PLUGIN_MANAGER>( &App() );
461
462 // Our unit test mocks break if we continue
463 // A bug caused InitPgm to terminate early in unit tests and the mocks are...simplistic
464 // TODO fix the unit tests so this can be removed
465 if( aIsUnitTest )
466 return false;
467
468 // Something got in the way of settings load: can't continue
469 if( !m_settings_manager->IsOK() )
470 return false;
471
472 // Set up built-in environment variables (and override them from the system environment if set)
473 COMMON_SETTINGS* commonSettings = GetCommonSettings();
474 commonSettings->InitializeEnvironment();
475
476 // Load color settings after env is initialized
477 m_settings_manager->ReloadColorSettings();
478
479 // Load common settings from disk after setting up env vars
480 GetSettingsManager().Load( commonSettings );
481
482 // If user doesn't have a saved Python interpreter, try (potentially again) to find one
483 if( commonSettings->m_Api.python_interpreter.IsEmpty() )
485
486 // Init user language *before* calling loadSettings, because
487 // env vars could be incorrectly initialized on Linux
488 // (if the value contains some non ASCII7 chars, the env var is not initialized)
489 SetLanguage( tmp, true );
490
491 // Now that translations are available, inform the user if the OS is unsupported
493
495
496 ReadPdfBrowserInfos(); // needs GetCommonSettings()
497
499
500 // TODO(JE): Remove this if apps are refactored to not assume Prj() always works
501 // Need to create a project early for now (it can have an empty path for the moment)
503
504 if( commonSettings->m_Api.enable_server )
505 m_plugin_manager->ReloadPlugins();
506
507 // This sets the maximum tooltip display duration to 10s (up from 5) but only affects
508 // Windows as other platforms display tooltips while the mouse is not moving
509 if( !aHeadless )
510 {
511 wxToolTip::Enable( true );
512 wxToolTip::SetAutoPop( 10000 );
513 }
514
515 if( ADVANCED_CFG::GetCfg().m_UpdateUIEventInterval != 0 )
516 wxUpdateUIEvent::SetUpdateInterval( ADVANCED_CFG::GetCfg().m_UpdateUIEventInterval );
517
518 // Now the application can safely start, show the splash screen
519 if( !aHeadless )
520 ShowSplash();
521
522 return true;
523}
524
525
527{
529
530 for( const std::pair<wxString, ENV_VAR_ITEM> it : GetCommonSettings()->m_Env.vars )
531 {
532 wxLogTrace( traceEnvVars, wxT( "PGM_BASE::loadSettings: Found entry %s = %s" ),
533 it.first, it.second.GetValue() );
534
535 // Do not store the env var PROJECT_VAR_NAME ("KIPRJMOD") definition if for some reason
536 // it is found in config. (It is reserved and defined as project path)
537 if( it.first == PROJECT_VAR_NAME )
538 continue;
539
540 // Don't set bogus empty entries in the environment
541 if( it.first.IsEmpty() )
542 continue;
543
544 // Do not overwrite vars set by the system environment with values from the settings file
545 if( it.second.GetDefinedExternally() )
546 continue;
547
548 SetLocalEnvVariable( it.first, it.second.GetValue() );
549 }
550}
551
552
554{
555 // GetCommonSettings() is not initialized until fairly late in the
556 // process startup: InitPgm(), so test before using:
557 if( GetCommonSettings() && IsGUI() )
558 GetCommonSettings()->m_System.working_dir = wxGetCwd();
559}
560
561
563{
564 return m_settings_manager ? m_settings_manager->GetCommonSettings() : nullptr;
565}
566
567
568bool PGM_BASE::SetLanguage( wxString& aErrMsg, bool first_time )
569{
570 // Suppress wxWidgets error popups if locale is not found
571 wxLogNull doNotLog;
572
573 if( first_time )
574 {
575 setLanguageId( wxLANGUAGE_DEFAULT );
576
577 // First time SetLanguage is called, the user selected language id is set
578 // from common user config settings
579 wxString languageSel = GetCommonSettings()->m_System.language;
580
581 // Search for the current selection
582 for( unsigned ii = 0; LanguagesList[ii].m_KI_Lang_Identifier != 0; ii++ )
583 {
584 if( LanguagesList[ii].m_Lang_Label == languageSel )
585 {
586 setLanguageId( LanguagesList[ii].m_WX_Lang_Identifier );
587 break;
588 }
589 }
590 }
591
592 // dictionary file name without extend (full name is kicad.mo)
593 wxString dictionaryName( wxT( "kicad" ) );
594
595 delete m_locale;
596 m_locale = new wxLocale;
597
598 // don't use wxLOCALE_LOAD_DEFAULT flag so that Init() doesn't return
599 // false just because it failed to load wxstd catalog
600 if( !m_locale->Init( m_language_id ) )
601 {
602 wxLogTrace( traceLocale, wxT( "This language is not supported by the system." ) );
603
604 setLanguageId( wxLANGUAGE_DEFAULT );
605 delete m_locale;
606
607 m_locale = new wxLocale;
608 m_locale->Init( wxLANGUAGE_DEFAULT );
609
610 aErrMsg = _( "This language is not supported by the operating system." );
611 return false;
612 }
613 else if( !first_time )
614 {
615 wxLogTrace( traceLocale, wxT( "Search for dictionary %s.mo in %s" ) ,
616 dictionaryName, m_locale->GetName() );
617 }
618
619 if( !first_time )
620 {
621 // If we are here, the user has selected another language.
622 // Therefore the new preferred language name is stored in common config.
623 // Do NOT store the wxWidgets language Id, it can change between wxWidgets
624 // versions, for a given language
625 wxString languageSel;
626
627 // Search for the current selection language name
628 for( unsigned ii = 0; LanguagesList[ii].m_KI_Lang_Identifier != 0; ii++ )
629 {
630 if( LanguagesList[ii].m_WX_Lang_Identifier == m_language_id )
631 {
632 languageSel = LanguagesList[ii].m_Lang_Label;
633 break;
634 }
635 }
636
638 cfg->m_System.language = languageSel;
639 cfg->SaveToFile( GetSettingsManager().GetPathForSettingsFile( cfg ) );
640 }
641
642 // Try adding the dictionary if it is not currently loaded
643 if( !m_locale->IsLoaded( dictionaryName ) )
644 m_locale->AddCatalog( dictionaryName );
645
646 // Verify the Kicad dictionary was loaded properly
647 // However, for the English language, the dictionary is not mandatory, as
648 // all messages are already in English, just restricted to ASCII7 chars,
649 // the verification is skipped.
650 if( !m_locale->IsLoaded( dictionaryName ) && m_language_id != wxLANGUAGE_ENGLISH )
651 {
652 wxLogTrace( traceLocale, wxT( "Unable to load dictionary %s.mo in %s" ),
653 dictionaryName, m_locale->GetName() );
654
655 setLanguageId( wxLANGUAGE_DEFAULT );
656 delete m_locale;
657
658 m_locale = new wxLocale;
659 m_locale->Init( wxLANGUAGE_DEFAULT );
660
661 aErrMsg = _( "The KiCad language file for this language is not installed." );
662 return false;
663 }
664
665 return true;
666}
667
668
669bool PGM_BASE::SetDefaultLanguage( wxString& aErrMsg )
670{
671 // Suppress error popups from wxLocale
672 wxLogNull doNotLog;
673
674 setLanguageId( wxLANGUAGE_DEFAULT );
675
676 // dictionary file name without extend (full name is kicad.mo)
677 wxString dictionaryName( wxT( "kicad" ) );
678
679 delete m_locale;
680 m_locale = new wxLocale;
681 m_locale->Init();
682
683 // Try adding the dictionary if it is not currently loaded
684 if( !m_locale->IsLoaded( dictionaryName ) )
685 m_locale->AddCatalog( dictionaryName );
686
687 // Verify the Kicad dictionary was loaded properly
688 // However, for the English language, the dictionary is not mandatory, as
689 // all messages are already in English, just restricted to ASCII7 chars,
690 // the verification is skipped.
691 if( !m_locale->IsLoaded( dictionaryName ) && m_language_id != wxLANGUAGE_ENGLISH )
692 {
693 wxLogTrace( traceLocale, wxT( "Unable to load dictionary %s.mo in %s" ),
694 dictionaryName, m_locale->GetName() );
695
696 setLanguageId( wxLANGUAGE_DEFAULT );
697 delete m_locale;
698
699 m_locale = new wxLocale;
700 m_locale->Init();
701
702 aErrMsg = _( "The KiCad language file for this language is not installed." );
703 return false;
704 }
705
706 return true;
707}
708
709
711{
712 wxLogTrace( traceLocale, wxT( "Select language ID %d from %d possible languages." ),
713 menu_id, (int)arrayDim( LanguagesList )-1 );
714
715 for( unsigned ii = 0; LanguagesList[ii].m_KI_Lang_Identifier != 0; ii++ )
716 {
717 if( menu_id == LanguagesList[ii].m_KI_Lang_Identifier )
718 {
719 setLanguageId( LanguagesList[ii].m_WX_Lang_Identifier );
720 break;
721 }
722 }
723}
724
725
727{
728 const wxLanguageInfo* langInfo = wxLocale::GetLanguageInfo( m_language_id );
729
730 if( !langInfo )
731 {
732 return "";
733 }
734 else
735 {
736 wxString str = langInfo->GetCanonicalWithRegion();
737 str.Replace( "_", "-" );
738
739 return str;
740 }
741}
742
743
745{
746#ifdef _MSC_VER
747 wxLocale::AddCatalogLookupPathPrefix( PATHS::GetWindowsBaseSharePath() + wxT( "locale" ) );
748#endif
749 wxLocale::AddCatalogLookupPathPrefix( PATHS::GetLocaleDataPath() );
750
751 if( wxGetEnv( wxT( "KICAD_RUN_FROM_BUILD_DIR" ), nullptr ) )
752 {
753 wxFileName fn( Pgm().GetExecutablePath() );
754 fn.RemoveLastDir();
755 fn.AppendDir( wxT( "translation" ) );
756 wxLocale::AddCatalogLookupPathPrefix( fn.GetPath() );
757 }
758}
759
760
761bool PGM_BASE::SetLocalEnvVariable( const wxString& aName, const wxString& aValue )
762{
763 wxString env;
764
765 if( aName.IsEmpty() )
766 {
767 wxLogTrace( traceEnvVars,
768 wxT( "PGM_BASE::SetLocalEnvVariable: Attempt to set empty variable to "
769 "value %s" ),
770 aValue );
771 return false;
772 }
773
774 // Check to see if the environment variable is already set.
775 if( wxGetEnv( aName, &env ) )
776 {
777 wxLogTrace( traceEnvVars,
778 wxT( "PGM_BASE::SetLocalEnvVariable: Environment variable %s already set "
779 "to %s" ),
780 aName, env );
781 return env == aValue;
782 }
783
784 wxLogTrace( traceEnvVars,
785 wxT( "PGM_BASE::SetLocalEnvVariable: Setting local environment variable %s to %s" ),
786 aName, aValue );
787
788 return wxSetEnv( aName, aValue );
789}
790
791
793{
794 // Overwrites externally defined environment variable until the next time the application
795 // is run.
796 for( const std::pair<wxString, ENV_VAR_ITEM> m_local_env_var : GetCommonSettings()->m_Env.vars )
797 {
798 wxLogTrace( traceEnvVars,
799 wxT( "PGM_BASE::SetLocalEnvVariables: Setting local environment variable %s "
800 "to %s" ),
801 m_local_env_var.first,
802 m_local_env_var.second.GetValue() );
803 wxSetEnv( m_local_env_var.first, m_local_env_var.second.GetValue() );
804 }
805}
806
807
812
813
815{
816 if( !wxTheApp )
817 return false;
818
819 return wxTheApp->IsGUI();
820}
821
822
823void PGM_BASE::HandleException( std::exception_ptr aPtr, bool aUnhandled )
824{
825 try
826 {
827 if( aPtr )
828 std::rethrow_exception( aPtr );
829 }
830 catch( const IO_ERROR& ioe )
831 {
832 wxLogError( ioe.What() );
833
834 if( aUnhandled )
835 {
836 // Log this IO_ERROR escaped our usual uses (bad)
837 APP_MONITOR::SENTRY::Instance()->LogException( ioe.What(), aUnhandled );
838 }
839 }
840 catch( const std::exception& e )
841 {
842 APP_MONITOR::SENTRY::Instance()->LogException( e.what(), aUnhandled );
843
844 wxLogError( wxT( "Unhandled exception class: %s what: %s" ),
845 From_UTF8( typeid( e ).name() ), From_UTF8( e.what() ) );
846 }
847 catch( ... )
848 {
849 // We really shouldn't have these but just in case...
850 wxLogError( wxT( "Unhandled exception of unknown type" ) );
851
852 if( aUnhandled )
853 {
854 APP_MONITOR::SENTRY::Instance()->LogException( "Unhandled exception of unknown type", aUnhandled );
855 }
856 }
857}
858
859
860void PGM_BASE::HandleAssert( const wxString& aFile, int aLine, const wxString& aFunc,
861 const wxString& aCond, const wxString& aMsg )
862{
863 wxString assertStr;
864
865 // Log the assertion details to standard log
866 if( !aMsg.empty() )
867 {
868 assertStr = wxString::Format( "Assertion failed at %s:%d in %s: %s - %s", aFile, aLine,
869 aFunc, aCond, aMsg );
870 }
871 else
872 {
873 assertStr = wxString::Format( "Assertion failed at %s:%d in %s: %s", aFile, aLine, aFunc,
874 aCond );
875 }
876
877#ifndef NDEBUG
878 wxLogError( assertStr );
879#endif
880
881#ifdef KICAD_USE_SENTRY
882 APP_MONITOR::ASSERT_CACHE_KEY key = { aFile, aLine, aFunc, aCond };
883 APP_MONITOR::SENTRY::Instance()->LogAssert( key, assertStr );
884#endif
885}
886
887
888const wxString& PGM_BASE::GetExecutablePath() const
889{
891}
892
893
899
900
906
907
909{
910 // TODO(JE) much of this code can be shared across the 3 preloads
911 constexpr static int interval = 150;
912 constexpr static int timeLimit = 120000;
913
914 if( m_libraryPreloadInProgress.load() )
915 return;
916
918 Pgm().GetBackgroundJobMonitor().Create( _( "Loading Design Block Libraries" ) );
919
920 auto preload =
921 [this, aKiway]() -> void
922 {
923 std::shared_ptr<BACKGROUND_JOB_REPORTER> reporter =
925
926 DESIGN_BLOCK_LIBRARY_ADAPTER* adapter = aKiway->Prj().DesignBlockLibs();
927
928 int elapsed = 0;
929 bool aborted = false;
930
931 reporter->Report( _( "Loading Design Block Libraries" ) );
932 adapter->AsyncLoad();
933
934 while( true )
935 {
936 if( m_libraryPreloadAbort.load() )
937 {
938 m_libraryPreloadAbort.store( false );
939 aborted = true;
940 break;
941 }
942
943 std::this_thread::sleep_for( std::chrono::milliseconds( interval ) );
944
945 if( std::optional<float> loadStatus = adapter->AsyncLoadProgress() )
946 {
947 float progress = *loadStatus;
948 reporter->SetCurrentProgress( progress );
949
950 if( progress >= 1 )
951 break;
952 }
953 else
954 {
955 reporter->SetCurrentProgress( 1 );
956 break;
957 }
958
959 elapsed += interval;
960
961 if( elapsed > timeLimit )
962 break;
963 }
964
965 // AbortAsyncLoad() sets the adapter's worker abort flag and then blocks,
966 // so workers exit at their next checkpoint. BlockUntilLoaded() alone just
967 // waits for each future to complete naturally, which can hang indefinitely
968 // if a worker is stuck on a stalled network or filesystem operation.
969 if( aborted )
970 adapter->AbortAsyncLoad();
971 else
972 adapter->BlockUntilLoaded();
973
976 m_libraryPreloadInProgress.store( false );
977
978 std::string payload = "";
979 aKiway->ExpressMail( FRAME_SCH, MAIL_RELOAD_LIB, payload, nullptr, true );
980 aKiway->ExpressMail( FRAME_PCB_EDITOR, MAIL_RELOAD_LIB, payload, nullptr, true );
981 };
982
984 m_libraryPreloadInProgress.store( true );
985 m_libraryPreloadReturn = tp.submit_task( preload );
986}
987
988
990{
991 std::lock_guard<std::mutex> lock( m_libraryLoadStatusBarsMutex );
992
993 wxLogTrace( traceLibraries, "RegisterLibraryLoadStatusBar: statusBar=%p", aStatusBar );
994
995 if( std::find( m_libraryLoadStatusBars.begin(), m_libraryLoadStatusBars.end(), aStatusBar )
996 == m_libraryLoadStatusBars.end() )
997 {
998 m_libraryLoadStatusBars.push_back( aStatusBar );
999 wxLogTrace( traceLibraries, " -> registered, total count=%zu",
1000 m_libraryLoadStatusBars.size() );
1001 }
1002 else
1003 {
1004 wxLogTrace( traceLibraries, " -> already registered" );
1005 }
1006}
1007
1008
1010{
1011 std::lock_guard<std::mutex> lock( m_libraryLoadStatusBarsMutex );
1012
1013 wxLogTrace( traceLibraries, "UnregisterLibraryLoadStatusBar: statusBar=%p", aStatusBar );
1014
1016 std::remove( m_libraryLoadStatusBars.begin(), m_libraryLoadStatusBars.end(),
1017 aStatusBar ),
1019
1020 wxLogTrace( traceLibraries, " -> remaining count=%zu", m_libraryLoadStatusBars.size() );
1021}
1022
1023
1024void PGM_BASE::AddLibraryLoadMessages( const std::vector<LOAD_MESSAGE>& aMessages )
1025{
1026 wxLogTrace( traceLibraries, "AddLibraryLoadMessages: message_count=%zu", aMessages.size() );
1027
1028 if( aMessages.empty() )
1029 return;
1030
1031 std::lock_guard<std::mutex> lock( m_libraryLoadStatusBarsMutex );
1032
1033 wxLogTrace( traceLibraries, " -> registered status bars=%zu",
1034 m_libraryLoadStatusBars.size() );
1035
1036 for( KISTATUSBAR* statusBar : m_libraryLoadStatusBars )
1037 {
1038 if( statusBar )
1039 {
1040 wxLogTrace( traceLibraries, " -> forwarding to statusBar=%p", statusBar );
1041 statusBar->AddWarningMessages( "load", aMessages );
1042 }
1043 }
1044}
1045
1046
1048{
1049 std::lock_guard<std::mutex> lock( m_libraryLoadStatusBarsMutex );
1050
1051 wxLogTrace( traceLibraries, "ClearLibraryLoadMessages: status bars=%zu",
1052 m_libraryLoadStatusBars.size() );
1053
1054 for( KISTATUSBAR* statusBar : m_libraryLoadStatusBars )
1055 {
1056 if( statusBar )
1057 statusBar->ClearWarningMessages( "load" );
1058 }
1059}
1060
1061
1063
1064
1066{
1067 wxASSERT( process ); // KIFACE_GETTER has already been called.
1068 return *process;
1069}
1070
1071
1072// Similar to PGM_BASE& Pgm(), but return nullptr when a *.ki_face is run from a python script.
1074{
1075 return process;
1076}
1077
1078
1079void SetPgm( PGM_BASE* pgm )
1080{
1081 process = pgm;
1082}
const char * name
constexpr std::size_t arrayDim(T const (&)[N]) noexcept
Returns # of elements in an array.
Definition arraydim.h:27
wxBitmap KiBitmap(BITMAPS aBitmap, int aHeightTag)
Construct a wxBitmap from an image identifier Returns the image from the active theme if the image ha...
Definition bitmap.cpp:100
wxString GetMajorMinorVersion()
Get only the major and minor version in a string major.minor.
static const ADVANCED_CFG & GetCfg()
Get the singleton instance's config, which is shared by all consumers.
void LogAssert(const ASSERT_CACHE_KEY &aKey, const wxString &aMsg)
void LogException(const wxString &aMsg, bool aUnhandled)
void AddTag(const wxString &aKey, const wxString &aValue)
static SENTRY * Instance()
std::shared_ptr< BACKGROUND_JOB > Create(const wxString &aName)
Creates a background job with the given name.
void Remove(std::shared_ptr< BACKGROUND_JOB > job)
Removes the given background job from any lists and frees it.
void InitializeEnvironment()
Creates the built-in environment variables and sets their default values.
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
virtual const wxString What() const
A composite of Problem() and Where()
virtual bool SaveToFile(const wxString &aDirectory="", bool aForce=false)
Calls Store() and then writes the contents of the JSON document to a file.
static void Cleanup()
Call curl_global_cleanup for the application.
static void Init()
Call curl_global_init for the application.
A minimalistic software bus for communications between various DLLs/DSOs (DSOs) within the same KiCad...
Definition kiway.h:311
virtual void ExpressMail(FRAME_T aDestination, MAIL_T aCommand, std::string &aPayload, wxWindow *aSource=nullptr, bool aFromOtherThread=false)
Send aPayload to aDestination from aSource.
Definition kiway.cpp:486
virtual PROJECT & Prj() const
Return the PROJECT associated with this KIWAY.
Definition kiway.cpp:201
std::optional< float > AsyncLoadProgress() const
Returns async load progress between 0.0 and 1.0, or nullopt if load is not in progress.
void AbortAsyncLoad()
Aborts any async load in progress; blocks until fully done aborting.
void AsyncLoad()
Loads all available libraries for this adapter type in the background.
void Load()
Load notifications stored from disk.
static wxString GetInstanceCheckerPath()
Gets the path used for wxSingleInstanceChecker lock files.
Definition paths.cpp:497
static void EnsureUserPathsExist()
Ensures/creates user default paths.
Definition paths.cpp:545
static bool EnsurePathExists(const wxString &aPath, bool aPathToFile=false)
Attempts to create a given path if it does not exist.
Definition paths.cpp:518
static wxString GetLocaleDataPath()
Gets the locales translation data path.
Definition paths.cpp:366
static const wxString & GetExecutablePath()
Definition paths.cpp:671
Container for data for KiCad programs.
Definition pgm_base.h:102
virtual COMMON_SETTINGS * GetCommonSettings() const
Definition pgm_base.cpp:562
virtual wxApp & App()
Return a bare naked wxApp which may come from wxPython, SINGLE_TOP, or kicad.exe.
Definition pgm_base.cpp:205
std::unique_ptr< NOTIFICATIONS_MANAGER > m_notifications_manager
Definition pgm_base.h:417
void PreloadDesignBlockLibraries(KIWAY *aKiway)
Starts a background job to preload the global and project design block libraries.
Definition pgm_base.cpp:908
int m_argcUtf8
Definition pgm_base.h:452
virtual ENV_VAR_MAP & GetLocalEnvVariables() const
Definition pgm_base.cpp:808
std::unique_ptr< LIBRARY_MANAGER > m_library_manager
Definition pgm_base.h:415
bool m_Printing
wxWidgets on MSW tends to crash if you spool up more than one print job at a time.
Definition pgm_base.h:393
void setLanguageId(int aId)
Trap all changes in here, simplifies debugging.
Definition pgm_base.h:406
std::unique_ptr< API_PLUGIN_MANAGER > m_plugin_manager
Definition pgm_base.h:422
std::unique_ptr< SETTINGS_MANAGER > m_settings_manager
Definition pgm_base.h:414
void loadCommonSettings()
Load internal settings from COMMON_SETTINGS.
Definition pgm_base.cpp:526
virtual void SetPdfBrowserName(const wxString &aFileName)
Definition pgm_base.h:179
std::vector< KISTATUSBAR * > m_libraryLoadStatusBars
Definition pgm_base.h:461
wxLocale * m_locale
Definition pgm_base.h:429
void Destroy()
Definition pgm_base.cpp:184
wxSplashScreen * m_splash
Definition pgm_base.h:454
virtual BACKGROUND_JOBS_MONITOR & GetBackgroundJobMonitor() const
Definition pgm_base.h:130
char ** m_argvUtf8
argv parameters converted to utf8 form because wxWidgets has opinions.
Definition pgm_base.h:450
BS::priority_thread_pool & GetThreadPool()
Definition pgm_base.cpp:145
void UnregisterLibraryLoadStatusBar(KISTATUSBAR *aStatusBar)
Unregister a status bar from receiving library load warning messages.
virtual void ReadPdfBrowserInfos()
Read the PDF browser choice from the common configuration.
Definition pgm_base.cpp:894
void HandleException(std::exception_ptr aPtr, bool aUnhandled=false)
A exception handler to be used at the top level if exceptions bubble up that for.
Definition pgm_base.cpp:823
bool IsGUI()
Determine if the application is running with a GUI.
Definition pgm_base.cpp:814
bool m_use_system_pdf_browser
Definition pgm_base.h:432
bool m_Quitting
Definition pgm_base.h:397
void RegisterLibraryLoadStatusBar(KISTATUSBAR *aStatusBar)
Register a status bar to receive library load warning messages.
Definition pgm_base.cpp:989
std::future< void > m_libraryPreloadReturn
Definition pgm_base.h:457
virtual NOTIFICATIONS_MANAGER & GetNotificationsManager() const
Definition pgm_base.h:135
std::shared_ptr< BACKGROUND_JOB > m_libraryPreloadBackgroundJob
Definition pgm_base.h:456
void BuildArgvUtf8()
Builds the UTF8 based argv variable.
Definition pgm_base.cpp:276
virtual const wxString & GetPdfBrowserName() const
Definition pgm_base.h:177
std::atomic_bool m_libraryPreloadAbort
Definition pgm_base.h:459
void ClearLibraryLoadMessages()
Clear library load messages from all registered status bars.
virtual void SetTextEditor(const wxString &aFileName)
Definition pgm_base.cpp:212
std::unique_ptr< wxSingleInstanceChecker > m_pgm_checker
Check if there is another copy of Kicad running at the same time.
Definition pgm_base.h:420
virtual bool SetLocalEnvVariable(const wxString &aName, const wxString &aValue)
Set the environment variable aName to aValue.
Definition pgm_base.cpp:761
bool InitPgm(bool aHeadless=false, bool aIsUnitTest=false)
Initialize this program.
Definition pgm_base.cpp:343
wxString m_kicad_env
The KICAD system environment variable.
Definition pgm_base.h:425
virtual void ForceSystemPdfBrowser(bool aFlg)
Force the use of system PDF browser, even if a preferred PDF browser is set.
Definition pgm_base.h:194
virtual void SetLocalEnvVariables()
Update the local environment with the contents of the current ENV_VAR_MAP stored in the COMMON_SETTIN...
Definition pgm_base.cpp:792
virtual void SetLanguagePath()
Definition pgm_base.cpp:744
bool SetDefaultLanguage(wxString &aErrMsg)
Set the default language without reference to any preferences.
Definition pgm_base.cpp:669
void ShowSplash()
Definition pgm_base.cpp:291
wxString m_text_editor
Definition pgm_base.h:435
std::atomic_bool m_libraryPreloadInProgress
Definition pgm_base.h:458
virtual ~PGM_BASE()
Definition pgm_base.cpp:167
wxString m_desktopAppId
freedesktop app id of this process, or empty.
Definition pgm_base.h:427
virtual void SetLanguageIdentifier(int menu_id)
Set in .m_language_id member the wxWidgets language identifier ID from the KiCad menu id (internal me...
Definition pgm_base.cpp:710
int m_language_id
Definition pgm_base.h:430
std::unique_ptr< BACKGROUND_JOBS_MONITOR > m_background_jobs_monitor
Definition pgm_base.h:416
void HandleAssert(const wxString &aFile, int aLine, const wxString &aFunc, const wxString &aCond, const wxString &aMsg)
A common assert handler to be used between single_top and kicad.
Definition pgm_base.cpp:860
virtual wxString GetLanguageTag()
Definition pgm_base.cpp:726
virtual const wxString & GetTextEditor(bool aCanShowFileChooser=true)
Return the path to the preferred text editor application.
Definition pgm_base.cpp:219
virtual const wxString & GetExecutablePath() const
Definition pgm_base.cpp:888
void AddLibraryLoadMessages(const std::vector< LOAD_MESSAGE > &aMessages)
Add library load messages to all registered status bars.
virtual SETTINGS_MANAGER & GetSettingsManager() const
Definition pgm_base.h:124
void HideSplash()
Definition pgm_base.cpp:310
virtual void WritePdfBrowserInfos()
Save the PDF browser choice to the common configuration.
Definition pgm_base.cpp:901
static wxString DesktopAppIdForProgram(const wxString &aPgmName)
Map a program name (argv[0] basename, lowercased) to the freedesktop application id of its installed ...
Definition pgm_base.cpp:321
void SaveCommonSettings()
Save the program (process) settings subset which are stored .kicad_common.
Definition pgm_base.cpp:553
bool m_PropertyGridInitialized
Definition pgm_base.h:399
KICAD_SINGLETON m_singleton
Definition pgm_base.h:437
std::mutex m_libraryLoadStatusBarsMutex
Definition pgm_base.h:462
virtual const wxString AskUserForPreferredEditor(const wxString &aDefaultEditor=wxEmptyString)
Show a dialog that instructs the user to select a new preferred editor.
Definition pgm_base.cpp:255
virtual bool SetLanguage(wxString &aErrMsg, bool first_time=false)
Set the dictionary file name for internationalization.
Definition pgm_base.cpp:568
virtual DESIGN_BLOCK_LIBRARY_ADAPTER * DesignBlockLibs()
Return the table of design block libraries.
Definition project.cpp:433
static wxString FindPythonInterpreter()
Searches for a Python intepreter on the user's system.
bool LoadProject(const wxString &aFullPath, bool aSetActive=true)
Load a project or sets up a new project with a specified path.
bool WarnUserIfOperatingSystemUnsupported()
Checks if the operating system is explicitly unsupported and displays a disclaimer message box.
Definition common.cpp:945
The common library.
void DisplayInfoMessage(wxWindow *aParent, const wxString &aMessage, const wxString &aExtraInfo)
Display an informational message box with aMessage.
Definition confirm.cpp:245
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
Definition confirm.cpp:217
This file is part of the common library.
#define _(s)
@ FRAME_PCB_EDITOR
Definition frame_type.h:38
@ FRAME_SCH
Definition frame_type.h:30
#define WIN_STRING_DIR_SEP
Definition gestfich.h:39
#define UNIX_STRING_DIR_SEP
Definition gestfich.h:38
const wxChar *const traceLibraries
Flag to enable library table and library manager tracing.
const wxChar *const traceLocale
Flag to enable locale debug output.
const wxChar *const traceEnvVars
Flag to enable debug output of environment variable operations.
@ ID_LANGUAGE_SWEDISH
Definition id.h:97
@ ID_LANGUAGE_CATALAN
Definition id.h:86
@ ID_LANGUAGE_NORWEGIAN_BOKMAL
Definition id.h:104
@ ID_LANGUAGE_CHINESE_SIMPLIFIED
Definition id.h:87
@ ID_LANGUAGE_GERMAN
Definition id.h:71
@ ID_LANGUAGE_DUTCH
Definition id.h:89
@ ID_LANGUAGE_FARSI
Definition id.h:101
@ ID_LANGUAGE_GREEK
Definition id.h:72
@ ID_LANGUAGE_HUNGARIAN
Definition id.h:82
@ ID_LANGUAGE_LITHUANIAN
Definition id.h:93
@ ID_LANGUAGE_TAMIL
Definition id.h:105
@ ID_LANGUAGE_ESTONIAN
Definition id.h:100
@ ID_LANGUAGE_HINDI
Definition id.h:107
@ ID_LANGUAGE_PORTUGUESE_BRAZILIAN
Definition id.h:76
@ ID_LANGUAGE_DEFAULT
Definition id.h:64
@ ID_LANGUAGE_POLISH
Definition id.h:83
@ ID_LANGUAGE_THAI
Definition id.h:96
@ ID_LANGUAGE_JAPANESE
Definition id.h:90
@ ID_LANGUAGE_VIETNAMESE
Definition id.h:94
@ ID_LANGUAGE_ITALIAN
Definition id.h:79
@ ID_LANGUAGE_KOREAN
Definition id.h:85
@ ID_LANGUAGE_SERBIAN
Definition id.h:95
@ ID_LANGUAGE_RUSSIAN
Definition id.h:74
@ ID_LANGUAGE_CZECH
Definition id.h:84
@ ID_LANGUAGE_TELUGU
Definition id.h:106
@ ID_LANGUAGE_GEORGIAN
Definition id.h:108
@ ID_LANGUAGE_LATVIAN
Definition id.h:92
@ ID_LANGUAGE_SLOVENIAN
Definition id.h:80
@ ID_LANGUAGE_SPANISH
Definition id.h:69
@ ID_LANGUAGE_PORTUGUESE
Definition id.h:75
@ ID_LANGUAGE_ENGLISH
Definition id.h:65
@ ID_LANGUAGE_CROATIAN
Definition id.h:102
@ ID_LANGUAGE_SPANISH_MEXICAN
Definition id.h:70
@ ID_LANGUAGE_SLOVAK
Definition id.h:81
@ ID_LANGUAGE_CHINESE_TRADITIONAL
Definition id.h:88
@ ID_LANGUAGE_FINNISH
Definition id.h:67
@ ID_LANGUAGE_BULGARIAN
Definition id.h:91
@ ID_LANGUAGE_ARABIC
Definition id.h:99
@ ID_LANGUAGE_UKRAINIAN
Definition id.h:98
@ ID_LANGUAGE_LAOTHIAN
Definition id.h:109
@ ID_LANGUAGE_TURKISH
Definition id.h:77
@ ID_LANGUAGE_DANISH
Definition id.h:63
@ ID_LANGUAGE_FRENCH
Definition id.h:66
@ ID_LANGUAGE_HEBREW
Definition id.h:68
@ ID_LANGUAGE_ROMANIAN
Definition id.h:103
@ ID_LANGUAGE_INDONESIAN
Definition id.h:78
std::map< wxString, ENV_VAR_ITEM > ENV_VAR_MAP
This file contains miscellaneous commonly used macros and functions.
@ MAIL_RELOAD_LIB
Definition mail_type.h:54
thread_pool< 1 > priority_thread_pool
Definition singleton.h:31
void SetPgm(PGM_BASE *pgm)
static PGM_BASE * process
PGM_BASE & Pgm()
The global program "get" accessor.
PGM_BASE * PgmOrNull()
Return a reference that can be nullptr when running a shared lib from a script, not from a kicad app.
LANGUAGE_DESCR LanguagesList[]
An array containing all the languages that KiCad supports.
Definition pgm_base.cpp:87
#define _(s)
Current list of languages supported by KiCad.
Definition pgm_base.cpp:86
see class PGM_BASE
KICOMMON_API LANGUAGE_DESCR LanguagesList[]
An array containing all the languages that KiCad supports.
Definition pgm_base.cpp:87
KICOMMON_API PGM_BASE & Pgm()
The global program "get" accessor.
#define PROJECT_VAR_NAME
A variable name whose value holds the current project directory.
Definition project.h:38
APIIMPORT wxPGGlobalVarsClass * wxPGGlobalVars
wxString From_UTF8(const char *cstring)
This struct represents a key being used for the std::set that deduplicates asserts during this runnin...
Definition app_monitor.h:86
A small class to handle the list of existing translations.
Definition pgm_base.h:68
System directories search utilities.
std::string path
IbisParser parser & reporter
thread_pool & GetKiCadThreadPool()
Get a reference to the current thread pool.
static thread_pool * tp
BS::priority_thread_pool thread_pool
Definition thread_pool.h:27
wxLogTrace helper definitions.