Merge ~qu1ck/kicad:plugin-icon-squashed into ~kicad-product-committers/kicad:master
- Git
- lp:~qu1ck/kicad
- plugin-icon-squashed
- Merge into master
Status: | Superseded |
---|---|
Proposed branch: | ~qu1ck/kicad:plugin-icon-squashed |
Merge into: | ~kicad-product-committers/kicad:master |
Diff against target: |
2260 lines (+1637/-186) 21 files modified
common/bitmap.cpp (+19/-0) common/widgets/grid_icon_text_helpers.cpp (+40/-1) include/bitmap_types.h (+8/-0) include/widgets/grid_icon_text_helpers.h (+18/-1) pcbnew/CMakeLists.txt (+7/-2) pcbnew/action_plugin.cpp (+44/-2) pcbnew/action_plugin.h (+49/-11) pcbnew/dialogs/panel_pcbnew_action_plugins.cpp (+199/-0) pcbnew/dialogs/panel_pcbnew_action_plugins.h (+70/-0) pcbnew/dialogs/panel_pcbnew_action_plugins_base.cpp (+98/-0) pcbnew/dialogs/panel_pcbnew_action_plugins_base.fbp (+578/-0) pcbnew/dialogs/panel_pcbnew_action_plugins_base.h (+58/-0) pcbnew/pcb_edit_frame.cpp (+2/-0) pcbnew/pcb_edit_frame.h (+55/-4) pcbnew/pcb_general_settings.cpp (+45/-0) pcbnew/pcb_general_settings.h (+5/-0) pcbnew/pcbnew_config.cpp (+4/-0) pcbnew/swig/pcbnew_action_plugins.cpp (+308/-164) pcbnew/swig/pcbnew_action_plugins.h (+3/-0) pcbnew/tool_pcb_editor.cpp (+4/-0) scripting/kicadplugins.i (+23/-1) |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Seth Hillbrand | Pending | ||
Jeff Young | Pending | ||
Review via email: mp+353692@code.launchpad.net |
This proposal supersedes a proposal from 2018-08-24.
This proposal has been superseded by a proposal from 2018-08-25.
Commit message
Add toolbar buttons for action plugins
Description of the change
This adds toolbar buttons for pcbnew action plugins and a corresponding settings dialog in preferences which allows you to choose which buttons to show and their order.
Seth Hillbrand (sethh) wrote : Posted in a previous version of this proposal | # |
Jeff Young (jeyjey) wrote : Posted in a previous version of this proposal | # |
I didn't try to compile it yet as my tree's in the middle of something.
Andrew Lutsenko (qu1ck) wrote : Posted in a previous version of this proposal | # |
Thanks for comments, I replied to all of them inline.
> Can you squash these into a single commit (this is to allow git bisect without errors)?
Can launchpad not do it on merge? If so I think I'll have to open separate merge request in the end. Will LP review system tolerate rewritten commit history?
Andrew Lutsenko (qu1ck) wrote : | # |
I found a way to squash commits and resubmit current proposal.
Jeff Young (jeyjey) wrote : | # |
A few more comments for you, Andrew. Looking good!
Wayne Stambaugh (stambaughw) wrote : Posted in a previous version of this proposal | # |
On 08/23/2018 05:01 PM, Seth Hillbrand wrote:
> Review: Needs Fixing
>
> Overall looks good. I haven't checked MacOS compatibility, so I tagged Jeff Young to comment.
>
> The code style issues are scattered around, I think I found most all.
>
> You should remove the unsafe/unused functions.
>
> I don't think we should be mixing IDs between buttons and menus.
@Seth, event IDs for menu and toolbar actions should be the same. In
fact wxMENU_EVENT is the same as wxTOOL_EVENT. It's merely a #define in
wxwidgets. Please use the same event ID for the toolbar and the menu
for running the same script or you will be creating a maintenance issue.
>
> You can simplify your map usage to just a vector (O(n) is fine for searching this)
>
> Can you squash these into a single commit (this is to allow git bisect without errors)?
>
> Diff comments:
>
>> diff --git a/common/
>> index 8d348c7..feb04bb 100644
>> --- a/common/
>> +++ b/common/
>> @@ -68,6 +68,45 @@ void GRID_CELL_
>> aGrid.DrawTextR
>> }
>>
>> +//---- Grid helpers: custom wxGridCellRenderer that renders just an icon ----------------
>> +//
>> +// Note: this renderer is supposed to be used with read only cells
>> +
>> +GRID_CELL_
>> +{
>> +}
>> +
>> +
>> +void GRID_CELL_
>> + const wxRect& aRect, int aRow, int aCol, bool isSelected )
>> +{
>> + wxRect rect = aRect;
>> + rect.Inflate( -1 );
>> +
>> + // erase background
>> + wxGridCellRende
>> +
>> + // Draw icon
>> + if( m_icon.IsOk() )
>> + {
>> + aDC.DrawBitmap( m_icon,
>> + rect.GetLeft() + (rect.GetWidth() - m_icon.GetWidth()) / 2,
>
> Whitespace here around parentheses
>
>> + rect.GetTop() + (rect.GetHeight() - m_icon.GetHeight()) / 2,
>> + true );
>> + }
>> +}
>> +
>> +
>> +wxSize GRID_CELL_
>
> Whitespace here around parentheses.
>
>> +{
>> + return wxSize( m_icon.GetWidth() + 6, m_icon.GetHeight() + 4 );
>> +}
>> +
>> +
>> +wxGridCellRend
>> +{
>> + return new GRID_CELL_
>> +}
>>
>>
>> //---- Grid helpers: custom wxGridCellEditor -------
>> diff --git a/include/
>> index 9e14829..e859f11 100644
>> --- a/include/
>> +++ b/include/
>> @@ -49,6 +49,23 @@ private:
>> const wxArrayString& m_names;
>> };
>>
>> +//---- Grid helpers: custom wxGridCellRenderer that re...
Seth Hillbrand (sethh) wrote : Posted in a previous version of this proposal | # |
@Wayne- My comment here was unclear. The IDs are generated by wx when the menu items are added and a different ID is generated when the toolbar button is added. However, they are linked in the same callback handler, checking first for the menu button ID in the event and then, failing that, for the toolbar button ID. My concern was that separating the event handling based on wx's autogenerated IDs makes an assumption about the IDs. I'd feel better about that line if the handler split based on an event type and then did the ID lookup in the related list.
Wayne Stambaugh (stambaughw) wrote : Posted in a previous version of this proposal | # |
@Seth, got it. I don't have any further issues.
Andrew Lutsenko (qu1ck) wrote : | # |
Some comments got lost after I force pushed an update. That's why I didn't want to squash commits early.
@Seth
I split event handler for buttons and menus. They call common function. Is that what you had in mind?
@Jeff
I addressed your comments. About pythons calls: they don't throw, they return errors and there is also PyErr_Occurred() which checks for python exception state. It's done in CallMethod()
Also if you are worried about backward compatibility with old plugins I made sure that they still work. New fields in ActionPlugin class are set by default so plugin writers don't have to change anything unless they want to add a custom icon.
Andrew Lutsenko (qu1ck) : | # |
Unmerged commits
- 41192c0... by Andrew Lutsenko
-
Add toolbar buttons for action plugins
Add icons to action menu items as well
Fix backwards compatibility for plugins that don't define icon
Fix compilation errors for action plugin icon code
Fixes compilation with actio menu option off.
Fixes compilation error on non windows platforms.Make showing toolbar button optional for action plugins
Add "Action Plugins" panel stub in pcbnew settings
Add action plugin grid form and stub
Load action plugin list in pcbnew prefs
Add category, description and path to action plugin grid
Store and read action plugin settings display buttons accordingly
Add action plugin ordering buttons in preferences
Don't show error on icon load failure
Fix build with actions menu disabled
Adjust action plugins grid properties
Fix bug with plugin order when one is removed and another added
Also fix formatting
Scale plugin icons on toolbar
Address review comments
Removed unused methods, switched to std::vector from map where possible,
fixed formatting and spelling.Address another round of comments
Also append class name to plugin path to avoid issues with multiple classes in single plugin file
Preview Diff
1 | diff --git a/common/bitmap.cpp b/common/bitmap.cpp |
2 | index 031b2cc..bce8344 100644 |
3 | --- a/common/bitmap.cpp |
4 | +++ b/common/bitmap.cpp |
5 | @@ -144,6 +144,25 @@ wxBitmap KiScaledBitmap( BITMAP_DEF aBitmap, EDA_BASE_FRAME* aWindow ) |
6 | } |
7 | |
8 | |
9 | +wxBitmap KiScaledBitmap( const wxBitmap& aBitmap, EDA_BASE_FRAME* aWindow ) |
10 | +{ |
11 | + const int scale = get_scale_factor( aWindow ); |
12 | + |
13 | + if( scale == 4) |
14 | + { |
15 | + return wxBitmap( aBitmap ); |
16 | + } |
17 | + else |
18 | + { |
19 | + wxImage image = aBitmap.ConvertToImage(); |
20 | + image.Rescale( scale * image.GetWidth() / 4, scale * image.GetHeight() / 4, |
21 | + wxIMAGE_QUALITY_BILINEAR ); |
22 | + |
23 | + return wxBitmap( image ); |
24 | + } |
25 | +} |
26 | + |
27 | + |
28 | void KiScaledSeparator( wxAuiToolBar* aToolbar, EDA_BASE_FRAME* aWindow ) |
29 | { |
30 | const int scale = get_scale_factor( aWindow ); |
31 | diff --git a/common/widgets/grid_icon_text_helpers.cpp b/common/widgets/grid_icon_text_helpers.cpp |
32 | index 8d348c7..b1f949e 100644 |
33 | --- a/common/widgets/grid_icon_text_helpers.cpp |
34 | +++ b/common/widgets/grid_icon_text_helpers.cpp |
35 | @@ -27,7 +27,7 @@ |
36 | #include <wx/dc.h> |
37 | |
38 | |
39 | -//---- Grid helpers: custom wxGridCellRenderer ------------------------------------------ |
40 | +//---- Grid helpers: custom wxGridCellRenderer that renders icon and a label ------------ |
41 | |
42 | |
43 | GRID_CELL_ICON_TEXT_RENDERER::GRID_CELL_ICON_TEXT_RENDERER( const std::vector<BITMAP_DEF>& icons, |
44 | @@ -68,6 +68,45 @@ void GRID_CELL_ICON_TEXT_RENDERER::Draw( wxGrid& aGrid, wxGridCellAttr& aAttr, w |
45 | aGrid.DrawTextRectangle( aDC, value, rect, wxALIGN_LEFT, wxALIGN_CENTRE ); |
46 | } |
47 | |
48 | +//---- Grid helpers: custom wxGridCellRenderer that renders just an icon ---------------- |
49 | +// |
50 | +// Note: this renderer is supposed to be used with read only cells |
51 | + |
52 | +GRID_CELL_ICON_RENDERER::GRID_CELL_ICON_RENDERER(const wxBitmap& icon) : m_icon( icon ) |
53 | +{ |
54 | +} |
55 | + |
56 | + |
57 | +void GRID_CELL_ICON_RENDERER::Draw( wxGrid& aGrid, wxGridCellAttr& aAttr, wxDC& aDC, |
58 | + const wxRect& aRect, int aRow, int aCol, bool isSelected ) |
59 | +{ |
60 | + wxRect rect = aRect; |
61 | + rect.Inflate( -1 ); |
62 | + |
63 | + // erase background |
64 | + wxGridCellRenderer::Draw( aGrid, aAttr, aDC, aRect, aRow, aCol, isSelected ); |
65 | + |
66 | + // Draw icon |
67 | + if( m_icon.IsOk() ) |
68 | + { |
69 | + aDC.DrawBitmap( m_icon, |
70 | + rect.GetLeft() + ( rect.GetWidth() - m_icon.GetWidth() ) / 2, |
71 | + rect.GetTop() + ( rect.GetHeight() - m_icon.GetHeight() ) / 2, |
72 | + true ); |
73 | + } |
74 | +} |
75 | + |
76 | + |
77 | +wxSize GRID_CELL_ICON_RENDERER::GetBestSize( wxGrid& grid, wxGridCellAttr& attr, wxDC& dc, int row, int col ) |
78 | +{ |
79 | + return wxSize( m_icon.GetWidth() + 6, m_icon.GetHeight() + 4 ); |
80 | +} |
81 | + |
82 | + |
83 | +wxGridCellRenderer* GRID_CELL_ICON_RENDERER::Clone() const |
84 | +{ |
85 | + return new GRID_CELL_ICON_RENDERER( m_icon ); |
86 | +} |
87 | |
88 | |
89 | //---- Grid helpers: custom wxGridCellEditor ------------------------------------------ |
90 | diff --git a/include/bitmap_types.h b/include/bitmap_types.h |
91 | index 8657df4..f703ddb 100644 |
92 | --- a/include/bitmap_types.h |
93 | +++ b/include/bitmap_types.h |
94 | @@ -73,6 +73,14 @@ wxBitmap KiBitmap( BITMAP_DEF aBitmap ); |
95 | */ |
96 | wxBitmap KiScaledBitmap( BITMAP_DEF aBitmap, EDA_BASE_FRAME* aWindow ); |
97 | |
98 | +/** |
99 | + * Function KiScaledBitmap |
100 | + * Overload of the above function that takes another wxBitmap as a parameter |
101 | + * |
102 | + * @param aBitmap bitmap definition |
103 | + * @param aWindow target window for scaling context |
104 | + */ |
105 | +wxBitmap KiScaledBitmap( const wxBitmap& aBitmap, EDA_BASE_FRAME* aWindow ); |
106 | |
107 | /** |
108 | * Function KiScaledSeparator |
109 | diff --git a/include/widgets/grid_icon_text_helpers.h b/include/widgets/grid_icon_text_helpers.h |
110 | index 9e14829..60ea612 100644 |
111 | --- a/include/widgets/grid_icon_text_helpers.h |
112 | +++ b/include/widgets/grid_icon_text_helpers.h |
113 | @@ -34,7 +34,7 @@ |
114 | class wxGrid; |
115 | |
116 | |
117 | -//---- Grid helpers: custom wxGridCellRenderer ------------------------------------------ |
118 | +//---- Grid helpers: custom wxGridCellRenderer that renders icon and a label ------------ |
119 | |
120 | class GRID_CELL_ICON_TEXT_RENDERER : public wxGridCellStringRenderer |
121 | { |
122 | @@ -49,6 +49,23 @@ private: |
123 | const wxArrayString& m_names; |
124 | }; |
125 | |
126 | +//---- Grid helpers: custom wxGridCellRenderer that renders just an icon ---------------- |
127 | +// |
128 | +// Note: use with read only cells |
129 | + |
130 | +class GRID_CELL_ICON_RENDERER : public wxGridCellRenderer |
131 | +{ |
132 | +public: |
133 | + GRID_CELL_ICON_RENDERER( const wxBitmap& icon ); |
134 | + |
135 | + void Draw( wxGrid& aGrid, wxGridCellAttr& aAttr, wxDC& aDC, |
136 | + const wxRect& aRect, int aRow, int aCol, bool isSelected ) override; |
137 | + wxSize GetBestSize( wxGrid & grid, wxGridCellAttr & attr, wxDC & dc, int row, int col ) override; |
138 | + wxGridCellRenderer* Clone() const override; |
139 | + |
140 | +private: |
141 | + const wxBitmap& m_icon; |
142 | +}; |
143 | |
144 | //---- Grid helpers: custom wxGridCellEditor ------------------------------------------ |
145 | // |
146 | diff --git a/pcbnew/CMakeLists.txt b/pcbnew/CMakeLists.txt |
147 | index a77f8eb..2202080 100644 |
148 | --- a/pcbnew/CMakeLists.txt |
149 | +++ b/pcbnew/CMakeLists.txt |
150 | @@ -152,8 +152,6 @@ set( PCBNEW_DIALOGS |
151 | dialogs/panel_modedit_settings_base.cpp |
152 | dialogs/panel_pcbnew_display_options.cpp |
153 | dialogs/panel_pcbnew_display_options_base.cpp |
154 | - dialogs/panel_pcbnew_display_options.cpp |
155 | - dialogs/panel_pcbnew_display_options_base.cpp |
156 | dialogs/panel_pcbnew_settings.cpp |
157 | dialogs/panel_pcbnew_settings_base.cpp |
158 | dialogs/panel_setup_mask_and_paste.cpp |
159 | @@ -174,6 +172,13 @@ set( PCBNEW_DIALOGS |
160 | ${GITHUB_3DLIBRARIES_WIZARD} |
161 | ) |
162 | |
163 | +if( KICAD_SCRIPTING AND KICAD_SCRIPTING_ACTION_MENU ) |
164 | + set( PCBNEW_DIALOGS ${PCBNEW_DIALOGS} |
165 | + dialogs/panel_pcbnew_action_plugins.cpp |
166 | + dialogs/panel_pcbnew_action_plugins_base.cpp |
167 | + ) |
168 | +endif() |
169 | + |
170 | set( PCBNEW_IMPORT_DXF |
171 | import_dxf/dialog_dxf_import.cpp |
172 | import_dxf/dialog_dxf_import_base.cpp |
173 | diff --git a/pcbnew/action_plugin.cpp b/pcbnew/action_plugin.cpp |
174 | index c10d0fa..e79ea29 100644 |
175 | --- a/pcbnew/action_plugin.cpp |
176 | +++ b/pcbnew/action_plugin.cpp |
177 | @@ -73,9 +73,37 @@ void ACTION_PLUGINS::SetActionMenu( int aIndex, int idMenu ) |
178 | } |
179 | |
180 | |
181 | -int ACTION_PLUGINS::GetActionMenu( int aIndex ) |
182 | +ACTION_PLUGIN* ACTION_PLUGINS::GetActionByButton( int aButton ) |
183 | { |
184 | - return m_actionsList[aIndex]->m_actionMenuId; |
185 | + int max = GetActionsCount(); |
186 | + |
187 | + for( int i = 0; i < max; i++ ) |
188 | + { |
189 | + if( m_actionsList[i]->m_actionButtonId == aButton ) |
190 | + return m_actionsList[i]; |
191 | + } |
192 | + |
193 | + return NULL; |
194 | +} |
195 | + |
196 | + |
197 | +void ACTION_PLUGINS::SetActionButton( ACTION_PLUGIN* aAction, int idButton ) |
198 | +{ |
199 | + aAction->m_actionButtonId = idButton; |
200 | +} |
201 | + |
202 | + |
203 | +ACTION_PLUGIN* ACTION_PLUGINS::GetActionByPath(const wxString& aPath) |
204 | +{ |
205 | + for( int i = 0; i < GetActionsCount() ; i++ ) |
206 | + { |
207 | + if( m_actionsList[i]->GetPluginPath() == aPath) |
208 | + { |
209 | + return m_actionsList[i]; |
210 | + } |
211 | + } |
212 | + |
213 | + return NULL; |
214 | } |
215 | |
216 | |
217 | @@ -127,6 +155,20 @@ void ACTION_PLUGINS::register_action( ACTION_PLUGIN* aAction ) |
218 | } |
219 | } |
220 | |
221 | + // Load icon if supplied |
222 | + if (!aAction->GetIconFileName().IsEmpty()) |
223 | + { |
224 | + { |
225 | + wxLogNull eat_errors; |
226 | + aAction->iconBitmap.LoadFile( aAction->GetIconFileName() , wxBITMAP_TYPE_PNG ); |
227 | + } |
228 | + |
229 | + if ( !aAction->iconBitmap.IsOk() ) |
230 | + { |
231 | + wxLogVerbose( "Failed to load icon " + aAction->GetIconFileName() + " for action plugin " ); |
232 | + } |
233 | + } |
234 | + |
235 | m_actionsList.push_back( aAction ); |
236 | } |
237 | |
238 | diff --git a/pcbnew/action_plugin.h b/pcbnew/action_plugin.h |
239 | index ff3ed14..8bb6c9c 100644 |
240 | --- a/pcbnew/action_plugin.h |
241 | +++ b/pcbnew/action_plugin.h |
242 | @@ -44,9 +44,16 @@ public: |
243 | // m_actionMenuId set to 0 means the corresponding menuitem to call this |
244 | // action is not yet created |
245 | int m_actionMenuId; |
246 | + // Same for button id |
247 | + int m_actionButtonId; |
248 | + // Icon for the action button and menu entry |
249 | + wxBitmap iconBitmap; |
250 | + // If show_on_toolbar is true a button will be added to top toolbar |
251 | + bool show_on_toolbar; |
252 | |
253 | public: |
254 | - ACTION_PLUGIN() : m_actionMenuId( 0 ) {} |
255 | + ACTION_PLUGIN() : m_actionMenuId( 0 ), m_actionButtonId( 0 ), |
256 | + show_on_toolbar( false ) {} |
257 | virtual ~ACTION_PLUGIN(); |
258 | |
259 | /** |
260 | @@ -69,6 +76,24 @@ public: |
261 | virtual wxString GetDescription() = 0; |
262 | |
263 | /** |
264 | + * Function GetShowToolbarButton |
265 | + * @return true if button should be shown on top toolbar |
266 | + */ |
267 | + virtual bool GetShowToolbarButton() = 0; |
268 | + |
269 | + /** |
270 | + * Function GetIconFileName |
271 | + * @return a path to icon for the action plugin button |
272 | + */ |
273 | + virtual wxString GetIconFileName() = 0; |
274 | + |
275 | + /** |
276 | + * Function GetPluginPath |
277 | + * @return a path this plugin was loaded from |
278 | + */ |
279 | + virtual wxString GetPluginPath() = 0; |
280 | + |
281 | + /** |
282 | * Function GetObject |
283 | * This method gets the pointer to the object from where this action constructs |
284 | * @return it's a void pointer, as it could be a PyObject or any other |
285 | @@ -137,16 +162,6 @@ public: |
286 | */ |
287 | static void SetActionMenu( int aIndex, int idMenu ); |
288 | |
289 | - |
290 | - /** |
291 | - * Function GetActionMenu |
292 | - * Provide menu id for a plugin index |
293 | - * @param aIndex is the action index |
294 | - * @return associated menuitem id |
295 | - */ |
296 | - static int GetActionMenu( int aIndex ); |
297 | - |
298 | - |
299 | /** |
300 | * Function GetActionByMenu |
301 | * find action plugin associated to a menu id |
302 | @@ -155,6 +170,29 @@ public: |
303 | */ |
304 | static ACTION_PLUGIN* GetActionByMenu( int aMenu ); |
305 | |
306 | + /** |
307 | + * Function SetActionButton |
308 | + * Associate a button id to an action plugin |
309 | + * @param aAction is the action |
310 | + * @param idButton is the associated menuitem id |
311 | + */ |
312 | + static void SetActionButton( ACTION_PLUGIN* aAction, int idButton ); |
313 | + |
314 | + /** |
315 | + * Function GetActionByButton |
316 | + * find action plugin associated to a button id |
317 | + * @param aButton is the button id (defined with SetActionButton) |
318 | + * @return the associated ACTION_PLUGIN (or null if not found) |
319 | + */ |
320 | + static ACTION_PLUGIN* GetActionByButton( int aButton ); |
321 | + |
322 | + /** |
323 | + * Function GetActionByPath |
324 | + * find action plugin by module path |
325 | + * @param aPath the path of plugin |
326 | + * @return the corresponding ACTION_PLUGIN (or null if not found) |
327 | + */ |
328 | + static ACTION_PLUGIN* GetActionByPath( const wxString& aPath ); |
329 | |
330 | /** |
331 | * Function GetAction |
332 | diff --git a/pcbnew/dialogs/panel_pcbnew_action_plugins.cpp b/pcbnew/dialogs/panel_pcbnew_action_plugins.cpp |
333 | new file mode 100644 |
334 | index 0000000..3887fe9 |
335 | --- /dev/null |
336 | +++ b/pcbnew/dialogs/panel_pcbnew_action_plugins.cpp |
337 | @@ -0,0 +1,199 @@ |
338 | +/* |
339 | + * This program source code file is part of KiCad, a free EDA CAD application. |
340 | + * |
341 | + * Copyright (C) 2018 Andrew Lutsenko, anlutsenko at gmail dot com |
342 | + * Copyright (C) 1992-2018 KiCad Developers, see AUTHORS.txt for contributors. |
343 | + * |
344 | + * This program is free software: you can redistribute it and/or modify it |
345 | + * under the terms of the GNU General Public License as published by the |
346 | + * Free Software Foundation, either version 3 of the License, or (at your |
347 | + * option) any later version. |
348 | + * |
349 | + * This program is distributed in the hope that it will be useful, but |
350 | + * WITHOUT ANY WARRANTY; without even the implied warranty of |
351 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
352 | + * General Public License for more details. |
353 | + * |
354 | + * You should have received a copy of the GNU General Public License along |
355 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
356 | + */ |
357 | + |
358 | +#include <pcb_edit_frame.h> |
359 | +#include <panel_pcbnew_action_plugins.h> |
360 | +#include <widgets/paged_dialog.h> |
361 | +#include <widgets/grid_icon_text_helpers.h> |
362 | +#include <bitmaps.h> |
363 | +#include <action_plugin.h> |
364 | +#include <grid_tricks.h> |
365 | +#include <widgets/wx_grid.h> |
366 | + |
367 | + |
368 | +PANEL_PCBNEW_ACTION_PLUGINS::PANEL_PCBNEW_ACTION_PLUGINS( PCB_EDIT_FRAME* aFrame, PAGED_DIALOG* aWindow ) : |
369 | + PANEL_PCBNEW_ACTION_PLUGINS_BASE( aWindow->GetTreebook() ), |
370 | + m_frame( aFrame ) |
371 | +{ |
372 | + m_genericIcon = KiBitmap( hammer_xpm ); |
373 | + m_grid->PushEventHandler( new GRID_TRICKS( m_grid ) ); |
374 | + |
375 | + m_moveUpButton->SetBitmap( KiBitmap( up_xpm ) ); |
376 | + m_moveDownButton->SetBitmap( KiBitmap( down_xpm ) ); |
377 | + m_reloadButton->SetBitmap( KiBitmap( refresh_xpm ) ); |
378 | +} |
379 | + |
380 | + |
381 | +PANEL_PCBNEW_ACTION_PLUGINS::~PANEL_PCBNEW_ACTION_PLUGINS() |
382 | +{ |
383 | + m_grid->PopEventHandler( true ); |
384 | +} |
385 | + |
386 | + |
387 | +void PANEL_PCBNEW_ACTION_PLUGINS::OnGridCellClick( wxGridEvent& event ) |
388 | +{ |
389 | + SelectRow( event.GetRow() ); |
390 | +} |
391 | + |
392 | + |
393 | +void PANEL_PCBNEW_ACTION_PLUGINS::SelectRow( int aRow ) |
394 | +{ |
395 | + m_grid->ClearSelection(); |
396 | + m_grid->SelectRow( aRow ); |
397 | +} |
398 | + |
399 | + |
400 | +void PANEL_PCBNEW_ACTION_PLUGINS::OnMoveUpButtonClick( wxCommandEvent& event ) |
401 | +{ |
402 | + auto selectedRows = m_grid->GetSelectedRows(); |
403 | + |
404 | + // If nothing is selected or multiple rows are selected don't do anything. |
405 | + if( selectedRows.size() != 1 ) return; |
406 | + |
407 | + int selectedRow = selectedRows[0]; |
408 | + |
409 | + // If first row is selected, then it can't go any further up. |
410 | + if( selectedRow == 0 ) |
411 | + { |
412 | + wxBell(); |
413 | + return; |
414 | + } |
415 | + |
416 | + SwapRows( selectedRow, selectedRow - 1 ); |
417 | + |
418 | + SelectRow( selectedRow - 1 ); |
419 | +} |
420 | + |
421 | + |
422 | +void PANEL_PCBNEW_ACTION_PLUGINS::OnMoveDownButtonClick( wxCommandEvent& event ) |
423 | +{ |
424 | + auto selectedRows = m_grid->GetSelectedRows(); |
425 | + |
426 | + // If nothing is selected or multiple rows are selected don't do anything. |
427 | + if( selectedRows.size() != 1 ) return; |
428 | + |
429 | + int selectedRow = selectedRows[0]; |
430 | + |
431 | + // If last row is selected, then it can't go any further down. |
432 | + if( selectedRow + 1 == m_grid->GetNumberRows() ) |
433 | + { |
434 | + wxBell(); |
435 | + return; |
436 | + } |
437 | + |
438 | + SwapRows( selectedRow, selectedRow + 1 ); |
439 | + |
440 | + SelectRow( selectedRow + 1 ); |
441 | +} |
442 | + |
443 | + |
444 | +void PANEL_PCBNEW_ACTION_PLUGINS::SwapRows( int aRowA, int aRowB ) |
445 | +{ |
446 | + m_grid->Freeze(); |
447 | + |
448 | + // Swap all columns except icon |
449 | + wxString tempStr; |
450 | + |
451 | + for( int column = 1; column < m_grid->GetNumberCols(); column++ ) |
452 | + { |
453 | + tempStr = m_grid->GetCellValue( aRowA, column ); |
454 | + m_grid->SetCellValue( aRowA, column, m_grid->GetCellValue( aRowB, column ) ); |
455 | + m_grid->SetCellValue( aRowB, column, tempStr ); |
456 | + } |
457 | + |
458 | + // Swap icon column renderers |
459 | + auto cellRenderer = m_grid->GetCellRenderer( aRowA, COLUMN_ICON ); |
460 | + m_grid->SetCellRenderer( aRowA, COLUMN_ICON, m_grid->GetCellRenderer( aRowB, COLUMN_ICON ) ); |
461 | + m_grid->SetCellRenderer( aRowB, COLUMN_ICON, cellRenderer ); |
462 | + |
463 | + m_grid->Thaw(); |
464 | +} |
465 | + |
466 | + |
467 | +void PANEL_PCBNEW_ACTION_PLUGINS::OnReloadButtonClick( wxCommandEvent& event ) |
468 | +{ |
469 | + m_frame->PythonPluginsReload(); |
470 | + TransferDataToWindow(); |
471 | +} |
472 | + |
473 | + |
474 | +bool PANEL_PCBNEW_ACTION_PLUGINS::TransferDataFromWindow() |
475 | +{ |
476 | + std::vector< std::pair<wxString, wxString> > pluginSettings; |
477 | + |
478 | + for( int ii = 0; ii < m_grid->GetNumberRows(); ii++ ) |
479 | + { |
480 | + pluginSettings.push_back( std::make_pair( |
481 | + m_grid->GetCellValue( ii, COLUMN_PATH ), |
482 | + m_grid->GetCellValue( ii, COLUMN_VISIBLE ) == wxT("1") ? wxT( "Visible" ) : wxT( "Hidden" ) |
483 | + ) ); |
484 | + } |
485 | + |
486 | + m_frame->SetActionPluginSettings( pluginSettings ); |
487 | + |
488 | + return true; |
489 | +} |
490 | + |
491 | + |
492 | +bool PANEL_PCBNEW_ACTION_PLUGINS::TransferDataToWindow() |
493 | +{ |
494 | + m_grid->Freeze(); |
495 | + m_grid->DeleteRows( 0, m_grid->GetNumberRows() ); |
496 | + |
497 | + const auto& orderedPlugins = m_frame->GetOrderedActionPlugins(); |
498 | + m_grid->AppendRows( orderedPlugins.size() ); |
499 | + |
500 | + for( size_t row = 0; row < orderedPlugins.size(); row++ ) |
501 | + { |
502 | + ACTION_PLUGIN* ap = orderedPlugins[row]; |
503 | + |
504 | + // Icon |
505 | + m_grid->SetCellRenderer( row, COLUMN_ICON, new GRID_CELL_ICON_RENDERER( |
506 | + ap->iconBitmap.IsOk() ? ap->iconBitmap : m_genericIcon ) ); |
507 | + |
508 | + // Toolbar button checkbox |
509 | + m_grid->SetCellRenderer( row, COLUMN_VISIBLE, new wxGridCellBoolRenderer() ); |
510 | + m_grid->SetCellAlignment( row, COLUMN_VISIBLE, wxALIGN_CENTER, wxALIGN_CENTER ); |
511 | + |
512 | + bool showButton = m_frame->GetActionPluginButtonVisible( |
513 | + ap->GetPluginPath(), ap->GetShowToolbarButton() ); |
514 | + |
515 | + m_grid->SetCellValue( row, COLUMN_VISIBLE, showButton ? wxT( "1" ) : wxEmptyString ); |
516 | + |
517 | + // Name |
518 | + m_grid->SetCellValue( row, COLUMN_NAME, ap->GetName() ); |
519 | + |
520 | + // Category |
521 | + m_grid->SetCellValue( row, COLUMN_CATEGORY, ap->GetCategoryName() ); |
522 | + |
523 | + // Description |
524 | + m_grid->SetCellValue( row, COLUMN_DESCRIPTION, ap->GetDescription() ); |
525 | + |
526 | + // Path |
527 | + m_grid->SetCellValue( row, COLUMN_PATH, ap->GetPluginPath() ); |
528 | + } |
529 | + |
530 | + m_grid->AutoSizeColumns(); |
531 | + m_grid->AutoSizeRows(); |
532 | + |
533 | + m_grid->Thaw(); |
534 | + |
535 | + return true; |
536 | +} |
537 | diff --git a/pcbnew/dialogs/panel_pcbnew_action_plugins.h b/pcbnew/dialogs/panel_pcbnew_action_plugins.h |
538 | new file mode 100644 |
539 | index 0000000..48e8dc0 |
540 | --- /dev/null |
541 | +++ b/pcbnew/dialogs/panel_pcbnew_action_plugins.h |
542 | @@ -0,0 +1,70 @@ |
543 | +/* |
544 | + * This program source code file is part of KiCad, a free EDA CAD application. |
545 | + * |
546 | + * Copyright (C) 2018 Andrew Lutsenko, anlutsenko at gmail dot com |
547 | + * Copyright (C) 1992-2018 KiCad Developers, see AUTHORS.txt for contributors. |
548 | + * |
549 | + * This program is free software: you can redistribute it and/or modify it |
550 | + * under the terms of the GNU General Public License as published by the |
551 | + * Free Software Foundation, either version 3 of the License, or (at your |
552 | + * option) any later version. |
553 | + * |
554 | + * This program is distributed in the hope that it will be useful, but |
555 | + * WITHOUT ANY WARRANTY; without even the implied warranty of |
556 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
557 | + * General Public License for more details. |
558 | + * |
559 | + * You should have received a copy of the GNU General Public License along |
560 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
561 | + */ |
562 | + |
563 | +#include "panel_pcbnew_action_plugins_base.h" |
564 | + |
565 | +class PANEL_PCBNEW_ACTION_PLUGINS : public PANEL_PCBNEW_ACTION_PLUGINS_BASE |
566 | +{ |
567 | +public: |
568 | + PANEL_PCBNEW_ACTION_PLUGINS ( PCB_EDIT_FRAME* aFrame, PAGED_DIALOG* aWindow ); |
569 | + |
570 | + bool TransferDataFromWindow() override; |
571 | + bool TransferDataToWindow() override; |
572 | + ~PANEL_PCBNEW_ACTION_PLUGINS() override; |
573 | + |
574 | + /** |
575 | + * Selects a whole row |
576 | + */ |
577 | + void OnGridCellClick( wxGridEvent& event ) override; |
578 | + |
579 | + /** |
580 | + * Moves plugin up in the grid |
581 | + */ |
582 | + void OnMoveUpButtonClick( wxCommandEvent& event ) override; |
583 | + |
584 | + /** |
585 | + * Moves plugin down in the grid |
586 | + */ |
587 | + void OnMoveDownButtonClick( wxCommandEvent& event ) override; |
588 | + |
589 | + /** |
590 | + * Reloads plugins and updates grid |
591 | + */ |
592 | + void OnReloadButtonClick( wxCommandEvent& event ) override; |
593 | + |
594 | +private: |
595 | + |
596 | + enum GRID_COLUMNS |
597 | + { |
598 | + COLUMN_ICON, |
599 | + COLUMN_VISIBLE, |
600 | + COLUMN_NAME, |
601 | + COLUMN_CATEGORY, |
602 | + COLUMN_DESCRIPTION, |
603 | + COLUMN_PATH |
604 | + }; |
605 | + |
606 | + PCB_EDIT_FRAME* m_frame; |
607 | + wxBitmap m_genericIcon; |
608 | + |
609 | + void SwapRows( int aRowA, int aRowB ); |
610 | + void SelectRow( int aRow ); |
611 | +}; |
612 | + |
613 | diff --git a/pcbnew/dialogs/panel_pcbnew_action_plugins_base.cpp b/pcbnew/dialogs/panel_pcbnew_action_plugins_base.cpp |
614 | new file mode 100644 |
615 | index 0000000..d8f8909 |
616 | --- /dev/null |
617 | +++ b/pcbnew/dialogs/panel_pcbnew_action_plugins_base.cpp |
618 | @@ -0,0 +1,98 @@ |
619 | +/////////////////////////////////////////////////////////////////////////// |
620 | +// C++ code generated with wxFormBuilder (version Jul 11 2018) |
621 | +// http://www.wxformbuilder.org/ |
622 | +// |
623 | +// PLEASE DO *NOT* EDIT THIS FILE! |
624 | +/////////////////////////////////////////////////////////////////////////// |
625 | + |
626 | +#include "widgets/wx_grid.h" |
627 | + |
628 | +#include "panel_pcbnew_action_plugins_base.h" |
629 | + |
630 | +/////////////////////////////////////////////////////////////////////////// |
631 | + |
632 | +PANEL_PCBNEW_ACTION_PLUGINS_BASE::PANEL_PCBNEW_ACTION_PLUGINS_BASE( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style ) : wxPanel( parent, id, pos, size, style ) |
633 | +{ |
634 | + wxBoxSizer* bPanelSizer; |
635 | + bPanelSizer = new wxBoxSizer( wxHORIZONTAL ); |
636 | + |
637 | + wxBoxSizer* bGridSizer; |
638 | + bGridSizer = new wxBoxSizer( wxVERTICAL ); |
639 | + |
640 | + m_grid = new WX_GRID( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxBORDER_SIMPLE ); |
641 | + |
642 | + // Grid |
643 | + m_grid->CreateGrid( 3, 6 ); |
644 | + m_grid->EnableEditing( false ); |
645 | + m_grid->EnableGridLines( true ); |
646 | + m_grid->EnableDragGridSize( false ); |
647 | + m_grid->SetMargins( 0, 0 ); |
648 | + |
649 | + // Columns |
650 | + m_grid->AutoSizeColumns(); |
651 | + m_grid->EnableDragColMove( false ); |
652 | + m_grid->EnableDragColSize( true ); |
653 | + m_grid->SetColLabelSize( 22 ); |
654 | + m_grid->SetColLabelValue( 0, wxT("Icon") ); |
655 | + m_grid->SetColLabelValue( 1, wxT("Show button") ); |
656 | + m_grid->SetColLabelValue( 2, wxT("Name") ); |
657 | + m_grid->SetColLabelValue( 3, wxT("Category") ); |
658 | + m_grid->SetColLabelValue( 4, wxT("Description") ); |
659 | + m_grid->SetColLabelValue( 5, wxT("Path") ); |
660 | + m_grid->SetColLabelAlignment( wxALIGN_CENTRE, wxALIGN_CENTRE ); |
661 | + |
662 | + // Rows |
663 | + m_grid->EnableDragRowSize( true ); |
664 | + m_grid->SetRowLabelSize( 0 ); |
665 | + m_grid->SetRowLabelAlignment( wxALIGN_CENTRE, wxALIGN_CENTRE ); |
666 | + |
667 | + // Label Appearance |
668 | + |
669 | + // Cell Defaults |
670 | + m_grid->SetDefaultCellAlignment( wxALIGN_LEFT, wxALIGN_CENTRE ); |
671 | + bGridSizer->Add( m_grid, 1, wxALL|wxEXPAND, 5 ); |
672 | + |
673 | + |
674 | + bPanelSizer->Add( bGridSizer, 1, wxALIGN_LEFT|wxEXPAND|wxLEFT, 0 ); |
675 | + |
676 | + wxBoxSizer* bButtonsSizer; |
677 | + bButtonsSizer = new wxBoxSizer( wxVERTICAL ); |
678 | + |
679 | + m_moveUpButton = new wxBitmapButton( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, 0 ); |
680 | + m_moveUpButton->SetMinSize( wxSize( 32,32 ) ); |
681 | + |
682 | + bButtonsSizer->Add( m_moveUpButton, 0, wxALIGN_TOP|wxALL, 5 ); |
683 | + |
684 | + m_moveDownButton = new wxBitmapButton( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, 0 ); |
685 | + m_moveDownButton->SetMinSize( wxSize( 32,32 ) ); |
686 | + |
687 | + bButtonsSizer->Add( m_moveDownButton, 0, wxALL, 5 ); |
688 | + |
689 | + m_reloadButton = new wxBitmapButton( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, 0 ); |
690 | + m_reloadButton->SetMinSize( wxSize( 32,32 ) ); |
691 | + |
692 | + bButtonsSizer->Add( m_reloadButton, 0, wxALL, 5 ); |
693 | + |
694 | + |
695 | + bPanelSizer->Add( bButtonsSizer, 0, wxALIGN_RIGHT|wxALIGN_TOP, 0 ); |
696 | + |
697 | + |
698 | + this->SetSizer( bPanelSizer ); |
699 | + this->Layout(); |
700 | + |
701 | + // Connect Events |
702 | + m_grid->Connect( wxEVT_GRID_CELL_LEFT_CLICK, wxGridEventHandler( PANEL_PCBNEW_ACTION_PLUGINS_BASE::OnGridCellClick ), NULL, this ); |
703 | + m_moveUpButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_PCBNEW_ACTION_PLUGINS_BASE::OnMoveUpButtonClick ), NULL, this ); |
704 | + m_moveDownButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_PCBNEW_ACTION_PLUGINS_BASE::OnMoveDownButtonClick ), NULL, this ); |
705 | + m_reloadButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_PCBNEW_ACTION_PLUGINS_BASE::OnReloadButtonClick ), NULL, this ); |
706 | +} |
707 | + |
708 | +PANEL_PCBNEW_ACTION_PLUGINS_BASE::~PANEL_PCBNEW_ACTION_PLUGINS_BASE() |
709 | +{ |
710 | + // Disconnect Events |
711 | + m_grid->Disconnect( wxEVT_GRID_CELL_LEFT_CLICK, wxGridEventHandler( PANEL_PCBNEW_ACTION_PLUGINS_BASE::OnGridCellClick ), NULL, this ); |
712 | + m_moveUpButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_PCBNEW_ACTION_PLUGINS_BASE::OnMoveUpButtonClick ), NULL, this ); |
713 | + m_moveDownButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_PCBNEW_ACTION_PLUGINS_BASE::OnMoveDownButtonClick ), NULL, this ); |
714 | + m_reloadButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_PCBNEW_ACTION_PLUGINS_BASE::OnReloadButtonClick ), NULL, this ); |
715 | + |
716 | +} |
717 | diff --git a/pcbnew/dialogs/panel_pcbnew_action_plugins_base.fbp b/pcbnew/dialogs/panel_pcbnew_action_plugins_base.fbp |
718 | new file mode 100644 |
719 | index 0000000..6c91f1f |
720 | --- /dev/null |
721 | +++ b/pcbnew/dialogs/panel_pcbnew_action_plugins_base.fbp |
722 | @@ -0,0 +1,578 @@ |
723 | +<?xml version="1.0" encoding="UTF-8" standalone="yes" ?> |
724 | +<wxFormBuilder_Project> |
725 | + <FileVersion major="1" minor="14" /> |
726 | + <object class="Project" expanded="1"> |
727 | + <property name="class_decoration"></property> |
728 | + <property name="code_generation">C++</property> |
729 | + <property name="disconnect_events">1</property> |
730 | + <property name="disconnect_mode">source_name</property> |
731 | + <property name="disconnect_php_events">0</property> |
732 | + <property name="disconnect_python_events">0</property> |
733 | + <property name="embedded_files_path">res</property> |
734 | + <property name="encoding">UTF-8</property> |
735 | + <property name="event_generation">connect</property> |
736 | + <property name="file">panel_pcbnew_action_plugins_base</property> |
737 | + <property name="first_id">1000</property> |
738 | + <property name="help_provider">none</property> |
739 | + <property name="indent_with_spaces">0</property> |
740 | + <property name="internationalize">0</property> |
741 | + <property name="name">PanelPcbnewActionPlugins</property> |
742 | + <property name="namespace"></property> |
743 | + <property name="path">.</property> |
744 | + <property name="precompiled_header"></property> |
745 | + <property name="relative_path">1</property> |
746 | + <property name="skip_lua_events">1</property> |
747 | + <property name="skip_php_events">1</property> |
748 | + <property name="skip_python_events">1</property> |
749 | + <property name="ui_table">UI</property> |
750 | + <property name="use_enum">1</property> |
751 | + <property name="use_microsoft_bom">0</property> |
752 | + <object class="Panel" expanded="1"> |
753 | + <property name="aui_managed">0</property> |
754 | + <property name="aui_manager_style">wxAUI_MGR_DEFAULT</property> |
755 | + <property name="bg"></property> |
756 | + <property name="context_help"></property> |
757 | + <property name="context_menu">1</property> |
758 | + <property name="enabled">1</property> |
759 | + <property name="event_handler">impl_virtual</property> |
760 | + <property name="fg"></property> |
761 | + <property name="font"></property> |
762 | + <property name="hidden">0</property> |
763 | + <property name="id">wxID_ANY</property> |
764 | + <property name="maximum_size"></property> |
765 | + <property name="minimum_size"></property> |
766 | + <property name="name">PANEL_PCBNEW_ACTION_PLUGINS_BASE</property> |
767 | + <property name="pos"></property> |
768 | + <property name="size">485,200</property> |
769 | + <property name="subclass">; forward_declare</property> |
770 | + <property name="tooltip"></property> |
771 | + <property name="window_extra_style"></property> |
772 | + <property name="window_name"></property> |
773 | + <property name="window_style">wxTAB_TRAVERSAL</property> |
774 | + <event name="OnAuiPaneActivated"></event> |
775 | + <event name="OnAuiPaneButton"></event> |
776 | + <event name="OnAuiPaneClose"></event> |
777 | + <event name="OnAuiPaneMaximize"></event> |
778 | + <event name="OnAuiPaneRestore"></event> |
779 | + <event name="OnAuiRender"></event> |
780 | + <event name="OnAux1DClick"></event> |
781 | + <event name="OnAux1Down"></event> |
782 | + <event name="OnAux1Up"></event> |
783 | + <event name="OnAux2DClick"></event> |
784 | + <event name="OnAux2Down"></event> |
785 | + <event name="OnAux2Up"></event> |
786 | + <event name="OnChar"></event> |
787 | + <event name="OnCharHook"></event> |
788 | + <event name="OnEnterWindow"></event> |
789 | + <event name="OnEraseBackground"></event> |
790 | + <event name="OnInitDialog"></event> |
791 | + <event name="OnKeyDown"></event> |
792 | + <event name="OnKeyUp"></event> |
793 | + <event name="OnKillFocus"></event> |
794 | + <event name="OnLeaveWindow"></event> |
795 | + <event name="OnLeftDClick"></event> |
796 | + <event name="OnLeftDown"></event> |
797 | + <event name="OnLeftUp"></event> |
798 | + <event name="OnMiddleDClick"></event> |
799 | + <event name="OnMiddleDown"></event> |
800 | + <event name="OnMiddleUp"></event> |
801 | + <event name="OnMotion"></event> |
802 | + <event name="OnMouseEvents"></event> |
803 | + <event name="OnMouseWheel"></event> |
804 | + <event name="OnPaint"></event> |
805 | + <event name="OnRightDClick"></event> |
806 | + <event name="OnRightDown"></event> |
807 | + <event name="OnRightUp"></event> |
808 | + <event name="OnSetFocus"></event> |
809 | + <event name="OnSize"></event> |
810 | + <event name="OnUpdateUI"></event> |
811 | + <object class="wxBoxSizer" expanded="1"> |
812 | + <property name="minimum_size"></property> |
813 | + <property name="name">bPanelSizer</property> |
814 | + <property name="orient">wxHORIZONTAL</property> |
815 | + <property name="permission">none</property> |
816 | + <object class="sizeritem" expanded="1"> |
817 | + <property name="border">0</property> |
818 | + <property name="flag">wxALIGN_LEFT|wxEXPAND|wxLEFT</property> |
819 | + <property name="proportion">1</property> |
820 | + <object class="wxBoxSizer" expanded="1"> |
821 | + <property name="minimum_size"></property> |
822 | + <property name="name">bGridSizer</property> |
823 | + <property name="orient">wxVERTICAL</property> |
824 | + <property name="permission">none</property> |
825 | + <object class="sizeritem" expanded="1"> |
826 | + <property name="border">5</property> |
827 | + <property name="flag">wxALL|wxEXPAND</property> |
828 | + <property name="proportion">1</property> |
829 | + <object class="wxGrid" expanded="1"> |
830 | + <property name="BottomDockable">1</property> |
831 | + <property name="LeftDockable">1</property> |
832 | + <property name="RightDockable">1</property> |
833 | + <property name="TopDockable">1</property> |
834 | + <property name="aui_layer"></property> |
835 | + <property name="aui_name"></property> |
836 | + <property name="aui_position"></property> |
837 | + <property name="aui_row"></property> |
838 | + <property name="autosize_cols">1</property> |
839 | + <property name="autosize_rows">0</property> |
840 | + <property name="best_size"></property> |
841 | + <property name="bg"></property> |
842 | + <property name="caption"></property> |
843 | + <property name="caption_visible">1</property> |
844 | + <property name="cell_bg"></property> |
845 | + <property name="cell_font"></property> |
846 | + <property name="cell_horiz_alignment">wxALIGN_LEFT</property> |
847 | + <property name="cell_text"></property> |
848 | + <property name="cell_vert_alignment">wxALIGN_CENTRE</property> |
849 | + <property name="center_pane">0</property> |
850 | + <property name="close_button">1</property> |
851 | + <property name="col_label_horiz_alignment">wxALIGN_CENTRE</property> |
852 | + <property name="col_label_size">22</property> |
853 | + <property name="col_label_values">"Icon" "Show button" "Name" "Category" "Description" "Path"</property> |
854 | + <property name="col_label_vert_alignment">wxALIGN_CENTRE</property> |
855 | + <property name="cols">6</property> |
856 | + <property name="column_sizes"></property> |
857 | + <property name="context_help"></property> |
858 | + <property name="context_menu">1</property> |
859 | + <property name="default_pane">0</property> |
860 | + <property name="dock">Dock</property> |
861 | + <property name="dock_fixed">0</property> |
862 | + <property name="docking">Left</property> |
863 | + <property name="drag_col_move">0</property> |
864 | + <property name="drag_col_size">1</property> |
865 | + <property name="drag_grid_size">0</property> |
866 | + <property name="drag_row_size">1</property> |
867 | + <property name="editing">0</property> |
868 | + <property name="enabled">1</property> |
869 | + <property name="fg"></property> |
870 | + <property name="floatable">1</property> |
871 | + <property name="font"></property> |
872 | + <property name="grid_line_color"></property> |
873 | + <property name="grid_lines">1</property> |
874 | + <property name="gripper">0</property> |
875 | + <property name="hidden">0</property> |
876 | + <property name="id">wxID_ANY</property> |
877 | + <property name="label_bg"></property> |
878 | + <property name="label_font"></property> |
879 | + <property name="label_text"></property> |
880 | + <property name="margin_height">0</property> |
881 | + <property name="margin_width">0</property> |
882 | + <property name="max_size"></property> |
883 | + <property name="maximize_button">0</property> |
884 | + <property name="maximum_size"></property> |
885 | + <property name="min_size"></property> |
886 | + <property name="minimize_button">0</property> |
887 | + <property name="minimum_size"></property> |
888 | + <property name="moveable">1</property> |
889 | + <property name="name">m_grid</property> |
890 | + <property name="pane_border">1</property> |
891 | + <property name="pane_position"></property> |
892 | + <property name="pane_size"></property> |
893 | + <property name="permission">protected</property> |
894 | + <property name="pin_button">1</property> |
895 | + <property name="pos"></property> |
896 | + <property name="resize">Resizable</property> |
897 | + <property name="row_label_horiz_alignment">wxALIGN_CENTRE</property> |
898 | + <property name="row_label_size">0</property> |
899 | + <property name="row_label_values"></property> |
900 | + <property name="row_label_vert_alignment">wxALIGN_CENTRE</property> |
901 | + <property name="row_sizes"></property> |
902 | + <property name="rows">3</property> |
903 | + <property name="show">1</property> |
904 | + <property name="size"></property> |
905 | + <property name="subclass">WX_GRID; widgets/wx_grid.h; forward_declare</property> |
906 | + <property name="toolbar_pane">0</property> |
907 | + <property name="tooltip"></property> |
908 | + <property name="window_extra_style"></property> |
909 | + <property name="window_name"></property> |
910 | + <property name="window_style">wxBORDER_SIMPLE</property> |
911 | + <event name="OnAux1DClick"></event> |
912 | + <event name="OnAux1Down"></event> |
913 | + <event name="OnAux1Up"></event> |
914 | + <event name="OnAux2DClick"></event> |
915 | + <event name="OnAux2Down"></event> |
916 | + <event name="OnAux2Up"></event> |
917 | + <event name="OnChar"></event> |
918 | + <event name="OnCharHook"></event> |
919 | + <event name="OnEnterWindow"></event> |
920 | + <event name="OnEraseBackground"></event> |
921 | + <event name="OnGridCellChange"></event> |
922 | + <event name="OnGridCellLeftClick">OnGridCellClick</event> |
923 | + <event name="OnGridCellLeftDClick"></event> |
924 | + <event name="OnGridCellRightClick"></event> |
925 | + <event name="OnGridCellRightDClick"></event> |
926 | + <event name="OnGridCmdCellChange"></event> |
927 | + <event name="OnGridCmdCellLeftClick"></event> |
928 | + <event name="OnGridCmdCellLeftDClick"></event> |
929 | + <event name="OnGridCmdCellRightClick"></event> |
930 | + <event name="OnGridCmdCellRightDClick"></event> |
931 | + <event name="OnGridCmdColSize"></event> |
932 | + <event name="OnGridCmdEditorCreated"></event> |
933 | + <event name="OnGridCmdEditorHidden"></event> |
934 | + <event name="OnGridCmdEditorShown"></event> |
935 | + <event name="OnGridCmdLabelLeftClick"></event> |
936 | + <event name="OnGridCmdLabelLeftDClick"></event> |
937 | + <event name="OnGridCmdLabelRightClick"></event> |
938 | + <event name="OnGridCmdLabelRightDClick"></event> |
939 | + <event name="OnGridCmdRangeSelect"></event> |
940 | + <event name="OnGridCmdRowSize"></event> |
941 | + <event name="OnGridCmdSelectCell"></event> |
942 | + <event name="OnGridColSize"></event> |
943 | + <event name="OnGridEditorCreated"></event> |
944 | + <event name="OnGridEditorHidden"></event> |
945 | + <event name="OnGridEditorShown"></event> |
946 | + <event name="OnGridLabelLeftClick"></event> |
947 | + <event name="OnGridLabelLeftDClick"></event> |
948 | + <event name="OnGridLabelRightClick"></event> |
949 | + <event name="OnGridLabelRightDClick"></event> |
950 | + <event name="OnGridRangeSelect"></event> |
951 | + <event name="OnGridRowSize"></event> |
952 | + <event name="OnGridSelectCell"></event> |
953 | + <event name="OnKeyDown"></event> |
954 | + <event name="OnKeyUp"></event> |
955 | + <event name="OnKillFocus"></event> |
956 | + <event name="OnLeaveWindow"></event> |
957 | + <event name="OnLeftDClick"></event> |
958 | + <event name="OnLeftDown"></event> |
959 | + <event name="OnLeftUp"></event> |
960 | + <event name="OnMiddleDClick"></event> |
961 | + <event name="OnMiddleDown"></event> |
962 | + <event name="OnMiddleUp"></event> |
963 | + <event name="OnMotion"></event> |
964 | + <event name="OnMouseEvents"></event> |
965 | + <event name="OnMouseWheel"></event> |
966 | + <event name="OnPaint"></event> |
967 | + <event name="OnRightDClick"></event> |
968 | + <event name="OnRightDown"></event> |
969 | + <event name="OnRightUp"></event> |
970 | + <event name="OnSetFocus"></event> |
971 | + <event name="OnSize"></event> |
972 | + <event name="OnUpdateUI"></event> |
973 | + </object> |
974 | + </object> |
975 | + </object> |
976 | + </object> |
977 | + <object class="sizeritem" expanded="1"> |
978 | + <property name="border">0</property> |
979 | + <property name="flag">wxALIGN_RIGHT|wxALIGN_TOP</property> |
980 | + <property name="proportion">0</property> |
981 | + <object class="wxBoxSizer" expanded="1"> |
982 | + <property name="minimum_size"></property> |
983 | + <property name="name">bButtonsSizer</property> |
984 | + <property name="orient">wxVERTICAL</property> |
985 | + <property name="permission">none</property> |
986 | + <object class="sizeritem" expanded="0"> |
987 | + <property name="border">5</property> |
988 | + <property name="flag">wxALIGN_TOP|wxALL</property> |
989 | + <property name="proportion">0</property> |
990 | + <object class="wxBitmapButton" expanded="0"> |
991 | + <property name="BottomDockable">1</property> |
992 | + <property name="LeftDockable">1</property> |
993 | + <property name="RightDockable">1</property> |
994 | + <property name="TopDockable">1</property> |
995 | + <property name="aui_layer"></property> |
996 | + <property name="aui_name"></property> |
997 | + <property name="aui_position"></property> |
998 | + <property name="aui_row"></property> |
999 | + <property name="best_size"></property> |
1000 | + <property name="bg"></property> |
1001 | + <property name="bitmap"></property> |
1002 | + <property name="caption"></property> |
1003 | + <property name="caption_visible">1</property> |
1004 | + <property name="center_pane">0</property> |
1005 | + <property name="close_button">1</property> |
1006 | + <property name="context_help"></property> |
1007 | + <property name="context_menu">1</property> |
1008 | + <property name="current"></property> |
1009 | + <property name="default">0</property> |
1010 | + <property name="default_pane">0</property> |
1011 | + <property name="disabled"></property> |
1012 | + <property name="dock">Dock</property> |
1013 | + <property name="dock_fixed">0</property> |
1014 | + <property name="docking">Left</property> |
1015 | + <property name="enabled">1</property> |
1016 | + <property name="fg"></property> |
1017 | + <property name="floatable">1</property> |
1018 | + <property name="focus"></property> |
1019 | + <property name="font"></property> |
1020 | + <property name="gripper">0</property> |
1021 | + <property name="hidden">0</property> |
1022 | + <property name="id">wxID_ANY</property> |
1023 | + <property name="label">Move Up</property> |
1024 | + <property name="margins"></property> |
1025 | + <property name="markup">0</property> |
1026 | + <property name="max_size"></property> |
1027 | + <property name="maximize_button">0</property> |
1028 | + <property name="maximum_size"></property> |
1029 | + <property name="min_size"></property> |
1030 | + <property name="minimize_button">0</property> |
1031 | + <property name="minimum_size">32,32</property> |
1032 | + <property name="moveable">1</property> |
1033 | + <property name="name">m_moveUpButton</property> |
1034 | + <property name="pane_border">1</property> |
1035 | + <property name="pane_position"></property> |
1036 | + <property name="pane_size"></property> |
1037 | + <property name="permission">protected</property> |
1038 | + <property name="pin_button">1</property> |
1039 | + <property name="pos"></property> |
1040 | + <property name="position"></property> |
1041 | + <property name="pressed"></property> |
1042 | + <property name="resize">Resizable</property> |
1043 | + <property name="show">1</property> |
1044 | + <property name="size"></property> |
1045 | + <property name="style"></property> |
1046 | + <property name="subclass">; forward_declare</property> |
1047 | + <property name="toolbar_pane">0</property> |
1048 | + <property name="tooltip"></property> |
1049 | + <property name="validator_data_type"></property> |
1050 | + <property name="validator_style">wxFILTER_NONE</property> |
1051 | + <property name="validator_type">wxDefaultValidator</property> |
1052 | + <property name="validator_variable"></property> |
1053 | + <property name="window_extra_style"></property> |
1054 | + <property name="window_name"></property> |
1055 | + <property name="window_style"></property> |
1056 | + <event name="OnAux1DClick"></event> |
1057 | + <event name="OnAux1Down"></event> |
1058 | + <event name="OnAux1Up"></event> |
1059 | + <event name="OnAux2DClick"></event> |
1060 | + <event name="OnAux2Down"></event> |
1061 | + <event name="OnAux2Up"></event> |
1062 | + <event name="OnButtonClick">OnMoveUpButtonClick</event> |
1063 | + <event name="OnChar"></event> |
1064 | + <event name="OnCharHook"></event> |
1065 | + <event name="OnEnterWindow"></event> |
1066 | + <event name="OnEraseBackground"></event> |
1067 | + <event name="OnKeyDown"></event> |
1068 | + <event name="OnKeyUp"></event> |
1069 | + <event name="OnKillFocus"></event> |
1070 | + <event name="OnLeaveWindow"></event> |
1071 | + <event name="OnLeftDClick"></event> |
1072 | + <event name="OnLeftDown"></event> |
1073 | + <event name="OnLeftUp"></event> |
1074 | + <event name="OnMiddleDClick"></event> |
1075 | + <event name="OnMiddleDown"></event> |
1076 | + <event name="OnMiddleUp"></event> |
1077 | + <event name="OnMotion"></event> |
1078 | + <event name="OnMouseEvents"></event> |
1079 | + <event name="OnMouseWheel"></event> |
1080 | + <event name="OnPaint"></event> |
1081 | + <event name="OnRightDClick"></event> |
1082 | + <event name="OnRightDown"></event> |
1083 | + <event name="OnRightUp"></event> |
1084 | + <event name="OnSetFocus"></event> |
1085 | + <event name="OnSize"></event> |
1086 | + <event name="OnUpdateUI"></event> |
1087 | + </object> |
1088 | + </object> |
1089 | + <object class="sizeritem" expanded="1"> |
1090 | + <property name="border">5</property> |
1091 | + <property name="flag">wxALL</property> |
1092 | + <property name="proportion">0</property> |
1093 | + <object class="wxBitmapButton" expanded="1"> |
1094 | + <property name="BottomDockable">1</property> |
1095 | + <property name="LeftDockable">1</property> |
1096 | + <property name="RightDockable">1</property> |
1097 | + <property name="TopDockable">1</property> |
1098 | + <property name="aui_layer"></property> |
1099 | + <property name="aui_name"></property> |
1100 | + <property name="aui_position"></property> |
1101 | + <property name="aui_row"></property> |
1102 | + <property name="best_size"></property> |
1103 | + <property name="bg"></property> |
1104 | + <property name="bitmap"></property> |
1105 | + <property name="caption"></property> |
1106 | + <property name="caption_visible">1</property> |
1107 | + <property name="center_pane">0</property> |
1108 | + <property name="close_button">1</property> |
1109 | + <property name="context_help"></property> |
1110 | + <property name="context_menu">1</property> |
1111 | + <property name="current"></property> |
1112 | + <property name="default">0</property> |
1113 | + <property name="default_pane">0</property> |
1114 | + <property name="disabled"></property> |
1115 | + <property name="dock">Dock</property> |
1116 | + <property name="dock_fixed">0</property> |
1117 | + <property name="docking">Left</property> |
1118 | + <property name="enabled">1</property> |
1119 | + <property name="fg"></property> |
1120 | + <property name="floatable">1</property> |
1121 | + <property name="focus"></property> |
1122 | + <property name="font"></property> |
1123 | + <property name="gripper">0</property> |
1124 | + <property name="hidden">0</property> |
1125 | + <property name="id">wxID_ANY</property> |
1126 | + <property name="label">Move Down</property> |
1127 | + <property name="margins"></property> |
1128 | + <property name="markup">0</property> |
1129 | + <property name="max_size"></property> |
1130 | + <property name="maximize_button">0</property> |
1131 | + <property name="maximum_size"></property> |
1132 | + <property name="min_size"></property> |
1133 | + <property name="minimize_button">0</property> |
1134 | + <property name="minimum_size">32,32</property> |
1135 | + <property name="moveable">1</property> |
1136 | + <property name="name">m_moveDownButton</property> |
1137 | + <property name="pane_border">1</property> |
1138 | + <property name="pane_position"></property> |
1139 | + <property name="pane_size"></property> |
1140 | + <property name="permission">protected</property> |
1141 | + <property name="pin_button">1</property> |
1142 | + <property name="pos"></property> |
1143 | + <property name="position"></property> |
1144 | + <property name="pressed"></property> |
1145 | + <property name="resize">Resizable</property> |
1146 | + <property name="show">1</property> |
1147 | + <property name="size"></property> |
1148 | + <property name="style"></property> |
1149 | + <property name="subclass">; forward_declare</property> |
1150 | + <property name="toolbar_pane">0</property> |
1151 | + <property name="tooltip"></property> |
1152 | + <property name="validator_data_type"></property> |
1153 | + <property name="validator_style">wxFILTER_NONE</property> |
1154 | + <property name="validator_type">wxDefaultValidator</property> |
1155 | + <property name="validator_variable"></property> |
1156 | + <property name="window_extra_style"></property> |
1157 | + <property name="window_name"></property> |
1158 | + <property name="window_style"></property> |
1159 | + <event name="OnAux1DClick"></event> |
1160 | + <event name="OnAux1Down"></event> |
1161 | + <event name="OnAux1Up"></event> |
1162 | + <event name="OnAux2DClick"></event> |
1163 | + <event name="OnAux2Down"></event> |
1164 | + <event name="OnAux2Up"></event> |
1165 | + <event name="OnButtonClick">OnMoveDownButtonClick</event> |
1166 | + <event name="OnChar"></event> |
1167 | + <event name="OnCharHook"></event> |
1168 | + <event name="OnEnterWindow"></event> |
1169 | + <event name="OnEraseBackground"></event> |
1170 | + <event name="OnKeyDown"></event> |
1171 | + <event name="OnKeyUp"></event> |
1172 | + <event name="OnKillFocus"></event> |
1173 | + <event name="OnLeaveWindow"></event> |
1174 | + <event name="OnLeftDClick"></event> |
1175 | + <event name="OnLeftDown"></event> |
1176 | + <event name="OnLeftUp"></event> |
1177 | + <event name="OnMiddleDClick"></event> |
1178 | + <event name="OnMiddleDown"></event> |
1179 | + <event name="OnMiddleUp"></event> |
1180 | + <event name="OnMotion"></event> |
1181 | + <event name="OnMouseEvents"></event> |
1182 | + <event name="OnMouseWheel"></event> |
1183 | + <event name="OnPaint"></event> |
1184 | + <event name="OnRightDClick"></event> |
1185 | + <event name="OnRightDown"></event> |
1186 | + <event name="OnRightUp"></event> |
1187 | + <event name="OnSetFocus"></event> |
1188 | + <event name="OnSize"></event> |
1189 | + <event name="OnUpdateUI"></event> |
1190 | + </object> |
1191 | + </object> |
1192 | + <object class="sizeritem" expanded="1"> |
1193 | + <property name="border">5</property> |
1194 | + <property name="flag">wxALL</property> |
1195 | + <property name="proportion">0</property> |
1196 | + <object class="wxBitmapButton" expanded="1"> |
1197 | + <property name="BottomDockable">1</property> |
1198 | + <property name="LeftDockable">1</property> |
1199 | + <property name="RightDockable">1</property> |
1200 | + <property name="TopDockable">1</property> |
1201 | + <property name="aui_layer"></property> |
1202 | + <property name="aui_name"></property> |
1203 | + <property name="aui_position"></property> |
1204 | + <property name="aui_row"></property> |
1205 | + <property name="best_size"></property> |
1206 | + <property name="bg"></property> |
1207 | + <property name="bitmap"></property> |
1208 | + <property name="caption"></property> |
1209 | + <property name="caption_visible">1</property> |
1210 | + <property name="center_pane">0</property> |
1211 | + <property name="close_button">1</property> |
1212 | + <property name="context_help"></property> |
1213 | + <property name="context_menu">1</property> |
1214 | + <property name="current"></property> |
1215 | + <property name="default">0</property> |
1216 | + <property name="default_pane">0</property> |
1217 | + <property name="disabled"></property> |
1218 | + <property name="dock">Dock</property> |
1219 | + <property name="dock_fixed">0</property> |
1220 | + <property name="docking">Left</property> |
1221 | + <property name="enabled">1</property> |
1222 | + <property name="fg"></property> |
1223 | + <property name="floatable">1</property> |
1224 | + <property name="focus"></property> |
1225 | + <property name="font"></property> |
1226 | + <property name="gripper">0</property> |
1227 | + <property name="hidden">0</property> |
1228 | + <property name="id">wxID_ANY</property> |
1229 | + <property name="label">Reload Plugins</property> |
1230 | + <property name="margins"></property> |
1231 | + <property name="markup">0</property> |
1232 | + <property name="max_size"></property> |
1233 | + <property name="maximize_button">0</property> |
1234 | + <property name="maximum_size"></property> |
1235 | + <property name="min_size"></property> |
1236 | + <property name="minimize_button">0</property> |
1237 | + <property name="minimum_size">32,32</property> |
1238 | + <property name="moveable">1</property> |
1239 | + <property name="name">m_reloadButton</property> |
1240 | + <property name="pane_border">1</property> |
1241 | + <property name="pane_position"></property> |
1242 | + <property name="pane_size"></property> |
1243 | + <property name="permission">protected</property> |
1244 | + <property name="pin_button">1</property> |
1245 | + <property name="pos"></property> |
1246 | + <property name="position"></property> |
1247 | + <property name="pressed"></property> |
1248 | + <property name="resize">Resizable</property> |
1249 | + <property name="show">1</property> |
1250 | + <property name="size"></property> |
1251 | + <property name="style"></property> |
1252 | + <property name="subclass">; forward_declare</property> |
1253 | + <property name="toolbar_pane">0</property> |
1254 | + <property name="tooltip"></property> |
1255 | + <property name="validator_data_type"></property> |
1256 | + <property name="validator_style">wxFILTER_NONE</property> |
1257 | + <property name="validator_type">wxDefaultValidator</property> |
1258 | + <property name="validator_variable"></property> |
1259 | + <property name="window_extra_style"></property> |
1260 | + <property name="window_name"></property> |
1261 | + <property name="window_style"></property> |
1262 | + <event name="OnAux1DClick"></event> |
1263 | + <event name="OnAux1Down"></event> |
1264 | + <event name="OnAux1Up"></event> |
1265 | + <event name="OnAux2DClick"></event> |
1266 | + <event name="OnAux2Down"></event> |
1267 | + <event name="OnAux2Up"></event> |
1268 | + <event name="OnButtonClick">OnReloadButtonClick</event> |
1269 | + <event name="OnChar"></event> |
1270 | + <event name="OnCharHook"></event> |
1271 | + <event name="OnEnterWindow"></event> |
1272 | + <event name="OnEraseBackground"></event> |
1273 | + <event name="OnKeyDown"></event> |
1274 | + <event name="OnKeyUp"></event> |
1275 | + <event name="OnKillFocus"></event> |
1276 | + <event name="OnLeaveWindow"></event> |
1277 | + <event name="OnLeftDClick"></event> |
1278 | + <event name="OnLeftDown"></event> |
1279 | + <event name="OnLeftUp"></event> |
1280 | + <event name="OnMiddleDClick"></event> |
1281 | + <event name="OnMiddleDown"></event> |
1282 | + <event name="OnMiddleUp"></event> |
1283 | + <event name="OnMotion"></event> |
1284 | + <event name="OnMouseEvents"></event> |
1285 | + <event name="OnMouseWheel"></event> |
1286 | + <event name="OnPaint"></event> |
1287 | + <event name="OnRightDClick"></event> |
1288 | + <event name="OnRightDown"></event> |
1289 | + <event name="OnRightUp"></event> |
1290 | + <event name="OnSetFocus"></event> |
1291 | + <event name="OnSize"></event> |
1292 | + <event name="OnUpdateUI"></event> |
1293 | + </object> |
1294 | + </object> |
1295 | + </object> |
1296 | + </object> |
1297 | + </object> |
1298 | + </object> |
1299 | + </object> |
1300 | +</wxFormBuilder_Project> |
1301 | diff --git a/pcbnew/dialogs/panel_pcbnew_action_plugins_base.h b/pcbnew/dialogs/panel_pcbnew_action_plugins_base.h |
1302 | new file mode 100644 |
1303 | index 0000000..8766d0c |
1304 | --- /dev/null |
1305 | +++ b/pcbnew/dialogs/panel_pcbnew_action_plugins_base.h |
1306 | @@ -0,0 +1,58 @@ |
1307 | +/////////////////////////////////////////////////////////////////////////// |
1308 | +// C++ code generated with wxFormBuilder (version Jul 11 2018) |
1309 | +// http://www.wxformbuilder.org/ |
1310 | +// |
1311 | +// PLEASE DO *NOT* EDIT THIS FILE! |
1312 | +/////////////////////////////////////////////////////////////////////////// |
1313 | + |
1314 | +#ifndef __PANEL_PCBNEW_ACTION_PLUGINS_BASE_H__ |
1315 | +#define __PANEL_PCBNEW_ACTION_PLUGINS_BASE_H__ |
1316 | + |
1317 | +#include <wx/artprov.h> |
1318 | +#include <wx/xrc/xmlres.h> |
1319 | +class WX_GRID; |
1320 | + |
1321 | +#include <wx/colour.h> |
1322 | +#include <wx/settings.h> |
1323 | +#include <wx/string.h> |
1324 | +#include <wx/font.h> |
1325 | +#include <wx/grid.h> |
1326 | +#include <wx/gdicmn.h> |
1327 | +#include <wx/sizer.h> |
1328 | +#include <wx/bmpbuttn.h> |
1329 | +#include <wx/bitmap.h> |
1330 | +#include <wx/image.h> |
1331 | +#include <wx/icon.h> |
1332 | +#include <wx/button.h> |
1333 | +#include <wx/panel.h> |
1334 | + |
1335 | +/////////////////////////////////////////////////////////////////////////// |
1336 | + |
1337 | +/////////////////////////////////////////////////////////////////////////////// |
1338 | +/// Class PANEL_PCBNEW_ACTION_PLUGINS_BASE |
1339 | +/////////////////////////////////////////////////////////////////////////////// |
1340 | +class PANEL_PCBNEW_ACTION_PLUGINS_BASE : public wxPanel |
1341 | +{ |
1342 | + private: |
1343 | + |
1344 | + protected: |
1345 | + WX_GRID* m_grid; |
1346 | + wxBitmapButton* m_moveUpButton; |
1347 | + wxBitmapButton* m_moveDownButton; |
1348 | + wxBitmapButton* m_reloadButton; |
1349 | + |
1350 | + // Virtual event handlers, overide them in your derived class |
1351 | + virtual void OnGridCellClick( wxGridEvent& event ) { event.Skip(); } |
1352 | + virtual void OnMoveUpButtonClick( wxCommandEvent& event ) { event.Skip(); } |
1353 | + virtual void OnMoveDownButtonClick( wxCommandEvent& event ) { event.Skip(); } |
1354 | + virtual void OnReloadButtonClick( wxCommandEvent& event ) { event.Skip(); } |
1355 | + |
1356 | + |
1357 | + public: |
1358 | + |
1359 | + PANEL_PCBNEW_ACTION_PLUGINS_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 485,200 ), long style = wxTAB_TRAVERSAL ); |
1360 | + ~PANEL_PCBNEW_ACTION_PLUGINS_BASE(); |
1361 | + |
1362 | +}; |
1363 | + |
1364 | +#endif //__PANEL_PCBNEW_ACTION_PLUGINS_BASE_H__ |
1365 | diff --git a/pcbnew/pcb_edit_frame.cpp b/pcbnew/pcb_edit_frame.cpp |
1366 | index e8bbb88..5c4a8d5 100644 |
1367 | --- a/pcbnew/pcb_edit_frame.cpp |
1368 | +++ b/pcbnew/pcb_edit_frame.cpp |
1369 | @@ -1243,6 +1243,8 @@ void PCB_EDIT_FRAME::PythonPluginsReload() |
1370 | // Action plugins can be modified, therefore the plugins menu |
1371 | // must be updated: |
1372 | RebuildActionPluginMenus(); |
1373 | + // Recreate top toolbar to add action plugin buttons |
1374 | + ReCreateHToolbar(); |
1375 | #endif |
1376 | #endif |
1377 | } |
1378 | diff --git a/pcbnew/pcb_edit_frame.h b/pcbnew/pcb_edit_frame.h |
1379 | index 4179353..4788841 100644 |
1380 | --- a/pcbnew/pcb_edit_frame.h |
1381 | +++ b/pcbnew/pcb_edit_frame.h |
1382 | @@ -25,13 +25,14 @@ |
1383 | #define WXPCB_STRUCT_H_ |
1384 | |
1385 | #include <unordered_map> |
1386 | +#include <map> |
1387 | #include "pcb_base_edit_frame.h" |
1388 | #include "config_params.h" |
1389 | #include "undo_redo_container.h" |
1390 | #include "zones.h" |
1391 | |
1392 | - |
1393 | /* Forward declarations of classes. */ |
1394 | +class ACTION_PLUGIN; |
1395 | class PCB_SCREEN; |
1396 | class BOARD; |
1397 | class BOARD_COMMIT; |
1398 | @@ -117,16 +118,36 @@ protected: |
1399 | #if defined(KICAD_SCRIPTING) && defined(KICAD_SCRIPTING_ACTION_MENU) |
1400 | /** |
1401 | * Function RebuildActionPluginMenus |
1402 | - * Fill action menu with all registred action plugins |
1403 | + * Fill action menu with all registered action plugins |
1404 | */ |
1405 | void RebuildActionPluginMenus(); |
1406 | |
1407 | /** |
1408 | - * Function OnActionPlugin |
1409 | + * Function AddActionPluginTools |
1410 | + * Append action plugin buttons to main toolbar |
1411 | + */ |
1412 | + void AddActionPluginTools(); |
1413 | + |
1414 | + /** |
1415 | + * Function RunActionPlugin |
1416 | + * Executes action plugin's Run() method and updates undo buffer |
1417 | + * @param aActionPlugin action plugin |
1418 | + */ |
1419 | + void RunActionPlugin( ACTION_PLUGIN* aActionPlugin ); |
1420 | + |
1421 | + /** |
1422 | + * Function OnActionPluginMenu |
1423 | * Launched by the menu when an action is called |
1424 | * @param aEvent sent by wx |
1425 | */ |
1426 | - void OnActionPlugin( wxCommandEvent& aEvent); |
1427 | + void OnActionPluginMenu( wxCommandEvent& aEvent); |
1428 | + |
1429 | + /** |
1430 | + * Function OnActionPluginButton |
1431 | + * Launched by the button when an action is called |
1432 | + * @param aEvent sent by wx |
1433 | + */ |
1434 | + void OnActionPluginButton( wxCommandEvent& aEvent ); |
1435 | |
1436 | /** |
1437 | * Function OnActionPluginRefresh |
1438 | @@ -379,6 +400,36 @@ public: |
1439 | // Configurations: |
1440 | void Process_Config( wxCommandEvent& event ); |
1441 | |
1442 | +#if defined(KICAD_SCRIPTING) && defined(KICAD_SCRIPTING_ACTION_MENU) |
1443 | + |
1444 | + /** |
1445 | + * Function SetActionPluginSettings |
1446 | + * Set a set of plugins that have visible buttons on toolbar |
1447 | + * Plugins are identified by their module path |
1448 | + */ |
1449 | + void SetActionPluginSettings( const std::vector< std::pair<wxString, wxString> >& aPluginsWithButtons ); |
1450 | + |
1451 | + /** |
1452 | + * Function GetActionPluginSettings |
1453 | + * Get a set of plugins that have visible buttons on toolbar |
1454 | + */ |
1455 | + std::vector< std::pair<wxString, wxString> > GetActionPluginSettings(); |
1456 | + |
1457 | + /** |
1458 | + * Function GetActionPluginButtonVisible |
1459 | + * Returns true if button visibility action plugin setting was set to true |
1460 | + * or it is unset and plugin defaults to true. |
1461 | + */ |
1462 | + bool GetActionPluginButtonVisible( const wxString& aPluginPath, bool aPluginDefault ); |
1463 | + |
1464 | + /** |
1465 | + * Function GetOrderedActionPlugins |
1466 | + * Returns ordered list of plugins in sequence in which they should appear on toolbar or in settings |
1467 | + */ |
1468 | + std::vector<ACTION_PLUGIN*> GetOrderedActionPlugins(); |
1469 | + |
1470 | +#endif |
1471 | + |
1472 | /** |
1473 | * Function GetProjectFileParameters |
1474 | * returns a project file parameter list for Pcbnew. |
1475 | diff --git a/pcbnew/pcb_general_settings.cpp b/pcbnew/pcb_general_settings.cpp |
1476 | index a8c70cd..96c525a 100644 |
1477 | --- a/pcbnew/pcb_general_settings.cpp |
1478 | +++ b/pcbnew/pcb_general_settings.cpp |
1479 | @@ -22,6 +22,7 @@ |
1480 | */ |
1481 | |
1482 | #include <pcb_general_settings.h> |
1483 | +#include <wx/tokenzr.h> |
1484 | |
1485 | PCB_GENERAL_SETTINGS::PCB_GENERAL_SETTINGS( FRAME_T aFrameType ) |
1486 | : m_frameType( aFrameType ), m_colorsSettings( aFrameType ) |
1487 | @@ -54,6 +55,32 @@ PCB_GENERAL_SETTINGS::PCB_GENERAL_SETTINGS( FRAME_T aFrameType ) |
1488 | void PCB_GENERAL_SETTINGS::Load( wxConfigBase* aCfg ) |
1489 | { |
1490 | m_colorsSettings.Load( aCfg ); |
1491 | + |
1492 | +#if defined(KICAD_SCRIPTING) && defined(KICAD_SCRIPTING_ACTION_MENU) |
1493 | + |
1494 | + m_pluginSettings.clear(); |
1495 | + |
1496 | + wxString pluginSettings = aCfg->Read( "ActionPluginButtons" ); |
1497 | + |
1498 | + wxStringTokenizer pluginSettingsTokenizer = wxStringTokenizer( pluginSettings, ";" ); |
1499 | + |
1500 | + while( pluginSettingsTokenizer.HasMoreTokens() ) |
1501 | + { |
1502 | + wxString plugin = pluginSettingsTokenizer.GetNextToken(); |
1503 | + wxStringTokenizer pluginTokenizer = wxStringTokenizer( plugin, "=" ); |
1504 | + |
1505 | + if( pluginTokenizer.CountTokens() != 2 ) |
1506 | + { |
1507 | + // Bad config |
1508 | + continue; |
1509 | + } |
1510 | + |
1511 | + plugin = pluginTokenizer.GetNextToken(); |
1512 | + m_pluginSettings.push_back( std::make_pair( plugin, pluginTokenizer.GetNextToken() ) ); |
1513 | + } |
1514 | + |
1515 | +#endif |
1516 | + |
1517 | SETTINGS::Load( aCfg ); |
1518 | } |
1519 | |
1520 | @@ -61,6 +88,24 @@ void PCB_GENERAL_SETTINGS::Load( wxConfigBase* aCfg ) |
1521 | void PCB_GENERAL_SETTINGS::Save( wxConfigBase* aCfg ) |
1522 | { |
1523 | m_colorsSettings.Save( aCfg ); |
1524 | + |
1525 | +#if defined(KICAD_SCRIPTING) && defined(KICAD_SCRIPTING_ACTION_MENU) |
1526 | + |
1527 | + wxString pluginSettings; |
1528 | + |
1529 | + for( auto const& entry : m_pluginSettings ) |
1530 | + { |
1531 | + if( !pluginSettings.IsEmpty() ) |
1532 | + { |
1533 | + pluginSettings = pluginSettings + wxT( ";" ); |
1534 | + } |
1535 | + pluginSettings = pluginSettings + entry.first + wxT( "=" ) + entry.second; |
1536 | + } |
1537 | + |
1538 | + aCfg->Write( "ActionPluginButtons" , pluginSettings ); |
1539 | + |
1540 | +#endif |
1541 | + |
1542 | SETTINGS::Save( aCfg ); |
1543 | } |
1544 | |
1545 | diff --git a/pcbnew/pcb_general_settings.h b/pcbnew/pcb_general_settings.h |
1546 | index bc8f953..fbcbe90 100644 |
1547 | --- a/pcbnew/pcb_general_settings.h |
1548 | +++ b/pcbnew/pcb_general_settings.h |
1549 | @@ -25,6 +25,7 @@ |
1550 | #define __PCBNEW_GENERAL_SETTINGS_H |
1551 | |
1552 | #include <colors_design_settings.h> |
1553 | +#include <vector> |
1554 | |
1555 | class wxConfigBase; |
1556 | class wxString; |
1557 | @@ -65,6 +66,10 @@ public: |
1558 | MAGNETIC_PAD_OPTION_VALUES m_magneticPads = CAPTURE_CURSOR_IN_TRACK_TOOL; |
1559 | MAGNETIC_PAD_OPTION_VALUES m_magneticTracks = CAPTURE_CURSOR_IN_TRACK_TOOL; |
1560 | |
1561 | +#if defined(KICAD_SCRIPTING) && defined(KICAD_SCRIPTING_ACTION_MENU) |
1562 | + std::vector< std::pair<wxString, wxString> > m_pluginSettings; // Settings for action plugins |
1563 | +#endif |
1564 | + |
1565 | protected: |
1566 | const FRAME_T m_frameType; |
1567 | COLORS_DESIGN_SETTINGS m_colorsSettings; |
1568 | diff --git a/pcbnew/pcbnew_config.cpp b/pcbnew/pcbnew_config.cpp |
1569 | index ae164fd..b6025a5 100644 |
1570 | --- a/pcbnew/pcbnew_config.cpp |
1571 | +++ b/pcbnew/pcbnew_config.cpp |
1572 | @@ -45,6 +45,7 @@ |
1573 | #include <panel_hotkeys_editor.h> |
1574 | #include <panel_pcbnew_settings.h> |
1575 | #include <panel_pcbnew_display_options.h> |
1576 | +#include <panel_pcbnew_action_plugins.h> |
1577 | #include <fp_lib_table.h> |
1578 | #include <worksheet_shape_builder.h> |
1579 | #include <class_board.h> |
1580 | @@ -97,6 +98,9 @@ void PCB_EDIT_FRAME::InstallPreferences( PAGED_DIALOG* aParent ) |
1581 | |
1582 | book->AddPage( new PANEL_PCBNEW_SETTINGS( this, aParent ), _( "Pcbnew" ) ); |
1583 | book->AddSubPage( new PANEL_PCBNEW_DISPLAY_OPTIONS( this, aParent ), _( "Display Options" ) ); |
1584 | +#if defined(KICAD_SCRIPTING) && defined(KICAD_SCRIPTING_ACTION_MENU) |
1585 | + book->AddSubPage( new PANEL_PCBNEW_ACTION_PLUGINS( this, aParent ), _( "Action Plugins" ) ); |
1586 | +#endif |
1587 | } |
1588 | |
1589 | |
1590 | diff --git a/pcbnew/swig/pcbnew_action_plugins.cpp b/pcbnew/swig/pcbnew_action_plugins.cpp |
1591 | index 4fb232e..0de6526 100644 |
1592 | --- a/pcbnew/swig/pcbnew_action_plugins.cpp |
1593 | +++ b/pcbnew/swig/pcbnew_action_plugins.cpp |
1594 | @@ -140,6 +140,32 @@ wxString PYTHON_ACTION_PLUGIN::GetDescription() |
1595 | } |
1596 | |
1597 | |
1598 | +bool PYTHON_ACTION_PLUGIN::GetShowToolbarButton() |
1599 | +{ |
1600 | + PyLOCK lock; |
1601 | + |
1602 | + PyObject* result = CallMethod( "GetShowToolbarButton"); |
1603 | + |
1604 | + return PyObject_IsTrue(result); |
1605 | +} |
1606 | + |
1607 | + |
1608 | +wxString PYTHON_ACTION_PLUGIN::GetIconFileName() |
1609 | +{ |
1610 | + PyLOCK lock; |
1611 | + |
1612 | + return CallRetStrMethod( "GetIconFileName" ); |
1613 | +} |
1614 | + |
1615 | + |
1616 | +wxString PYTHON_ACTION_PLUGIN::GetPluginPath() |
1617 | +{ |
1618 | + PyLOCK lock; |
1619 | + |
1620 | + return CallRetStrMethod( "GetPluginPath" ); |
1621 | +} |
1622 | + |
1623 | + |
1624 | void PYTHON_ACTION_PLUGIN::Run() |
1625 | { |
1626 | PyLOCK lock; |
1627 | @@ -164,217 +190,226 @@ void PYTHON_ACTION_PLUGINS::register_action( PyObject* aPyAction ) |
1628 | |
1629 | void PYTHON_ACTION_PLUGINS::deregister_action( PyObject* aPyAction ) |
1630 | { |
1631 | - // deregister also destroyes the previously created "PYTHON_ACTION_PLUGIN object" |
1632 | + // deregister also destroys the previously created "PYTHON_ACTION_PLUGIN object" |
1633 | ACTION_PLUGINS::deregister_object( (void*) aPyAction ); |
1634 | } |
1635 | |
1636 | |
1637 | #if defined(KICAD_SCRIPTING) && defined(KICAD_SCRIPTING_ACTION_MENU) |
1638 | |
1639 | -void PCB_EDIT_FRAME::OnActionPlugin( wxCommandEvent& aEvent ) |
1640 | +void PCB_EDIT_FRAME::OnActionPluginMenu( wxCommandEvent& aEvent ) |
1641 | { |
1642 | - int id = aEvent.GetId(); |
1643 | + ACTION_PLUGIN* actionPlugin = ACTION_PLUGINS::GetActionByMenu( aEvent.GetId() ); |
1644 | |
1645 | - ACTION_PLUGIN* actionPlugin = ACTION_PLUGINS::GetActionByMenu( id ); |
1646 | + if( actionPlugin ) |
1647 | + RunActionPlugin( actionPlugin ); |
1648 | +} |
1649 | |
1650 | - if( actionPlugin ) |
1651 | - { |
1652 | - PICKED_ITEMS_LIST itemsList; |
1653 | - BOARD* currentPcb = GetBoard(); |
1654 | - bool fromEmpty = false; |
1655 | +void PCB_EDIT_FRAME::OnActionPluginButton( wxCommandEvent& aEvent ) |
1656 | +{ |
1657 | + ACTION_PLUGIN* actionPlugin = ACTION_PLUGINS::GetActionByButton( aEvent.GetId() ); |
1658 | |
1659 | - itemsList.m_Status = UR_CHANGED; |
1660 | + if( actionPlugin ) |
1661 | + RunActionPlugin( actionPlugin ); |
1662 | +} |
1663 | |
1664 | - OnModify(); |
1665 | +void PCB_EDIT_FRAME::RunActionPlugin( ACTION_PLUGIN* aActionPlugin ) |
1666 | +{ |
1667 | + PICKED_ITEMS_LIST itemsList; |
1668 | + BOARD* currentPcb = GetBoard(); |
1669 | + bool fromEmpty = false; |
1670 | |
1671 | - // Append tracks: |
1672 | - for( BOARD_ITEM* item = currentPcb->m_Track; item != NULL; item = item->Next() ) |
1673 | - { |
1674 | - ITEM_PICKER picker( item, UR_CHANGED ); |
1675 | - itemsList.PushItem( picker ); |
1676 | - } |
1677 | + itemsList.m_Status = UR_CHANGED; |
1678 | |
1679 | - // Append modules: |
1680 | - for( BOARD_ITEM* item = currentPcb->m_Modules; item != NULL; item = item->Next() ) |
1681 | - { |
1682 | - ITEM_PICKER picker( item, UR_CHANGED ); |
1683 | - itemsList.PushItem( picker ); |
1684 | - } |
1685 | + OnModify(); |
1686 | |
1687 | - // Append drawings |
1688 | - for( BOARD_ITEM* item = currentPcb->m_Drawings; item != NULL; item = item->Next() ) |
1689 | - { |
1690 | - ITEM_PICKER picker( item, UR_CHANGED ); |
1691 | - itemsList.PushItem( picker ); |
1692 | - } |
1693 | + // Append tracks: |
1694 | + for( BOARD_ITEM* item = currentPcb->m_Track; item != NULL; item = item->Next() ) |
1695 | + { |
1696 | + ITEM_PICKER picker( item, UR_CHANGED ); |
1697 | + itemsList.PushItem( picker ); |
1698 | + } |
1699 | |
1700 | - // Append zones outlines |
1701 | - for( int ii = 0; ii < currentPcb->GetAreaCount(); ii++ ) |
1702 | - { |
1703 | - ITEM_PICKER picker( (EDA_ITEM*) currentPcb->GetArea( |
1704 | - ii ), UR_CHANGED ); |
1705 | - itemsList.PushItem( picker ); |
1706 | - } |
1707 | + // Append modules: |
1708 | + for( BOARD_ITEM* item = currentPcb->m_Modules; item != NULL; item = item->Next() ) |
1709 | + { |
1710 | + ITEM_PICKER picker( item, UR_CHANGED ); |
1711 | + itemsList.PushItem( picker ); |
1712 | + } |
1713 | |
1714 | - // Append zones segm: |
1715 | - for( BOARD_ITEM* item = currentPcb->m_SegZoneDeprecated; item != NULL; item = item->Next() ) |
1716 | - { |
1717 | - ITEM_PICKER picker( item, UR_CHANGED ); |
1718 | - itemsList.PushItem( picker ); |
1719 | - } |
1720 | + // Append drawings |
1721 | + for( BOARD_ITEM* item = currentPcb->m_Drawings; item != NULL; item = item->Next() ) |
1722 | + { |
1723 | + ITEM_PICKER picker( item, UR_CHANGED ); |
1724 | + itemsList.PushItem( picker ); |
1725 | + } |
1726 | |
1727 | - if( itemsList.GetCount() > 0 ) |
1728 | - SaveCopyInUndoList( itemsList, UR_CHANGED, wxPoint( 0.0, 0.0 ) ); |
1729 | - else |
1730 | - fromEmpty = true; |
1731 | + // Append zones outlines |
1732 | + for( int ii = 0; ii < currentPcb->GetAreaCount(); ii++ ) |
1733 | + { |
1734 | + ITEM_PICKER picker( (EDA_ITEM*) currentPcb->GetArea( |
1735 | + ii ), UR_CHANGED ); |
1736 | + itemsList.PushItem( picker ); |
1737 | + } |
1738 | |
1739 | - itemsList.ClearItemsList(); |
1740 | + // Append zones segm: |
1741 | + for( BOARD_ITEM* item = currentPcb->m_SegZoneDeprecated; item != NULL; item = item->Next() ) |
1742 | + { |
1743 | + ITEM_PICKER picker( item, UR_CHANGED ); |
1744 | + itemsList.PushItem( picker ); |
1745 | + } |
1746 | |
1747 | - // Execute plugin himself... |
1748 | - ACTION_PLUGINS::SetActionRunning( true ); |
1749 | - actionPlugin->Run(); |
1750 | - ACTION_PLUGINS::SetActionRunning( false ); |
1751 | + if( itemsList.GetCount() > 0 ) |
1752 | + SaveCopyInUndoList( itemsList, UR_CHANGED, wxPoint( 0.0, 0.0 ) ); |
1753 | + else |
1754 | + fromEmpty = true; |
1755 | |
1756 | - currentPcb->m_Status_Pcb = 0; |
1757 | + itemsList.ClearItemsList(); |
1758 | |
1759 | - // Get back the undo buffer to fix some modifications |
1760 | - PICKED_ITEMS_LIST* oldBuffer = NULL; |
1761 | + // Execute plugin itself... |
1762 | + ACTION_PLUGINS::SetActionRunning( true ); |
1763 | + aActionPlugin->Run(); |
1764 | + ACTION_PLUGINS::SetActionRunning( false ); |
1765 | |
1766 | - if( fromEmpty ) |
1767 | - { |
1768 | - oldBuffer = new PICKED_ITEMS_LIST(); |
1769 | - oldBuffer->m_Status = UR_NEW; |
1770 | - } |
1771 | - else |
1772 | - { |
1773 | - oldBuffer = GetScreen()->PopCommandFromUndoList(); |
1774 | - wxASSERT( oldBuffer ); |
1775 | - } |
1776 | + currentPcb->m_Status_Pcb = 0; |
1777 | |
1778 | - // Try do discover what was modified |
1779 | + // Get back the undo buffer to fix some modifications |
1780 | + PICKED_ITEMS_LIST* oldBuffer = NULL; |
1781 | |
1782 | - PICKED_ITEMS_LIST deletedItemsList; |
1783 | + if( fromEmpty ) |
1784 | + { |
1785 | + oldBuffer = new PICKED_ITEMS_LIST(); |
1786 | + oldBuffer->m_Status = UR_NEW; |
1787 | + } |
1788 | + else |
1789 | + { |
1790 | + oldBuffer = GetScreen()->PopCommandFromUndoList(); |
1791 | + wxASSERT( oldBuffer ); |
1792 | + } |
1793 | |
1794 | - // Found deleted modules |
1795 | - for( unsigned int i = 0; i < oldBuffer->GetCount(); i++ ) |
1796 | - { |
1797 | - BOARD_ITEM* item = (BOARD_ITEM*) oldBuffer->GetPickedItem( i ); |
1798 | - ITEM_PICKER picker( item, UR_DELETED ); |
1799 | + // Try do discover what was modified |
1800 | |
1801 | - wxASSERT( item ); |
1802 | + PICKED_ITEMS_LIST deletedItemsList; |
1803 | |
1804 | - switch( item->Type() ) |
1805 | - { |
1806 | - case PCB_NETINFO_T: |
1807 | - case PCB_MARKER_T: |
1808 | - case PCB_MODULE_T: |
1809 | - case PCB_TRACE_T: |
1810 | - case PCB_VIA_T: |
1811 | - case PCB_LINE_T: |
1812 | - case PCB_TEXT_T: |
1813 | - case PCB_DIMENSION_T: |
1814 | - case PCB_TARGET_T: |
1815 | - case PCB_ZONE_T: |
1816 | - |
1817 | - // If item has a list it's mean that the element is on the board |
1818 | - if( item->GetList() == NULL ) |
1819 | - { |
1820 | - deletedItemsList.PushItem( picker ); |
1821 | - } |
1822 | - |
1823 | - break; |
1824 | - |
1825 | - case PCB_ZONE_AREA_T: |
1826 | + // Found deleted modules |
1827 | + for( unsigned int i = 0; i < oldBuffer->GetCount(); i++ ) |
1828 | + { |
1829 | + BOARD_ITEM* item = (BOARD_ITEM*) oldBuffer->GetPickedItem( i ); |
1830 | + ITEM_PICKER picker( item, UR_DELETED ); |
1831 | + |
1832 | + wxASSERT( item ); |
1833 | + |
1834 | + switch( item->Type() ) |
1835 | + { |
1836 | + case PCB_NETINFO_T: |
1837 | + case PCB_MARKER_T: |
1838 | + case PCB_MODULE_T: |
1839 | + case PCB_TRACE_T: |
1840 | + case PCB_VIA_T: |
1841 | + case PCB_LINE_T: |
1842 | + case PCB_TEXT_T: |
1843 | + case PCB_DIMENSION_T: |
1844 | + case PCB_TARGET_T: |
1845 | + case PCB_ZONE_T: |
1846 | + |
1847 | + // If item has a list it's mean that the element is on the board |
1848 | + if( item->GetList() == NULL ) |
1849 | { |
1850 | - bool zoneFound = false; |
1851 | + deletedItemsList.PushItem( picker ); |
1852 | + } |
1853 | |
1854 | - for( int ii = 0; ii < currentPcb->GetAreaCount(); ii++ ) |
1855 | - zoneFound |= currentPcb->GetArea( ii ) == item; |
1856 | + break; |
1857 | |
1858 | - if( !zoneFound ) |
1859 | - { |
1860 | - deletedItemsList.PushItem( picker ); |
1861 | - } |
1862 | + case PCB_ZONE_AREA_T: |
1863 | + { |
1864 | + bool zoneFound = false; |
1865 | |
1866 | - break; |
1867 | - } |
1868 | + for( int ii = 0; ii < currentPcb->GetAreaCount(); ii++ ) |
1869 | + zoneFound |= currentPcb->GetArea( ii ) == item; |
1870 | |
1871 | - default: |
1872 | - wxString msg; |
1873 | - msg.Printf( _( "(PCB_EDIT_FRAME::OnActionPlugin) needs work: " |
1874 | - "BOARD_ITEM type (%d) not handled" ), |
1875 | - item->Type() ); |
1876 | - wxFAIL_MSG( msg ); |
1877 | - break; |
1878 | + if( !zoneFound ) |
1879 | + { |
1880 | + deletedItemsList.PushItem( picker ); |
1881 | } |
1882 | + |
1883 | + break; |
1884 | } |
1885 | |
1886 | - // Mark deleted elements in undolist |
1887 | - for( unsigned int i = 0; i < deletedItemsList.GetCount(); i++ ) |
1888 | - { |
1889 | - oldBuffer->PushItem( deletedItemsList.GetItemWrapper( i ) ); |
1890 | + default: |
1891 | + wxString msg; |
1892 | + msg.Printf( _( "(PCB_EDIT_FRAME::OnActionPlugin) needs work: " |
1893 | + "BOARD_ITEM type (%d) not handled" ), |
1894 | + item->Type() ); |
1895 | + wxFAIL_MSG( msg ); |
1896 | + break; |
1897 | } |
1898 | + } |
1899 | |
1900 | - // Find new modules |
1901 | - for( BOARD_ITEM* item = currentPcb->m_Modules; item != NULL; item = item->Next() ) |
1902 | + // Mark deleted elements in undolist |
1903 | + for( unsigned int i = 0; i < deletedItemsList.GetCount(); i++ ) |
1904 | + { |
1905 | + oldBuffer->PushItem( deletedItemsList.GetItemWrapper( i ) ); |
1906 | + } |
1907 | + |
1908 | + // Find new modules |
1909 | + for( BOARD_ITEM* item = currentPcb->m_Modules; item != NULL; item = item->Next() ) |
1910 | + { |
1911 | + if( !oldBuffer->ContainsItem( item ) ) |
1912 | { |
1913 | - if( !oldBuffer->ContainsItem( item ) ) |
1914 | - { |
1915 | - ITEM_PICKER picker( item, UR_NEW ); |
1916 | - oldBuffer->PushItem( picker ); |
1917 | - } |
1918 | + ITEM_PICKER picker( item, UR_NEW ); |
1919 | + oldBuffer->PushItem( picker ); |
1920 | } |
1921 | + } |
1922 | |
1923 | - for( BOARD_ITEM* item = currentPcb->m_Track; item != NULL; item = item->Next() ) |
1924 | + for( BOARD_ITEM* item = currentPcb->m_Track; item != NULL; item = item->Next() ) |
1925 | + { |
1926 | + if( !oldBuffer->ContainsItem( item ) ) |
1927 | { |
1928 | - if( !oldBuffer->ContainsItem( item ) ) |
1929 | - { |
1930 | - ITEM_PICKER picker( item, UR_NEW ); |
1931 | - oldBuffer->PushItem( picker ); |
1932 | - } |
1933 | + ITEM_PICKER picker( item, UR_NEW ); |
1934 | + oldBuffer->PushItem( picker ); |
1935 | } |
1936 | + } |
1937 | |
1938 | - for( BOARD_ITEM* item = currentPcb->m_Drawings; item != NULL; item = item->Next() ) |
1939 | + for( BOARD_ITEM* item = currentPcb->m_Drawings; item != NULL; item = item->Next() ) |
1940 | + { |
1941 | + if( !oldBuffer->ContainsItem( item ) ) |
1942 | { |
1943 | - if( !oldBuffer->ContainsItem( item ) ) |
1944 | - { |
1945 | - ITEM_PICKER picker( item, UR_NEW ); |
1946 | - oldBuffer->PushItem( picker ); |
1947 | - } |
1948 | + ITEM_PICKER picker( item, UR_NEW ); |
1949 | + oldBuffer->PushItem( picker ); |
1950 | } |
1951 | + } |
1952 | |
1953 | - for( BOARD_ITEM* item = currentPcb->m_SegZoneDeprecated; item != NULL; item = item->Next() ) |
1954 | + for( BOARD_ITEM* item = currentPcb->m_SegZoneDeprecated; item != NULL; item = item->Next() ) |
1955 | + { |
1956 | + if( !oldBuffer->ContainsItem( item ) ) |
1957 | { |
1958 | - if( !oldBuffer->ContainsItem( item ) ) |
1959 | - { |
1960 | - ITEM_PICKER picker( item, UR_NEW ); |
1961 | - oldBuffer->PushItem( picker ); |
1962 | - } |
1963 | + ITEM_PICKER picker( item, UR_NEW ); |
1964 | + oldBuffer->PushItem( picker ); |
1965 | } |
1966 | + } |
1967 | |
1968 | - for( int ii = 0; ii < currentPcb->GetAreaCount(); ii++ ) |
1969 | + for( int ii = 0; ii < currentPcb->GetAreaCount(); ii++ ) |
1970 | + { |
1971 | + if( !oldBuffer->ContainsItem( (EDA_ITEM*) currentPcb->GetArea( ii ) ) ) |
1972 | { |
1973 | - if( !oldBuffer->ContainsItem( (EDA_ITEM*) currentPcb->GetArea( ii ) ) ) |
1974 | - { |
1975 | - ITEM_PICKER picker( (EDA_ITEM*) currentPcb->GetArea( |
1976 | - ii ), UR_NEW ); |
1977 | - oldBuffer->PushItem( picker ); |
1978 | - } |
1979 | + ITEM_PICKER picker( (EDA_ITEM*) currentPcb->GetArea( |
1980 | + ii ), UR_NEW ); |
1981 | + oldBuffer->PushItem( picker ); |
1982 | } |
1983 | + } |
1984 | |
1985 | |
1986 | - GetScreen()->PushCommandToUndoList( oldBuffer ); |
1987 | + GetScreen()->PushCommandToUndoList( oldBuffer ); |
1988 | |
1989 | - if( IsGalCanvasActive() ) |
1990 | - { |
1991 | - UseGalCanvas( GetGalCanvas() ); |
1992 | - } |
1993 | - else |
1994 | - { |
1995 | - UpdateUserInterface(); |
1996 | - GetScreen()->SetModify(); |
1997 | - Refresh(); |
1998 | - } |
1999 | + if( IsGalCanvasActive() ) |
2000 | + { |
2001 | + UseGalCanvas( GetGalCanvas() ); |
2002 | + } |
2003 | + else |
2004 | + { |
2005 | + UpdateUserInterface(); |
2006 | + GetScreen()->SetModify(); |
2007 | + Refresh(); |
2008 | } |
2009 | } |
2010 | |
2011 | @@ -409,30 +444,39 @@ void PCB_EDIT_FRAME::RebuildActionPluginMenus() |
2012 | // Remove menus which are not usable for our current plugin list |
2013 | Disconnect( item->GetId(), wxEVT_COMMAND_MENU_SELECTED, |
2014 | (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) & |
2015 | - PCB_EDIT_FRAME::OnActionPlugin ); |
2016 | + PCB_EDIT_FRAME::OnActionPluginMenu ); |
2017 | actionMenu->Delete( item ); |
2018 | } |
2019 | |
2020 | for( int ii = 0; ii < ACTION_PLUGINS::GetActionsCount(); ii++ ) |
2021 | { |
2022 | wxMenuItem* item; |
2023 | + ACTION_PLUGIN* ap = ACTION_PLUGINS::GetAction( ii ); |
2024 | + const wxBitmap& bitmap = ap->iconBitmap.IsOk() ? ap->iconBitmap : KiBitmap( hammer_xpm ); |
2025 | |
2026 | if( ii < (int) available_menus.size() ) |
2027 | { |
2028 | item = available_menus[ii]; |
2029 | - item->SetItemLabel( ACTION_PLUGINS::GetAction( ii )->GetName() ); |
2030 | - item->SetHelp( ACTION_PLUGINS::GetAction( ii )->GetDescription() ); |
2031 | + item->SetItemLabel( ap->GetName() ); |
2032 | + item->SetHelp( ap->GetDescription() ); |
2033 | + |
2034 | + // On windows we need to set "unchecked" bitmap |
2035 | +#if defined(__WXMSW__) |
2036 | + item->SetBitmap( bitmap, false ); |
2037 | +#else |
2038 | + item->SetBitmap( bitmap ); |
2039 | +#endif |
2040 | } |
2041 | else |
2042 | { |
2043 | item = AddMenuItem( actionMenu, wxID_ANY, |
2044 | - ACTION_PLUGINS::GetAction( ii )->GetName(), |
2045 | - ACTION_PLUGINS::GetAction( ii )->GetDescription(), |
2046 | - KiBitmap( hammer_xpm ) ); |
2047 | + ap->GetName(), |
2048 | + ap->GetDescription(), |
2049 | + bitmap ); |
2050 | |
2051 | Connect( item->GetId(), wxEVT_COMMAND_MENU_SELECTED, |
2052 | (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) & |
2053 | - PCB_EDIT_FRAME::OnActionPlugin ); |
2054 | + PCB_EDIT_FRAME::OnActionPluginMenu ); |
2055 | } |
2056 | |
2057 | ACTION_PLUGINS::SetActionMenu( ii, item->GetId() ); |
2058 | @@ -440,4 +484,104 @@ void PCB_EDIT_FRAME::RebuildActionPluginMenus() |
2059 | } |
2060 | |
2061 | |
2062 | +void PCB_EDIT_FRAME::AddActionPluginTools() |
2063 | +{ |
2064 | + bool need_separator = true; |
2065 | + const auto& orderedPlugins = GetOrderedActionPlugins(); |
2066 | + |
2067 | + for( const auto& ap : orderedPlugins ) |
2068 | + { |
2069 | + if( GetActionPluginButtonVisible( ap->GetPluginPath(), ap->GetShowToolbarButton() ) ) |
2070 | + { |
2071 | + |
2072 | + if ( need_separator ) |
2073 | + { |
2074 | + KiScaledSeparator( m_mainToolBar, this ); |
2075 | + need_separator = false; |
2076 | + } |
2077 | + |
2078 | + // Add button |
2079 | + wxBitmap bitmap; |
2080 | + |
2081 | + if ( ap->iconBitmap.IsOk() ) |
2082 | + bitmap = KiScaledBitmap( ap->iconBitmap, this ); |
2083 | + else |
2084 | + bitmap = KiScaledBitmap( hammer_xpm, this ); |
2085 | + |
2086 | + wxAuiToolBarItem* button = m_mainToolBar->AddTool( |
2087 | + wxID_ANY, wxEmptyString, bitmap, ap->GetName() ); |
2088 | + |
2089 | + Connect( button->GetId(), wxEVT_COMMAND_MENU_SELECTED, |
2090 | + (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) & |
2091 | + PCB_EDIT_FRAME::OnActionPluginButton ); |
2092 | + |
2093 | + // Link action plugin to button |
2094 | + ACTION_PLUGINS::SetActionButton( ap, button->GetId() ); |
2095 | + } |
2096 | + } |
2097 | +} |
2098 | + |
2099 | + |
2100 | +void PCB_EDIT_FRAME::SetActionPluginSettings( const std::vector< std::pair<wxString, wxString> >& aPluginSettings ) |
2101 | +{ |
2102 | + m_configSettings.m_pluginSettings = aPluginSettings; |
2103 | + ReCreateHToolbar(); |
2104 | +} |
2105 | + |
2106 | + |
2107 | +std::vector< std::pair<wxString, wxString> > PCB_EDIT_FRAME::GetActionPluginSettings() |
2108 | +{ |
2109 | + return m_configSettings.m_pluginSettings; |
2110 | +} |
2111 | + |
2112 | + |
2113 | +std::vector<ACTION_PLUGIN*> PCB_EDIT_FRAME::GetOrderedActionPlugins() |
2114 | +{ |
2115 | + std::vector<ACTION_PLUGIN*> orderedPlugins; |
2116 | + const auto& pluginSettings = GetActionPluginSettings(); |
2117 | + |
2118 | + // First add plugins that have entries in settings |
2119 | + for( size_t ii = 0; ii < pluginSettings.size(); ii++ ) |
2120 | + { |
2121 | + for( int jj = 0; jj < ACTION_PLUGINS::GetActionsCount(); jj++ ) |
2122 | + { |
2123 | + if( ACTION_PLUGINS::GetAction( jj )->GetPluginPath() == pluginSettings[ii].first ) |
2124 | + orderedPlugins.push_back( ACTION_PLUGINS::GetAction( jj ) ); |
2125 | + } |
2126 | + } |
2127 | + |
2128 | + // Now append new plugins that have not been configured yet |
2129 | + for( int ii = 0; ii < ACTION_PLUGINS::GetActionsCount(); ii++ ) |
2130 | + { |
2131 | + bool found = false; |
2132 | + |
2133 | + for( size_t jj = 0; jj < orderedPlugins.size(); jj++ ) |
2134 | + { |
2135 | + if( ACTION_PLUGINS::GetAction( ii ) == orderedPlugins[jj] ) |
2136 | + found = true; |
2137 | + } |
2138 | + |
2139 | + if ( !found ) |
2140 | + orderedPlugins.push_back( ACTION_PLUGINS::GetAction( ii ) ); |
2141 | + } |
2142 | + |
2143 | + return orderedPlugins; |
2144 | +} |
2145 | + |
2146 | + |
2147 | +bool PCB_EDIT_FRAME::GetActionPluginButtonVisible( const wxString& aPluginPath, bool aPluginDefault ) |
2148 | +{ |
2149 | + auto& settings = m_configSettings.m_pluginSettings; |
2150 | + |
2151 | + for(const auto& entry : settings ) |
2152 | + { |
2153 | + if (entry.first == aPluginPath ) |
2154 | + return entry.second == wxT( "Visible" ); |
2155 | + } |
2156 | + |
2157 | + // Plugin is not in settings, return default. |
2158 | + return aPluginDefault; |
2159 | +} |
2160 | + |
2161 | + |
2162 | #endif |
2163 | diff --git a/pcbnew/swig/pcbnew_action_plugins.h b/pcbnew/swig/pcbnew_action_plugins.h |
2164 | index 08dfa14..a1d6d9f 100644 |
2165 | --- a/pcbnew/swig/pcbnew_action_plugins.h |
2166 | +++ b/pcbnew/swig/pcbnew_action_plugins.h |
2167 | @@ -47,6 +47,9 @@ public: |
2168 | wxString GetCategoryName() override; |
2169 | wxString GetName() override; |
2170 | wxString GetDescription() override; |
2171 | + bool GetShowToolbarButton() override; |
2172 | + wxString GetIconFileName() override; |
2173 | + wxString GetPluginPath() override; |
2174 | void Run() override; |
2175 | void* GetObject() override; |
2176 | }; |
2177 | diff --git a/pcbnew/tool_pcb_editor.cpp b/pcbnew/tool_pcb_editor.cpp |
2178 | index 66b6223..b5c64c3 100644 |
2179 | --- a/pcbnew/tool_pcb_editor.cpp |
2180 | +++ b/pcbnew/tool_pcb_editor.cpp |
2181 | @@ -321,6 +321,10 @@ void PCB_EDIT_FRAME::ReCreateHToolbar() |
2182 | m_mainToolBar->AddTool( ID_TOOLBARH_PCB_SCRIPTING_CONSOLE, wxEmptyString, |
2183 | KiScaledBitmap( py_script_xpm, this ), |
2184 | _( "Show/Hide the Python Scripting console" ), wxITEM_CHECK ); |
2185 | + |
2186 | +#if defined(KICAD_SCRIPTING) && defined(KICAD_SCRIPTING_ACTION_MENU) |
2187 | + AddActionPluginTools(); |
2188 | +#endif |
2189 | } |
2190 | #endif |
2191 | |
2192 | diff --git a/scripting/kicadplugins.i b/scripting/kicadplugins.i |
2193 | index 8c1781d..ebd8db2 100644 |
2194 | --- a/scripting/kicadplugins.i |
2195 | +++ b/scripting/kicadplugins.i |
2196 | @@ -260,7 +260,7 @@ def LoadPlugins(bundlepath=None): |
2197 | if module == '__init__.py' or module[-3:] != '.py': |
2198 | continue |
2199 | |
2200 | - LoadOnePlugin(plugins_dir, module); |
2201 | + LoadOnePlugin(plugins_dir, module) |
2202 | |
2203 | |
2204 | class KiCadPlugin: |
2205 | @@ -268,6 +268,9 @@ class KiCadPlugin: |
2206 | pass |
2207 | |
2208 | def register(self): |
2209 | + import inspect |
2210 | + import os |
2211 | + |
2212 | if isinstance(self,FilePlugin): |
2213 | pass # register to file plugins in C++ |
2214 | |
2215 | @@ -276,6 +279,14 @@ class KiCadPlugin: |
2216 | return |
2217 | |
2218 | if isinstance(self,ActionPlugin): |
2219 | + """ |
2220 | + Get path to .py or .pyc that has definition of plugin class. |
2221 | + If path is binary but source also exists, assume definition is in source. |
2222 | + """ |
2223 | + self.__plugin_path = inspect.getfile(self.__class__) |
2224 | + if self.__plugin_path.endswith('.pyc') and os.path.isfile(self.__plugin_path[:-1]): |
2225 | + self.__plugin_path = self.__plugin_path[:-1] |
2226 | + self.__plugin_path = self.__plugin_path + '/' + self.__class__.__name__ |
2227 | PYTHON_ACTION_PLUGINS.register_action(self) |
2228 | return |
2229 | |
2230 | @@ -295,6 +306,9 @@ class KiCadPlugin: |
2231 | |
2232 | return |
2233 | |
2234 | + def GetPluginPath( self ): |
2235 | + return self.__plugin_path |
2236 | + |
2237 | |
2238 | class FilePlugin(KiCadPlugin): |
2239 | def __init__(self): |
2240 | @@ -633,6 +647,8 @@ class FootprintWizardPlugin(KiCadPlugin, object): |
2241 | class ActionPlugin(KiCadPlugin, object): |
2242 | def __init__( self ): |
2243 | KiCadPlugin.__init__( self ) |
2244 | + self.icon_file_name = "" |
2245 | + self.show_toolbar_button = False |
2246 | self.defaults() |
2247 | |
2248 | def defaults( self ): |
2249 | @@ -649,6 +665,12 @@ class ActionPlugin(KiCadPlugin, object): |
2250 | def GetDescription( self ): |
2251 | return self.description |
2252 | |
2253 | + def GetShowToolbarButton( self ): |
2254 | + return self.show_toolbar_button |
2255 | + |
2256 | + def GetIconFileName( self ): |
2257 | + return self.icon_file_name |
2258 | + |
2259 | def Run(self): |
2260 | return |
2261 |
Overall looks good. I haven't checked MacOS compatibility, so I tagged Jeff Young to comment.
The code style issues are scattered around, I think I found most all.
You should remove the unsafe/unused functions.
I don't think we should be mixing IDs between buttons and menus.
You can simplify your map usage to just a vector (O(n) is fine for searching this)
Can you squash these into a single commit (this is to allow git bisect without errors)?