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