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