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>
37#include <widgets/wx_grid.h>
39
40
41#define GRID_CELL_MARGIN 4
42
43enum
44{
46};
47
49{
50public:
52 GRID_TRICKS( aGrid )
53 {}
54
55protected:
56 void showPopupMenu( wxMenu& menu, wxGridEvent& aEvent ) override;
57 void doPopupSelection( wxCommandEvent& event ) override;
58};
59
60
61void PLUGINS_GRID_TRICKS::showPopupMenu( wxMenu& menu, wxGridEvent& aEvent )
62{
63#ifdef KICAD_IPC_API
64 API_PLUGIN_MANAGER& mgr = Pgm().GetPluginManager();
65 wxString id = m_grid->GetCellValue( m_grid->GetGridCursorRow(),
67
68 if( std::optional<const PLUGIN_ACTION*> action = mgr.GetAction( id ) )
69 {
70 menu.Append( MYID_RECREATE_ENV, _( "Recreate Plugin Environment" ),
71 _( "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 {
91 mgr.RecreatePluginEnvironment( ( *action )->plugin.Identifier() );
92 }
93#endif
94 }
95 else
96 {
98 }
99}
100
101
104{
105 m_genericIcon = KiBitmapBundle( BITMAPS::puzzle_piece );
106 m_grid->PushEventHandler( new PLUGINS_GRID_TRICKS( m_grid ) );
107 m_grid->SetUseNativeColLabels();
108
109 m_moveUpButton->SetBitmap( KiBitmapBundle( BITMAPS::small_up ) );
110 m_moveDownButton->SetBitmap( KiBitmapBundle( BITMAPS::small_down ) );
111 m_openDirectoryButton->SetBitmap( KiBitmapBundle( BITMAPS::small_folder ) );
112 m_reloadButton->SetBitmap( KiBitmapBundle( BITMAPS::small_refresh ) );
113 m_showErrorsButton->SetBitmap( KiBitmapBundle( BITMAPS::small_warning ) );
114}
115
116
118{
119 m_grid->PopEventHandler( true );
120}
121
122
124{
125 SelectRow( event.GetRow() );
126}
127
128
130{
131 m_grid->ClearSelection();
132 m_grid->SelectRow( aRow );
133}
134
135
137{
138 auto selectedRows = m_grid->GetSelectedRows();
139
140 // If nothing is selected or multiple rows are selected don't do anything.
141 if( selectedRows.size() != 1 ) return;
142
143 int selectedRow = selectedRows[0];
144
145 // If first row is selected, then it can't go any further up.
146 if( selectedRow == 0 )
147 {
148 wxBell();
149 return;
150 }
151
152 SwapRows( selectedRow, selectedRow - 1 );
153
154 SelectRow( selectedRow - 1 );
155}
156
157
159{
160 auto selectedRows = m_grid->GetSelectedRows();
161
162 // If nothing is selected or multiple rows are selected don't do anything.
163 if( selectedRows.size() != 1 ) return;
164
165 int selectedRow = selectedRows[0];
166
167 // If last row is selected, then it can't go any further down.
168 if( selectedRow + 1 == m_grid->GetNumberRows() )
169 {
170 wxBell();
171 return;
172 }
173
174 SwapRows( selectedRow, selectedRow + 1 );
175
176 SelectRow( selectedRow + 1 );
177}
178
179
180void PANEL_PCBNEW_ACTION_PLUGINS::SwapRows( int aRowA, int aRowB )
181{
182 m_grid->Freeze();
183
184 wxString tempStr;
185
186 for( int column = 0; column < m_grid->GetNumberCols(); column++ )
187 {
188 tempStr = m_grid->GetCellValue( aRowA, column );
189 m_grid->SetCellValue( aRowA, column, m_grid->GetCellValue( aRowB, column ) );
190 m_grid->SetCellValue( aRowB, column, tempStr );
191 }
192
193 // Swap icon column renderers
194 auto cellRenderer = m_grid->GetCellRenderer( aRowA, COLUMN_ACTION_NAME );
195 m_grid->SetCellRenderer( aRowA, COLUMN_ACTION_NAME,
196 m_grid->GetCellRenderer( aRowB, COLUMN_ACTION_NAME ) );
197 m_grid->SetCellRenderer( aRowB, COLUMN_ACTION_NAME, cellRenderer );
198
199 m_grid->Thaw();
200}
201
202
204{
207}
208
209
211{
212 PCBNEW_SETTINGS* settings = dynamic_cast<PCBNEW_SETTINGS*>( Kiface().KifaceSettings() );
213 wxASSERT( settings );
214
215#ifdef KICAD_IPC_API
216 API_PLUGIN_MANAGER& mgr = Pgm().GetPluginManager();
217
218 if( settings )
219 {
220 settings->m_VisibleActionPlugins.clear();
221 settings->m_Plugins.actions.clear();
222
223 for( int ii = 0; ii < m_grid->GetNumberRows(); ii++ )
224 {
225 wxString id = m_grid->GetCellValue( ii, COLUMN_SETTINGS_IDENTIFIER );
226
227 if( mgr.GetAction( id ) != std::nullopt )
228 {
229 settings->m_Plugins.actions.emplace_back( std::make_pair(
230 id, m_grid->GetCellValue( ii, COLUMN_VISIBLE ) == wxT( "1" ) ) );
231 }
232 else
233 {
234 settings->m_VisibleActionPlugins.emplace_back( std::make_pair(
235 id, m_grid->GetCellValue( ii, COLUMN_VISIBLE ) == wxT( "1" ) ) );
236 }
237 }
238 }
239#else
240 if( settings )
241 {
242 settings->m_VisibleActionPlugins.clear();
243
244 for( int ii = 0; ii < m_grid->GetNumberRows(); ii++ )
245 {
246 wxString id = m_grid->GetCellValue( ii, COLUMN_SETTINGS_IDENTIFIER );
247
248 settings->m_VisibleActionPlugins.emplace_back( std::make_pair(
249 id, m_grid->GetCellValue( ii, COLUMN_VISIBLE ) == wxT( "1" ) ) );
250 }
251 }
252#endif
253
254 return true;
255}
256
257
259{
260 m_grid->Freeze();
261
262 m_grid->ClearRows();
263
264 const std::vector<LEGACY_OR_API_PLUGIN>& orderedPlugins =
266 m_grid->AppendRows( orderedPlugins.size() );
267
269 wxSize iconSize( size, size );
270
271 for( size_t row = 0; row < orderedPlugins.size(); row++ )
272 {
273 if( std::holds_alternative<ACTION_PLUGIN*>( orderedPlugins[row] ) )
274 {
275 auto ap = std::get<ACTION_PLUGIN*>( orderedPlugins[row] );
276
277 // Icon
278 m_grid->SetCellRenderer( row, COLUMN_ACTION_NAME,
279 new GRID_CELL_ICON_TEXT_RENDERER( ap->iconBitmap.IsOk()
280 ? wxBitmapBundle( ap->iconBitmap )
282 iconSize ) );
283 m_grid->SetCellValue( row, COLUMN_ACTION_NAME, ap->GetName() );
284 m_grid->SetCellValue( row, COLUMN_SETTINGS_IDENTIFIER, ap->GetPluginPath() );
285
286 // Toolbar button checkbox
287 m_grid->SetCellRenderer( row, COLUMN_VISIBLE, new wxGridCellBoolRenderer() );
288 m_grid->SetCellAlignment( row, COLUMN_VISIBLE, wxALIGN_CENTER, wxALIGN_CENTER );
289
290 bool show = PCB_EDIT_FRAME::GetActionPluginButtonVisible( ap->GetPluginPath(),
291 ap->GetShowToolbarButton() );
292
293 m_grid->SetCellValue( row, COLUMN_VISIBLE, show ? wxT( "1" ) : wxEmptyString );
294
295 m_grid->SetCellValue( row, COLUMN_PLUGIN_NAME, ap->GetClassName() );
296 m_grid->SetCellValue( row, COLUMN_DESCRIPTION, ap->GetDescription() );
297 }
298 else
299 {
300#ifdef KICAD_IPC_API
301 auto action = std::get<const PLUGIN_ACTION*>( orderedPlugins[row] );
302
303 const wxBitmapBundle& icon = KIPLATFORM::UI::IsDarkTheme() && action->icon_dark.IsOk()
304 ? action->icon_dark
305 : action->icon_light;
306
307 // Icon
308 m_grid->SetCellRenderer( row, COLUMN_ACTION_NAME, new GRID_CELL_ICON_TEXT_RENDERER(
309 icon.IsOk() ? icon : m_genericIcon, iconSize ) );
310 m_grid->SetCellValue( row, COLUMN_ACTION_NAME, action->name );
311 m_grid->SetCellValue( row, COLUMN_SETTINGS_IDENTIFIER, action->identifier );
312
313 // Toolbar button checkbox
314 m_grid->SetCellRenderer( row, COLUMN_VISIBLE, new wxGridCellBoolRenderer() );
315 m_grid->SetCellAlignment( row, COLUMN_VISIBLE, wxALIGN_CENTER, wxALIGN_CENTER );
316
317 bool show = PCB_EDIT_FRAME::GetActionPluginButtonVisible( action->identifier,
318 action->show_button );
319
320 m_grid->SetCellValue( row, COLUMN_VISIBLE, show ? wxT( "1" ) : wxEmptyString );
321
322 m_grid->SetCellValue( row, COLUMN_PLUGIN_NAME, action->plugin.Name() );
323 m_grid->SetCellValue( row, COLUMN_DESCRIPTION, action->description );
324#endif
325 }
326 }
327
328 for( int col = 0; col < m_grid->GetNumberCols(); col++ )
329 {
330 const wxString& heading = m_grid->GetColLabelValue( col );
331 int headingWidth = GetTextExtent( heading ).x + 2 * GRID_CELL_MARGIN;
332
333 // Set the minimal width to the column label size.
334 m_grid->SetColMinimalWidth( col, headingWidth );
335 // Set the width to see the full contents
336 m_grid->SetColSize( col, m_grid->GetVisibleWidth( col ) );
337 }
338
339 m_grid->AutoSizeRows();
340 m_grid->AutoSizeColumns();
342
343 m_grid->Thaw();
344
345 // Show errors button should be disabled if there are no errors.
346 wxString trace;
347
350
351 if( trace.empty() )
352 {
353 m_showErrorsButton->Disable();
354 m_showErrorsButton->Hide();
355 }
356 else
357 {
359 m_showErrorsButton->Show();
360 }
361
362 return true;
363}
364
365
367{
369}
370
371
373{
374 wxString trace;
376
377 // Now display the filtered trace in our dialog
378 // (a simple wxMessageBox is really not suitable for long messages)
379 DIALOG_FOOTPRINT_WIZARD_LOG logWindow( wxGetTopLevelParent( this ) );
380 logWindow.m_Message->SetValue( trace );
381 logWindow.ShowModal();
382}
Class PCBNEW_ACTION_PLUGINS.
KIFACE_BASE & Kiface()
Global KIFACE_BASE "get" accessor.
wxBitmapBundle KiBitmapBundle(BITMAPS aBitmap)
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
Add mouse and command handling (such as cut, copy, and paste) to a WX_GRID instance.
Definition: grid_tricks.h:61
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.
Definition: grid_tricks.h:125
APP_SETTINGS_BASE * KifaceSettings() const
Definition: kiface_base.h:95
Class PANEL_PCBNEW_ACTION_PLUGINS_BASE.
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:689
void showPopupMenu(wxMenu &menu, wxGridEvent &aEvent) override
void doPopupSelection(wxCommandEvent &event) override
static void ShowPluginFolder()
static void ReloadPlugins()
bool Enable(bool aEnable=true) override
void SetBitmap(const wxBitmapBundle &aBmp)
int GetVisibleWidth(int aCol, bool aHeader=true, bool aContents=true, bool aKeep=false)
Calculate the specified column based on the actual size of the text on screen.
Definition: wx_grid.cpp:778
void ClearRows()
wxWidgets recently added an ASSERT which fires if the position is greater than or equal to the number...
Definition: wx_grid.h:193
#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:48
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.
Definition: pgm_base.cpp:1073
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.
Definition: app_settings.h:166