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/stdpaths.h>
36#include <wx/sysopt.h>
37#include <wx/filedlg.h>
38#include <wx/ffile.h>
39#include <wx/tooltip.h>
40
41#include <advanced_config.h>
43#include <api/api_server.h>
44#include <api/python_manager.h>
45#include <app_monitor.h>
47#include <bitmaps.h>
48#include <build_version.h>
49#include <common.h>
50#include <confirm.h>
51#include <core/arraydim.h>
52#include <id.h>
54#include <kiplatform/policy.h>
56#include <macros.h>
58#include <paths.h>
59#include <pgm_base.h>
61#include <policy_keys.h>
64#include <string_utils.h>
65#include <systemdirsappend.h>
66#include <thread_pool.h>
67#include <trace_helpers.h>
68
69#include <widgets/kistatusbar.h>
70#include <widgets/wx_splash.h>
71
72#ifdef _MSC_VER
73#include <winrt/base.h>
74#endif
84#undef _
85#define _(s) s
87{
88 { wxLANGUAGE_DEFAULT, ID_LANGUAGE_DEFAULT, _( "Default" ), false },
89 { wxLANGUAGE_ARABIC, ID_LANGUAGE_ARABIC, wxT( "العربية" ), true },
90 { wxLANGUAGE_FARSI, ID_LANGUAGE_FARSI, wxT( "فارسی" ), true },
91 { wxLANGUAGE_INDONESIAN, ID_LANGUAGE_INDONESIAN, wxT( "Bahasa Indonesia" ), true },
92 { wxLANGUAGE_BULGARIAN, ID_LANGUAGE_BULGARIAN, wxT( "Български" ), true },
93 { wxLANGUAGE_CATALAN, ID_LANGUAGE_CATALAN, wxT( "Català" ), true },
94 { wxLANGUAGE_CZECH, ID_LANGUAGE_CZECH, wxT( "Čeština" ), true },
95 { wxLANGUAGE_DANISH, ID_LANGUAGE_DANISH, wxT( "Dansk" ), true },
96 { wxLANGUAGE_GERMAN, ID_LANGUAGE_GERMAN, wxT( "Deutsch" ), true },
97 { wxLANGUAGE_GREEK, ID_LANGUAGE_GREEK, wxT( "Ελληνικά" ), true },
98 { wxLANGUAGE_ESTONIAN, ID_LANGUAGE_ESTONIAN, wxT( "Eesti" ), true },
99 { wxLANGUAGE_ENGLISH, ID_LANGUAGE_ENGLISH, wxT( "English" ), true },
100 { wxLANGUAGE_SPANISH, ID_LANGUAGE_SPANISH, wxT( "Español" ), true },
101 { wxLANGUAGE_SPANISH_MEXICAN, ID_LANGUAGE_SPANISH_MEXICAN,
102 wxT( "Español (Latinoamericano)" ), true },
103 { wxLANGUAGE_FRENCH, ID_LANGUAGE_FRENCH, wxT( "Français" ), true },
104 { wxLANGUAGE_HEBREW, ID_LANGUAGE_HEBREW, wxT( "עברית" ), true },
105 { wxLANGUAGE_HINDI, ID_LANGUAGE_HINDI, wxT( "हिन्दी" ), true },
106 { wxLANGUAGE_CROATIAN, ID_LANGUAGE_CROATIAN, wxT( "Hrvatski" ), true },
107 { wxLANGUAGE_KOREAN, ID_LANGUAGE_KOREAN, wxT( "한국어"), true },
108 { wxLANGUAGE_ITALIAN, ID_LANGUAGE_ITALIAN, wxT( "Italiano" ), true },
109 { wxLANGUAGE_LAOTHIAN, ID_LANGUAGE_LAOTHIAN, wxT( "ພາສາລາວ" ), 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#ifdef _MSC_VER
190 winrt::uninit_apartment();
191#endif
192
193 // Shut down the thread pool explicitly here, before static destruction begins.
194 // On macOS, if the thread pool destructor runs during static destruction
195 // (via __cxa_finalize_ranges), the condition variables may be in an invalid state,
196 // causing a crash. By destroying the thread pool here, we ensure it's cleaned up
197 // while the C++ runtime is still in a valid state.
198 m_singleton.Shutdown();
199}
200
201
203{
204 wxASSERT( wxTheApp );
205 return *wxTheApp;
206}
207
208
209void PGM_BASE::SetTextEditor( const wxString& aFileName )
210{
211 m_text_editor = aFileName;
213}
214
215
216const wxString& PGM_BASE::GetTextEditor( bool aCanShowFileChooser )
217{
218 wxString editorname = m_text_editor;
219
220 if( !editorname )
221 {
222 if( !wxGetEnv( wxT( "EDITOR" ), &editorname ) )
223 {
224 // If there is no EDITOR variable set, try the desktop default
225#ifdef __WXMAC__
226 editorname = wxT( "/usr/bin/open -e" );
227#elif __WXX11__
228 editorname = wxT( "/usr/bin/xdg-open" );
229#endif
230 }
231 }
232
233 // If we still don't have an editor name show a dialog asking the user to select one
234 if( !editorname && aCanShowFileChooser )
235 {
236 DisplayInfoMessage( nullptr, _( "No default editor found, you must choose one." ) );
237
238 editorname = AskUserForPreferredEditor();
239 }
240
241 // If we finally have a new editor name request it to be copied to m_text_editor and
242 // saved to the preferences file.
243 if( !editorname.IsEmpty() )
244 SetTextEditor( editorname );
245
246 // m_text_editor already has the same value that editorname, or empty if no editor was
247 // found/chosen.
248 return m_text_editor;
249}
250
251
252const wxString PGM_BASE::AskUserForPreferredEditor( const wxString& aDefaultEditor )
253{
254 // Create a mask representing the executable files in the current platform
255#ifdef __WINDOWS__
256 wxString mask( _( "Executable file" ) + wxT( " (*.exe)|*.exe" ) );
257#else
258 wxString mask( _( "Executable file" ) + wxT( " (*)|*" ) );
259#endif
260
261 // Extract the path, name and extension from the default editor (even if the editor's
262 // name was empty, this method will succeed and return empty strings).
263 wxString path, name, ext;
264 wxFileName::SplitPath( aDefaultEditor, &path, &name, &ext );
265
266 // Show the modal editor and return the file chosen (may be empty if the user cancels
267 // the dialog).
268 return wxFileSelector( _( "Select Preferred Editor" ), path, name, wxT( "." ) + ext,
269 mask, wxFD_OPEN | wxFD_FILE_MUST_EXIST, nullptr );
270}
271
272
274{
275 const wxArrayString& argArray = App().argv.GetArguments();
276 m_argcUtf8 = argArray.size();
277
278 m_argvUtf8 = new char*[m_argcUtf8 + 1];
279 for( int n = 0; n < m_argcUtf8; n++ )
280 {
281 m_argvUtf8[n] = wxStrdup( argArray[n].ToUTF8() );
282 }
283
284 m_argvUtf8[m_argcUtf8] = NULL; // null terminator at end of argv
285}
286
287
289{
290 // Disabling until we change to load each DSO at startup rather than lazy-load when needed.
291 // Note that once the splash screen is re-enabled, there are some remaining bugs to fix:
292 // Any wxWidgets error dialogs that appear during startup are hidden by the splash screen,
293 // so we either need to prevent these from happening (probably not feasible) or else change
294 // the error-handling path to make sure errors go on top of the splash.
295#if 0
296 if( m_splash )
297 return;
298
299 m_splash = new WX_SPLASH( KiBitmap( BITMAPS::splash ), wxSPLASH_CENTRE_ON_SCREEN, 0,
300 NULL, -1, wxDefaultPosition, wxDefaultSize,
301 wxBORDER_NONE | wxSTAY_ON_TOP );
302 wxYield();
303#endif
304}
305
306
308{
309 if( !m_splash )
310 return;
311
312 m_splash->Close( true );
313 m_splash->Destroy();
314 m_splash = nullptr;
315}
316
317
318wxString PGM_BASE::DesktopAppIdForProgram( const wxString& aPgmName )
319{
320#if defined( __WXGTK__ ) && defined( KICAD_DESKTOP_APP_NAME )
321 // The prefix varies by build (regular, Flatpak, Nightly) and is supplied by CMake. The main
322 // manager keeps the bare app name; the other GUI apps are prefixed.
323 if( aPgmName == wxT( "kicad" ) )
324 return wxT( KICAD_DESKTOP_APP_NAME );
325
326 if( aPgmName == wxT( "eeschema" ) || aPgmName == wxT( "pcbnew" )
327 || aPgmName == wxT( "gerbview" ) || aPgmName == wxT( "bitmap2component" )
328 || aPgmName == wxT( "pcb_calculator" ) )
329 {
330 // pcb_calculator installs as pcbcalculator to satisfy freedesktop naming rules.
331 wxString appName = aPgmName == wxT( "pcb_calculator" ) ? wxT( "pcbcalculator" ) : aPgmName;
332 return wxString( wxT( KICAD_DESKTOP_APP_PREFIX ) ) + wxT( "." ) + appName;
333 }
334#endif
335
336 return wxEmptyString;
337}
338
339
340bool PGM_BASE::InitPgm( bool aHeadless, bool aIsUnitTest )
341{
342#if defined( __WXMAC__ )
343 // Set the application locale to the system default
344 wxLogNull noLog;
345 wxLocale loc;
346 loc.Init();
347#endif
348
349 // Just make sure we init precreate any folders early for later code
350 // In particular, the user cache path is the most likely to be hit by startup code
352
354
356
357 // Initialize the singleton instance
358 m_singleton.Init();
359
360 wxString pgm_name;
361
363 if( App().argc == 0 )
364 pgm_name = wxT( "kicad" );
365 else
366 pgm_name = wxFileName( App().argv[0] ).GetName().Lower();
367
368 APP_MONITOR::SENTRY::Instance()->AddTag( "kicad.app", pgm_name );
369
370 wxInitAllImageHandlers();
371
372 // libpng warnings such as "iCCP: known incorrect sRGB profile" otherwise pop up for
373 // benign plugin and user images; load failures are still reported by the callers
374 wxImage::SetDefaultLoadFlags( wxImage::GetDefaultLoadFlags() & ~wxImage::Load_Verbose );
375
376#if !wxCHECK_VERSION( 3, 3, 0 )
377 // Without this the wxPropertyGridManager segfaults on Windows.
378 if( !wxPGGlobalVars )
379 wxPGInitResourceModule();
380#endif
381
382#ifndef __WINDOWS__
383 if( wxString( wxGetenv( "HOME" ) ).IsEmpty() )
384 {
385 DisplayErrorMessage( nullptr, _( "Environment variable HOME is empty. "
386 "Unable to continue." ) );
387 return false;
388 }
389#endif
390
391 // Init KiCad environment
392 // the environment variable KICAD (if exists) gives the kicad path:
393 // something like set KICAD=d:\kicad
394 bool isDefined = wxGetEnv( wxT( "KICAD" ), &m_kicad_env );
395
396 if( isDefined ) // ensure m_kicad_env ends by "/"
397 {
399
400 if( !m_kicad_env.IsEmpty() && m_kicad_env.Last() != '/' )
402 }
403
404 // Init parameters for configuration
405 App().SetVendorName( wxT( "KiCad" ) );
406 App().SetAppName( pgm_name );
407
409
410#if defined( __WXGTK__ ) && defined( KICAD_DESKTOP_APP_NAME )
411 // On wx >= 3.3.1 wxGTK feeds the class name to gdk_wayland_window_set_application_id(),
412 // which lets Wayland compositors resolve the correct window icon and launch feedback. The
413 // X11 WM_CLASS is applied per window in EDA_BASE_FRAME instead, because wxGTK derives it
414 // from the (human-facing) app display name and would otherwise not match the launcher.
415 if( !m_desktopAppId.IsEmpty() )
416 App().SetClassName( m_desktopAppId );
417#endif
418
419 // Analyze the command line & initialize the binary path
420 wxString tmp;
422 SetDefaultLanguage( tmp );
423
424#ifdef _MSC_VER
425 if( !wxGetEnv( "FONTCONFIG_PATH", NULL ) )
426 {
427 // We need to set this because the internal fontconfig logic
428 // seems to search relative to the dll rather the other logic it
429 // has to look for the /etc folder above the dll
430 // Also don't set it because we need it in QA cli tests to be set by ctest
431 wxSetEnv( "FONTCONFIG_PATH", PATHS::GetWindowsFontConfigDir() );
432 }
433#endif
434
435#ifdef _MSC_VER
436 winrt::init_apartment(winrt::apartment_type::single_threaded);
437#endif
438
439 m_settings_manager = std::make_unique<SETTINGS_MANAGER>();
440 m_library_manager = std::make_unique<LIBRARY_MANAGER>();
441 m_background_jobs_monitor = std::make_unique<BACKGROUND_JOBS_MONITOR>();
442 m_notifications_manager = std::make_unique<NOTIFICATIONS_MANAGER>();
443
444 m_plugin_manager = std::make_unique<API_PLUGIN_MANAGER>( &App() );
445
446 // Our unit test mocks break if we continue
447 // A bug caused InitPgm to terminate early in unit tests and the mocks are...simplistic
448 // TODO fix the unit tests so this can be removed
449 if( aIsUnitTest )
450 return false;
451
452 // Something got in the way of settings load: can't continue
453 if( !m_settings_manager->IsOK() )
454 return false;
455
456 // Set up built-in environment variables (and override them from the system environment if set)
457 COMMON_SETTINGS* commonSettings = GetCommonSettings();
458 commonSettings->InitializeEnvironment();
459
460 // Load color settings after env is initialized
461 m_settings_manager->ReloadColorSettings();
462
463 // Load common settings from disk after setting up env vars
464 GetSettingsManager().Load( commonSettings );
465
466 // If user doesn't have a saved Python interpreter, try (potentially again) to find one
467 if( commonSettings->m_Api.python_interpreter.IsEmpty() )
469
470 // Init user language *before* calling loadSettings, because
471 // env vars could be incorrectly initialized on Linux
472 // (if the value contains some non ASCII7 chars, the env var is not initialized)
473 SetLanguage( tmp, true );
474
475 // Now that translations are available, inform the user if the OS is unsupported
477
479
480 ReadPdfBrowserInfos(); // needs GetCommonSettings()
481
483
484 // TODO(JE): Remove this if apps are refactored to not assume Prj() always works
485 // Need to create a project early for now (it can have an empty path for the moment)
487
488 if( commonSettings->m_Api.enable_server )
489 m_plugin_manager->ReloadPlugins();
490
491 // This sets the maximum tooltip display duration to 10s (up from 5) but only affects
492 // Windows as other platforms display tooltips while the mouse is not moving
493 if( !aHeadless )
494 {
495 wxToolTip::Enable( true );
496 wxToolTip::SetAutoPop( 10000 );
497 }
498
499 if( ADVANCED_CFG::GetCfg().m_UpdateUIEventInterval != 0 )
500 wxUpdateUIEvent::SetUpdateInterval( ADVANCED_CFG::GetCfg().m_UpdateUIEventInterval );
501
502 // Now the application can safely start, show the splash screen
503 if( !aHeadless )
504 ShowSplash();
505
506 return true;
507}
508
509
511{
513
514 for( const std::pair<wxString, ENV_VAR_ITEM> it : GetCommonSettings()->m_Env.vars )
515 {
516 wxLogTrace( traceEnvVars, wxT( "PGM_BASE::loadSettings: Found entry %s = %s" ),
517 it.first, it.second.GetValue() );
518
519 // Do not store the env var PROJECT_VAR_NAME ("KIPRJMOD") definition if for some reason
520 // it is found in config. (It is reserved and defined as project path)
521 if( it.first == PROJECT_VAR_NAME )
522 continue;
523
524 // Don't set bogus empty entries in the environment
525 if( it.first.IsEmpty() )
526 continue;
527
528 // Do not overwrite vars set by the system environment with values from the settings file
529 if( it.second.GetDefinedExternally() )
530 continue;
531
532 SetLocalEnvVariable( it.first, it.second.GetValue() );
533 }
534}
535
536
538{
539 // GetCommonSettings() is not initialized until fairly late in the
540 // process startup: InitPgm(), so test before using:
541 if( GetCommonSettings() && IsGUI() )
542 GetCommonSettings()->m_System.working_dir = wxGetCwd();
543}
544
545
547{
548 return m_settings_manager ? m_settings_manager->GetCommonSettings() : nullptr;
549}
550
551
552bool PGM_BASE::SetLanguage( wxString& aErrMsg, bool first_time )
553{
554 // Suppress wxWidgets error popups if locale is not found
555 wxLogNull doNotLog;
556
557 if( first_time )
558 {
559 setLanguageId( wxLANGUAGE_DEFAULT );
560
561 // First time SetLanguage is called, the user selected language id is set
562 // from common user config settings
563 wxString languageSel = GetCommonSettings()->m_System.language;
564
565 // Search for the current selection
566 for( unsigned ii = 0; LanguagesList[ii].m_KI_Lang_Identifier != 0; ii++ )
567 {
568 if( LanguagesList[ii].m_Lang_Label == languageSel )
569 {
570 setLanguageId( LanguagesList[ii].m_WX_Lang_Identifier );
571 break;
572 }
573 }
574 }
575
576 // dictionary file name without extend (full name is kicad.mo)
577 wxString dictionaryName( wxT( "kicad" ) );
578
579 delete m_locale;
580 m_locale = new wxLocale;
581
582 // don't use wxLOCALE_LOAD_DEFAULT flag so that Init() doesn't return
583 // false just because it failed to load wxstd catalog
584 if( !m_locale->Init( m_language_id ) )
585 {
586 wxLogTrace( traceLocale, wxT( "This language is not supported by the system." ) );
587
588 setLanguageId( wxLANGUAGE_DEFAULT );
589 delete m_locale;
590
591 m_locale = new wxLocale;
592 m_locale->Init( wxLANGUAGE_DEFAULT );
593
594 aErrMsg = _( "This language is not supported by the operating system." );
595 return false;
596 }
597 else if( !first_time )
598 {
599 wxLogTrace( traceLocale, wxT( "Search for dictionary %s.mo in %s" ) ,
600 dictionaryName, m_locale->GetName() );
601 }
602
603 if( !first_time )
604 {
605 // If we are here, the user has selected another language.
606 // Therefore the new preferred language name is stored in common config.
607 // Do NOT store the wxWidgets language Id, it can change between wxWidgets
608 // versions, for a given language
609 wxString languageSel;
610
611 // Search for the current selection language name
612 for( unsigned ii = 0; LanguagesList[ii].m_KI_Lang_Identifier != 0; ii++ )
613 {
614 if( LanguagesList[ii].m_WX_Lang_Identifier == m_language_id )
615 {
616 languageSel = LanguagesList[ii].m_Lang_Label;
617 break;
618 }
619 }
620
622 cfg->m_System.language = languageSel;
623 cfg->SaveToFile( GetSettingsManager().GetPathForSettingsFile( cfg ) );
624 }
625
626 // Try adding the dictionary if it is not currently loaded
627 if( !m_locale->IsLoaded( dictionaryName ) )
628 m_locale->AddCatalog( dictionaryName );
629
630 // Verify the Kicad dictionary was loaded properly
631 // However, for the English language, the dictionary is not mandatory, as
632 // all messages are already in English, just restricted to ASCII7 chars,
633 // the verification is skipped.
634 if( !m_locale->IsLoaded( dictionaryName ) && m_language_id != wxLANGUAGE_ENGLISH )
635 {
636 wxLogTrace( traceLocale, wxT( "Unable to load dictionary %s.mo in %s" ),
637 dictionaryName, m_locale->GetName() );
638
639 setLanguageId( wxLANGUAGE_DEFAULT );
640 delete m_locale;
641
642 m_locale = new wxLocale;
643 m_locale->Init( wxLANGUAGE_DEFAULT );
644
645 aErrMsg = _( "The KiCad language file for this language is not installed." );
646 return false;
647 }
648
649 return true;
650}
651
652
653bool PGM_BASE::SetDefaultLanguage( wxString& aErrMsg )
654{
655 // Suppress error popups from wxLocale
656 wxLogNull doNotLog;
657
658 setLanguageId( wxLANGUAGE_DEFAULT );
659
660 // dictionary file name without extend (full name is kicad.mo)
661 wxString dictionaryName( wxT( "kicad" ) );
662
663 delete m_locale;
664 m_locale = new wxLocale;
665 m_locale->Init();
666
667 // Try adding the dictionary if it is not currently loaded
668 if( !m_locale->IsLoaded( dictionaryName ) )
669 m_locale->AddCatalog( dictionaryName );
670
671 // Verify the Kicad dictionary was loaded properly
672 // However, for the English language, the dictionary is not mandatory, as
673 // all messages are already in English, just restricted to ASCII7 chars,
674 // the verification is skipped.
675 if( !m_locale->IsLoaded( dictionaryName ) && m_language_id != wxLANGUAGE_ENGLISH )
676 {
677 wxLogTrace( traceLocale, wxT( "Unable to load dictionary %s.mo in %s" ),
678 dictionaryName, m_locale->GetName() );
679
680 setLanguageId( wxLANGUAGE_DEFAULT );
681 delete m_locale;
682
683 m_locale = new wxLocale;
684 m_locale->Init();
685
686 aErrMsg = _( "The KiCad language file for this language is not installed." );
687 return false;
688 }
689
690 return true;
691}
692
693
695{
696 wxLogTrace( traceLocale, wxT( "Select language ID %d from %d possible languages." ),
697 menu_id, (int)arrayDim( LanguagesList )-1 );
698
699 for( unsigned ii = 0; LanguagesList[ii].m_KI_Lang_Identifier != 0; ii++ )
700 {
701 if( menu_id == LanguagesList[ii].m_KI_Lang_Identifier )
702 {
703 setLanguageId( LanguagesList[ii].m_WX_Lang_Identifier );
704 break;
705 }
706 }
707}
708
709
711{
712 const wxLanguageInfo* langInfo = wxLocale::GetLanguageInfo( m_language_id );
713
714 if( !langInfo )
715 {
716 return "";
717 }
718 else
719 {
720 wxString str = langInfo->GetCanonicalWithRegion();
721 str.Replace( "_", "-" );
722
723 return str;
724 }
725}
726
727
729{
730#ifdef _MSC_VER
731 wxLocale::AddCatalogLookupPathPrefix( PATHS::GetWindowsBaseSharePath() + wxT( "locale" ) );
732#endif
733 wxLocale::AddCatalogLookupPathPrefix( PATHS::GetLocaleDataPath() );
734
735 if( wxGetEnv( wxT( "KICAD_RUN_FROM_BUILD_DIR" ), nullptr ) )
736 {
737 wxFileName fn( Pgm().GetExecutablePath() );
738 fn.RemoveLastDir();
739 fn.AppendDir( wxT( "translation" ) );
740 wxLocale::AddCatalogLookupPathPrefix( fn.GetPath() );
741 }
742}
743
744
745bool PGM_BASE::SetLocalEnvVariable( const wxString& aName, const wxString& aValue )
746{
747 wxString env;
748
749 if( aName.IsEmpty() )
750 {
751 wxLogTrace( traceEnvVars,
752 wxT( "PGM_BASE::SetLocalEnvVariable: Attempt to set empty variable to "
753 "value %s" ),
754 aValue );
755 return false;
756 }
757
758 // Check to see if the environment variable is already set.
759 if( wxGetEnv( aName, &env ) )
760 {
761 wxLogTrace( traceEnvVars,
762 wxT( "PGM_BASE::SetLocalEnvVariable: Environment variable %s already set "
763 "to %s" ),
764 aName, env );
765 return env == aValue;
766 }
767
768 wxLogTrace( traceEnvVars,
769 wxT( "PGM_BASE::SetLocalEnvVariable: Setting local environment variable %s to %s" ),
770 aName, aValue );
771
772 return wxSetEnv( aName, aValue );
773}
774
775
777{
778 // Overwrites externally defined environment variable until the next time the application
779 // is run.
780 for( const std::pair<wxString, ENV_VAR_ITEM> m_local_env_var : GetCommonSettings()->m_Env.vars )
781 {
782 wxLogTrace( traceEnvVars,
783 wxT( "PGM_BASE::SetLocalEnvVariables: Setting local environment variable %s "
784 "to %s" ),
785 m_local_env_var.first,
786 m_local_env_var.second.GetValue() );
787 wxSetEnv( m_local_env_var.first, m_local_env_var.second.GetValue() );
788 }
789}
790
791
796
797
799{
800 if( !wxTheApp )
801 return false;
802
803 return wxTheApp->IsGUI();
804}
805
806
807void PGM_BASE::HandleException( std::exception_ptr aPtr, bool aUnhandled )
808{
809 try
810 {
811 if( aPtr )
812 std::rethrow_exception( aPtr );
813 }
814 catch( const IO_ERROR& ioe )
815 {
816 wxLogError( ioe.What() );
817
818 if( aUnhandled )
819 {
820 // Log this IO_ERROR escaped our usual uses (bad)
821 APP_MONITOR::SENTRY::Instance()->LogException( ioe.What(), aUnhandled );
822 }
823 }
824 catch( const std::exception& e )
825 {
826 APP_MONITOR::SENTRY::Instance()->LogException( e.what(), aUnhandled );
827
828 wxLogError( wxT( "Unhandled exception class: %s what: %s" ),
829 From_UTF8( typeid( e ).name() ), From_UTF8( e.what() ) );
830 }
831 catch( ... )
832 {
833 // We really shouldn't have these but just in case...
834 wxLogError( wxT( "Unhandled exception of unknown type" ) );
835
836 if( aUnhandled )
837 {
838 APP_MONITOR::SENTRY::Instance()->LogException( "Unhandled exception of unknown type", aUnhandled );
839 }
840 }
841}
842
843
844void PGM_BASE::HandleAssert( const wxString& aFile, int aLine, const wxString& aFunc,
845 const wxString& aCond, const wxString& aMsg )
846{
847 wxString assertStr;
848
849 // Log the assertion details to standard log
850 if( !aMsg.empty() )
851 {
852 assertStr = wxString::Format( "Assertion failed at %s:%d in %s: %s - %s", aFile, aLine,
853 aFunc, aCond, aMsg );
854 }
855 else
856 {
857 assertStr = wxString::Format( "Assertion failed at %s:%d in %s: %s", aFile, aLine, aFunc,
858 aCond );
859 }
860
861#ifndef NDEBUG
862 wxLogError( assertStr );
863#endif
864
865#ifdef KICAD_USE_SENTRY
866 APP_MONITOR::ASSERT_CACHE_KEY key = { aFile, aLine, aFunc, aCond };
867 APP_MONITOR::SENTRY::Instance()->LogAssert( key, assertStr );
868#endif
869}
870
871
872const wxString& PGM_BASE::GetExecutablePath() const
873{
875}
876
877
883
884
890
891
893{
894 // TODO(JE) much of this code can be shared across the 3 preloads
895 constexpr static int interval = 150;
896 constexpr static int timeLimit = 120000;
897
898 if( m_libraryPreloadInProgress.load() )
899 return;
900
902 Pgm().GetBackgroundJobMonitor().Create( _( "Loading Design Block Libraries" ) );
903
904 auto preload =
905 [this, aKiway]() -> void
906 {
907 std::shared_ptr<BACKGROUND_JOB_REPORTER> reporter =
909
910 DESIGN_BLOCK_LIBRARY_ADAPTER* adapter = aKiway->Prj().DesignBlockLibs();
911
912 int elapsed = 0;
913 bool aborted = false;
914
915 reporter->Report( _( "Loading Design Block Libraries" ) );
916 adapter->AsyncLoad();
917
918 while( true )
919 {
920 if( m_libraryPreloadAbort.load() )
921 {
922 m_libraryPreloadAbort.store( false );
923 aborted = true;
924 break;
925 }
926
927 std::this_thread::sleep_for( std::chrono::milliseconds( interval ) );
928
929 if( std::optional<float> loadStatus = adapter->AsyncLoadProgress() )
930 {
931 float progress = *loadStatus;
932 reporter->SetCurrentProgress( progress );
933
934 if( progress >= 1 )
935 break;
936 }
937 else
938 {
939 reporter->SetCurrentProgress( 1 );
940 break;
941 }
942
943 elapsed += interval;
944
945 if( elapsed > timeLimit )
946 break;
947 }
948
949 // AbortAsyncLoad() sets the adapter's worker abort flag and then blocks,
950 // so workers exit at their next checkpoint. BlockUntilLoaded() alone just
951 // waits for each future to complete naturally, which can hang indefinitely
952 // if a worker is stuck on a stalled network or filesystem operation.
953 if( aborted )
954 adapter->AbortAsyncLoad();
955 else
956 adapter->BlockUntilLoaded();
957
960 m_libraryPreloadInProgress.store( false );
961
962 std::string payload = "";
963 aKiway->ExpressMail( FRAME_SCH, MAIL_RELOAD_LIB, payload, nullptr, true );
964 aKiway->ExpressMail( FRAME_PCB_EDITOR, MAIL_RELOAD_LIB, payload, nullptr, true );
965 };
966
968 m_libraryPreloadInProgress.store( true );
969 m_libraryPreloadReturn = tp.submit_task( preload );
970}
971
972
974{
975 std::lock_guard<std::mutex> lock( m_libraryLoadStatusBarsMutex );
976
977 wxLogTrace( traceLibraries, "RegisterLibraryLoadStatusBar: statusBar=%p", aStatusBar );
978
979 if( std::find( m_libraryLoadStatusBars.begin(), m_libraryLoadStatusBars.end(), aStatusBar )
980 == m_libraryLoadStatusBars.end() )
981 {
982 m_libraryLoadStatusBars.push_back( aStatusBar );
983 wxLogTrace( traceLibraries, " -> registered, total count=%zu",
985 }
986 else
987 {
988 wxLogTrace( traceLibraries, " -> already registered" );
989 }
990}
991
992
994{
995 std::lock_guard<std::mutex> lock( m_libraryLoadStatusBarsMutex );
996
997 wxLogTrace( traceLibraries, "UnregisterLibraryLoadStatusBar: statusBar=%p", aStatusBar );
998
1000 std::remove( m_libraryLoadStatusBars.begin(), m_libraryLoadStatusBars.end(),
1001 aStatusBar ),
1003
1004 wxLogTrace( traceLibraries, " -> remaining count=%zu", m_libraryLoadStatusBars.size() );
1005}
1006
1007
1008void PGM_BASE::AddLibraryLoadMessages( const std::vector<KI_ERROR>& aMessages )
1009{
1010 wxLogTrace( traceLibraries, "AddLibraryLoadMessages: message_count=%zu", aMessages.size() );
1011
1012 if( aMessages.empty() )
1013 return;
1014
1015 std::lock_guard<std::mutex> lock( m_libraryLoadStatusBarsMutex );
1016
1017 wxLogTrace( traceLibraries, " -> registered status bars=%zu",
1018 m_libraryLoadStatusBars.size() );
1019
1020 for( KISTATUSBAR* statusBar : m_libraryLoadStatusBars )
1021 {
1022 if( statusBar )
1023 {
1024 wxLogTrace( traceLibraries, " -> forwarding to statusBar=%p", statusBar );
1025 statusBar->AddWarningMessages( "load", aMessages );
1026 }
1027 }
1028}
1029
1030
1032{
1033 std::lock_guard<std::mutex> lock( m_libraryLoadStatusBarsMutex );
1034
1035 wxLogTrace( traceLibraries, "ClearLibraryLoadMessages: status bars=%zu",
1036 m_libraryLoadStatusBars.size() );
1037
1038 for( KISTATUSBAR* statusBar : m_libraryLoadStatusBars )
1039 {
1040 if( statusBar )
1041 statusBar->ClearWarningMessages( "load" );
1042 }
1043}
1044
1045
1047
1048
1050{
1051 wxASSERT( process ); // KIFACE_GETTER has already been called.
1052 return *process;
1053}
1054
1055
1056// Similar to PGM_BASE& Pgm(), but return nullptr when a *.ki_face is run from a python script.
1058{
1059 return process;
1060}
1061
1062
1063void SetPgm( PGM_BASE* pgm )
1064{
1065 process = pgm;
1066}
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
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.
KISTATUSBAR is a wxStatusBar suitable for Kicad manager.
Definition kistatusbar.h:50
A minimalistic software bus for communications between various DLLs/DSOs (DSOs) within the same KiCad...
Definition kiway.h:340
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 void EnsureUserPathsExist()
Ensures/creates user default paths.
Definition paths.cpp:535
static wxString GetLocaleDataPath()
Gets the locales translation data path.
Definition paths.cpp:366
static const wxString & GetExecutablePath()
Definition paths.cpp:661
Container for data for KiCad programs.
Definition pgm_base.h:101
virtual COMMON_SETTINGS * GetCommonSettings() const
Definition pgm_base.cpp:546
virtual wxApp & App()
Return a bare naked wxApp which may come from wxPython, SINGLE_TOP, or kicad.exe.
Definition pgm_base.cpp:202
std::unique_ptr< NOTIFICATIONS_MANAGER > m_notifications_manager
Definition pgm_base.h:408
void PreloadDesignBlockLibraries(KIWAY *aKiway)
Starts a background job to preload the global and project design block libraries.
Definition pgm_base.cpp:892
int m_argcUtf8
Definition pgm_base.h:440
virtual ENV_VAR_MAP & GetLocalEnvVariables() const
Definition pgm_base.cpp:792
std::unique_ptr< LIBRARY_MANAGER > m_library_manager
Definition pgm_base.h:406
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:384
void setLanguageId(int aId)
Trap all changes in here, simplifies debugging.
Definition pgm_base.h:397
std::unique_ptr< API_PLUGIN_MANAGER > m_plugin_manager
Definition pgm_base.h:410
std::unique_ptr< SETTINGS_MANAGER > m_settings_manager
Definition pgm_base.h:405
void loadCommonSettings()
Load internal settings from COMMON_SETTINGS.
Definition pgm_base.cpp:510
virtual void SetPdfBrowserName(const wxString &aFileName)
Definition pgm_base.h:178
std::vector< KISTATUSBAR * > m_libraryLoadStatusBars
Definition pgm_base.h:449
wxLocale * m_locale
Definition pgm_base.h:417
void Destroy()
Definition pgm_base.cpp:183
wxSplashScreen * m_splash
Definition pgm_base.h:442
virtual BACKGROUND_JOBS_MONITOR & GetBackgroundJobMonitor() const
Definition pgm_base.h:129
char ** m_argvUtf8
argv parameters converted to utf8 form because wxWidgets has opinions.
Definition pgm_base.h:438
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:993
void AddLibraryLoadMessages(const std::vector< KI_ERROR > &aMessages)
Add library load messages to all registered status bars.
virtual void ReadPdfBrowserInfos()
Read the PDF browser choice from the common configuration.
Definition pgm_base.cpp:878
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:807
bool IsGUI()
Determine if the application is running with a GUI.
Definition pgm_base.cpp:798
bool m_use_system_pdf_browser
Definition pgm_base.h:420
bool m_Quitting
Definition pgm_base.h:388
void RegisterLibraryLoadStatusBar(KISTATUSBAR *aStatusBar)
Register a status bar to receive library load warning messages.
Definition pgm_base.cpp:973
std::future< void > m_libraryPreloadReturn
Definition pgm_base.h:445
virtual NOTIFICATIONS_MANAGER & GetNotificationsManager() const
Definition pgm_base.h:134
std::shared_ptr< BACKGROUND_JOB > m_libraryPreloadBackgroundJob
Definition pgm_base.h:444
void BuildArgvUtf8()
Builds the UTF8 based argv variable.
Definition pgm_base.cpp:273
virtual const wxString & GetPdfBrowserName() const
Definition pgm_base.h:176
std::atomic_bool m_libraryPreloadAbort
Definition pgm_base.h:447
void ClearLibraryLoadMessages()
Clear library load messages from all registered status bars.
virtual void SetTextEditor(const wxString &aFileName)
Definition pgm_base.cpp:209
virtual bool SetLocalEnvVariable(const wxString &aName, const wxString &aValue)
Set the environment variable aName to aValue.
Definition pgm_base.cpp:745
bool InitPgm(bool aHeadless=false, bool aIsUnitTest=false)
Initialize this program.
Definition pgm_base.cpp:340
wxString m_kicad_env
The KICAD system environment variable.
Definition pgm_base.h:413
virtual void ForceSystemPdfBrowser(bool aFlg)
Force the use of system PDF browser, even if a preferred PDF browser is set.
Definition pgm_base.h:193
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:776
virtual void SetLanguagePath()
Definition pgm_base.cpp:728
bool SetDefaultLanguage(wxString &aErrMsg)
Set the default language without reference to any preferences.
Definition pgm_base.cpp:653
void ShowSplash()
Definition pgm_base.cpp:288
wxString m_text_editor
Definition pgm_base.h:423
std::atomic_bool m_libraryPreloadInProgress
Definition pgm_base.h:446
virtual ~PGM_BASE()
Definition pgm_base.cpp:166
wxString m_desktopAppId
freedesktop app id of this process, or empty.
Definition pgm_base.h:415
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:694
int m_language_id
Definition pgm_base.h:418
std::unique_ptr< BACKGROUND_JOBS_MONITOR > m_background_jobs_monitor
Definition pgm_base.h:407
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:844
virtual wxString GetLanguageTag()
Definition pgm_base.cpp:710
virtual const wxString & GetTextEditor(bool aCanShowFileChooser=true)
Return the path to the preferred text editor application.
Definition pgm_base.cpp:216
virtual const wxString & GetExecutablePath() const
Definition pgm_base.cpp:872
virtual SETTINGS_MANAGER & GetSettingsManager() const
Definition pgm_base.h:123
void HideSplash()
Definition pgm_base.cpp:307
virtual void WritePdfBrowserInfos()
Save the PDF browser choice to the common configuration.
Definition pgm_base.cpp:885
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:318
void SaveCommonSettings()
Save the program (process) settings subset which are stored .kicad_common.
Definition pgm_base.cpp:537
bool m_PropertyGridInitialized
Definition pgm_base.h:390
KICAD_SINGLETON m_singleton
Definition pgm_base.h:425
std::mutex m_libraryLoadStatusBarsMutex
Definition pgm_base.h:450
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:252
virtual bool SetLanguage(wxString &aErrMsg, bool first_time=false)
Set the dictionary file name for internationalization.
Definition pgm_base.cpp:552
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:1001
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:53
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:86
#define _(s)
Current list of languages supported by KiCad.
Definition pgm_base.cpp:85
see class PGM_BASE
KICOMMON_API LANGUAGE_DESCR LanguagesList[]
An array containing all the languages that KiCad supports.
Definition pgm_base.cpp:86
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:67
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.