diff --git a/common/api/api_plugin_manager.cpp b/common/api/api_plugin_manager.cpp index aaa4e76f5a..77f10d3f70 100644 --- a/common/api/api_plugin_manager.cpp +++ b/common/api/api_plugin_manager.cpp @@ -159,9 +159,42 @@ void API_PLUGIN_MANAGER::ReloadPlugins() } +void API_PLUGIN_MANAGER::RecreatePluginEnvironment( const wxString& aIdentifier ) +{ + if( !m_pluginsCache.contains( aIdentifier ) ) + return; + + const API_PLUGIN* plugin = m_pluginsCache.at( aIdentifier ); + wxCHECK( plugin, /* void */ ); + + std::optional<wxString> env = PYTHON_MANAGER::GetPythonEnvironment( plugin->Identifier() ); + wxCHECK( env.has_value(), /* void */ ); + + wxFileName envConfigPath( *env, wxS( "pyvenv.cfg" ) ); + envConfigPath.MakeAbsolute(); + + if( envConfigPath.DirExists() && envConfigPath.Rmdir( wxPATH_RMDIR_RECURSIVE ) ) + { + wxLogTrace( traceApi, + wxString::Format( "Manager: Removed existing Python environment at %s for %s", + envConfigPath.GetPath(), plugin->Identifier() ) ); + + JOB job; + job.type = JOB_TYPE::CREATE_ENV; + job.identifier = plugin->Identifier(); + job.plugin_path = plugin->BasePath(); + job.env_path = envConfigPath.GetPath(); + m_jobs.emplace_back( job ); + + wxCommandEvent* evt = new wxCommandEvent( EDA_EVT_PLUGIN_MANAGER_JOB_FINISHED, wxID_ANY ); + QueueEvent( evt ); + } +} + + std::optional<const PLUGIN_ACTION*> API_PLUGIN_MANAGER::GetAction( const wxString& aIdentifier ) { - if( !m_actionsCache.count( aIdentifier ) ) + if( !m_actionsCache.contains( aIdentifier ) ) return std::nullopt; return m_actionsCache.at( aIdentifier ); @@ -170,7 +203,7 @@ std::optional<const PLUGIN_ACTION*> API_PLUGIN_MANAGER::GetAction( const wxStrin void API_PLUGIN_MANAGER::InvokeAction( const wxString& aIdentifier ) { - if( !m_actionsCache.count( aIdentifier ) ) + if( !m_actionsCache.contains( aIdentifier ) ) return; const PLUGIN_ACTION* action = m_actionsCache.at( aIdentifier ); diff --git a/include/api/api_plugin_manager.h b/include/api/api_plugin_manager.h index 0ab9996702..1b34895a30 100644 --- a/include/api/api_plugin_manager.h +++ b/include/api/api_plugin_manager.h @@ -44,6 +44,8 @@ public: void ReloadPlugins(); + void RecreatePluginEnvironment( const wxString& aIdentifier ); + void InvokeAction( const wxString& aIdentifier ); std::optional<const PLUGIN_ACTION*> GetAction( const wxString& aIdentifier ); diff --git a/pcbnew/dialogs/panel_pcbnew_action_plugins.cpp b/pcbnew/dialogs/panel_pcbnew_action_plugins.cpp index 5e4e7bd0e5..60e541b506 100644 --- a/pcbnew/dialogs/panel_pcbnew_action_plugins.cpp +++ b/pcbnew/dialogs/panel_pcbnew_action_plugins.cpp @@ -40,11 +40,70 @@ #define GRID_CELL_MARGIN 4 +enum +{ + MYID_RECREATE_ENV = GRIDTRICKS_FIRST_CLIENT_ID +}; + +class PLUGINS_GRID_TRICKS : public GRID_TRICKS +{ +public: + PLUGINS_GRID_TRICKS( WX_GRID* aGrid ) : + GRID_TRICKS( aGrid ) + {} + +protected: + void showPopupMenu( wxMenu& menu, wxGridEvent& aEvent ) override; + void doPopupSelection( wxCommandEvent& event ) override; +}; + + +void PLUGINS_GRID_TRICKS::showPopupMenu( wxMenu& menu, wxGridEvent& aEvent ) +{ +#ifdef KICAD_IPC_API + API_PLUGIN_MANAGER& mgr = Pgm().GetPluginManager(); + wxString id = m_grid->GetCellValue( m_grid->GetGridCursorRow(), + PANEL_PCBNEW_ACTION_PLUGINS::COLUMN_SETTINGS_IDENTIFIER ); + + if( std::optional<const PLUGIN_ACTION*> action = mgr.GetAction( id ) ) + { + menu.Append( MYID_RECREATE_ENV, _( "Recreate Plugin Environment" ), + _( "Recreate Plugin Environment" ) ); + menu.AppendSeparator(); + } +#endif + + GRID_TRICKS::showPopupMenu( menu, aEvent ); +} + + +void PLUGINS_GRID_TRICKS::doPopupSelection( wxCommandEvent& event ) +{ + if( event.GetId() == MYID_RECREATE_ENV ) + { +#ifdef KICAD_IPC_API + API_PLUGIN_MANAGER& mgr = Pgm().GetPluginManager(); + wxString id = m_grid->GetCellValue( m_grid->GetGridCursorRow(), + PANEL_PCBNEW_ACTION_PLUGINS::COLUMN_SETTINGS_IDENTIFIER ); + + if( std::optional<const PLUGIN_ACTION*> action = mgr.GetAction( id ) ) + { + mgr.RecreatePluginEnvironment( ( *action )->plugin.Identifier() ); + } +#endif + } + else + { + GRID_TRICKS::doPopupSelection( event ); + } +} + + PANEL_PCBNEW_ACTION_PLUGINS::PANEL_PCBNEW_ACTION_PLUGINS( wxWindow* aParent ) : PANEL_PCBNEW_ACTION_PLUGINS_BASE( aParent ) { m_genericIcon = KiBitmapBundle( BITMAPS::puzzle_piece ); - m_grid->PushEventHandler( new GRID_TRICKS( m_grid ) ); + m_grid->PushEventHandler( new PLUGINS_GRID_TRICKS( m_grid ) ); m_grid->SetUseNativeColLabels(); m_moveUpButton->SetBitmap( KiBitmapBundle( BITMAPS::small_up ) ); diff --git a/pcbnew/dialogs/panel_pcbnew_action_plugins.h b/pcbnew/dialogs/panel_pcbnew_action_plugins.h index 2036f27f88..fbb78b2dfd 100644 --- a/pcbnew/dialogs/panel_pcbnew_action_plugins.h +++ b/pcbnew/dialogs/panel_pcbnew_action_plugins.h @@ -20,8 +20,13 @@ #include "panel_pcbnew_action_plugins_base.h" +class PLUGINS_GRID_TRICKS; + + class PANEL_PCBNEW_ACTION_PLUGINS : public PANEL_PCBNEW_ACTION_PLUGINS_BASE { + friend class PLUGINS_GRID_TRICKS; + public: PANEL_PCBNEW_ACTION_PLUGINS ( wxWindow* aParent );