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
478 if(
App().argc == 0 )
479 pgm_name = wxT(
"kicad" );
481 pgm_name = wxFileName(
App().argv[0] ).GetName().Lower();
483#ifdef KICAD_USE_SENTRY
484 sentry_set_tag(
"kicad.app", pgm_name.c_str() );
487 wxInitAllImageHandlers();
491 wxPGInitResourceModule();
494 if( wxString( wxGetenv(
"HOME" ) ).IsEmpty() )
497 "Unable to continue." ) );
508 wxChmod( instanceCheckerDir, wxPOSIX_USER_READ | wxPOSIX_USER_WRITE | wxPOSIX_USER_EXECUTE |
509 wxPOSIX_GROUP_READ | wxPOSIX_GROUP_WRITE | wxPOSIX_GROUP_EXECUTE |
510 wxPOSIX_OTHERS_READ | wxPOSIX_OTHERS_WRITE | wxPOSIX_OTHERS_EXECUTE );
512 wxString instanceCheckerName = wxString::Format( wxS(
"%s-%s" ), pgm_name,
516 m_pgm_checker->Create( instanceCheckerName, instanceCheckerDir );
521 bool isDefined = wxGetEnv( wxT(
"KICAD" ), &
m_kicad_env );
532 App().SetVendorName( wxT(
"KiCad" ) );
533 App().SetAppName( pgm_name );
536 if( wxImage::FindHandler( wxBITMAP_TYPE_PNG ) ==
nullptr )
537 wxImage::AddHandler(
new wxPNGHandler );
539 if( wxImage::FindHandler( wxBITMAP_TYPE_GIF ) ==
nullptr )
540 wxImage::AddHandler(
new wxGIFHandler );
542 if( wxImage::FindHandler( wxBITMAP_TYPE_JPEG ) ==
nullptr )
543 wxImage::AddHandler(
new wxJPEGHandler );
545 wxFileSystem::AddHandler(
new wxZipFSHandler );
556 wxSetEnv(
"FONTCONFIG_PATH", PATHS::GetWindowsFontConfigDir() );
564 m_plugin_manager = std::make_unique<API_PLUGIN_MANAGER>( &
App() );
603#ifdef KICAD_USE_SENTRY
621 m_plugin_manager->ReloadPlugins();
628 wxToolTip::Enable(
true );
629 wxToolTip::SetAutoPop( 10000 );
647 for(
const std::pair<wxString, ENV_VAR_ITEM> it :
GetCommonSettings()->m_Env.vars )
649 wxLogTrace(
traceEnvVars, wxT(
"PGM_BASE::loadSettings: Found entry %s = %s" ),
650 it.first, it.second.GetValue() );
658 if( it.first.IsEmpty() )
662 if( it.second.GetDefinedExternally() )
710 wxString dictionaryName( wxT(
"kicad" ) );
719 wxLogTrace(
traceLocale, wxT(
"This language is not supported by the system." ) );
725 m_locale->Init( wxLANGUAGE_DEFAULT );
727 aErrMsg =
_(
"This language is not supported by the operating system." );
730 else if( !first_time )
732 wxLogTrace(
traceLocale, wxT(
"Search for dictionary %s.mo in %s" ) ,
733 dictionaryName,
m_locale->GetName() );
742 wxString languageSel;
760 if( !
m_locale->IsLoaded( dictionaryName ) )
761 m_locale->AddCatalog( dictionaryName );
769 wxLogTrace(
traceLocale, wxT(
"Unable to load dictionary %s.mo in %s" ),
770 dictionaryName,
m_locale->GetName() );
776 m_locale->Init( wxLANGUAGE_DEFAULT );
778 aErrMsg =
_(
"The KiCad language file for this language is not installed." );
794 wxString dictionaryName( wxT(
"kicad" ) );
801 if( !
m_locale->IsLoaded( dictionaryName ) )
802 m_locale->AddCatalog( dictionaryName );
810 wxLogTrace(
traceLocale, wxT(
"Unable to load dictionary %s.mo in %s" ),
811 dictionaryName,
m_locale->GetName() );
819 aErrMsg =
_(
"The KiCad language file for this language is not installed." );
829 wxLogTrace(
traceLocale, wxT(
"Select language ID %d from %d possible languages." ),
845 const wxLanguageInfo* langInfo = wxLocale::GetLanguageInfo(
m_language_id );
851 wxString str = langInfo->GetCanonicalWithRegion();
852 str.Replace(
"_",
"-" );
862 wxLocale::AddCatalogLookupPathPrefix( PATHS::GetWindowsBaseSharePath()
867 if( wxGetEnv( wxT(
"KICAD_RUN_FROM_BUILD_DIR" ),
nullptr ) )
871 fn.AppendDir( wxT(
"translation" ) );
872 wxLocale::AddCatalogLookupPathPrefix( fn.GetPath() );
881 if( aName.IsEmpty() )
884 wxT(
"PGM_BASE::SetLocalEnvVariable: Attempt to set empty variable to "
891 if( wxGetEnv( aName, &env ) )
894 wxT(
"PGM_BASE::SetLocalEnvVariable: Environment variable %s already set "
897 return env == aValue;
901 wxT(
"PGM_BASE::SetLocalEnvVariable: Setting local environment variable %s to %s" ),
904 return wxSetEnv( aName, aValue );
912 for(
const std::pair<wxString, ENV_VAR_ITEM> m_local_env_var :
GetCommonSettings()->m_Env.vars )
915 wxT(
"PGM_BASE::SetLocalEnvVariables: Setting local environment variable %s "
917 m_local_env_var.first,
918 m_local_env_var.second.GetValue() );
919 wxSetEnv( m_local_env_var.first, m_local_env_var.second.GetValue() );
935 return wxTheApp->IsGUI();
944 std::rethrow_exception( aPtr );
948 wxLogError( ioe.
What() );
950 catch(
const std::exception& e )
952#ifdef KICAD_USE_SENTRY
953 if( IsSentryOptedIn() )
955 sentry_value_t exc = sentry_value_new_exception(
"exception", e.what() );
956 sentry_value_set_stacktrace( exc, NULL, 0 );
958 sentry_value_t sentryEvent = sentry_value_new_event();
959 sentry_event_add_exception( sentryEvent, exc );
960 sentry_capture_event( sentryEvent );
964 wxLogError( wxT(
"Unhandled exception class: %s what: %s" ),
969 wxLogError( wxT(
"Unhandled exception of unknown type" ) );
974#ifdef KICAD_USE_SENTRY
975struct SENTRY_ASSERT_CACHE_KEY
985bool operator<(
const SENTRY_ASSERT_CACHE_KEY& aKey1,
const SENTRY_ASSERT_CACHE_KEY& aKey2 )
987 return aKey1.file < aKey2.file ||
988 aKey1.line < aKey2.line ||
989 aKey1.func < aKey2.func ||
990 aKey1.cond < aKey2.cond ||
991 aKey1.msg < aKey2.msg;
997 const wxString& aCond,
const wxString& aMsg )
1004 assertStr = wxString::Format(
"Assertion failed at %s:%d in %s: %s - %s", aFile, aLine,
1005 aFunc, aCond, aMsg );
1009 assertStr = wxString::Format(
"Assertion failed at %s:%d in %s: %s", aFile, aLine, aFunc,
1014 wxLogError( assertStr );
1017#ifdef KICAD_USE_SENTRY
1018 if( IsSentryOptedIn() )
1020 static std::set<SENTRY_ASSERT_CACHE_KEY> assertCache;
1022 SENTRY_ASSERT_CACHE_KEY key = { aFile, aLine, aFunc, aCond };
1024 if( assertCache.find( key ) == assertCache.end() )
1026 sentry_value_t exc = sentry_value_new_exception(
"assert", assertStr );
1027 sentry_value_set_stacktrace( exc, NULL, 0 );
1029 sentry_value_t sentryEvent = sentry_value_new_event();
1030 sentry_event_add_exception( sentryEvent, exc );
1031 sentry_capture_event( sentryEvent );
1032 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()
Loads 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)
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()
Returns a bare naked wxApp which may come from wxPython, SINGLE_TOP, or kicad.exe.
std::unique_ptr< NOTIFICATIONS_MANAGER > m_notifications_manager
int m_argcUtf8
argv parameters converted to utf8 form, because wxwidgets has opinions and will return argv as either...
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()
Loads internal settings from COMMON_SETTINGS.
virtual void SetPdfBrowserName(const wxString &aFileName)
wxLocale * m_locale
The KICAD system environment variable.
wxSplashScreen * m_splash
bool InitPgm(bool aHeadless=false, bool aSkipPyInit=false, bool aIsUnitTest=false)
Initialize this program.
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
Checks if there is another copy of Kicad running at the same time.
virtual bool SetLocalEnvVariable(const wxString &aName, const wxString &aValue)
Sets the environment variable aName to aValue.
virtual void ForceSystemPdfBrowser(bool aFlg)
Force the use of system PDF browser, even if a preferred PDF browser is set.
virtual void SetLocalEnvVariables()
Updates the local environment with the contents of the current ENV_VAR_MAP stored in the COMMON_SETTI...
virtual void SetLanguagePath()
bool SetDefaultLanguage(wxString &aErrMsg)
Set the default language without reference to any preferences.
wxString m_text_editor
Filename of the app selected for browsing PDFs.
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
virtual const wxString AskUserForPreferredEditor(const wxString &aDefaultEditor=wxEmptyString)
Shows 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)
Loads 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.
@ 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()
similar to PGM_BASE& Pgm(), but return a reference that can be nullptr when running a shared lib from...
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.