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