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 },
118 wxT(
"Português (Brasil)" ),
true },
127 wxT(
"简体中文" ),
true },
129 wxT(
"繁體中文" ),
true },
133#define _(s) wxGetTranslation((s))
173#ifdef KICAD_USE_SENTRY
183 wxASSERT( wxTheApp );
201 if( !wxGetEnv( wxT(
"EDITOR" ), &editorname ) )
205 editorname = wxT(
"/usr/bin/open -e" );
207 editorname = wxT(
"/usr/bin/xdg-open" );
213 if( !editorname && aCanShowFileChooser )
222 if( !editorname.IsEmpty() )
235 wxString mask(
_(
"Executable file" ) + wxT(
" (*.exe)|*.exe" ) );
237 wxString mask(
_(
"Executable file" ) + wxT(
" (*)|*" ) );
243 wxFileName::SplitPath( aDefaultEditor, &
path, &
name, &ext );
247 return wxFileSelector(
_(
"Select Preferred Editor" ),
path,
name, wxT(
"." ) + ext,
248 mask, wxFD_OPEN | wxFD_FILE_MUST_EXIST,
nullptr );
252#ifdef KICAD_USE_SENTRY
253bool PGM_BASE::IsSentryOptedIn()
262 return m_sentry_optin_fn.Exists();
266void PGM_BASE::SetSentryOptIn(
bool aOptIn )
270 if( !m_sentry_uid_fn.Exists() )
275 if( !m_sentry_optin_fn.Exists() )
277 wxFFile sentryInitFile( m_sentry_optin_fn.GetFullPath(),
"w" );
278 sentryInitFile.Write(
"" );
279 sentryInitFile.Close();
284 if( m_sentry_optin_fn.Exists() )
286 wxRemoveFile( m_sentry_optin_fn.GetFullPath() );
293wxString PGM_BASE::sentryCreateUid()
295 boost::uuids::uuid uuid = boost::uuids::random_generator()();
296 wxString userGuid = boost::uuids::to_string( uuid );
298 wxFFile sentryInitFile( m_sentry_uid_fn.GetFullPath(),
"w" );
299 sentryInitFile.Write( userGuid );
300 sentryInitFile.Close();
306void PGM_BASE::ResetSentryId()
308 m_sentryUid = sentryCreateUid();
312const wxString& PGM_BASE::GetSentryId()
318void PGM_BASE::sentryInit()
323 if( IsSentryOptedIn() )
325 wxFFile sentryInitFile( m_sentry_uid_fn.GetFullPath() );
326 sentryInitFile.ReadAll( &m_sentryUid );
327 sentryInitFile.Close();
329 if( m_sentryUid.IsEmpty() || m_sentryUid.length() != 36 )
331 m_sentryUid = sentryCreateUid();
334 sentry_options_t* options = sentry_options_new();
336 #ifndef KICAD_SENTRY_DSN
337 # error "Project configuration error, missing KICAD_SENTRY_DSN"
340 sentry_options_set_dsn( options, KICAD_SENTRY_DSN );
344 tmp.AppendDir(
"sentry" );
347 sentry_options_set_database_pathw( options, tmp.GetPathWithSep().wc_str() );
349 sentry_options_set_database_path( options, tmp.GetPathWithSep().c_str() );
351 sentry_options_set_symbolize_stacktraces( options,
true );
352 sentry_options_set_auto_session_tracking( options,
false );
354 sentry_options_set_release( options,
GetCommitHash().ToStdString().c_str() );
360 sentry_init( options );
362 sentry_value_t user = sentry_value_new_object();
363 sentry_value_set_by_key( user,
"id", sentry_value_new_string( m_sentryUid.c_str() ) );
364 sentry_set_user( user );
366 sentry_set_tag(
"kicad.version",
GetBuildVersion().ToStdString().c_str() );
371void PGM_BASE::sentryPrompt()
380 && !
m_settings_manager->GetCommonSettings()->m_DoNotShowAgain.data_collection_prompt )
382 wxMessageDialog optIn = wxMessageDialog(
384 _(
"KiCad can anonymously report crashes and special event "
385 "data to developers in order to aid identifying critical bugs "
386 "across the user base more effectively and help profile "
387 "functionality to guide improvements. \n"
388 "If you choose to voluntarily participate, KiCad will automatically "
389 "handle sending said reports when crashes or events occur. \n"
390 "Your design files such as schematic or PCB are not shared in this process." ),
391 _(
"Data collection opt in request" ), wxYES_NO | wxCENTRE );
393 int result = optIn.ShowModal();
395 if( result == wxID_YES )
397 SetSentryOptIn(
true );
402 SetSentryOptIn(
false );
405 m_settings_manager->GetCommonSettings()->m_DoNotShowAgain.data_collection_prompt =
true;
413 const wxArrayString& argArray =
App().argv.GetArguments();
419 m_argvUtf8[n] = wxStrdup( argArray[n].ToUTF8() );
438 NULL, -1, wxDefaultPosition, wxDefaultSize,
439 wxBORDER_NONE | wxSTAY_ON_TOP );
458#if defined( __WXMAC__ )
471#ifdef KICAD_USE_SENTRY
477 if(
App().argc == 0 )
478 pgm_name = wxT(
"kicad" );
480 pgm_name = wxFileName(
App().argv[0] ).GetName().Lower();
482#ifdef KICAD_USE_SENTRY
483 sentry_set_tag(
"kicad.app", pgm_name.c_str() );
486 wxInitAllImageHandlers();
490 wxPGInitResourceModule();
493 if( wxString( wxGetenv(
"HOME" ) ).IsEmpty() )
496 "Unable to continue." ) );
507 wxChmod( instanceCheckerDir, wxPOSIX_USER_READ | wxPOSIX_USER_WRITE | wxPOSIX_USER_EXECUTE |
508 wxPOSIX_GROUP_READ | wxPOSIX_GROUP_WRITE | wxPOSIX_GROUP_EXECUTE |
509 wxPOSIX_OTHERS_READ | wxPOSIX_OTHERS_WRITE | wxPOSIX_OTHERS_EXECUTE );
511 wxString instanceCheckerName = wxString::Format( wxS(
"%s-%s" ), pgm_name,
515 m_pgm_checker->Create( instanceCheckerName, instanceCheckerDir );
520 bool isDefined = wxGetEnv( wxT(
"KICAD" ), &
m_kicad_env );
531 App().SetVendorName( wxT(
"KiCad" ) );
532 App().SetAppName( pgm_name );
535 if( wxImage::FindHandler( wxBITMAP_TYPE_PNG ) ==
nullptr )
536 wxImage::AddHandler(
new wxPNGHandler );
538 if( wxImage::FindHandler( wxBITMAP_TYPE_GIF ) ==
nullptr )
539 wxImage::AddHandler(
new wxGIFHandler );
541 if( wxImage::FindHandler( wxBITMAP_TYPE_JPEG ) ==
nullptr )
542 wxImage::AddHandler(
new wxJPEGHandler );
544 wxFileSystem::AddHandler(
new wxZipFSHandler );
555 wxSetEnv(
"FONTCONFIG_PATH", PATHS::GetWindowsFontConfigDir() );
563 m_plugin_manager = std::make_unique<API_PLUGIN_MANAGER>( &
App() );
602#ifdef KICAD_USE_SENTRY
620 m_plugin_manager->ReloadPlugins();
627 wxToolTip::Enable(
true );
628 wxToolTip::SetAutoPop( 10000 );
646 for(
const std::pair<wxString, ENV_VAR_ITEM> it :
GetCommonSettings()->m_Env.vars )
648 wxLogTrace(
traceEnvVars, wxT(
"PGM_BASE::loadSettings: Found entry %s = %s" ),
649 it.first, it.second.GetValue() );
657 if( it.first.IsEmpty() )
661 if( it.second.GetDefinedExternally() )
709 wxString dictionaryName( wxT(
"kicad" ) );
718 wxLogTrace(
traceLocale, wxT(
"This language is not supported by the system." ) );
724 m_locale->Init( wxLANGUAGE_DEFAULT );
726 aErrMsg =
_(
"This language is not supported by the operating system." );
729 else if( !first_time )
731 wxLogTrace(
traceLocale, wxT(
"Search for dictionary %s.mo in %s" ) ,
732 dictionaryName,
m_locale->GetName() );
741 wxString languageSel;
759 if( !
m_locale->IsLoaded( dictionaryName ) )
760 m_locale->AddCatalog( dictionaryName );
768 wxLogTrace(
traceLocale, wxT(
"Unable to load dictionary %s.mo in %s" ),
769 dictionaryName,
m_locale->GetName() );
775 m_locale->Init( wxLANGUAGE_DEFAULT );
777 aErrMsg =
_(
"The KiCad language file for this language is not installed." );
793 wxString dictionaryName( wxT(
"kicad" ) );
800 if( !
m_locale->IsLoaded( dictionaryName ) )
801 m_locale->AddCatalog( dictionaryName );
809 wxLogTrace(
traceLocale, wxT(
"Unable to load dictionary %s.mo in %s" ),
810 dictionaryName,
m_locale->GetName() );
818 aErrMsg =
_(
"The KiCad language file for this language is not installed." );
828 wxLogTrace(
traceLocale, wxT(
"Select language ID %d from %d possible languages." ),
844 const wxLanguageInfo* langInfo = wxLocale::GetLanguageInfo(
m_language_id );
850 wxString str = langInfo->GetCanonicalWithRegion();
851 str.Replace(
"_",
"-" );
861 wxLocale::AddCatalogLookupPathPrefix( PATHS::GetWindowsBaseSharePath()
866 if( wxGetEnv( wxT(
"KICAD_RUN_FROM_BUILD_DIR" ),
nullptr ) )
870 fn.AppendDir( wxT(
"translation" ) );
871 wxLocale::AddCatalogLookupPathPrefix( fn.GetPath() );
880 if( aName.IsEmpty() )
883 wxT(
"PGM_BASE::SetLocalEnvVariable: Attempt to set empty variable to "
890 if( wxGetEnv( aName, &env ) )
893 wxT(
"PGM_BASE::SetLocalEnvVariable: Environment variable %s already set "
896 return env == aValue;
900 wxT(
"PGM_BASE::SetLocalEnvVariable: Setting local environment variable %s to %s" ),
903 return wxSetEnv( aName, aValue );
911 for(
const std::pair<wxString, ENV_VAR_ITEM> m_local_env_var :
GetCommonSettings()->m_Env.vars )
914 wxT(
"PGM_BASE::SetLocalEnvVariables: Setting local environment variable %s "
916 m_local_env_var.first,
917 m_local_env_var.second.GetValue() );
918 wxSetEnv( m_local_env_var.first, m_local_env_var.second.GetValue() );
934 return wxTheApp->IsGUI();
943 std::rethrow_exception( aPtr );
947 wxLogError( ioe.
What() );
949 catch(
const std::exception& e )
951#ifdef KICAD_USE_SENTRY
952 if( IsSentryOptedIn() )
954 sentry_value_t exc = sentry_value_new_exception(
"exception", e.what() );
955 sentry_value_set_stacktrace( exc, NULL, 0 );
957 sentry_value_t sentryEvent = sentry_value_new_event();
958 sentry_event_add_exception( sentryEvent, exc );
959 sentry_capture_event( sentryEvent );
963 wxLogError( wxT(
"Unhandled exception class: %s what: %s" ),
968 wxLogError( wxT(
"Unhandled exception of unknown type" ) );
973#ifdef KICAD_USE_SENTRY
974struct SENTRY_ASSERT_CACHE_KEY
984bool operator<(
const SENTRY_ASSERT_CACHE_KEY& aKey1,
const SENTRY_ASSERT_CACHE_KEY& aKey2 )
986 return aKey1.file < aKey2.file ||
987 aKey1.line < aKey2.line ||
988 aKey1.func < aKey2.func ||
989 aKey1.cond < aKey2.cond ||
990 aKey1.msg < aKey2.msg;
996 const wxString& aCond,
const wxString& aMsg )
1003 assertStr = wxString::Format(
"Assertion failed at %s:%d in %s: %s - %s", aFile, aLine,
1004 aFunc, aCond, aMsg );
1008 assertStr = wxString::Format(
"Assertion failed at %s:%d in %s: %s", aFile, aLine, aFunc,
1013 wxLogError( assertStr );
1016#ifdef KICAD_USE_SENTRY
1017 if( IsSentryOptedIn() )
1019 static std::set<SENTRY_ASSERT_CACHE_KEY> assertCache;
1021 SENTRY_ASSERT_CACHE_KEY key = { aFile, aLine, aFunc, aCond };
1023 if( assertCache.find( key ) == assertCache.end() )
1025 sentry_value_t exc = sentry_value_new_exception(
"assert", assertStr );
1026 sentry_value_set_stacktrace( exc, NULL, 0 );
1028 sentry_value_t sentryEvent = sentry_value_new_event();
1029 sentry_event_add_exception( sentryEvent, exc );
1030 sentry_capture_event( sentryEvent );
1031 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.
#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.