KiCad PCB EDA Suite
Loading...
Searching...
No Matches
panel_pcbnew_action_plugins.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright (C) 2018 Andrew Lutsenko, anlutsenko at gmail dot com
5 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
6 *
7 * This program is free software: you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation, either version 3 of the License, or (at your
10 * option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21#include <action_plugin.h>
22#include <api/api_plugin.h>
23#include <bitmaps.h>
25#include <grid_tricks.h>
26#include <kiface_base.h>
27#include <kiplatform/ui.h>
29#include <pcb_edit_frame.h>
31#include <pcb_scripting_tool.h>
32#include <pcbnew_settings.h>
33#include <pgm_base.h>
38#include <widgets/wx_grid.h>
40
41
42#define GRID_CELL_MARGIN 4
43
44enum
45{
47};
48
50{
51public:
53 GRID_TRICKS( aGrid )
54 {}
55
56protected:
57 void showPopupMenu( wxMenu& menu, wxGridEvent& aEvent ) override;
58 void doPopupSelection( wxCommandEvent& event ) override;
59};
60
61
62void PLUGINS_GRID_TRICKS::showPopupMenu( wxMenu& menu, wxGridEvent& aEvent )
63{
64#ifdef KICAD_IPC_API
65 API_PLUGIN_MANAGER& mgr = Pgm().GetPluginManager();
66 wxString id = m_grid->GetCellValue( m_grid->GetGridCursorRow(),
68
69 if( std::optional<const PLUGIN_ACTION*> action = mgr.GetAction( id ) )
70 {
71 menu.Append( MYID_RECREATE_ENV, _( "Recreate Plugin Environment" ), _( "Recreate Plugin Environment" ) );
72 menu.AppendSeparator();
73 }
74#endif
75
76 GRID_TRICKS::showPopupMenu( menu, aEvent );
77}
78
79
80void PLUGINS_GRID_TRICKS::doPopupSelection( wxCommandEvent& event )
81{
82 if( event.GetId() == MYID_RECREATE_ENV )
83 {
84#ifdef KICAD_IPC_API
85 API_PLUGIN_MANAGER& mgr = Pgm().GetPluginManager();
86 wxString id = m_grid->GetCellValue( m_grid->GetGridCursorRow(),
88
89 if( std::optional<const PLUGIN_ACTION*> action = mgr.GetAction( id ) )
90 mgr.RecreatePluginEnvironment( ( *action )->plugin.Identifier() );
91#endif
92 }
93 else
94 {
96 }
97}
98
99
113
114
119
120
122{
123 SelectRow( event.GetRow() );
124}
125
126
128{
129 m_grid->ClearSelection();
130 m_grid->SelectRow( aRow );
131}
132
133
135{
136 m_grid->OnMoveRowUp(
137 [&]( int row )
138 {
139 SwapRows( row, row - 1 );
140 } );
141}
142
143
145{
146 m_grid->OnMoveRowDown(
147 [&]( int row )
148 {
149 SwapRows( row, row + 1 );
150 } );
151}
152
153
154void PANEL_PCBNEW_ACTION_PLUGINS::SwapRows( int aRowA, int aRowB )
155{
156 m_grid->Freeze();
157
158 m_grid->SwapRows( aRowA, aRowB );
159
160 // Swap icon column renderers
161 auto cellRenderer = m_grid->GetCellRenderer( aRowA, COLUMN_ACTION_NAME );
162 m_grid->SetCellRenderer( aRowA, COLUMN_ACTION_NAME, m_grid->GetCellRenderer( aRowB, COLUMN_ACTION_NAME ) );
163 m_grid->SetCellRenderer( aRowB, COLUMN_ACTION_NAME, cellRenderer );
164
165 m_grid->Thaw();
166}
167
168
174
175
177{
178 PCBNEW_SETTINGS* settings = dynamic_cast<PCBNEW_SETTINGS*>( Kiface().KifaceSettings() );
179 wxASSERT( settings );
180
181#ifdef KICAD_IPC_API
182 API_PLUGIN_MANAGER& mgr = Pgm().GetPluginManager();
183
184 if( settings )
185 {
186 settings->m_VisibleActionPlugins.clear();
187 settings->m_Plugins.actions.clear();
188
189 for( int ii = 0; ii < m_grid->GetNumberRows(); ii++ )
190 {
191 wxString id = m_grid->GetCellValue( ii, COLUMN_SETTINGS_IDENTIFIER );
192
193 if( mgr.GetAction( id ) != std::nullopt )
194 {
195 settings->m_Plugins.actions.emplace_back( std::make_pair(
196 id, m_grid->GetCellValue( ii, COLUMN_VISIBLE ) == wxT( "1" ) ) );
197 }
198 else
199 {
200 settings->m_VisibleActionPlugins.emplace_back( std::make_pair(
201 id, m_grid->GetCellValue( ii, COLUMN_VISIBLE ) == wxT( "1" ) ) );
202 }
203 }
204 }
205#else
206 if( settings )
207 {
208 settings->m_VisibleActionPlugins.clear();
209
210 for( int ii = 0; ii < m_grid->GetNumberRows(); ii++ )
211 {
212 wxString id = m_grid->GetCellValue( ii, COLUMN_SETTINGS_IDENTIFIER );
213
214 settings->m_VisibleActionPlugins.emplace_back( std::make_pair(
215 id, m_grid->GetCellValue( ii, COLUMN_VISIBLE ) == wxT( "1" ) ) );
216 }
217 }
218#endif
219
220 return true;
221}
222
223
225{
226 m_grid->Freeze();
227
228 m_grid->ClearRows();
229
230 const std::vector<LEGACY_OR_API_PLUGIN>& orderedPlugins = PCB_EDIT_FRAME::GetOrderedActionPlugins();
231 m_grid->AppendRows( orderedPlugins.size() );
232
234 wxSize iconSize( size, size );
235
236 for( size_t row = 0; row < orderedPlugins.size(); row++ )
237 {
238 if( std::holds_alternative<ACTION_PLUGIN*>( orderedPlugins[row] ) )
239 {
240 auto ap = std::get<ACTION_PLUGIN*>( orderedPlugins[row] );
241
242 // Icon
243 m_grid->SetCellRenderer( row, COLUMN_ACTION_NAME,
244 new GRID_CELL_ICON_TEXT_RENDERER( ap->iconBitmap.IsOk() ? wxBitmapBundle( ap->iconBitmap )
246 iconSize ) );
247 m_grid->SetCellValue( row, COLUMN_ACTION_NAME, ap->GetName() );
248 m_grid->SetCellValue( row, COLUMN_SETTINGS_IDENTIFIER, ap->GetPluginPath() );
249
250 // Toolbar button checkbox
251 m_grid->SetCellRenderer( row, COLUMN_VISIBLE, new wxGridCellBoolRenderer() );
252 m_grid->SetCellAlignment( row, COLUMN_VISIBLE, wxALIGN_CENTER, wxALIGN_CENTER );
253
254 bool show = PCB_EDIT_FRAME::GetActionPluginButtonVisible( ap->GetPluginPath(),
255 ap->GetShowToolbarButton() );
256
257 m_grid->SetCellValue( row, COLUMN_VISIBLE, show ? wxT( "1" ) : wxEmptyString );
258
259 m_grid->SetCellValue( row, COLUMN_PLUGIN_NAME, ap->GetClassName() );
260 m_grid->SetCellValue( row, COLUMN_DESCRIPTION, ap->GetDescription() );
261 }
262 else
263 {
264#ifdef KICAD_IPC_API
265 auto action = std::get<const PLUGIN_ACTION*>( orderedPlugins[row] );
266
267 const wxBitmapBundle& icon = KIPLATFORM::UI::IsDarkTheme() && action->icon_dark.IsOk() ? action->icon_dark
268 : action->icon_light;
269
270 // Icon
271 m_grid->SetCellRenderer( row, COLUMN_ACTION_NAME, new GRID_CELL_ICON_TEXT_RENDERER(
272 icon.IsOk() ? icon : m_genericIcon, iconSize ) );
273 m_grid->SetCellValue( row, COLUMN_ACTION_NAME, action->name );
274 m_grid->SetCellValue( row, COLUMN_SETTINGS_IDENTIFIER, action->identifier );
275
276 // Toolbar button checkbox
277 m_grid->SetCellRenderer( row, COLUMN_VISIBLE, new wxGridCellBoolRenderer() );
278 m_grid->SetCellAlignment( row, COLUMN_VISIBLE, wxALIGN_CENTER, wxALIGN_CENTER );
279
280 bool show = PCB_EDIT_FRAME::GetActionPluginButtonVisible( action->identifier, action->show_button );
281
282 m_grid->SetCellValue( row, COLUMN_VISIBLE, show ? wxT( "1" ) : wxEmptyString );
283
284 m_grid->SetCellValue( row, COLUMN_PLUGIN_NAME, action->plugin.Name() );
285 m_grid->SetCellValue( row, COLUMN_DESCRIPTION, action->description );
286#endif
287 }
288 }
289
290 for( int col = 0; col < m_grid->GetNumberCols(); col++ )
291 {
292 const wxString& heading = m_grid->GetColLabelValue( col );
293 int headingWidth = GetTextExtent( heading ).x + 2 * GRID_CELL_MARGIN;
294
295 // Set the minimal width to the column label size.
296 m_grid->SetColMinimalWidth( col, headingWidth );
297 // Set the width to see the full contents
298 m_grid->SetColSize( col, m_grid->GetVisibleWidth( col ) );
299 }
300
301 m_grid->AutoSizeRows();
302 m_grid->AutoSizeColumns();
304
305 m_grid->Thaw();
306
307 // Show errors button should be disabled if there are no errors.
308 wxString trace;
309
312
313 if( trace.empty() )
314 {
315 m_showErrorsButton->Disable();
316 m_showErrorsButton->Hide();
317 }
318 else
319 {
320 m_showErrorsButton->Enable();
321 m_showErrorsButton->Show();
322 }
323
324 return true;
325}
326
327
332
333
335{
336 wxString trace;
338
339 // Now display the filtered trace in our dialog
340 // (a simple wxMessageBox is really not suitable for long messages)
341 DIALOG_FOOTPRINT_WIZARD_LOG logWindow( wxGetTopLevelParent( this ) );
342 logWindow.m_Message->SetValue( trace );
343 logWindow.ShowModal();
344}
Class PCBNEW_ACTION_PLUGINS.
KIFACE_BASE & Kiface()
Global KIFACE_BASE "get" accessor.
wxBitmapBundle KiBitmapBundle(BITMAPS aBitmap, int aMinHeight)
Definition bitmap.cpp:110
static int GetActionsCount()
Responsible for loading plugin definitions for API-based plugins (ones that do not run inside KiCad i...
void RecreatePluginEnvironment(const wxString &aIdentifier)
std::optional< const PLUGIN_ACTION * > GetAction(const wxString &aIdentifier)
APPEARANCE m_Appearance
Class DIALOG_FOOTPRINT_WIZARD_LOG.
int ShowModal() override
GRID_TRICKS(WX_GRID *aGrid)
virtual void doPopupSelection(wxCommandEvent &event)
virtual void showPopupMenu(wxMenu &menu, wxGridEvent &aEvent)
WX_GRID * m_grid
I don't own the grid, but he owns me.
APP_SETTINGS_BASE * KifaceSettings() const
Definition kiface_base.h:95
PANEL_PCBNEW_ACTION_PLUGINS_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)
void OnShowErrorsButtonClick(wxCommandEvent &event) override
Shows plugin import errors.
void OnMoveUpButtonClick(wxCommandEvent &event) override
Moves plugin up in the grid.
void OnGridCellClick(wxGridEvent &event) override
Selects a whole row.
void OnMoveDownButtonClick(wxCommandEvent &event) override
Moves plugin down in the grid.
void OnOpenDirectoryButtonClick(wxCommandEvent &event) override
Opens user's action plugin directory.
void OnReloadButtonClick(wxCommandEvent &event) override
Reloads plugins and updates grid.
ACTION_PLUGIN_SETTINGS_LIST m_VisibleActionPlugins
static std::vector< std::variant< ACTION_PLUGIN *, const PLUGIN_ACTION * > > GetOrderedActionPlugins()
Return ordered list of plugins in sequence in which they should appear on toolbar or in settings.
static bool GetActionPluginButtonVisible(const wxString &aPluginPath, bool aPluginDefault)
Return true if button visibility action plugin setting was set to true or it is unset and plugin defa...
virtual COMMON_SETTINGS * GetCommonSettings() const
Definition pgm_base.cpp:541
void showPopupMenu(wxMenu &menu, wxGridEvent &aEvent) override
void doPopupSelection(wxCommandEvent &event) override
static void ShowPluginFolder()
static void ReloadPlugins()
#define GRID_CELL_MARGIN
#define _(s)
@ GRIDTRICKS_FIRST_CLIENT_ID
Definition grid_tricks.h:48
bool IsDarkTheme()
Determine if the desktop interface is currently using a dark theme or a light theme.
Definition wxgtk/ui.cpp:49
void pcbnewGetWizardsBackTrace(wxString &aTrace)
Return the backtrace of errors (if any) when wizard python scripts are loaded.
PGM_BASE & Pgm()
The global program "get" accessor.
see class PGM_BASE
std::vector< std::pair< wxString, bool > > actions
Ordered list of plugin actions mapped to whether or not they are shown in the toolbar.