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#if wxCHECK_VERSION( 3, 3, 1 ) && defined( __WXGTK__ ) && defined( KICAD_DESKTOP_APP_NAME )
402 // wxGTK feeds the class name to gdk_wayland_window_set_application_id(), so setting it
403 // to the installed desktop file basename lets Wayland compositors resolve the correct
404 // window icon and launch feedback. The prefix varies by build (regular, Flatpak, Nightly)
405 // and is supplied by CMake. The main manager keeps the bare app name; the other GUI apps
406 // are prefixed. Executables without a desktop file (pl_editor, kicad-cli) are left alone.
407 wxString desktopId;
408
409 if( pgm_name == wxT( "kicad" ) )
410 {
411 desktopId = wxT( KICAD_DESKTOP_APP_NAME );
412 }
413 else if( pgm_name == wxT( "eeschema" ) || pgm_name == wxT( "pcbnew" )
414 || pgm_name == wxT( "gerbview" ) || pgm_name == wxT( "bitmap2component" )
415 || pgm_name == wxT( "pcb_calculator" ) )
416 {
417 // pcb_calculator installs as pcbcalculator to satisfy freedesktop naming rules.
418 wxString appName = pgm_name == wxT( "pcb_calculator" ) ? wxT( "pcbcalculator" ) : pgm_name;
419 desktopId = wxString( wxT( KICAD_DESKTOP_APP_PREFIX ) ) + wxT( "." ) + appName;
420 }
421
422 if( !desktopId.IsEmpty() )
423 App().SetClassName( desktopId );
424#endif
425
426 // Analyze the command line & initialize the binary path
427 wxString tmp;
429 SetDefaultLanguage( tmp );
430
431#ifdef _MSC_VER
432 if( !wxGetEnv( "FONTCONFIG_PATH", NULL ) )
433 {
434 // We need to set this because the internal fontconfig logic
435 // seems to search relative to the dll rather the other logic it
436 // has to look for the /etc folder above the dll
437 // Also don't set it because we need it in QA cli tests to be set by ctest
438 wxSetEnv( "FONTCONFIG_PATH", PATHS::GetWindowsFontConfigDir() );
439 }
440#endif
441
442#ifdef _MSC_VER
443 winrt::init_apartment(winrt::apartment_type::single_threaded);
444#endif
445
446 m_settings_manager = std::make_unique<SETTINGS_MANAGER>();
447 m_library_manager = std::make_unique<LIBRARY_MANAGER>();
448 m_background_jobs_monitor = std::make_unique<BACKGROUND_JOBS_MONITOR>();
449 m_notifications_manager = std::make_unique<NOTIFICATIONS_MANAGER>();
450
451 m_plugin_manager = std::make_unique<API_PLUGIN_MANAGER>( &App() );
452
453 // Our unit test mocks break if we continue
454 // A bug caused InitPgm to terminate early in unit tests and the mocks are...simplistic
455 // TODO fix the unit tests so this can be removed
456 if( aIsUnitTest )
457 return false;
458
459 // Something got in the way of settings load: can't continue
460 if( !m_settings_manager->IsOK() )
461 return false;
462
463 // Set up built-in environment variables (and override them from the system environment if set)
464 COMMON_SETTINGS* commonSettings = GetCommonSettings();
465 commonSettings->InitializeEnvironment();
466
467 // Load color settings after env is initialized
468 m_settings_manager->ReloadColorSettings();
469
470 // Load common settings from disk after setting up env vars
471 GetSettingsManager().Load( commonSettings );
472
473 // If user doesn't have a saved Python interpreter, try (potentially again) to find one
474 if( commonSettings->m_Api.python_interpreter.IsEmpty() )
476
477 // Init user language *before* calling loadSettings, because
478 // env vars could be incorrectly initialized on Linux
479 // (if the value contains some non ASCII7 chars, the env var is not initialized)
480 SetLanguage( tmp, true );
481
482 // Now that translations are available, inform the user if the OS is unsupported
484
486
487 ReadPdfBrowserInfos(); // needs GetCommonSettings()
488
490
491 // TODO(JE): Remove this if apps are refactored to not assume Prj() always works
492 // Need to create a project early for now (it can have an empty path for the moment)
494
495 if( commonSettings->m_Api.enable_server )
496 m_plugin_manager->ReloadPlugins();
497
498 // This sets the maximum tooltip display duration to 10s (up from 5) but only affects
499 // Windows as other platforms display tooltips while the mouse is not moving
500 if( !aHeadless )
501 {
502 wxToolTip::Enable( true );
503 wxToolTip::SetAutoPop( 10000 );
504 }
505
506 if( ADVANCED_CFG::GetCfg().m_UpdateUIEventInterval != 0 )
507 wxUpdateUIEvent::SetUpdateInterval( ADVANCED_CFG::GetCfg().m_UpdateUIEventInterval );
508
509 // Now the application can safely start, show the splash screen
510 if( !aHeadless )
511 ShowSplash();
512
513 return true;
514}
515
516
518{
520
521 for( const std::pair<wxString, ENV_VAR_ITEM> it : GetCommonSettings()->m_Env.vars )
522 {
523 wxLogTrace( traceEnvVars, wxT( "PGM_BASE::loadSettings: Found entry %s = %s" ),
524 it.first, it.second.GetValue() );
525
526 // Do not store the env var PROJECT_VAR_NAME ("KIPRJMOD") definition if for some reason
527 // it is found in config. (It is reserved and defined as project path)
528 if( it.first == PROJECT_VAR_NAME )
529 continue;
530
531 // Don't set bogus empty entries in the environment
532 if( it.first.IsEmpty() )
533 continue;
534
535 // Do not overwrite vars set by the system environment with values from the settings file
536 if( it.second.GetDefinedExternally() )
537 continue;
538
539 SetLocalEnvVariable( it.first, it.second.GetValue() );
540 }
541}
542
543
545{
546 // GetCommonSettings() is not initialized until fairly late in the
547 // process startup: InitPgm(), so test before using:
548 if( GetCommonSettings() && IsGUI() )
549 GetCommonSettings()->m_System.working_dir = wxGetCwd();
550}
551
552
554{
555 return m_settings_manager ? m_settings_manager->GetCommonSettings() : nullptr;
556}
557
558
559bool PGM_BASE::SetLanguage( wxString& aErrMsg, bool first_time )
560{
561 // Suppress wxWidgets error popups if locale is not found
562 wxLogNull doNotLog;
563
564 if( first_time )
565 {
566 setLanguageId( wxLANGUAGE_DEFAULT );
567
568 // First time SetLanguage is called, the user selected language id is set
569 // from common user config settings
570 wxString languageSel = GetCommonSettings()->m_System.language;
571
572 // Search for the current selection
573 for( unsigned ii = 0; LanguagesList[ii].m_KI_Lang_Identifier != 0; ii++ )
574 {
575 if( LanguagesList[ii].m_Lang_Label == languageSel )
576 {
577 setLanguageId( LanguagesList[ii].m_WX_Lang_Identifier );
578 break;
579 }
580 }
581 }
582
583 // dictionary file name without extend (full name is kicad.mo)
584 wxString dictionaryName( wxT( "kicad" ) );
585
586 delete m_locale;
587 m_locale = new wxLocale;
588
589 // don't use wxLOCALE_LOAD_DEFAULT flag so that Init() doesn't return
590 // false just because it failed to load wxstd catalog
591 if( !m_locale->Init( m_language_id ) )
592 {
593 wxLogTrace( traceLocale, wxT( "This language is not supported by the system." ) );
594
595 setLanguageId( wxLANGUAGE_DEFAULT );
596 delete m_locale;
597
598 m_locale = new wxLocale;
599 m_locale->Init( wxLANGUAGE_DEFAULT );
600
601 aErrMsg = _( "This language is not supported by the operating system." );
602 return false;
603 }
604 else if( !first_time )
605 {
606 wxLogTrace( traceLocale, wxT( "Search for dictionary %s.mo in %s" ) ,
607 dictionaryName, m_locale->GetName() );
608 }
609
610 if( !first_time )
611 {
612 // If we are here, the user has selected another language.
613 // Therefore the new preferred language name is stored in common config.
614 // Do NOT store the wxWidgets language Id, it can change between wxWidgets
615 // versions, for a given language
616 wxString languageSel;
617
618 // Search for the current selection language name
619 for( unsigned ii = 0; LanguagesList[ii].m_KI_Lang_Identifier != 0; ii++ )
620 {
621 if( LanguagesList[ii].m_WX_Lang_Identifier == m_language_id )
622 {
623 languageSel = LanguagesList[ii].m_Lang_Label;
624 break;
625 }
626 }
627
629 cfg->m_System.language = languageSel;
630 cfg->SaveToFile( GetSettingsManager().GetPathForSettingsFile( cfg ) );
631 }
632
633 // Try adding the dictionary if it is not currently loaded
634 if( !m_locale->IsLoaded( dictionaryName ) )
635 m_locale->AddCatalog( dictionaryName );
636
637 // Verify the Kicad dictionary was loaded properly
638 // However, for the English language, the dictionary is not mandatory, as
639 // all messages are already in English, just restricted to ASCII7 chars,
640 // the verification is skipped.
641 if( !m_locale->IsLoaded( dictionaryName ) && m_language_id != wxLANGUAGE_ENGLISH )
642 {
643 wxLogTrace( traceLocale, wxT( "Unable to load dictionary %s.mo in %s" ),
644 dictionaryName, m_locale->GetName() );
645
646 setLanguageId( wxLANGUAGE_DEFAULT );
647 delete m_locale;
648
649 m_locale = new wxLocale;
650 m_locale->Init( wxLANGUAGE_DEFAULT );
651
652 aErrMsg = _( "The KiCad language file for this language is not installed." );
653 return false;
654 }
655
656 return true;
657}
658
659
660bool PGM_BASE::SetDefaultLanguage( wxString& aErrMsg )
661{
662 // Suppress error popups from wxLocale
663 wxLogNull doNotLog;
664
665 setLanguageId( wxLANGUAGE_DEFAULT );
666
667 // dictionary file name without extend (full name is kicad.mo)
668 wxString dictionaryName( wxT( "kicad" ) );
669
670 delete m_locale;
671 m_locale = new wxLocale;
672 m_locale->Init();
673
674 // Try adding the dictionary if it is not currently loaded
675 if( !m_locale->IsLoaded( dictionaryName ) )
676 m_locale->AddCatalog( dictionaryName );
677
678 // Verify the Kicad dictionary was loaded properly
679 // However, for the English language, the dictionary is not mandatory, as
680 // all messages are already in English, just restricted to ASCII7 chars,
681 // the verification is skipped.
682 if( !m_locale->IsLoaded( dictionaryName ) && m_language_id != wxLANGUAGE_ENGLISH )
683 {
684 wxLogTrace( traceLocale, wxT( "Unable to load dictionary %s.mo in %s" ),
685 dictionaryName, m_locale->GetName() );
686
687 setLanguageId( wxLANGUAGE_DEFAULT );
688 delete m_locale;
689
690 m_locale = new wxLocale;
691 m_locale->Init();
692
693 aErrMsg = _( "The KiCad language file for this language is not installed." );
694 return false;
695 }
696
697 return true;
698}
699
700
702{
703 wxLogTrace( traceLocale, wxT( "Select language ID %d from %d possible languages." ),
704 menu_id, (int)arrayDim( LanguagesList )-1 );
705
706 for( unsigned ii = 0; LanguagesList[ii].m_KI_Lang_Identifier != 0; ii++ )
707 {
708 if( menu_id == LanguagesList[ii].m_KI_Lang_Identifier )
709 {
710 setLanguageId( LanguagesList[ii].m_WX_Lang_Identifier );
711 break;
712 }
713 }
714}
715
716
718{
719 const wxLanguageInfo* langInfo = wxLocale::GetLanguageInfo( m_language_id );
720
721 if( !langInfo )
722 {
723 return "";
724 }
725 else
726 {
727 wxString str = langInfo->GetCanonicalWithRegion();
728 str.Replace( "_", "-" );
729
730 return str;
731 }
732}
733
734
736{
737#ifdef _MSC_VER
738 wxLocale::AddCatalogLookupPathPrefix( PATHS::GetWindowsBaseSharePath() + wxT( "locale" ) );
739#endif
740 wxLocale::AddCatalogLookupPathPrefix( PATHS::GetLocaleDataPath() );
741
742 if( wxGetEnv( wxT( "KICAD_RUN_FROM_BUILD_DIR" ), nullptr ) )
743 {
744 wxFileName fn( Pgm().GetExecutablePath() );
745 fn.RemoveLastDir();
746 fn.AppendDir( wxT( "translation" ) );
747 wxLocale::AddCatalogLookupPathPrefix( fn.GetPath() );
748 }
749}
750
751
752bool PGM_BASE::SetLocalEnvVariable( const wxString& aName, const wxString& aValue )
753{
754 wxString env;
755
756 if( aName.IsEmpty() )
757 {
758 wxLogTrace( traceEnvVars,
759 wxT( "PGM_BASE::SetLocalEnvVariable: Attempt to set empty variable to "
760 "value %s" ),
761 aValue );
762 return false;
763 }
764
765 // Check to see if the environment variable is already set.
766 if( wxGetEnv( aName, &env ) )
767 {
768 wxLogTrace( traceEnvVars,
769 wxT( "PGM_BASE::SetLocalEnvVariable: Environment variable %s already set "
770 "to %s" ),
771 aName, env );
772 return env == aValue;
773 }
774
775 wxLogTrace( traceEnvVars,
776 wxT( "PGM_BASE::SetLocalEnvVariable: Setting local environment variable %s to %s" ),
777 aName, aValue );
778
779 return wxSetEnv( aName, aValue );
780}
781
782
784{
785 // Overwrites externally defined environment variable until the next time the application
786 // is run.
787 for( const std::pair<wxString, ENV_VAR_ITEM> m_local_env_var : GetCommonSettings()->m_Env.vars )
788 {
789 wxLogTrace( traceEnvVars,
790 wxT( "PGM_BASE::SetLocalEnvVariables: Setting local environment variable %s "
791 "to %s" ),
792 m_local_env_var.first,
793 m_local_env_var.second.GetValue() );
794 wxSetEnv( m_local_env_var.first, m_local_env_var.second.GetValue() );
795 }
796}
797
798
803
804
806{
807 if( !wxTheApp )
808 return false;
809
810 return wxTheApp->IsGUI();
811}
812
813
814void PGM_BASE::HandleException( std::exception_ptr aPtr, bool aUnhandled )
815{
816 try
817 {
818 if( aPtr )
819 std::rethrow_exception( aPtr );
820 }
821 catch( const IO_ERROR& ioe )
822 {
823 wxLogError( ioe.What() );
824
825 if( aUnhandled )
826 {
827 // Log this IO_ERROR escaped our usual uses (bad)
828 APP_MONITOR::SENTRY::Instance()->LogException( ioe.What(), aUnhandled );
829 }
830 }
831 catch( const std::exception& e )
832 {
833 APP_MONITOR::SENTRY::Instance()->LogException( e.what(), aUnhandled );
834
835 wxLogError( wxT( "Unhandled exception class: %s what: %s" ),
836 From_UTF8( typeid( e ).name() ), From_UTF8( e.what() ) );
837 }
838 catch( ... )
839 {
840 // We really shouldn't have these but just in case...
841 wxLogError( wxT( "Unhandled exception of unknown type" ) );
842
843 if( aUnhandled )
844 {
845 APP_MONITOR::SENTRY::Instance()->LogException( "Unhandled exception of unknown type", aUnhandled );
846 }
847 }
848}
849
850
851void PGM_BASE::HandleAssert( const wxString& aFile, int aLine, const wxString& aFunc,
852 const wxString& aCond, const wxString& aMsg )
853{
854 wxString assertStr;
855
856 // Log the assertion details to standard log
857 if( !aMsg.empty() )
858 {
859 assertStr = wxString::Format( "Assertion failed at %s:%d in %s: %s - %s", aFile, aLine,
860 aFunc, aCond, aMsg );
861 }
862 else
863 {
864 assertStr = wxString::Format( "Assertion failed at %s:%d in %s: %s", aFile, aLine, aFunc,
865 aCond );
866 }
867
868#ifndef NDEBUG
869 wxLogError( assertStr );
870#endif
871
872#ifdef KICAD_USE_SENTRY
873 APP_MONITOR::ASSERT_CACHE_KEY key = { aFile, aLine, aFunc, aCond };
874 APP_MONITOR::SENTRY::Instance()->LogAssert( key, assertStr );
875#endif
876}
877
878
879const wxString& PGM_BASE::GetExecutablePath() const
880{
882}
883
884
890
891
897
898
900{
901 // TODO(JE) much of this code can be shared across the 3 preloads
902 constexpr static int interval = 150;
903 constexpr static int timeLimit = 120000;
904
905 if( m_libraryPreloadInProgress.load() )
906 return;
907
909 Pgm().GetBackgroundJobMonitor().Create( _( "Loading Design Block Libraries" ) );
910
911 auto preload =
912 [this, aKiway]() -> void
913 {
914 std::shared_ptr<BACKGROUND_JOB_REPORTER> reporter =
916
917 DESIGN_BLOCK_LIBRARY_ADAPTER* adapter = aKiway->Prj().DesignBlockLibs();
918
919 int elapsed = 0;
920 bool aborted = false;
921
922 reporter->Report( _( "Loading Design Block Libraries" ) );
923 adapter->AsyncLoad();
924
925 while( true )
926 {
927 if( m_libraryPreloadAbort.load() )
928 {
929 m_libraryPreloadAbort.store( false );
930 aborted = true;
931 break;
932 }
933
934 std::this_thread::sleep_for( std::chrono::milliseconds( interval ) );
935
936 if( std::optional<float> loadStatus = adapter->AsyncLoadProgress() )
937 {
938 float progress = *loadStatus;
939 reporter->SetCurrentProgress( progress );
940
941 if( progress >= 1 )
942 break;
943 }
944 else
945 {
946 reporter->SetCurrentProgress( 1 );
947 break;
948 }
949
950 elapsed += interval;
951
952 if( elapsed > timeLimit )
953 break;
954 }
955
956 // AbortAsyncLoad() sets the adapter's worker abort flag and then blocks,
957 // so workers exit at their next checkpoint. BlockUntilLoaded() alone just
958 // waits for each future to complete naturally, which can hang indefinitely
959 // if a worker is stuck on a stalled network or filesystem operation.
960 if( aborted )
961 adapter->AbortAsyncLoad();
962 else
963 adapter->BlockUntilLoaded();
964
967 m_libraryPreloadInProgress.store( false );
968
969 std::string payload = "";
970 aKiway->ExpressMail( FRAME_SCH, MAIL_RELOAD_LIB, payload, nullptr, true );
971 aKiway->ExpressMail( FRAME_PCB_EDITOR, MAIL_RELOAD_LIB, payload, nullptr, true );
972 };
973
975 m_libraryPreloadInProgress.store( true );
976 m_libraryPreloadReturn = tp.submit_task( preload );
977}
978
979
981{
982 std::lock_guard<std::mutex> lock( m_libraryLoadStatusBarsMutex );
983
984 wxLogTrace( traceLibraries, "RegisterLibraryLoadStatusBar: statusBar=%p", aStatusBar );
985
986 if( std::find( m_libraryLoadStatusBars.begin(), m_libraryLoadStatusBars.end(), aStatusBar )
987 == m_libraryLoadStatusBars.end() )
988 {
989 m_libraryLoadStatusBars.push_back( aStatusBar );
990 wxLogTrace( traceLibraries, " -> registered, total count=%zu",
992 }
993 else
994 {
995 wxLogTrace( traceLibraries, " -> already registered" );
996 }
997}
998
999
1001{
1002 std::lock_guard<std::mutex> lock( m_libraryLoadStatusBarsMutex );
1003
1004 wxLogTrace( traceLibraries, "UnregisterLibraryLoadStatusBar: statusBar=%p", aStatusBar );
1005
1007 std::remove( m_libraryLoadStatusBars.begin(), m_libraryLoadStatusBars.end(),
1008 aStatusBar ),
1010
1011 wxLogTrace( traceLibraries, " -> remaining count=%zu", m_libraryLoadStatusBars.size() );
1012}
1013
1014
1015void PGM_BASE::AddLibraryLoadMessages( const std::vector<LOAD_MESSAGE>& aMessages )
1016{
1017 wxLogTrace( traceLibraries, "AddLibraryLoadMessages: message_count=%zu", aMessages.size() );
1018
1019 if( aMessages.empty() )
1020 return;
1021
1022 std::lock_guard<std::mutex> lock( m_libraryLoadStatusBarsMutex );
1023
1024 wxLogTrace( traceLibraries, " -> registered status bars=%zu",
1025 m_libraryLoadStatusBars.size() );
1026
1027 for( KISTATUSBAR* statusBar : m_libraryLoadStatusBars )
1028 {
1029 if( statusBar )
1030 {
1031 wxLogTrace( traceLibraries, " -> forwarding to statusBar=%p", statusBar );
1032 statusBar->AddWarningMessages( "load", aMessages );
1033 }
1034 }
1035}
1036
1037
1039{
1040 std::lock_guard<std::mutex> lock( m_libraryLoadStatusBarsMutex );
1041
1042 wxLogTrace( traceLibraries, "ClearLibraryLoadMessages: status bars=%zu",
1043 m_libraryLoadStatusBars.size() );
1044
1045 for( KISTATUSBAR* statusBar : m_libraryLoadStatusBars )
1046 {
1047 if( statusBar )
1048 statusBar->ClearWarningMessages( "load" );
1049 }
1050}
1051
1052
1054
1055
1057{
1058 wxASSERT( process ); // KIFACE_GETTER has already been called.
1059 return *process;
1060}
1061
1062
1063// Similar to PGM_BASE& Pgm(), but return nullptr when a *.ki_face is run from a python script.
1065{
1066 return process;
1067}
1068
1069
1070void SetPgm( PGM_BASE* pgm )
1071{
1072 process = pgm;
1073}
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:553
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:899
int m_argcUtf8
Definition pgm_base.h:439
virtual ENV_VAR_MAP & GetLocalEnvVariables() const
Definition pgm_base.cpp:799
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:517
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.
virtual void ReadPdfBrowserInfos()
Read the PDF browser choice from the common configuration.
Definition pgm_base.cpp:885
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:814
bool IsGUI()
Determine if the application is running with a GUI.
Definition pgm_base.cpp:805
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:980
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:752
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:783
virtual void SetLanguagePath()
Definition pgm_base.cpp:735
bool SetDefaultLanguage(wxString &aErrMsg)
Set the default language without reference to any preferences.
Definition pgm_base.cpp:660
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:701
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:851
virtual wxString GetLanguageTag()
Definition pgm_base.cpp:717
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:879
void AddLibraryLoadMessages(const std::vector< LOAD_MESSAGE > &aMessages)
Add library load messages to all registered status bars.
virtual SETTINGS_MANAGER & GetSettingsManager() const
Definition pgm_base.h:124
void HideSplash()
Definition pgm_base.cpp:309
virtual void WritePdfBrowserInfos()
Save the PDF browser choice to the common configuration.
Definition pgm_base.cpp:892
void SaveCommonSettings()
Save the program (process) settings subset which are stored .kicad_common.
Definition pgm_base.cpp:544
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:559
virtual DESIGN_BLOCK_LIBRARY_ADAPTER * DesignBlockLibs()
Return the table of design block libraries.
Definition project.cpp:433
static wxString FindPythonInterpreter()
Searches for a Python intepreter on the user's system.
bool LoadProject(const wxString &aFullPath, bool aSetActive=true)
Load a project or sets up a new project with a specified path.
bool WarnUserIfOperatingSystemUnsupported()
Checks if the operating system is explicitly unsupported and displays a disclaimer message box.
Definition common.cpp:945
The common library.
void DisplayInfoMessage(wxWindow *aParent, const wxString &aMessage, const wxString &aExtraInfo)
Display an informational message box with aMessage.
Definition confirm.cpp:245
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
Definition confirm.cpp:217
This file is part of the common library.
#define _(s)
@ FRAME_PCB_EDITOR
Definition frame_type.h:38
@ FRAME_SCH
Definition frame_type.h:30
#define WIN_STRING_DIR_SEP
Definition gestfich.h: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.