33#include <wx/html/htmlwin.h>
36#include <wx/filename.h>
37#include <wx/propgrid/propgrid.h>
38#include <wx/snglinst.h>
39#include <wx/stdpaths.h>
41#include <wx/filedlg.h>
43#include <wx/tooltip.h>
63#include <python_scripting.h>
73#ifdef KICAD_USE_SENTRY
74#include <boost/uuid/uuid_io.hpp>
75#include <boost/uuid/uuid_generators.hpp>
121 wxT(
"简体中文" ),
true },
123 wxT(
"繁體中文" ),
false },
127#define _(s) wxGetTranslation((s))
163#ifdef KICAD_USE_SENTRY
177 wxASSERT( wxTheApp );
195 if( !wxGetEnv( wxT(
"EDITOR" ), &editorname ) )
199 editorname = wxT(
"/usr/bin/open -e" );
201 editorname = wxT(
"/usr/bin/xdg-open" );
207 if( !editorname && aCanShowFileChooser )
216 if( !editorname.IsEmpty() )
229 wxString mask(
_(
"Executable file" ) + wxT(
" (*.exe)|*.exe" ) );
231 wxString mask(
_(
"Executable file" ) + wxT(
" (*)|*" ) );
237 wxFileName::SplitPath( aDefaultEditor, &
path, &
name, &ext );
241 return wxFileSelector(
_(
"Select Preferred Editor" ),
path,
name, wxT(
"." ) + ext,
242 mask, wxFD_OPEN | wxFD_FILE_MUST_EXIST,
nullptr );
246#ifdef KICAD_USE_SENTRY
247bool PGM_BASE::IsSentryOptedIn()
256 return m_sentry_optin_fn.Exists();
260void PGM_BASE::SetSentryOptIn(
bool aOptIn )
264 if( !m_sentry_uid_fn.Exists() )
269 if( !m_sentry_optin_fn.Exists() )
271 wxFFile sentryInitFile( m_sentry_optin_fn.GetFullPath(),
"w" );
272 sentryInitFile.Write(
"" );
273 sentryInitFile.Close();
278 if( m_sentry_optin_fn.Exists() )
280 wxRemoveFile( m_sentry_optin_fn.GetFullPath() );
287wxString PGM_BASE::sentryCreateUid()
289 boost::uuids::uuid uuid = boost::uuids::random_generator()();
290 wxString userGuid = boost::uuids::to_string( uuid );
292 wxFFile sentryInitFile( m_sentry_uid_fn.GetFullPath(),
"w" );
293 sentryInitFile.Write( userGuid );
294 sentryInitFile.Close();
300void PGM_BASE::ResetSentryId()
302 m_sentryUid = sentryCreateUid();
306const wxString& PGM_BASE::GetSentryId()
312void PGM_BASE::sentryInit()
317 if( IsSentryOptedIn() )
319 wxFFile sentryInitFile( m_sentry_uid_fn.GetFullPath() );
320 sentryInitFile.ReadAll( &m_sentryUid );
321 sentryInitFile.Close();
323 if( m_sentryUid.IsEmpty() || m_sentryUid.length() != 36 )
325 m_sentryUid = sentryCreateUid();
328 sentry_options_t* options = sentry_options_new();
330 #ifndef KICAD_SENTRY_DSN
331 # error "Project configuration error, missing KICAD_SENTRY_DSN"
334 sentry_options_set_dsn( options, KICAD_SENTRY_DSN );
338 tmp.AppendDir(
"sentry" );
341 sentry_options_set_database_pathw( options, tmp.GetPathWithSep().wc_str() );
343 sentry_options_set_database_path( options, tmp.GetPathWithSep().c_str() );
345 sentry_options_set_symbolize_stacktraces( options,
true );
346 sentry_options_set_auto_session_tracking( options,
false );
348 sentry_options_set_release( options,
GetCommitHash().ToStdString().c_str() );
353 sentry_init( options );
355 sentry_value_t user = sentry_value_new_object();
356 sentry_value_set_by_key( user,
"id", sentry_value_new_string( m_sentryUid.c_str() ) );
357 sentry_set_user( user );
359 sentry_set_tag(
"kicad.version",
GetBuildVersion().ToStdString().c_str() );
364void PGM_BASE::sentryPrompt()
373 && !
m_settings_manager->GetCommonSettings()->m_DoNotShowAgain.data_collection_prompt )
375 wxMessageDialog optIn = wxMessageDialog(
377 _(
"KiCad can anonymously report crashes and special event "
378 "data to developers in order to aid identifying critical bugs "
379 "across the user base more effectively and help profile "
380 "functionality to guide improvements. \n"
381 "If you choose to voluntarily participate, KiCad will automatically "
382 "handle sending said reports when crashes or events occur. \n"
383 "Your design files such as schematic or PCB are not shared in this process." ),
384 _(
"Data collection opt in request" ), wxYES_NO | wxCENTRE );
386 int result = optIn.ShowModal();
388 if( result == wxID_YES )
390 SetSentryOptIn(
true );
395 SetSentryOptIn(
false );
398 m_settings_manager->GetCommonSettings()->m_DoNotShowAgain.data_collection_prompt =
true;
406 const wxArrayString& argArray =
App().argv.GetArguments();
412 m_argvUtf8[n] = wxStrdup( argArray[n].ToUTF8() );
425 NULL, -1, wxDefaultPosition, wxDefaultSize, wxBORDER_NONE | wxSTAY_ON_TOP );
443#if defined( __WXMAC__ )
456#ifdef KICAD_USE_SENTRY
462 if(
App().argc == 0 )
463 pgm_name = wxT(
"kicad" );
465 pgm_name = wxFileName(
App().argv[0] ).GetName().Lower();
467#ifdef KICAD_USE_SENTRY
468 sentry_set_tag(
"kicad.app", pgm_name.c_str() );
471 wxInitAllImageHandlers();
475 wxPGInitResourceModule();
478 if( wxString( wxGetenv(
"HOME" ) ).IsEmpty() )
481 "Unable to continue." ) );
486 m_pgm_checker->Create( pgm_name, wxStandardPaths::Get().GetTempDir() );
491 bool isDefined = wxGetEnv( wxT(
"KICAD" ), &
m_kicad_env );
502 App().SetVendorName( wxT(
"KiCad" ) );
503 App().SetAppName( pgm_name );
506 if( wxImage::FindHandler( wxBITMAP_TYPE_PNG ) ==
nullptr )
507 wxImage::AddHandler(
new wxPNGHandler );
509 if( wxImage::FindHandler( wxBITMAP_TYPE_GIF ) ==
nullptr )
510 wxImage::AddHandler(
new wxGIFHandler );
512 if( wxImage::FindHandler( wxBITMAP_TYPE_JPEG ) ==
nullptr )
513 wxImage::AddHandler(
new wxJPEGHandler );
515 wxFileSystem::AddHandler(
new wxZipFSHandler );
526 wxSetEnv(
"FONTCONFIG_PATH", PATHS::GetWindowsFontConfigDir() );
562#ifdef KICAD_USE_SENTRY
583 wxToolTip::Enable(
true );
584 wxToolTip::SetAutoPop( 10000 );
602 for(
const std::pair<wxString, ENV_VAR_ITEM> it :
GetCommonSettings()->m_Env.vars )
604 wxLogTrace(
traceEnvVars, wxT(
"PGM_BASE::loadSettings: Found entry %s = %s" ),
605 it.first, it.second.GetValue() );
613 if( it.first.IsEmpty() )
617 if( it.second.GetDefinedExternally() )
664 wxString dictionaryName( wxT(
"kicad" ) );
673 wxLogTrace(
traceLocale, wxT(
"This language is not supported by the system." ) );
679 m_locale->Init( wxLANGUAGE_DEFAULT );
681 aErrMsg =
_(
"This language is not supported by the operating system." );
684 else if( !first_time )
686 wxLogTrace(
traceLocale, wxT(
"Search for dictionary %s.mo in %s" ) ,
687 dictionaryName,
m_locale->GetName() );
696 wxString languageSel;
714 if( !
m_locale->IsLoaded( dictionaryName ) )
715 m_locale->AddCatalog( dictionaryName );
723 wxLogTrace(
traceLocale, wxT(
"Unable to load dictionary %s.mo in %s" ),
724 dictionaryName,
m_locale->GetName() );
730 m_locale->Init( wxLANGUAGE_DEFAULT );
732 aErrMsg =
_(
"The KiCad language file for this language is not installed." );
748 wxString dictionaryName( wxT(
"kicad" ) );
755 if( !
m_locale->IsLoaded( dictionaryName ) )
756 m_locale->AddCatalog( dictionaryName );
764 wxLogTrace(
traceLocale, wxT(
"Unable to load dictionary %s.mo in %s" ),
765 dictionaryName,
m_locale->GetName() );
773 aErrMsg =
_(
"The KiCad language file for this language is not installed." );
783 wxLogTrace(
traceLocale, wxT(
"Select language ID %d from %d possible languages." ),
799 const wxLanguageInfo* langInfo = wxLocale::GetLanguageInfo(
m_language_id );
805 wxString str = langInfo->GetCanonicalWithRegion();
806 str.Replace(
"_",
"-" );
817 if( wxGetEnv( wxT(
"KICAD_RUN_FROM_BUILD_DIR" ),
nullptr ) )
821 fn.AppendDir( wxT(
"translation" ) );
822 wxLocale::AddCatalogLookupPathPrefix( fn.GetPath() );
831 if( aName.IsEmpty() )
834 wxT(
"PGM_BASE::SetLocalEnvVariable: Attempt to set empty variable to value %s" ),
840 if( wxGetEnv( aName, &env ) )
843 wxT(
"PGM_BASE::SetLocalEnvVariable: Environment variable %s already set to %s" ),
845 return env == aValue;
849 wxT(
"PGM_BASE::SetLocalEnvVariable: Setting local environment variable %s to %s" ),
852 return wxSetEnv( aName, aValue );
860 for(
const std::pair<wxString, ENV_VAR_ITEM> m_local_env_var :
GetCommonSettings()->m_Env.vars )
863 wxT(
"PGM_BASE::SetLocalEnvVariables: Setting local environment variable %s to %s" ),
864 m_local_env_var.first,
865 m_local_env_var.second.GetValue() );
866 wxSetEnv( m_local_env_var.first, m_local_env_var.second.GetValue() );
882 return wxTheApp->IsGUI();
891 std::rethrow_exception( aPtr );
895 wxLogError( ioe.
What() );
897 catch(
const std::exception& e )
899#ifdef KICAD_USE_SENTRY
900 if( IsSentryOptedIn() )
902 sentry_value_t exc = sentry_value_new_exception(
"exception", e.what() );
903 sentry_value_set_stacktrace( exc, NULL, 0 );
905 sentry_value_t sentryEvent = sentry_value_new_event();
906 sentry_event_add_exception( sentryEvent, exc );
907 sentry_capture_event( sentryEvent );
911 wxLogError( wxT(
"Unhandled exception class: %s what: %s" ),
916 wxLogError( wxT(
"Unhandled exception of unknown type" ) );
922 const wxString& aCond,
const wxString& aMsg )
928 assertStr = wxString::Format(
"Assertion failed at %s:%d in %s: %s - %s", aFile, aLine,
929 aFunc, aCond, aMsg );
933 assertStr = wxString::Format(
"Assertion failed at %s:%d in %s: %s", aFile, aLine, aFunc,
938 wxLogError( assertStr );
941#ifdef KICAD_USE_SENTRY
942 if( IsSentryOptedIn() )
944 sentry_value_t exc = sentry_value_new_exception(
"assert", assertStr );
945 sentry_value_set_stacktrace( exc, NULL, 0 );
947 sentry_value_t sentryEvent = sentry_value_new_event();
948 sentry_event_add_exception( sentryEvent, exc );
949 sentry_capture_event( sentryEvent );
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)
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 void EnsureUserPathsExist()
Ensures/creates user default paths.
static wxString GetUserCachePath()
Gets the stock (install) 3d viewer plugins path.
static wxString GetLocaleDataPath()
Gets the locales translation data path.
static const wxString & GetExecutablePath()
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.
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.
virtual NOTIFICATIONS_MANAGER & GetNotificationsManager() const
void BuildArgvUtf8()
Builds the UTF8 based argv variable.
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
void SaveCommonSettings()
Save the program (process) settings subset which are stored .kicad_common.
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.
Base window classes and related definitions.
#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.
LANGUAGE_DESCR LanguagesList[]
An array containing all the languages that KiCad supports.
#define _(s)
Current list of languages supported by KiCad.
PGM_BASE & Pgm()
The global Program "get" accessor.
LANGUAGE_DESCR LanguagesList[]
An array containing all the languages that KiCad supports.
#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)
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.