33#include <wx/html/htmlwin.h>
36#include <wx/filename.h>
38#include <wx/propgrid/propgrid.h>
39#include <wx/snglinst.h>
40#include <wx/stdpaths.h>
42#include <wx/filedlg.h>
44#include <wx/tooltip.h>
61#include <python_scripting.h>
71#ifdef KICAD_USE_SENTRY
72#include <boost/uuid/uuid_io.hpp>
73#include <boost/uuid/uuid_generators.hpp>
81#include <python_manager.h>
106 wxT(
"Español (Latinoamericano)" ),
true },
119 wxT(
"Português (Brasil)" ),
true },
128 wxT(
"简体中文" ),
true },
130 wxT(
"繁體中文" ),
true },
134#define _(s) wxGetTranslation((s))
174#ifdef KICAD_USE_SENTRY
184 wxASSERT( wxTheApp );
202 if( !wxGetEnv( wxT(
"EDITOR" ), &editorname ) )
206 editorname = wxT(
"/usr/bin/open -e" );
208 editorname = wxT(
"/usr/bin/xdg-open" );
214 if( !editorname && aCanShowFileChooser )
223 if( !editorname.IsEmpty() )
236 wxString mask(
_(
"Executable file" ) + wxT(
" (*.exe)|*.exe" ) );
238 wxString mask(
_(
"Executable file" ) + wxT(
" (*)|*" ) );
244 wxFileName::SplitPath( aDefaultEditor, &
path, &
name, &ext );
248 return wxFileSelector(
_(
"Select Preferred Editor" ),
path,
name, wxT(
"." ) + ext,
249 mask, wxFD_OPEN | wxFD_FILE_MUST_EXIST,
nullptr );
253#ifdef KICAD_USE_SENTRY
254bool PGM_BASE::IsSentryOptedIn()
263 return m_sentry_optin_fn.Exists();
267void PGM_BASE::SetSentryOptIn(
bool aOptIn )
271 if( !m_sentry_uid_fn.Exists() )
276 if( !m_sentry_optin_fn.Exists() )
278 wxFFile sentryInitFile( m_sentry_optin_fn.GetFullPath(),
"w" );
279 sentryInitFile.Write(
"" );
280 sentryInitFile.Close();
285 if( m_sentry_optin_fn.Exists() )
287 wxRemoveFile( m_sentry_optin_fn.GetFullPath() );
294wxString PGM_BASE::sentryCreateUid()
296 boost::uuids::uuid uuid = boost::uuids::random_generator()();
297 wxString userGuid = boost::uuids::to_string( uuid );
299 wxFFile sentryInitFile( m_sentry_uid_fn.GetFullPath(),
"w" );
300 sentryInitFile.Write( userGuid );
301 sentryInitFile.Close();
307void PGM_BASE::ResetSentryId()
309 m_sentryUid = sentryCreateUid();
313const wxString& PGM_BASE::GetSentryId()
319void PGM_BASE::sentryInit()
324 if( IsSentryOptedIn() )
326 wxFFile sentryInitFile( m_sentry_uid_fn.GetFullPath() );
327 sentryInitFile.ReadAll( &m_sentryUid );
328 sentryInitFile.Close();
330 if( m_sentryUid.IsEmpty() || m_sentryUid.length() != 36 )
332 m_sentryUid = sentryCreateUid();
335 sentry_options_t* options = sentry_options_new();
337#ifndef KICAD_SENTRY_DSN
338# error "Project configuration error, missing KICAD_SENTRY_DSN"
341 sentry_options_set_dsn( options, KICAD_SENTRY_DSN );
345 tmp.AppendDir(
"sentry" );
348 sentry_options_set_database_pathw( options, tmp.GetPathWithSep().wc_str() );
350 sentry_options_set_database_path( options, tmp.GetPathWithSep().c_str() );
352 sentry_options_set_symbolize_stacktraces( options,
true );
353 sentry_options_set_auto_session_tracking( options,
false );
355 sentry_options_set_release( options,
GetCommitHash().ToStdString().c_str() );
361 sentry_init( options );
363 sentry_value_t user = sentry_value_new_object();
364 sentry_value_set_by_key( user,
"id", sentry_value_new_string( m_sentryUid.c_str() ) );
365 sentry_set_user( user );
367 sentry_set_tag(
"kicad.version",
GetBuildVersion().ToStdString().c_str() );
372void PGM_BASE::sentryPrompt()
381 && !
m_settings_manager->GetCommonSettings()->m_DoNotShowAgain.data_collection_prompt )
383 wxMessageDialog optIn = wxMessageDialog(
385 _(
"KiCad can anonymously report crashes and special event "
386 "data to developers in order to aid identifying critical bugs "
387 "across the user base more effectively and help profile "
388 "functionality to guide improvements. \n"
389 "If you choose to voluntarily participate, KiCad will automatically "
390 "handle sending said reports when crashes or events occur. \n"
391 "Your design files such as schematic or PCB are not shared in this process." ),
392 _(
"Data collection opt in request" ), wxYES_NO | wxCENTRE );
394 int result = optIn.ShowModal();
396 if( result == wxID_YES )
398 SetSentryOptIn(
true );
403 SetSentryOptIn(
false );
406 m_settings_manager->GetCommonSettings()->m_DoNotShowAgain.data_collection_prompt =
true;
414 const wxArrayString& argArray =
App().argv.GetArguments();
420 m_argvUtf8[n] = wxStrdup( argArray[n].ToUTF8() );
439 NULL, -1, wxDefaultPosition, wxDefaultSize,
440 wxBORDER_NONE | wxSTAY_ON_TOP );
459#if defined( __WXMAC__ )
472#ifdef KICAD_USE_SENTRY
482 if(
App().argc == 0 )
483 pgm_name = wxT(
"kicad" );
485 pgm_name = wxFileName(
App().argv[0] ).GetName().Lower();
487#ifdef KICAD_USE_SENTRY
488 sentry_set_tag(
"kicad.app", pgm_name.c_str() );
491 wxInitAllImageHandlers();
495 wxPGInitResourceModule();
498 if( wxString( wxGetenv(
"HOME" ) ).IsEmpty() )
501 "Unable to continue." ) );
512 wxChmod( instanceCheckerDir,
513 wxPOSIX_USER_READ | wxPOSIX_USER_WRITE | wxPOSIX_USER_EXECUTE |
514 wxPOSIX_GROUP_READ | wxPOSIX_GROUP_WRITE | wxPOSIX_GROUP_EXECUTE |
515 wxPOSIX_OTHERS_READ | wxPOSIX_OTHERS_WRITE | wxPOSIX_OTHERS_EXECUTE );
517 wxString instanceCheckerName = wxString::Format( wxS(
"%s-%s" ), pgm_name,
521 m_pgm_checker->Create( instanceCheckerName, instanceCheckerDir );
526 bool isDefined = wxGetEnv( wxT(
"KICAD" ), &
m_kicad_env );
537 App().SetVendorName( wxT(
"KiCad" ) );
538 App().SetAppName( pgm_name );
541 if( wxImage::FindHandler( wxBITMAP_TYPE_PNG ) ==
nullptr )
542 wxImage::AddHandler(
new wxPNGHandler );
544 if( wxImage::FindHandler( wxBITMAP_TYPE_GIF ) ==
nullptr )
545 wxImage::AddHandler(
new wxGIFHandler );
547 if( wxImage::FindHandler( wxBITMAP_TYPE_JPEG ) ==
nullptr )
548 wxImage::AddHandler(
new wxJPEGHandler );
550 wxFileSystem::AddHandler(
new wxZipFSHandler );
558 if( !wxGetEnv(
"FONTCONFIG_PATH", NULL ) )
564 wxSetEnv(
"FONTCONFIG_PATH", PATHS::GetWindowsFontConfigDir() );
573 m_plugin_manager = std::make_unique<API_PLUGIN_MANAGER>( &
App() );
612#ifdef KICAD_USE_SENTRY
631 m_plugin_manager->ReloadPlugins();
638 wxToolTip::Enable(
true );
639 wxToolTip::SetAutoPop( 10000 );
657 for(
const std::pair<wxString, ENV_VAR_ITEM> it :
GetCommonSettings()->m_Env.vars )
659 wxLogTrace(
traceEnvVars, wxT(
"PGM_BASE::loadSettings: Found entry %s = %s" ),
660 it.first, it.second.GetValue() );
668 if( it.first.IsEmpty() )
672 if( it.second.GetDefinedExternally() )
720 wxString dictionaryName( wxT(
"kicad" ) );
729 wxLogTrace(
traceLocale, wxT(
"This language is not supported by the system." ) );
735 m_locale->Init( wxLANGUAGE_DEFAULT );
737 aErrMsg =
_(
"This language is not supported by the operating system." );
740 else if( !first_time )
742 wxLogTrace(
traceLocale, wxT(
"Search for dictionary %s.mo in %s" ) ,
743 dictionaryName,
m_locale->GetName() );
752 wxString languageSel;
770 if( !
m_locale->IsLoaded( dictionaryName ) )
771 m_locale->AddCatalog( dictionaryName );
779 wxLogTrace(
traceLocale, wxT(
"Unable to load dictionary %s.mo in %s" ),
780 dictionaryName,
m_locale->GetName() );
786 m_locale->Init( wxLANGUAGE_DEFAULT );
788 aErrMsg =
_(
"The KiCad language file for this language is not installed." );
804 wxString dictionaryName( wxT(
"kicad" ) );
811 if( !
m_locale->IsLoaded( dictionaryName ) )
812 m_locale->AddCatalog( dictionaryName );
820 wxLogTrace(
traceLocale, wxT(
"Unable to load dictionary %s.mo in %s" ),
821 dictionaryName,
m_locale->GetName() );
829 aErrMsg =
_(
"The KiCad language file for this language is not installed." );
839 wxLogTrace(
traceLocale, wxT(
"Select language ID %d from %d possible languages." ),
855 const wxLanguageInfo* langInfo = wxLocale::GetLanguageInfo(
m_language_id );
863 wxString str = langInfo->GetCanonicalWithRegion();
864 str.Replace(
"_",
"-" );
874 wxLocale::AddCatalogLookupPathPrefix( PATHS::GetWindowsBaseSharePath() + wxT(
"locale" ) );
878 if( wxGetEnv( wxT(
"KICAD_RUN_FROM_BUILD_DIR" ),
nullptr ) )
882 fn.AppendDir( wxT(
"translation" ) );
883 wxLocale::AddCatalogLookupPathPrefix( fn.GetPath() );
892 if( aName.IsEmpty() )
895 wxT(
"PGM_BASE::SetLocalEnvVariable: Attempt to set empty variable to "
902 if( wxGetEnv( aName, &env ) )
905 wxT(
"PGM_BASE::SetLocalEnvVariable: Environment variable %s already set "
908 return env == aValue;
912 wxT(
"PGM_BASE::SetLocalEnvVariable: Setting local environment variable %s to %s" ),
915 return wxSetEnv( aName, aValue );
923 for(
const std::pair<wxString, ENV_VAR_ITEM> m_local_env_var :
GetCommonSettings()->m_Env.vars )
926 wxT(
"PGM_BASE::SetLocalEnvVariables: Setting local environment variable %s "
928 m_local_env_var.first,
929 m_local_env_var.second.GetValue() );
930 wxSetEnv( m_local_env_var.first, m_local_env_var.second.GetValue() );
946 return wxTheApp->IsGUI();
955 std::rethrow_exception( aPtr );
959 wxLogError( ioe.
What() );
961 catch(
const std::exception& e )
963#ifdef KICAD_USE_SENTRY
964 if( IsSentryOptedIn() )
966 sentry_value_t exc = sentry_value_new_exception(
"exception", e.what() );
967 sentry_value_set_stacktrace( exc, NULL, 0 );
969 sentry_value_t sentryEvent = sentry_value_new_event();
970 sentry_event_add_exception( sentryEvent, exc );
971 sentry_capture_event( sentryEvent );
975 wxLogError( wxT(
"Unhandled exception class: %s what: %s" ),
980 wxLogError( wxT(
"Unhandled exception of unknown type" ) );
985#ifdef KICAD_USE_SENTRY
986struct SENTRY_ASSERT_CACHE_KEY
996bool operator<(
const SENTRY_ASSERT_CACHE_KEY& aKey1,
const SENTRY_ASSERT_CACHE_KEY& aKey2 )
998 return aKey1.file < aKey2.file ||
999 aKey1.line < aKey2.line ||
1000 aKey1.func < aKey2.func ||
1001 aKey1.cond < aKey2.cond ||
1002 aKey1.msg < aKey2.msg;
1008 const wxString& aCond,
const wxString& aMsg )
1015 assertStr = wxString::Format(
"Assertion failed at %s:%d in %s: %s - %s", aFile, aLine,
1016 aFunc, aCond, aMsg );
1020 assertStr = wxString::Format(
"Assertion failed at %s:%d in %s: %s", aFile, aLine, aFunc,
1025 wxLogError( assertStr );
1028#ifdef KICAD_USE_SENTRY
1029 if( IsSentryOptedIn() )
1031 static std::set<SENTRY_ASSERT_CACHE_KEY> assertCache;
1033 SENTRY_ASSERT_CACHE_KEY key = { aFile, aLine, aFunc, aCond };
1035 if( assertCache.find( key ) == assertCache.end() )
1037 sentry_value_t exc = sentry_value_new_exception(
"assert", assertStr );
1038 sentry_value_set_stacktrace( exc, NULL, 0 );
1040 sentry_value_t sentryEvent = sentry_value_new_event();
1041 sentry_event_add_exception( sentryEvent, exc );
1042 sentry_capture_event( sentryEvent );
1043 assertCache.insert( key );
constexpr std::size_t arrayDim(T const (&)[N]) noexcept
Returns # of elements in an array.
wxBitmap KiBitmap(BITMAPS aBitmap, int aHeightTag)
Construct a wxBitmap from an image identifier Returns the image from the active theme if the image ha...
wxString GetMajorMinorVersion()
Get only the major and minor version in a string major.minor.
wxString GetCommitHash()
Get the commit hash as a string.
wxString GetBuildVersion()
Get the full KiCad version string.
static const ADVANCED_CFG & GetCfg()
Get the singleton instance's config, which is shared by all consumers.
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.
void Load()
Load notifications stored from disk.
static wxString GetInstanceCheckerPath()
Gets the path used for wxSingleInstanceChecker lock files.
static void EnsureUserPathsExist()
Ensures/creates user default paths.
static bool EnsurePathExists(const wxString &aPath, bool aPathToFile=false)
Attempts to create a given path if it does not exist.
static wxString GetUserCachePath()
Gets the stock (install) 3d viewer plugins path.
static wxString GetLocaleDataPath()
Gets the locales translation data path.
static const wxString & GetExecutablePath()
Container for data for KiCad programs.
virtual COMMON_SETTINGS * GetCommonSettings() const
virtual wxApp & App()
Return a bare naked wxApp which may come from wxPython, SINGLE_TOP, or kicad.exe.
std::unique_ptr< NOTIFICATIONS_MANAGER > m_notifications_manager
virtual ENV_VAR_MAP & GetLocalEnvVariables() const
bool m_Printing
wxWidgets on MSW tends to crash if you spool up more than one print job at a time.
void setLanguageId(int aId)
Trap all changes in here, simplifies debugging.
std::unique_ptr< SETTINGS_MANAGER > m_settings_manager
void loadCommonSettings()
Load internal settings from COMMON_SETTINGS.
virtual void SetPdfBrowserName(const wxString &aFileName)
wxSplashScreen * m_splash
bool InitPgm(bool aHeadless=false, bool aSkipPyInit=false, bool aIsUnitTest=false)
Initialize this program.
char ** m_argvUtf8
argv parameters converted to utf8 form because wxWidgets has opinions.
virtual void ReadPdfBrowserInfos()
Read the PDF browser choice from the common configuration.
bool IsGUI()
Determine if the application is running with a GUI.
bool m_use_system_pdf_browser
virtual NOTIFICATIONS_MANAGER & GetNotificationsManager() const
void BuildArgvUtf8()
Builds the UTF8 based argv variable.
virtual const wxString & GetPdfBrowserName() const
virtual void SetTextEditor(const wxString &aFileName)
std::unique_ptr< wxSingleInstanceChecker > m_pgm_checker
Check if there is another copy of Kicad running at the same time.
virtual bool SetLocalEnvVariable(const wxString &aName, const wxString &aValue)
Set the environment variable aName to aValue.
wxString m_kicad_env
The KICAD system environment variable.
virtual void ForceSystemPdfBrowser(bool aFlg)
Force the use of system PDF browser, even if a preferred PDF browser is set.
virtual void SetLocalEnvVariables()
Update the local environment with the contents of the current ENV_VAR_MAP stored in the COMMON_SETTIN...
virtual void SetLanguagePath()
bool SetDefaultLanguage(wxString &aErrMsg)
Set the default language without reference to any preferences.
std::unique_ptr< SCRIPTING > m_python_scripting
virtual void SetLanguageIdentifier(int menu_id)
Set in .m_language_id member the wxWidgets language identifier ID from the KiCad menu id (internal me...
std::unique_ptr< BACKGROUND_JOBS_MONITOR > m_background_jobs_monitor
void HandleException(std::exception_ptr aPtr)
A exception handler to be used at the top level if exceptions bubble up that for.
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.
virtual wxString GetLanguageTag()
virtual const wxString & GetTextEditor(bool aCanShowFileChooser=true)
Return the path to the preferred text editor application.
virtual const wxString & GetExecutablePath() const
virtual SETTINGS_MANAGER & GetSettingsManager() const
virtual void WritePdfBrowserInfos()
Save the PDF browser choice to the common configuration.
void SaveCommonSettings()
Save the program (process) settings subset which are stored .kicad_common.
bool m_PropertyGridInitialized
KICAD_SINGLETON m_singleton
virtual const wxString AskUserForPreferredEditor(const wxString &aDefaultEditor=wxEmptyString)
Show a dialog that instructs the user to select a new preferred editor.
virtual bool SetLanguage(wxString &aErrMsg, bool first_time=false)
Set the dictionary file name for internationalization.
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.
void DisplayInfoMessage(wxWindow *aParent, const wxString &aMessage, const wxString &aExtraInfo)
Display an informational message box with aMessage.
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
This file is part of the common library.
bool operator<(const DESIGN_BLOCK_INFO &lhs, const DESIGN_BLOCK_INFO &rhs)
#define WIN_STRING_DIR_SEP
#define UNIX_STRING_DIR_SEP
const wxChar *const traceLocale
Flag to enable locale debug output.
const wxChar *const traceEnvVars
Flag to enable debug output of environment variable operations.
Common command IDs shared by more than one of the KiCad applications.
@ ID_LANGUAGE_CHINESE_SIMPLIFIED
@ ID_LANGUAGE_PORTUGUESE_BRAZILIAN
@ ID_LANGUAGE_SPANISH_MEXICAN
@ ID_LANGUAGE_CHINESE_TRADITIONAL
std::map< wxString, ENV_VAR_ITEM > ENV_VAR_MAP
This file contains miscellaneous commonly used macros and functions.
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.
#define _(s)
Current list of languages supported by KiCad.
KICOMMON_API LANGUAGE_DESCR LanguagesList[]
An array containing all the languages that KiCad supports.
KICOMMON_API PGM_BASE & Pgm()
The global program "get" accessor.
#define POLICY_KEY_DATACOLLECTION
#define PROJECT_VAR_NAME
A variable name whose value holds the current project directory.
APIIMPORT wxPGGlobalVarsClass * wxPGGlobalVars
wxString From_UTF8(const char *cstring)
wxString python_interpreter
bool use_system_pdf_viewer
A small class to handle the list of existing translations.
int m_KI_Lang_Identifier
KiCad identifier used in menu selection (See id.h)
wxString m_Lang_Label
Labels used in menus.
System directories search utilities.
wxLogTrace helper definitions.