From 6bd02cae6dab98cc51606e81e9ea55314b1786ca Mon Sep 17 00:00:00 2001 From: Jon Evans <jon@craftyjon.com> Date: Wed, 17 Jan 2024 22:21:28 -0500 Subject: [PATCH] Refactor; add user control over API server --- common/CMakeLists.txt | 15 +- common/api/api_plugin_manager.cpp | 2 +- common/api/api_server.cpp | 56 +- ...settings.cpp => panel_plugin_settings.cpp} | 83 ++- common/dialogs/panel_plugin_settings_base.cpp | 91 +++ common/dialogs/panel_plugin_settings_base.fbp | 580 ++++++++++++++++++ ...gs_base.h => panel_plugin_settings_base.h} | 19 +- common/dialogs/panel_python_settings_base.cpp | 70 --- common/dialogs/panel_python_settings_base.fbp | 371 ----------- common/eda_base_frame.cpp | 4 +- common/pgm_base.cpp | 14 +- common/settings/common_settings.cpp | 9 +- include/api/api_server.h | 6 +- ...hon_settings.h => panel_plugin_settings.h} | 18 +- include/settings/common_settings.h | 7 +- libs/kinng/include/kinng.h | 4 +- libs/kinng/src/kinng.cpp | 16 +- pcbnew/toolbars_pcb_editor.cpp | 2 +- qa/tests/libs/kinng/test_kinng.cpp | 5 +- 19 files changed, 857 insertions(+), 515 deletions(-) rename common/dialogs/{panel_python_settings.cpp => panel_plugin_settings.cpp} (53%) create mode 100644 common/dialogs/panel_plugin_settings_base.cpp create mode 100644 common/dialogs/panel_plugin_settings_base.fbp rename common/dialogs/{panel_python_settings_base.h => panel_plugin_settings_base.h} (76%) delete mode 100644 common/dialogs/panel_python_settings_base.cpp delete mode 100644 common/dialogs/panel_python_settings_base.fbp rename include/dialogs/{panel_python_settings.h => panel_plugin_settings.h} (72%) diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index c785678426..c41bb9369b 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -182,8 +182,11 @@ set( KICOMMON_SRCS if( KICAD_IPC_API ) set( KICOMMON_SRCS ${KICOMMON_SRCS} + api/api_handler.cpp + api/api_handler_common.cpp api/api_plugin.cpp api/api_plugin_manager.cpp + api/api_server.cpp ../scripting/python_manager.cpp ) @@ -226,6 +229,12 @@ if( KICAD_USE_SENTRY ) set_property(SOURCE pgm_base.cpp APPEND PROPERTY COMPILE_DEFINITIONS KICAD_SENTRY_DSN="${KICAD_SENTRY_DSN}") endif() +if( KICAD_IPC_API ) + target_link_libraries( kicommon + kinng + ) +endif() + include( ${KICAD_CMAKE_MODULE_PATH}/KiCadVersion.cmake ) include( ${KICAD_CMAKE_MODULE_PATH}/CreateGitVersionHeader.cmake ) create_git_version_header(${CMAKE_SOURCE_DIR}) @@ -267,6 +276,7 @@ target_include_directories( kicommon ${CMAKE_BINARY_DIR} $<TARGET_PROPERTY:magic_enum,INTERFACE_INCLUDE_DIRECTORIES> $<TARGET_PROPERTY:pegtl,INTERFACE_INCLUDE_DIRECTORIES> + $<TARGET_PROPERTY:expected,INTERFACE_INCLUDE_DIRECTORIES> $<TARGET_PROPERTY:kiapi,INTERFACE_INCLUDE_DIRECTORIES> ) @@ -349,8 +359,8 @@ set( COMMON_DLG_SRCS dialogs/panel_mouse_settings_base.cpp dialogs/panel_packages_and_updates.cpp dialogs/panel_packages_and_updates_base.cpp - dialogs/panel_python_settings.cpp - dialogs/panel_python_settings_base.cpp + dialogs/panel_plugin_settings.cpp + dialogs/panel_plugin_settings_base.cpp dialogs/panel_setup_netclasses.cpp dialogs/panel_setup_netclasses_base.cpp dialogs/panel_setup_severities.cpp @@ -691,7 +701,6 @@ add_dependencies( common pegtl ) target_include_directories( common PUBLIC $<TARGET_PROPERTY:pegtl,INTERFACE_INCLUDE_DIRECTORIES> $<TARGET_PROPERTY:magic_enum,INTERFACE_INCLUDE_DIRECTORIES> - $<TARGET_PROPERTY:expected,INTERFACE_INCLUDE_DIRECTORIES> ) target_include_directories( common SYSTEM PUBLIC diff --git a/common/api/api_plugin_manager.cpp b/common/api/api_plugin_manager.cpp index fa4a71c4f4..4fd573ca67 100644 --- a/common/api/api_plugin_manager.cpp +++ b/common/api/api_plugin_manager.cpp @@ -309,7 +309,7 @@ void API_PLUGIN_MANAGER::processNextJob( wxCommandEvent& aEvent ) { wxLogTrace( traceApi, wxString::Format( "Manager: creating Python env at %s", job.env_path ) ); - PYTHON_MANAGER manager( Pgm().GetCommonSettings()->m_Python.interpreter_path ); + PYTHON_MANAGER manager( Pgm().GetCommonSettings()->m_Api.python_interpreter ); manager.Execute( wxString::Format( wxS( "-m venv %s"), job.env_path ), [=]( int aRetVal, const wxString& aOutput, const wxString& aError ) diff --git a/common/api/api_server.cpp b/common/api/api_server.cpp index 83b4c50db5..d45437cbc5 100644 --- a/common/api/api_server.cpp +++ b/common/api/api_server.cpp @@ -21,14 +21,17 @@ #include <wx/app.h> #include <wx/datetime.h> #include <wx/event.h> +#include <wx/stdpaths.h> #include <advanced_config.h> +#include <api/api_plugin_manager.h> // traceApi #include <api/api_server.h> #include <api/api_handler_common.h> #include <kiid.h> #include <kinng.h> #include <paths.h> #include <pgm_base.h> +#include <settings/common_settings.h> #include <string_utils.h> #include <api/common/envelope.pb.h> @@ -47,9 +50,43 @@ KICAD_API_SERVER::KICAD_API_SERVER() : m_token( KIID().AsStdString() ), m_readyToReply( false ) { - m_server = std::make_unique<KINNG_REQUEST_SERVER>(); + if( !Pgm().GetCommonSettings()->m_Api.enable_server ) + { + wxLogTrace( traceApi, "Server: disabled by user preferences." ); + return; + } + + wxFileName socket; +#ifdef __WXMAC__ + socket.AssignDir( wxS( "/tmp" ) ); +#else + socket.AssignDir( wxStandardPaths::Get().GetTempDir() ); +#endif + socket.AppendDir( wxS( "kicad" ) ); + socket.SetFullName( wxS( "api.sock" ) ); + + if( !PATHS::EnsurePathExists( socket.GetPath() ) ) + { + wxLogTrace( traceApi, wxString::Format( "Server: socket path %s could not be created", + socket.GetPath() ) ); + return; + } + + if( socket.FileExists() ) + { + socket.SetFullName( wxString::Format( wxS( "api-%ul.sock" ), ::wxGetProcessId() ) ); + + if( socket.FileExists() ) + { + wxLogTrace( traceApi, wxString::Format( "Server: PID socket path %s already exists!", + socket.GetFullPath() ) ); + return; + } + } + + m_server = std::make_unique<KINNG_REQUEST_SERVER>( + fmt::format( "ipc://{}", socket.GetFullPath().ToStdString() ) ); m_server->SetCallback( [&]( std::string* aRequest ) { onApiRequest( aRequest ); } ); - m_socketPath = m_server->SocketPath(); m_commonHandler = std::make_unique<API_HANDLER_COMMON>(); RegisterHandler( m_commonHandler.get() ); @@ -60,7 +97,8 @@ KICAD_API_SERVER::KICAD_API_SERVER() : if( ADVANCED_CFG::GetCfg().m_EnableAPILogging ) PATHS::EnsurePathExists( PATHS::GetLogsPath() ); - log( "--- KiCad API server started ---\n" ); + log( fmt::format( "--- KiCad API server started at {} ---\n", SocketPath() ) ); + wxLogTrace( traceApi, wxString::Format( "Server: listening at %s", SocketPath() ) ); Bind( API_REQUEST_EVENT, &KICAD_API_SERVER::handleApiEvent, this ); } @@ -71,6 +109,12 @@ KICAD_API_SERVER::~KICAD_API_SERVER() } +bool KICAD_API_SERVER::Running() const +{ + return m_server && m_server->Running(); +} + + void KICAD_API_SERVER::RegisterHandler( API_HANDLER* aHandler ) { wxCHECK( aHandler, /* void */ ); @@ -84,6 +128,12 @@ void KICAD_API_SERVER::DeregisterHandler( API_HANDLER* aHandler ) } +std::string KICAD_API_SERVER::SocketPath() const +{ + return m_server ? m_server->SocketPath() : ""; +} + + void KICAD_API_SERVER::onApiRequest( std::string* aRequest ) { if( !m_readyToReply ) diff --git a/common/dialogs/panel_python_settings.cpp b/common/dialogs/panel_plugin_settings.cpp similarity index 53% rename from common/dialogs/panel_python_settings.cpp rename to common/dialogs/panel_plugin_settings.cpp index 586ae93524..137a2f7329 100644 --- a/common/dialogs/panel_python_settings.cpp +++ b/common/dialogs/panel_plugin_settings.cpp @@ -18,7 +18,8 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include <dialogs/panel_python_settings.h> +#include <dialogs/panel_plugin_settings.h> +#include <api/api_server.h> #include <widgets/ui_common.h> #include <pgm_base.h> #include <python_manager.h> @@ -26,70 +27,98 @@ #include <settings/settings_manager.h> -PANEL_PYTHON_SETTINGS::PANEL_PYTHON_SETTINGS( wxWindow* aParent ) : - PANEL_PYTHON_SETTINGS_BASE( aParent ) +PANEL_PLUGIN_SETTINGS::PANEL_PLUGIN_SETTINGS( wxWindow* aParent ) : + PANEL_PLUGIN_SETTINGS_BASE( aParent ) { wxFont helpFont = KIUI::GetInfoFont( this ).Italic(); m_stPythonStatus->SetFont( helpFont ); + m_stApiStatus->SetFont( helpFont ); } -void PANEL_PYTHON_SETTINGS::ResetPanel() +void PANEL_PLUGIN_SETTINGS::ResetPanel() { } -bool PANEL_PYTHON_SETTINGS::TransferDataToWindow() +bool PANEL_PLUGIN_SETTINGS::TransferDataToWindow() { SETTINGS_MANAGER& mgr = Pgm().GetSettingsManager(); + COMMON_SETTINGS* settings = mgr.GetCommonSettings(); - m_pickerPythonInterpreter->SetFileName( mgr.GetCommonSettings()->m_Python.interpreter_path ); - validateInterpreter(); + m_cbEnableApi->SetValue( settings->m_Api.enable_server ); + m_pickerPythonInterpreter->SetFileName( settings->m_Api.python_interpreter ); + validatePythonInterpreter(); + updateApiStatusText(); return true; } -bool PANEL_PYTHON_SETTINGS::TransferDataFromWindow() +bool PANEL_PLUGIN_SETTINGS::TransferDataFromWindow() { SETTINGS_MANAGER& mgr = Pgm().GetSettingsManager(); + COMMON_SETTINGS* settings = mgr.GetCommonSettings(); wxString interpreter = m_pickerPythonInterpreter->GetTextCtrlValue(); - if( m_interpreterValid || interpreter.IsEmpty() ) - mgr.GetCommonSettings()->m_Python.interpreter_path = interpreter; + if( m_pythonInterpreterValid || interpreter.IsEmpty() ) + settings->m_Api.python_interpreter = interpreter; + + settings->m_Api.enable_server = m_cbEnableApi->GetValue(); return true; } -void PANEL_PYTHON_SETTINGS::OnPythonInterpreterChanged( wxFileDirPickerEvent& event ) +void PANEL_PLUGIN_SETTINGS::OnPythonInterpreterChanged( wxFileDirPickerEvent& event ) { - validateInterpreter(); + validatePythonInterpreter(); } -void PANEL_PYTHON_SETTINGS::OnBtnDetectAutomaticallyClicked( wxCommandEvent& aEvent ) +void PANEL_PLUGIN_SETTINGS::OnBtnDetectAutomaticallyClicked( wxCommandEvent& aEvent ) { -#ifdef __WXMSW__ - // TODO(JE) where -#else - wxArrayString output; + wxString interpreter = PYTHON_MANAGER::FindPythonInterpreter(); - if( 0 == wxExecute( wxS( "which -a python" ), output, wxEXEC_SYNC ) ) + if( !interpreter.IsEmpty() ) { - if( !output.IsEmpty() ) - { - m_pickerPythonInterpreter->SetPath( output[0] ); - validateInterpreter(); - } + m_pickerPythonInterpreter->SetPath( interpreter ); + validatePythonInterpreter(); } -#endif } -void PANEL_PYTHON_SETTINGS::validateInterpreter() +void PANEL_PLUGIN_SETTINGS::OnEnableApiChecked( wxCommandEvent& aEvent ) { - m_interpreterValid = false; + validatePythonInterpreter(); + updateApiStatusText(); +} + + +void PANEL_PLUGIN_SETTINGS::updateApiStatusText() +{ + if( m_cbEnableApi->GetValue() && Pgm().GetApiServer().Running() ) + { + m_stApiStatus->SetLabel( wxString::Format( _( "Listening at %s" ), + Pgm().GetApiServer().SocketPath() ) ); + } + else + { + m_stApiStatus->SetLabel( wxEmptyString ); + } +} + + +void PANEL_PLUGIN_SETTINGS::validatePythonInterpreter() +{ + if( !m_cbEnableApi->GetValue() ) + { + m_stPythonStatus->SetLabel( _( "KiCad API is not enabled; external Python plugins will " + "not be available" ) ); + return; + } + + m_pythonInterpreterValid = false; wxFileName pythonExe( m_pickerPythonInterpreter->GetTextCtrlValue() ); @@ -110,7 +139,7 @@ void PANEL_PYTHON_SETTINGS::validateInterpreter() if( aRetCode == 0 && aStdOut.Contains( wxS( "Python 3" ) ) ) { msg = wxString::Format( _( "Found %s" ), aStdOut ); - m_interpreterValid = true; + m_pythonInterpreterValid = true; } else { diff --git a/common/dialogs/panel_plugin_settings_base.cpp b/common/dialogs/panel_plugin_settings_base.cpp new file mode 100644 index 0000000000..dd93ddf941 --- /dev/null +++ b/common/dialogs/panel_plugin_settings_base.cpp @@ -0,0 +1,91 @@ +/////////////////////////////////////////////////////////////////////////// +// C++ code generated with wxFormBuilder (version 4.0.0-0-g0efcecf-dirty) +// http://www.wxformbuilder.org/ +// +// PLEASE DO *NOT* EDIT THIS FILE! +/////////////////////////////////////////////////////////////////////////// + +#include "panel_plugin_settings_base.h" + +/////////////////////////////////////////////////////////////////////////// + +PANEL_PLUGIN_SETTINGS_BASE::PANEL_PLUGIN_SETTINGS_BASE( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style, const wxString& name ) : RESETTABLE_PANEL( parent, id, pos, size, style, name ) +{ + wxBoxSizer* bPanelSizer; + bPanelSizer = new wxBoxSizer( wxHORIZONTAL ); + + wxBoxSizer* bSizer8; + bSizer8 = new wxBoxSizer( wxVERTICAL ); + + wxStaticBoxSizer* sbSizerServer; + sbSizerServer = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("KiCad API") ), wxVERTICAL ); + + m_staticText3 = new wxStaticText( sbSizerServer->GetStaticBox(), wxID_ANY, _("When the KiCad API is enabled, plugins and other software running on this computer can connect to KiCad."), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText3->Wrap( -1 ); + sbSizerServer->Add( m_staticText3, 0, wxALL, 5 ); + + m_cbEnableApi = new wxCheckBox( sbSizerServer->GetStaticBox(), wxID_ANY, _("Enable KiCad API"), wxDefaultPosition, wxDefaultSize, 0 ); + m_cbEnableApi->SetToolTip( _("Enable the KiCad API. Doing so will allow third-party software running on your computer to access KiCad.") ); + + sbSizerServer->Add( m_cbEnableApi, 0, wxALL, 5 ); + + m_stApiStatus = new wxStaticText( sbSizerServer->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + m_stApiStatus->Wrap( -1 ); + sbSizerServer->Add( m_stApiStatus, 0, wxALL, 5 ); + + + bSizer8->Add( sbSizerServer, 0, wxALL|wxEXPAND, 5 ); + + wxStaticBoxSizer* sbSizerPython; + sbSizerPython = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Python Interpreter") ), wxVERTICAL ); + + wxBoxSizer* bSizer4; + bSizer4 = new wxBoxSizer( wxHORIZONTAL ); + + m_staticText2 = new wxStaticText( sbSizerPython->GetStaticBox(), wxID_ANY, _("Path to Python interpreter:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText2->Wrap( -1 ); + bSizer4->Add( m_staticText2, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + m_pickerPythonInterpreter = new wxFilePickerCtrl( sbSizerPython->GetStaticBox(), wxID_ANY, wxEmptyString, _("Select the path to a Python interpreter"), _("*.*"), wxDefaultPosition, wxDefaultSize, wxFLP_DEFAULT_STYLE|wxFLP_USE_TEXTCTRL ); + bSizer4->Add( m_pickerPythonInterpreter, 1, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + m_btnDetectAutomatically = new wxButton( sbSizerPython->GetStaticBox(), wxID_ANY, _("Detect Automatically"), wxDefaultPosition, wxDefaultSize, 0 ); + bSizer4->Add( m_btnDetectAutomatically, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + + sbSizerPython->Add( bSizer4, 0, wxEXPAND, 5 ); + + m_stPythonStatus = new wxStaticText( sbSizerPython->GetStaticBox(), wxID_ANY, _("No Python interpreter chosen; external Python plugins will not be available"), wxDefaultPosition, wxDefaultSize, 0 ); + m_stPythonStatus->Wrap( -1 ); + m_stPythonStatus->SetToolTip( _("Python interpreter status") ); + + sbSizerPython->Add( m_stPythonStatus, 0, wxALL, 5 ); + + + bSizer8->Add( sbSizerPython, 0, wxALL|wxEXPAND, 5 ); + + + bSizer8->Add( 0, 0, 1, wxEXPAND, 5 ); + + + bPanelSizer->Add( bSizer8, 1, wxEXPAND, 5 ); + + + this->SetSizer( bPanelSizer ); + this->Layout(); + bPanelSizer->Fit( this ); + + // Connect Events + m_cbEnableApi->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( PANEL_PLUGIN_SETTINGS_BASE::OnEnableApiChecked ), NULL, this ); + m_pickerPythonInterpreter->Connect( wxEVT_COMMAND_FILEPICKER_CHANGED, wxFileDirPickerEventHandler( PANEL_PLUGIN_SETTINGS_BASE::OnPythonInterpreterChanged ), NULL, this ); + m_btnDetectAutomatically->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_PLUGIN_SETTINGS_BASE::OnBtnDetectAutomaticallyClicked ), NULL, this ); +} + +PANEL_PLUGIN_SETTINGS_BASE::~PANEL_PLUGIN_SETTINGS_BASE() +{ + // Disconnect Events + m_cbEnableApi->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( PANEL_PLUGIN_SETTINGS_BASE::OnEnableApiChecked ), NULL, this ); + m_pickerPythonInterpreter->Disconnect( wxEVT_COMMAND_FILEPICKER_CHANGED, wxFileDirPickerEventHandler( PANEL_PLUGIN_SETTINGS_BASE::OnPythonInterpreterChanged ), NULL, this ); + m_btnDetectAutomatically->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_PLUGIN_SETTINGS_BASE::OnBtnDetectAutomaticallyClicked ), NULL, this ); + +} diff --git a/common/dialogs/panel_plugin_settings_base.fbp b/common/dialogs/panel_plugin_settings_base.fbp new file mode 100644 index 0000000000..04bec7f651 --- /dev/null +++ b/common/dialogs/panel_plugin_settings_base.fbp @@ -0,0 +1,580 @@ +<?xml version="1.0" encoding="UTF-8" standalone="yes"?> +<wxFormBuilder_Project> + <FileVersion major="1" minor="17"/> + <object class="Project" expanded="true"> + <property name="class_decoration"></property> + <property name="code_generation">C++</property> + <property name="disconnect_events">1</property> + <property name="disconnect_mode">source_name</property> + <property name="disconnect_php_events">0</property> + <property name="disconnect_python_events">0</property> + <property name="embedded_files_path">res</property> + <property name="encoding">UTF-8</property> + <property name="event_generation">connect</property> + <property name="file">panel_plugin_settings_base</property> + <property name="first_id">1000</property> + <property name="help_provider">none</property> + <property name="image_path_wrapper_function_name"></property> + <property name="indent_with_spaces"></property> + <property name="internationalize">1</property> + <property name="name">PanelPluginSettings</property> + <property name="namespace"></property> + <property name="path">.</property> + <property name="precompiled_header"></property> + <property name="relative_path">1</property> + <property name="skip_lua_events">1</property> + <property name="skip_php_events">1</property> + <property name="skip_python_events">1</property> + <property name="ui_table">UI</property> + <property name="use_array_enum">0</property> + <property name="use_enum">1</property> + <property name="use_microsoft_bom">0</property> + <object class="Panel" expanded="true"> + <property name="aui_managed">0</property> + <property name="aui_manager_style">wxAUI_MGR_DEFAULT</property> + <property name="bg"></property> + <property name="context_help"></property> + <property name="context_menu">1</property> + <property name="drag_accept_files">0</property> + <property name="enabled">1</property> + <property name="event_handler">impl_virtual</property> + <property name="fg"></property> + <property name="font"></property> + <property name="hidden">0</property> + <property name="id">wxID_ANY</property> + <property name="maximum_size"></property> + <property name="minimum_size"></property> + <property name="name">PANEL_PLUGIN_SETTINGS_BASE</property> + <property name="pos"></property> + <property name="size">-1,-1</property> + <property name="subclass">RESETTABLE_PANEL; widgets/resettable_panel.h; Not forward_declare</property> + <property name="tooltip"></property> + <property name="two_step_creation">0</property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style">wxTAB_TRAVERSAL</property> + <object class="wxBoxSizer" expanded="true"> + <property name="minimum_size"></property> + <property name="name">bPanelSizer</property> + <property name="orient">wxHORIZONTAL</property> + <property name="permission">none</property> + <object class="sizeritem" expanded="true"> + <property name="border">5</property> + <property name="flag">wxEXPAND</property> + <property name="proportion">1</property> + <object class="wxBoxSizer" expanded="true"> + <property name="minimum_size"></property> + <property name="name">bSizer8</property> + <property name="orient">wxVERTICAL</property> + <property name="permission">none</property> + <object class="sizeritem" expanded="true"> + <property name="border">5</property> + <property name="flag">wxALL|wxEXPAND</property> + <property name="proportion">0</property> + <object class="wxStaticBoxSizer" expanded="true"> + <property name="id">wxID_ANY</property> + <property name="label">KiCad API</property> + <property name="minimum_size"></property> + <property name="name">sbSizerServer</property> + <property name="orient">wxVERTICAL</property> + <property name="parent">1</property> + <property name="permission">none</property> + <object class="sizeritem" expanded="true"> + <property name="border">5</property> + <property name="flag">wxALL</property> + <property name="proportion">0</property> + <object class="wxStaticText" expanded="true"> + <property name="BottomDockable">1</property> + <property name="LeftDockable">1</property> + <property name="RightDockable">1</property> + <property name="TopDockable">1</property> + <property name="aui_layer"></property> + <property name="aui_name"></property> + <property name="aui_position"></property> + <property name="aui_row"></property> + <property name="best_size"></property> + <property name="bg"></property> + <property name="caption"></property> + <property name="caption_visible">1</property> + <property name="center_pane">0</property> + <property name="close_button">1</property> + <property name="context_help"></property> + <property name="context_menu">1</property> + <property name="default_pane">0</property> + <property name="dock">Dock</property> + <property name="dock_fixed">0</property> + <property name="docking">Left</property> + <property name="drag_accept_files">0</property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="floatable">1</property> + <property name="font"></property> + <property name="gripper">0</property> + <property name="hidden">0</property> + <property name="id">wxID_ANY</property> + <property name="label">When the KiCad API is enabled, plugins and other software running on this computer can connect to KiCad.</property> + <property name="markup">0</property> + <property name="max_size"></property> + <property name="maximize_button">0</property> + <property name="maximum_size"></property> + <property name="min_size"></property> + <property name="minimize_button">0</property> + <property name="minimum_size"></property> + <property name="moveable">1</property> + <property name="name">m_staticText3</property> + <property name="pane_border">1</property> + <property name="pane_position"></property> + <property name="pane_size"></property> + <property name="permission">protected</property> + <property name="pin_button">1</property> + <property name="pos"></property> + <property name="resize">Resizable</property> + <property name="show">1</property> + <property name="size"></property> + <property name="style"></property> + <property name="subclass">; ; forward_declare</property> + <property name="toolbar_pane">0</property> + <property name="tooltip"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <property name="wrap">-1</property> + </object> + </object> + <object class="sizeritem" expanded="true"> + <property name="border">5</property> + <property name="flag">wxALL</property> + <property name="proportion">0</property> + <object class="wxCheckBox" expanded="true"> + <property name="BottomDockable">1</property> + <property name="LeftDockable">1</property> + <property name="RightDockable">1</property> + <property name="TopDockable">1</property> + <property name="aui_layer"></property> + <property name="aui_name"></property> + <property name="aui_position"></property> + <property name="aui_row"></property> + <property name="best_size"></property> + <property name="bg"></property> + <property name="caption"></property> + <property name="caption_visible">1</property> + <property name="center_pane">0</property> + <property name="checked">0</property> + <property name="close_button">1</property> + <property name="context_help"></property> + <property name="context_menu">1</property> + <property name="default_pane">0</property> + <property name="dock">Dock</property> + <property name="dock_fixed">0</property> + <property name="docking">Left</property> + <property name="drag_accept_files">0</property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="floatable">1</property> + <property name="font"></property> + <property name="gripper">0</property> + <property name="hidden">0</property> + <property name="id">wxID_ANY</property> + <property name="label">Enable KiCad API</property> + <property name="max_size"></property> + <property name="maximize_button">0</property> + <property name="maximum_size"></property> + <property name="min_size"></property> + <property name="minimize_button">0</property> + <property name="minimum_size"></property> + <property name="moveable">1</property> + <property name="name">m_cbEnableApi</property> + <property name="pane_border">1</property> + <property name="pane_position"></property> + <property name="pane_size"></property> + <property name="permission">protected</property> + <property name="pin_button">1</property> + <property name="pos"></property> + <property name="resize">Resizable</property> + <property name="show">1</property> + <property name="size"></property> + <property name="style"></property> + <property name="subclass">; ; forward_declare</property> + <property name="toolbar_pane">0</property> + <property name="tooltip">Enable the KiCad API. Doing so will allow third-party software running on your computer to access KiCad.</property> + <property name="validator_data_type"></property> + <property name="validator_style">wxFILTER_NONE</property> + <property name="validator_type">wxDefaultValidator</property> + <property name="validator_variable"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <event name="OnCheckBox">OnEnableApiChecked</event> + </object> + </object> + <object class="sizeritem" expanded="true"> + <property name="border">5</property> + <property name="flag">wxALL</property> + <property name="proportion">0</property> + <object class="wxStaticText" expanded="true"> + <property name="BottomDockable">1</property> + <property name="LeftDockable">1</property> + <property name="RightDockable">1</property> + <property name="TopDockable">1</property> + <property name="aui_layer"></property> + <property name="aui_name"></property> + <property name="aui_position"></property> + <property name="aui_row"></property> + <property name="best_size"></property> + <property name="bg"></property> + <property name="caption"></property> + <property name="caption_visible">1</property> + <property name="center_pane">0</property> + <property name="close_button">1</property> + <property name="context_help"></property> + <property name="context_menu">1</property> + <property name="default_pane">0</property> + <property name="dock">Dock</property> + <property name="dock_fixed">0</property> + <property name="docking">Left</property> + <property name="drag_accept_files">0</property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="floatable">1</property> + <property name="font"></property> + <property name="gripper">0</property> + <property name="hidden">0</property> + <property name="id">wxID_ANY</property> + <property name="label"></property> + <property name="markup">0</property> + <property name="max_size"></property> + <property name="maximize_button">0</property> + <property name="maximum_size"></property> + <property name="min_size"></property> + <property name="minimize_button">0</property> + <property name="minimum_size"></property> + <property name="moveable">1</property> + <property name="name">m_stApiStatus</property> + <property name="pane_border">1</property> + <property name="pane_position"></property> + <property name="pane_size"></property> + <property name="permission">protected</property> + <property name="pin_button">1</property> + <property name="pos"></property> + <property name="resize">Resizable</property> + <property name="show">1</property> + <property name="size"></property> + <property name="style"></property> + <property name="subclass">; ; forward_declare</property> + <property name="toolbar_pane">0</property> + <property name="tooltip"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <property name="wrap">-1</property> + </object> + </object> + </object> + </object> + <object class="sizeritem" expanded="true"> + <property name="border">5</property> + <property name="flag">wxALL|wxEXPAND</property> + <property name="proportion">0</property> + <object class="wxStaticBoxSizer" expanded="true"> + <property name="id">wxID_ANY</property> + <property name="label">Python Interpreter</property> + <property name="minimum_size"></property> + <property name="name">sbSizerPython</property> + <property name="orient">wxVERTICAL</property> + <property name="parent">1</property> + <property name="permission">none</property> + <object class="sizeritem" expanded="true"> + <property name="border">5</property> + <property name="flag">wxEXPAND</property> + <property name="proportion">0</property> + <object class="wxBoxSizer" expanded="true"> + <property name="minimum_size"></property> + <property name="name">bSizer4</property> + <property name="orient">wxHORIZONTAL</property> + <property name="permission">none</property> + <object class="sizeritem" expanded="true"> + <property name="border">5</property> + <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property> + <property name="proportion">0</property> + <object class="wxStaticText" expanded="true"> + <property name="BottomDockable">1</property> + <property name="LeftDockable">1</property> + <property name="RightDockable">1</property> + <property name="TopDockable">1</property> + <property name="aui_layer"></property> + <property name="aui_name"></property> + <property name="aui_position"></property> + <property name="aui_row"></property> + <property name="best_size"></property> + <property name="bg"></property> + <property name="caption"></property> + <property name="caption_visible">1</property> + <property name="center_pane">0</property> + <property name="close_button">1</property> + <property name="context_help"></property> + <property name="context_menu">1</property> + <property name="default_pane">0</property> + <property name="dock">Dock</property> + <property name="dock_fixed">0</property> + <property name="docking">Left</property> + <property name="drag_accept_files">0</property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="floatable">1</property> + <property name="font"></property> + <property name="gripper">0</property> + <property name="hidden">0</property> + <property name="id">wxID_ANY</property> + <property name="label">Path to Python interpreter:</property> + <property name="markup">0</property> + <property name="max_size"></property> + <property name="maximize_button">0</property> + <property name="maximum_size"></property> + <property name="min_size"></property> + <property name="minimize_button">0</property> + <property name="minimum_size"></property> + <property name="moveable">1</property> + <property name="name">m_staticText2</property> + <property name="pane_border">1</property> + <property name="pane_position"></property> + <property name="pane_size"></property> + <property name="permission">protected</property> + <property name="pin_button">1</property> + <property name="pos"></property> + <property name="resize">Resizable</property> + <property name="show">1</property> + <property name="size"></property> + <property name="style"></property> + <property name="subclass">; ; forward_declare</property> + <property name="toolbar_pane">0</property> + <property name="tooltip"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <property name="wrap">-1</property> + </object> + </object> + <object class="sizeritem" expanded="true"> + <property name="border">5</property> + <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property> + <property name="proportion">1</property> + <object class="wxFilePickerCtrl" expanded="true"> + <property name="BottomDockable">1</property> + <property name="LeftDockable">1</property> + <property name="RightDockable">1</property> + <property name="TopDockable">1</property> + <property name="aui_layer"></property> + <property name="aui_name"></property> + <property name="aui_position"></property> + <property name="aui_row"></property> + <property name="best_size"></property> + <property name="bg"></property> + <property name="caption"></property> + <property name="caption_visible">1</property> + <property name="center_pane">0</property> + <property name="close_button">1</property> + <property name="context_help"></property> + <property name="context_menu">1</property> + <property name="default_pane">0</property> + <property name="dock">Dock</property> + <property name="dock_fixed">0</property> + <property name="docking">Left</property> + <property name="drag_accept_files">0</property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="floatable">1</property> + <property name="font"></property> + <property name="gripper">0</property> + <property name="hidden">0</property> + <property name="id">wxID_ANY</property> + <property name="max_size"></property> + <property name="maximize_button">0</property> + <property name="maximum_size"></property> + <property name="message">Select the path to a Python interpreter</property> + <property name="min_size"></property> + <property name="minimize_button">0</property> + <property name="minimum_size"></property> + <property name="moveable">1</property> + <property name="name">m_pickerPythonInterpreter</property> + <property name="pane_border">1</property> + <property name="pane_position"></property> + <property name="pane_size"></property> + <property name="permission">protected</property> + <property name="pin_button">1</property> + <property name="pos"></property> + <property name="resize">Resizable</property> + <property name="show">1</property> + <property name="size"></property> + <property name="style">wxFLP_DEFAULT_STYLE|wxFLP_USE_TEXTCTRL</property> + <property name="subclass">; ; forward_declare</property> + <property name="toolbar_pane">0</property> + <property name="tooltip"></property> + <property name="validator_data_type"></property> + <property name="validator_style">wxFILTER_NONE</property> + <property name="validator_type">wxDefaultValidator</property> + <property name="validator_variable"></property> + <property name="value"></property> + <property name="wildcard">*.*</property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <event name="OnFileChanged">OnPythonInterpreterChanged</event> + </object> + </object> + <object class="sizeritem" expanded="true"> + <property name="border">5</property> + <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property> + <property name="proportion">0</property> + <object class="wxButton" expanded="true"> + <property name="BottomDockable">1</property> + <property name="LeftDockable">1</property> + <property name="RightDockable">1</property> + <property name="TopDockable">1</property> + <property name="aui_layer"></property> + <property name="aui_name"></property> + <property name="aui_position"></property> + <property name="aui_row"></property> + <property name="auth_needed">0</property> + <property name="best_size"></property> + <property name="bg"></property> + <property name="bitmap"></property> + <property name="caption"></property> + <property name="caption_visible">1</property> + <property name="center_pane">0</property> + <property name="close_button">1</property> + <property name="context_help"></property> + <property name="context_menu">1</property> + <property name="current"></property> + <property name="default">0</property> + <property name="default_pane">0</property> + <property name="disabled"></property> + <property name="dock">Dock</property> + <property name="dock_fixed">0</property> + <property name="docking">Left</property> + <property name="drag_accept_files">0</property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="floatable">1</property> + <property name="focus"></property> + <property name="font"></property> + <property name="gripper">0</property> + <property name="hidden">0</property> + <property name="id">wxID_ANY</property> + <property name="label">Detect Automatically</property> + <property name="margins"></property> + <property name="markup">0</property> + <property name="max_size"></property> + <property name="maximize_button">0</property> + <property name="maximum_size"></property> + <property name="min_size"></property> + <property name="minimize_button">0</property> + <property name="minimum_size"></property> + <property name="moveable">1</property> + <property name="name">m_btnDetectAutomatically</property> + <property name="pane_border">1</property> + <property name="pane_position"></property> + <property name="pane_size"></property> + <property name="permission">protected</property> + <property name="pin_button">1</property> + <property name="pos"></property> + <property name="position"></property> + <property name="pressed"></property> + <property name="resize">Resizable</property> + <property name="show">1</property> + <property name="size"></property> + <property name="style"></property> + <property name="subclass">; ; forward_declare</property> + <property name="toolbar_pane">0</property> + <property name="tooltip"></property> + <property name="validator_data_type"></property> + <property name="validator_style">wxFILTER_NONE</property> + <property name="validator_type">wxDefaultValidator</property> + <property name="validator_variable"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <event name="OnButtonClick">OnBtnDetectAutomaticallyClicked</event> + </object> + </object> + </object> + </object> + <object class="sizeritem" expanded="true"> + <property name="border">5</property> + <property name="flag">wxALL</property> + <property name="proportion">0</property> + <object class="wxStaticText" expanded="true"> + <property name="BottomDockable">1</property> + <property name="LeftDockable">1</property> + <property name="RightDockable">1</property> + <property name="TopDockable">1</property> + <property name="aui_layer"></property> + <property name="aui_name"></property> + <property name="aui_position"></property> + <property name="aui_row"></property> + <property name="best_size"></property> + <property name="bg"></property> + <property name="caption"></property> + <property name="caption_visible">1</property> + <property name="center_pane">0</property> + <property name="close_button">1</property> + <property name="context_help"></property> + <property name="context_menu">1</property> + <property name="default_pane">0</property> + <property name="dock">Dock</property> + <property name="dock_fixed">0</property> + <property name="docking">Left</property> + <property name="drag_accept_files">0</property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="floatable">1</property> + <property name="font"></property> + <property name="gripper">0</property> + <property name="hidden">0</property> + <property name="id">wxID_ANY</property> + <property name="label">No Python interpreter chosen; external Python plugins will not be available</property> + <property name="markup">0</property> + <property name="max_size"></property> + <property name="maximize_button">0</property> + <property name="maximum_size"></property> + <property name="min_size"></property> + <property name="minimize_button">0</property> + <property name="minimum_size"></property> + <property name="moveable">1</property> + <property name="name">m_stPythonStatus</property> + <property name="pane_border">1</property> + <property name="pane_position"></property> + <property name="pane_size"></property> + <property name="permission">public</property> + <property name="pin_button">1</property> + <property name="pos"></property> + <property name="resize">Resizable</property> + <property name="show">1</property> + <property name="size"></property> + <property name="style"></property> + <property name="subclass">; ; forward_declare</property> + <property name="toolbar_pane">0</property> + <property name="tooltip">Python interpreter status</property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <property name="wrap">-1</property> + </object> + </object> + </object> + </object> + <object class="sizeritem" expanded="true"> + <property name="border">5</property> + <property name="flag">wxEXPAND</property> + <property name="proportion">1</property> + <object class="spacer" expanded="true"> + <property name="height">0</property> + <property name="permission">protected</property> + <property name="width">0</property> + </object> + </object> + </object> + </object> + </object> + </object> + </object> +</wxFormBuilder_Project> diff --git a/common/dialogs/panel_python_settings_base.h b/common/dialogs/panel_plugin_settings_base.h similarity index 76% rename from common/dialogs/panel_python_settings_base.h rename to common/dialogs/panel_plugin_settings_base.h index 05f13508d5..ab977531d3 100644 --- a/common/dialogs/panel_python_settings_base.h +++ b/common/dialogs/panel_plugin_settings_base.h @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////// -// C++ code generated with wxFormBuilder (version 3.10.1-0-g8feb16b3) +// C++ code generated with wxFormBuilder (version 4.0.0-0-g0efcecf-dirty) // http://www.wxformbuilder.org/ // // PLEASE DO *NOT* EDIT THIS FILE! @@ -17,30 +17,35 @@ #include <wx/font.h> #include <wx/colour.h> #include <wx/settings.h> +#include <wx/checkbox.h> +#include <wx/sizer.h> +#include <wx/statbox.h> #include <wx/filepicker.h> #include <wx/button.h> #include <wx/bitmap.h> #include <wx/image.h> #include <wx/icon.h> -#include <wx/sizer.h> -#include <wx/statbox.h> #include <wx/panel.h> /////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// -/// Class PANEL_PYTHON_SETTINGS_BASE +/// Class PANEL_PLUGIN_SETTINGS_BASE /////////////////////////////////////////////////////////////////////////////// -class PANEL_PYTHON_SETTINGS_BASE : public RESETTABLE_PANEL +class PANEL_PLUGIN_SETTINGS_BASE : public RESETTABLE_PANEL { private: protected: + wxStaticText* m_staticText3; + wxCheckBox* m_cbEnableApi; + wxStaticText* m_stApiStatus; wxStaticText* m_staticText2; wxFilePickerCtrl* m_pickerPythonInterpreter; wxButton* m_btnDetectAutomatically; // Virtual event handlers, override them in your derived class + virtual void OnEnableApiChecked( wxCommandEvent& event ) { event.Skip(); } virtual void OnPythonInterpreterChanged( wxFileDirPickerEvent& event ) { event.Skip(); } virtual void OnBtnDetectAutomaticallyClicked( wxCommandEvent& event ) { event.Skip(); } @@ -48,9 +53,9 @@ class PANEL_PYTHON_SETTINGS_BASE : public RESETTABLE_PANEL public: wxStaticText* m_stPythonStatus; - PANEL_PYTHON_SETTINGS_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxTAB_TRAVERSAL, const wxString& name = wxEmptyString ); + PANEL_PLUGIN_SETTINGS_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxTAB_TRAVERSAL, const wxString& name = wxEmptyString ); - ~PANEL_PYTHON_SETTINGS_BASE(); + ~PANEL_PLUGIN_SETTINGS_BASE(); }; diff --git a/common/dialogs/panel_python_settings_base.cpp b/common/dialogs/panel_python_settings_base.cpp deleted file mode 100644 index 0027bfde2e..0000000000 --- a/common/dialogs/panel_python_settings_base.cpp +++ /dev/null @@ -1,70 +0,0 @@ -/////////////////////////////////////////////////////////////////////////// -// C++ code generated with wxFormBuilder (version 3.10.1-0-g8feb16b3) -// http://www.wxformbuilder.org/ -// -// PLEASE DO *NOT* EDIT THIS FILE! -/////////////////////////////////////////////////////////////////////////// - -#include "panel_python_settings_base.h" - -/////////////////////////////////////////////////////////////////////////// - -PANEL_PYTHON_SETTINGS_BASE::PANEL_PYTHON_SETTINGS_BASE( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style, const wxString& name ) : RESETTABLE_PANEL( parent, id, pos, size, style, name ) -{ - wxBoxSizer* bPanelSizer; - bPanelSizer = new wxBoxSizer( wxHORIZONTAL ); - - wxBoxSizer* bSizer8; - bSizer8 = new wxBoxSizer( wxVERTICAL ); - - wxStaticBoxSizer* sbSizer1; - sbSizer1 = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Python Interpreter") ), wxVERTICAL ); - - wxBoxSizer* bSizer4; - bSizer4 = new wxBoxSizer( wxHORIZONTAL ); - - m_staticText2 = new wxStaticText( sbSizer1->GetStaticBox(), wxID_ANY, _("Path to Python interpreter:"), wxDefaultPosition, wxDefaultSize, 0 ); - m_staticText2->Wrap( -1 ); - bSizer4->Add( m_staticText2, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); - - m_pickerPythonInterpreter = new wxFilePickerCtrl( sbSizer1->GetStaticBox(), wxID_ANY, wxEmptyString, _("Select the path to a Python interpreter"), _("*.*"), wxDefaultPosition, wxDefaultSize, wxFLP_DEFAULT_STYLE|wxFLP_USE_TEXTCTRL ); - bSizer4->Add( m_pickerPythonInterpreter, 1, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); - - m_btnDetectAutomatically = new wxButton( sbSizer1->GetStaticBox(), wxID_ANY, _("Detect Automatically"), wxDefaultPosition, wxDefaultSize, 0 ); - bSizer4->Add( m_btnDetectAutomatically, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); - - - sbSizer1->Add( bSizer4, 0, wxEXPAND, 5 ); - - m_stPythonStatus = new wxStaticText( sbSizer1->GetStaticBox(), wxID_ANY, _("No Python interpreter chosen; external Python plugins will not be available"), wxDefaultPosition, wxDefaultSize, 0 ); - m_stPythonStatus->Wrap( -1 ); - m_stPythonStatus->SetToolTip( _("Python interpreter status") ); - - sbSizer1->Add( m_stPythonStatus, 0, wxALL, 5 ); - - - bSizer8->Add( sbSizer1, 0, wxALL|wxEXPAND, 5 ); - - - bSizer8->Add( 0, 0, 1, wxEXPAND, 5 ); - - - bPanelSizer->Add( bSizer8, 1, wxEXPAND, 5 ); - - - this->SetSizer( bPanelSizer ); - this->Layout(); - bPanelSizer->Fit( this ); - - // Connect Events - m_pickerPythonInterpreter->Connect( wxEVT_COMMAND_FILEPICKER_CHANGED, wxFileDirPickerEventHandler( PANEL_PYTHON_SETTINGS_BASE::OnPythonInterpreterChanged ), NULL, this ); - m_btnDetectAutomatically->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_PYTHON_SETTINGS_BASE::OnBtnDetectAutomaticallyClicked ), NULL, this ); -} - -PANEL_PYTHON_SETTINGS_BASE::~PANEL_PYTHON_SETTINGS_BASE() -{ - // Disconnect Events - m_pickerPythonInterpreter->Disconnect( wxEVT_COMMAND_FILEPICKER_CHANGED, wxFileDirPickerEventHandler( PANEL_PYTHON_SETTINGS_BASE::OnPythonInterpreterChanged ), NULL, this ); - m_btnDetectAutomatically->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_PYTHON_SETTINGS_BASE::OnBtnDetectAutomaticallyClicked ), NULL, this ); - -} diff --git a/common/dialogs/panel_python_settings_base.fbp b/common/dialogs/panel_python_settings_base.fbp deleted file mode 100644 index c55caeea53..0000000000 --- a/common/dialogs/panel_python_settings_base.fbp +++ /dev/null @@ -1,371 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="yes" ?> -<wxFormBuilder_Project> - <FileVersion major="1" minor="16" /> - <object class="Project" expanded="1"> - <property name="class_decoration"></property> - <property name="code_generation">C++</property> - <property name="disconnect_events">1</property> - <property name="disconnect_mode">source_name</property> - <property name="disconnect_php_events">0</property> - <property name="disconnect_python_events">0</property> - <property name="embedded_files_path">res</property> - <property name="encoding">UTF-8</property> - <property name="event_generation">connect</property> - <property name="file">panel_python_settings_base</property> - <property name="first_id">1000</property> - <property name="help_provider">none</property> - <property name="image_path_wrapper_function_name"></property> - <property name="indent_with_spaces"></property> - <property name="internationalize">1</property> - <property name="name">PanelPythonSettings</property> - <property name="namespace"></property> - <property name="path">.</property> - <property name="precompiled_header"></property> - <property name="relative_path">1</property> - <property name="skip_lua_events">1</property> - <property name="skip_php_events">1</property> - <property name="skip_python_events">1</property> - <property name="ui_table">UI</property> - <property name="use_array_enum">0</property> - <property name="use_enum">1</property> - <property name="use_microsoft_bom">0</property> - <object class="Panel" expanded="1"> - <property name="aui_managed">0</property> - <property name="aui_manager_style">wxAUI_MGR_DEFAULT</property> - <property name="bg"></property> - <property name="context_help"></property> - <property name="context_menu">1</property> - <property name="enabled">1</property> - <property name="event_handler">impl_virtual</property> - <property name="fg"></property> - <property name="font"></property> - <property name="hidden">0</property> - <property name="id">wxID_ANY</property> - <property name="maximum_size"></property> - <property name="minimum_size"></property> - <property name="name">PANEL_PYTHON_SETTINGS_BASE</property> - <property name="pos"></property> - <property name="size">-1,-1</property> - <property name="subclass">RESETTABLE_PANEL; widgets/resettable_panel.h; Not forward_declare</property> - <property name="tooltip"></property> - <property name="two_step_creation">0</property> - <property name="window_extra_style"></property> - <property name="window_name"></property> - <property name="window_style">wxTAB_TRAVERSAL</property> - <object class="wxBoxSizer" expanded="1"> - <property name="minimum_size"></property> - <property name="name">bPanelSizer</property> - <property name="orient">wxHORIZONTAL</property> - <property name="permission">none</property> - <object class="sizeritem" expanded="1"> - <property name="border">5</property> - <property name="flag">wxEXPAND</property> - <property name="proportion">1</property> - <object class="wxBoxSizer" expanded="1"> - <property name="minimum_size"></property> - <property name="name">bSizer8</property> - <property name="orient">wxVERTICAL</property> - <property name="permission">none</property> - <object class="sizeritem" expanded="1"> - <property name="border">5</property> - <property name="flag">wxALL|wxEXPAND</property> - <property name="proportion">0</property> - <object class="wxStaticBoxSizer" expanded="1"> - <property name="id">wxID_ANY</property> - <property name="label">Python Interpreter</property> - <property name="minimum_size"></property> - <property name="name">sbSizer1</property> - <property name="orient">wxVERTICAL</property> - <property name="parent">1</property> - <property name="permission">none</property> - <object class="sizeritem" expanded="1"> - <property name="border">5</property> - <property name="flag">wxEXPAND</property> - <property name="proportion">0</property> - <object class="wxBoxSizer" expanded="1"> - <property name="minimum_size"></property> - <property name="name">bSizer4</property> - <property name="orient">wxHORIZONTAL</property> - <property name="permission">none</property> - <object class="sizeritem" expanded="1"> - <property name="border">5</property> - <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property> - <property name="proportion">0</property> - <object class="wxStaticText" expanded="1"> - <property name="BottomDockable">1</property> - <property name="LeftDockable">1</property> - <property name="RightDockable">1</property> - <property name="TopDockable">1</property> - <property name="aui_layer"></property> - <property name="aui_name"></property> - <property name="aui_position"></property> - <property name="aui_row"></property> - <property name="best_size"></property> - <property name="bg"></property> - <property name="caption"></property> - <property name="caption_visible">1</property> - <property name="center_pane">0</property> - <property name="close_button">1</property> - <property name="context_help"></property> - <property name="context_menu">1</property> - <property name="default_pane">0</property> - <property name="dock">Dock</property> - <property name="dock_fixed">0</property> - <property name="docking">Left</property> - <property name="enabled">1</property> - <property name="fg"></property> - <property name="floatable">1</property> - <property name="font"></property> - <property name="gripper">0</property> - <property name="hidden">0</property> - <property name="id">wxID_ANY</property> - <property name="label">Path to Python interpreter:</property> - <property name="markup">0</property> - <property name="max_size"></property> - <property name="maximize_button">0</property> - <property name="maximum_size"></property> - <property name="min_size"></property> - <property name="minimize_button">0</property> - <property name="minimum_size"></property> - <property name="moveable">1</property> - <property name="name">m_staticText2</property> - <property name="pane_border">1</property> - <property name="pane_position"></property> - <property name="pane_size"></property> - <property name="permission">protected</property> - <property name="pin_button">1</property> - <property name="pos"></property> - <property name="resize">Resizable</property> - <property name="show">1</property> - <property name="size"></property> - <property name="style"></property> - <property name="subclass">; ; forward_declare</property> - <property name="toolbar_pane">0</property> - <property name="tooltip"></property> - <property name="window_extra_style"></property> - <property name="window_name"></property> - <property name="window_style"></property> - <property name="wrap">-1</property> - </object> - </object> - <object class="sizeritem" expanded="1"> - <property name="border">5</property> - <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property> - <property name="proportion">1</property> - <object class="wxFilePickerCtrl" expanded="1"> - <property name="BottomDockable">1</property> - <property name="LeftDockable">1</property> - <property name="RightDockable">1</property> - <property name="TopDockable">1</property> - <property name="aui_layer"></property> - <property name="aui_name"></property> - <property name="aui_position"></property> - <property name="aui_row"></property> - <property name="best_size"></property> - <property name="bg"></property> - <property name="caption"></property> - <property name="caption_visible">1</property> - <property name="center_pane">0</property> - <property name="close_button">1</property> - <property name="context_help"></property> - <property name="context_menu">1</property> - <property name="default_pane">0</property> - <property name="dock">Dock</property> - <property name="dock_fixed">0</property> - <property name="docking">Left</property> - <property name="enabled">1</property> - <property name="fg"></property> - <property name="floatable">1</property> - <property name="font"></property> - <property name="gripper">0</property> - <property name="hidden">0</property> - <property name="id">wxID_ANY</property> - <property name="max_size"></property> - <property name="maximize_button">0</property> - <property name="maximum_size"></property> - <property name="message">Select the path to a Python interpreter</property> - <property name="min_size"></property> - <property name="minimize_button">0</property> - <property name="minimum_size"></property> - <property name="moveable">1</property> - <property name="name">m_pickerPythonInterpreter</property> - <property name="pane_border">1</property> - <property name="pane_position"></property> - <property name="pane_size"></property> - <property name="permission">protected</property> - <property name="pin_button">1</property> - <property name="pos"></property> - <property name="resize">Resizable</property> - <property name="show">1</property> - <property name="size"></property> - <property name="style">wxFLP_DEFAULT_STYLE|wxFLP_USE_TEXTCTRL</property> - <property name="subclass">; ; forward_declare</property> - <property name="toolbar_pane">0</property> - <property name="tooltip"></property> - <property name="validator_data_type"></property> - <property name="validator_style">wxFILTER_NONE</property> - <property name="validator_type">wxDefaultValidator</property> - <property name="validator_variable"></property> - <property name="value"></property> - <property name="wildcard">*.*</property> - <property name="window_extra_style"></property> - <property name="window_name"></property> - <property name="window_style"></property> - <event name="OnFileChanged">OnPythonInterpreterChanged</event> - </object> - </object> - <object class="sizeritem" expanded="1"> - <property name="border">5</property> - <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property> - <property name="proportion">0</property> - <object class="wxButton" expanded="1"> - <property name="BottomDockable">1</property> - <property name="LeftDockable">1</property> - <property name="RightDockable">1</property> - <property name="TopDockable">1</property> - <property name="aui_layer"></property> - <property name="aui_name"></property> - <property name="aui_position"></property> - <property name="aui_row"></property> - <property name="auth_needed">0</property> - <property name="best_size"></property> - <property name="bg"></property> - <property name="bitmap"></property> - <property name="caption"></property> - <property name="caption_visible">1</property> - <property name="center_pane">0</property> - <property name="close_button">1</property> - <property name="context_help"></property> - <property name="context_menu">1</property> - <property name="current"></property> - <property name="default">0</property> - <property name="default_pane">0</property> - <property name="disabled"></property> - <property name="dock">Dock</property> - <property name="dock_fixed">0</property> - <property name="docking">Left</property> - <property name="enabled">1</property> - <property name="fg"></property> - <property name="floatable">1</property> - <property name="focus"></property> - <property name="font"></property> - <property name="gripper">0</property> - <property name="hidden">0</property> - <property name="id">wxID_ANY</property> - <property name="label">Detect Automatically</property> - <property name="margins"></property> - <property name="markup">0</property> - <property name="max_size"></property> - <property name="maximize_button">0</property> - <property name="maximum_size"></property> - <property name="min_size"></property> - <property name="minimize_button">0</property> - <property name="minimum_size"></property> - <property name="moveable">1</property> - <property name="name">m_btnDetectAutomatically</property> - <property name="pane_border">1</property> - <property name="pane_position"></property> - <property name="pane_size"></property> - <property name="permission">protected</property> - <property name="pin_button">1</property> - <property name="pos"></property> - <property name="position"></property> - <property name="pressed"></property> - <property name="resize">Resizable</property> - <property name="show">1</property> - <property name="size"></property> - <property name="style"></property> - <property name="subclass">; ; forward_declare</property> - <property name="toolbar_pane">0</property> - <property name="tooltip"></property> - <property name="validator_data_type"></property> - <property name="validator_style">wxFILTER_NONE</property> - <property name="validator_type">wxDefaultValidator</property> - <property name="validator_variable"></property> - <property name="window_extra_style"></property> - <property name="window_name"></property> - <property name="window_style"></property> - <event name="OnButtonClick">OnBtnDetectAutomaticallyClicked</event> - </object> - </object> - </object> - </object> - <object class="sizeritem" expanded="1"> - <property name="border">5</property> - <property name="flag">wxALL</property> - <property name="proportion">0</property> - <object class="wxStaticText" expanded="1"> - <property name="BottomDockable">1</property> - <property name="LeftDockable">1</property> - <property name="RightDockable">1</property> - <property name="TopDockable">1</property> - <property name="aui_layer"></property> - <property name="aui_name"></property> - <property name="aui_position"></property> - <property name="aui_row"></property> - <property name="best_size"></property> - <property name="bg"></property> - <property name="caption"></property> - <property name="caption_visible">1</property> - <property name="center_pane">0</property> - <property name="close_button">1</property> - <property name="context_help"></property> - <property name="context_menu">1</property> - <property name="default_pane">0</property> - <property name="dock">Dock</property> - <property name="dock_fixed">0</property> - <property name="docking">Left</property> - <property name="enabled">1</property> - <property name="fg"></property> - <property name="floatable">1</property> - <property name="font"></property> - <property name="gripper">0</property> - <property name="hidden">0</property> - <property name="id">wxID_ANY</property> - <property name="label">No Python interpreter chosen; external Python plugins will not be available</property> - <property name="markup">0</property> - <property name="max_size"></property> - <property name="maximize_button">0</property> - <property name="maximum_size"></property> - <property name="min_size"></property> - <property name="minimize_button">0</property> - <property name="minimum_size"></property> - <property name="moveable">1</property> - <property name="name">m_stPythonStatus</property> - <property name="pane_border">1</property> - <property name="pane_position"></property> - <property name="pane_size"></property> - <property name="permission">public</property> - <property name="pin_button">1</property> - <property name="pos"></property> - <property name="resize">Resizable</property> - <property name="show">1</property> - <property name="size"></property> - <property name="style"></property> - <property name="subclass">; ; forward_declare</property> - <property name="toolbar_pane">0</property> - <property name="tooltip">Python interpreter status</property> - <property name="window_extra_style"></property> - <property name="window_name"></property> - <property name="window_style"></property> - <property name="wrap">-1</property> - </object> - </object> - </object> - </object> - <object class="sizeritem" expanded="1"> - <property name="border">5</property> - <property name="flag">wxEXPAND</property> - <property name="proportion">1</property> - <object class="spacer" expanded="1"> - <property name="height">0</property> - <property name="permission">protected</property> - <property name="width">0</property> - </object> - </object> - </object> - </object> - </object> - </object> - </object> -</wxFormBuilder_Project> diff --git a/common/eda_base_frame.cpp b/common/eda_base_frame.cpp index 4333c77f48..8f5629716e 100644 --- a/common/eda_base_frame.cpp +++ b/common/eda_base_frame.cpp @@ -32,7 +32,7 @@ #include <dialogs/panel_common_settings.h> #include <dialogs/panel_mouse_settings.h> #include <dialogs/panel_data_collection.h> -#include <dialogs/panel_python_settings.h> +#include <dialogs/panel_plugin_settings.h> #include <eda_dde.h> #include <file_history.h> #include <id.h> @@ -1237,7 +1237,7 @@ void EDA_BASE_FRAME::ShowPreferences( wxString aStartPage, wxString aStartParent } #ifdef KICAD_IPC_API - book->AddPage( new PANEL_PYTHON_SETTINGS( book ), _( "Python Scripting" ) ); + book->AddPage( new PANEL_PLUGIN_SETTINGS( book ), _( "Plugins" ) ); #endif // Update all of the action hotkeys. The process of loading the actions through diff --git a/common/pgm_base.cpp b/common/pgm_base.cpp index 3a63de7bd5..5347753b47 100644 --- a/common/pgm_base.cpp +++ b/common/pgm_base.cpp @@ -77,6 +77,7 @@ #ifdef KICAD_IPC_API #include <api/api_plugin_manager.h> #include <api/api_server.h> +#include <python_manager.h> #endif /** @@ -570,13 +571,20 @@ bool PGM_BASE::InitPgm( bool aHeadless, bool aSkipPyInit, bool aIsUnitTest ) return false; // Set up built-in environment variables (and override them from the system environment if set) - GetCommonSettings()->InitializeEnvironment(); + COMMON_SETTINGS* commonSettings = GetCommonSettings(); + commonSettings->InitializeEnvironment(); // Load color settings after env is initialized m_settings_manager->ReloadColorSettings(); // Load common settings from disk after setting up env vars - GetSettingsManager().Load( GetCommonSettings() ); + GetSettingsManager().Load( commonSettings ); + +#ifdef KICAD_IPC_API + // If user doesn't have a saved Python interpreter, try (potentially again) to find one + if( commonSettings->m_Api.python_interpreter.IsEmpty() ) + commonSettings->m_Api.python_interpreter = PYTHON_MANAGER::FindPythonInterpreter(); +#endif // Init user language *before* calling loadSettings, because // env vars could be incorrectly initialized on Linux @@ -1058,4 +1066,4 @@ PGM_BASE* PgmOrNull() void SetPgm(PGM_BASE* pgm) { process = pgm; -} \ No newline at end of file +} diff --git a/common/settings/common_settings.cpp b/common/settings/common_settings.cpp index 7ff028d306..49920717a1 100644 --- a/common/settings/common_settings.cpp +++ b/common/settings/common_settings.cpp @@ -54,7 +54,7 @@ COMMON_SETTINGS::COMMON_SETTINGS() : m_DoNotShowAgain(), m_NetclassPanel(), m_PackageManager(), - m_Python() + m_Api() { /* * Automatic dark mode detection works fine on Mac. @@ -398,8 +398,11 @@ COMMON_SETTINGS::COMMON_SETTINGS() : m_params.emplace_back( new PARAM<bool>( "git.useDefaultAuthor", &m_Git.useDefaultAuthor, true ) ); - m_params.emplace_back( new PARAM<wxString>( "python.interpreter_path", - &m_Python.interpreter_path, wxS( "" ) ) ); + m_params.emplace_back( new PARAM<wxString>( "api.interpreter_path", + &m_Api.python_interpreter, wxS( "" ) ) ); + + m_params.emplace_back( new PARAM<bool>( "api.enable_server", + &m_Api.enable_server, false ) ); registerMigration( 0, 1, std::bind( &COMMON_SETTINGS::migrateSchema0to1, this ) ); registerMigration( 1, 2, std::bind( &COMMON_SETTINGS::migrateSchema1to2, this ) ); diff --git a/include/api/api_server.h b/include/api/api_server.h index 6e635ed1c4..c19ca3744e 100644 --- a/include/api/api_server.h +++ b/include/api/api_server.h @@ -44,6 +44,8 @@ public: ~KICAD_API_SERVER(); + bool Running() const; + /** * Adds a new request handler to the server. Each handler maintains its own list of API * messages that it knows how to handle, and the server will pass every incoming message to all @@ -60,7 +62,7 @@ public: void SetReadyToReply( bool aReady = true ) { m_readyToReply = aReady; } - const std::string& SocketPath() const { return m_socketPath; } + std::string SocketPath() const; const std::string& Token() const { return m_token; } @@ -87,8 +89,6 @@ private: std::set<API_HANDLER*> m_handlers; - std::string m_socketPath; - std::string m_token; bool m_readyToReply; diff --git a/include/dialogs/panel_python_settings.h b/include/dialogs/panel_plugin_settings.h similarity index 72% rename from include/dialogs/panel_python_settings.h rename to include/dialogs/panel_plugin_settings.h index 3750b3bb7d..d1b2017115 100644 --- a/include/dialogs/panel_python_settings.h +++ b/include/dialogs/panel_plugin_settings.h @@ -18,18 +18,18 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#ifndef KICAD_PANEL_PYTHON_SETTINGS_H -#define KICAD_PANEL_PYTHON_SETTINGS_H +#ifndef KICAD_PANEL_PLUGIN_SETTINGS_H +#define KICAD_PANEL_PLUGIN_SETTINGS_H -#include <dialogs/panel_python_settings_base.h> +#include <dialogs/panel_plugin_settings_base.h> class PAGED_DIALOG; -class PANEL_PYTHON_SETTINGS : public PANEL_PYTHON_SETTINGS_BASE +class PANEL_PLUGIN_SETTINGS : public PANEL_PLUGIN_SETTINGS_BASE { public: - PANEL_PYTHON_SETTINGS( wxWindow* aParent ); + PANEL_PLUGIN_SETTINGS( wxWindow* aParent ); void ResetPanel() override; @@ -39,11 +39,13 @@ protected: void OnPythonInterpreterChanged( wxFileDirPickerEvent& event ) override; void OnBtnDetectAutomaticallyClicked( wxCommandEvent& aEvent ) override; + void OnEnableApiChecked( wxCommandEvent& aEvent ) override; private: - void validateInterpreter(); + void updateApiStatusText(); + void validatePythonInterpreter(); - bool m_interpreterValid; + bool m_pythonInterpreterValid; }; -#endif //KICAD_PANEL_PYTHON_SETTINGS_H +#endif //KICAD_PANEL_PLUGIN_SETTINGS_H diff --git a/include/settings/common_settings.h b/include/settings/common_settings.h index e6105ba886..438bae7ac5 100644 --- a/include/settings/common_settings.h +++ b/include/settings/common_settings.h @@ -166,9 +166,10 @@ public: wxString authorEmail; }; - struct PYTHON + struct API { - wxString interpreter_path; + wxString python_interpreter; + bool enable_server; }; COMMON_SETTINGS(); @@ -223,7 +224,7 @@ public: GIT m_Git; - PYTHON m_Python; + API m_Api; }; #endif diff --git a/libs/kinng/include/kinng.h b/libs/kinng/include/kinng.h index 165175d081..a10c57df12 100644 --- a/libs/kinng/include/kinng.h +++ b/libs/kinng/include/kinng.h @@ -31,7 +31,7 @@ class KINNG_REQUEST_SERVER { public: - KINNG_REQUEST_SERVER(); + KINNG_REQUEST_SERVER( const std::string& aSocketUrl ); ~KINNG_REQUEST_SERVER(); @@ -39,6 +39,8 @@ public: void Stop(); + bool Running() const; + void SetCallback( std::function<void(std::string*)> aFunc ) { m_callback = aFunc; } void Reply( const std::string& aReply ); diff --git a/libs/kinng/src/kinng.cpp b/libs/kinng/src/kinng.cpp index 8c86e540ec..efce869e89 100644 --- a/libs/kinng/src/kinng.cpp +++ b/libs/kinng/src/kinng.cpp @@ -21,18 +21,12 @@ #include <kinng.h> #include <nng/nng.h> #include <nng/protocol/reqrep0/rep.h> -#include <nng/protocol/reqrep0/req.h> -KINNG_REQUEST_SERVER::KINNG_REQUEST_SERVER() : +KINNG_REQUEST_SERVER::KINNG_REQUEST_SERVER( const std::string& aSocketUrl ) : + m_socketUrl( aSocketUrl ), m_callback() { -#ifdef WIN32 - m_socketUrl = "ipc://\\.\\pipe\\kicad"; -#else - m_socketUrl = "ipc:///tmp/kicad.sock"; -#endif - Start(); } @@ -43,6 +37,12 @@ KINNG_REQUEST_SERVER::~KINNG_REQUEST_SERVER() } +bool KINNG_REQUEST_SERVER::Running() const +{ + return m_thread.joinable(); +} + + bool KINNG_REQUEST_SERVER::Start() { m_shutdown.store( false ); diff --git a/pcbnew/toolbars_pcb_editor.cpp b/pcbnew/toolbars_pcb_editor.cpp index e84620cfbc..9e1def8378 100644 --- a/pcbnew/toolbars_pcb_editor.cpp +++ b/pcbnew/toolbars_pcb_editor.cpp @@ -284,7 +284,7 @@ void PCB_EDIT_FRAME::ReCreateHToolbar() // Add SWIG and API plugins bool scriptingAvailable = SCRIPTING::IsWxAvailable(); - bool haveApiPlugins = + bool haveApiPlugins = Pgm().GetCommonSettings()->m_Api.enable_server && !Pgm().GetPluginManager().GetActionsForScope( PLUGIN_ACTION_SCOPE::PCB ).empty(); if( scriptingAvailable || haveApiPlugins ) diff --git a/qa/tests/libs/kinng/test_kinng.cpp b/qa/tests/libs/kinng/test_kinng.cpp index 74b1d2ad2e..0898a55558 100644 --- a/qa/tests/libs/kinng/test_kinng.cpp +++ b/qa/tests/libs/kinng/test_kinng.cpp @@ -18,6 +18,9 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include <wx/filename.h> +#include <wx/stdpaths.h> + #include <qa_utils/wx_utils/unit_test_utils.h> #include <kinng.h> @@ -28,7 +31,7 @@ BOOST_AUTO_TEST_SUITE( KiNNG ) BOOST_AUTO_TEST_CASE( CreateIPCResponder ) { - KINNG_REQUEST_SERVER server; + KINNG_REQUEST_SERVER server( wxFileName::CreateTempFileName( "test-kinng" ).ToStdString() ); } BOOST_AUTO_TEST_SUITE_END()