Merge ~imcinerney/kicad:cvpcb_actions into ~kicad-product-committers/kicad:master

Proposed by Ian McInerney
Status: Merged
Merge reported by: Wayne Stambaugh
Merged at revision: 69f5abb12616d9557a2212b27447e34c4bd293b8
Proposed branch: ~imcinerney/kicad:cvpcb_actions
Merge into: ~kicad-product-committers/kicad:master
Diff against target: 3973 lines (+1951/-901)
33 files modified
common/wildcards_and_files_ext.cpp (+1/-0)
cvpcb/CMakeLists.txt (+3/-63)
cvpcb/auto_associate.cpp (+14/-12)
cvpcb/auto_associate.h (+1/-0)
cvpcb/cfg.cpp (+2/-11)
cvpcb/components_listbox.cpp (+3/-13)
cvpcb/cvpcb.cpp (+1/-12)
cvpcb/cvpcb_association.h (+127/-0)
cvpcb/cvpcb_id.h (+1/-14)
cvpcb/cvpcb_mainframe.cpp (+426/-342)
cvpcb/cvpcb_mainframe.h (+184/-82)
cvpcb/dialogs/dialog_config_equfiles.cpp (+0/-12)
cvpcb/dialogs/dialog_display_options.cpp (+0/-3)
cvpcb/display_footprints_frame.cpp (+19/-21)
cvpcb/display_footprints_frame.h (+0/-2)
cvpcb/footprints_listbox.cpp (+9/-21)
cvpcb/library_listbox.cpp (+6/-18)
cvpcb/listbox_base.cpp (+0/-5)
cvpcb/menubar.cpp (+36/-19)
cvpcb/readwrite_dlgs.cpp (+8/-91)
cvpcb/toolbars_cvpcb.cpp (+39/-51)
cvpcb/tools/cvpcb_actions.cpp (+122/-7)
cvpcb/tools/cvpcb_actions.h (+33/-8)
cvpcb/tools/cvpcb_association_tool.cpp (+296/-0)
cvpcb/tools/cvpcb_association_tool.h (+116/-0)
cvpcb/tools/cvpcb_control.cpp (+294/-24)
cvpcb/tools/cvpcb_control.h (+81/-26)
cvpcb/tools/cvpcb_fpviewer_control.cpp (+30/-10)
cvpcb/tools/cvpcb_fpviewer_control.h (+59/-0)
cvpcb/tools/cvpcb_fpviewer_selection_tool.cpp (+18/-21)
cvpcb/tools/cvpcb_fpviewer_selection_tool.h (+17/-10)
include/tool/action_toolbar.h (+4/-3)
include/wildcards_and_files_ext.h (+1/-0)
Reviewer Review Type Date Requested Status
Wayne Stambaugh Approve
Seth Hillbrand Approve
Review via email: mp+371156@code.launchpad.net

Description of the change

This change set upgrades cvpcb significantly, including:

* Switching it to the tool framework
* Refactoring the structure to make association modifications easier to code
* Add a hotkey infrastructure through the tool framework
* Add undo/redo of associations
* Add single association delete (and fix the name of the delete all tool and its confirmation text)
* Add cut/copy/paste of associations (you can also copy from the footprint box to paste into the component box).
* Add the library location display
* General cleanup of the cmake build, includes, and events to correspond to the rework.

Sorry for the size of this, but I didn't think splitting into the refator part and the new material would be good since then you couldn't see how the refactor made the new material very easy to add.

So, grab a coffee, sit back, and let me know if you have any comments/critiques.

To post a comment you must log in.
Revision history for this message
Ian McInerney (imcinerney) wrote :

Hm, for some reason it isn't showing the first 3 commits in the chain in the unmerged commits list (it should start with a commit called "Rename cvpcb footprint viewer tools
"). Anyone know why that would be?

Revision history for this message
Seth Hillbrand (sethh) wrote :

Hi Ian-

This looks good. The commit list is probably limited to 10 by launchpad (Thanks, launchpad!)

I just so happened to have a schematic I needed to run through assignment for. Here are my impressions. Overall, this works nicely. No crashes or major issues. Undo/redo is good.

- After double-clicking to assign a footprint, I expected the highlight to move to the next unassigned symbol.

Where you make new files (e.g. cvpcb_fpviewer_control.h), you should not list others as the author. Similarly with substantially changed files (e.g. cvpcb_control.h), it would be good to leave the boilerplate copyright/license in place and simply update the KiCad Developers copyright. Some of this may have been an artifact of the git diff algorithm assigning closest matches, so please disregard if that's the case.

Overall, this looks like a good patch set. I'd be in favor of merging.

review: Approve
~imcinerney/kicad:cvpcb_actions updated
69f5abb... by Ian McInerney

cvpcb: Auto move to next NA after association

Also perform some cleanup of objects when windows close

Revision history for this message
Ian McInerney (imcinerney) wrote :

Seth,

The move to next not associated after performing an association was an oversight. It should be fixed with the most recent commit (I also added some cleanup that I noticed was missing).

As for the copyright statements, the reason why the cvpcb_fpviewer_control.* files list others as the authors is because those were _renamed_ from the original cvpcb_control.* files in the first commit. So the original cvpcb_control.cpp file that they authored had become cvpcb_fpviewer_control.cpp, and I believe the authorship should transfer with the rename since the authored code did. Also, I did the rename in a separate commit from the creation of the new cvpcb_control.* files so after the rename the cvpcb_control.* files didn't exist until I created them later.

Revision history for this message
Seth Hillbrand (sethh) wrote :

Makes sense. It looked like some form of git association but I couldn't be certain.

We'll hold off for an MSW test before merging but I see no issues right now on Mac or Linux here.

Revision history for this message
jean-pierre charras (jp-charras) wrote :

Le 12/08/2019 à 04:48, Seth Hillbrand a écrit :
> Makes sense. It looked like some form of git association but I couldn't be certain.
>
> We'll hold off for an MSW test before merging but I see no issues right now on Mac or Linux here.
>

Works for me on W7 32bits

--
Jean-Pierre CHARRAS

Revision history for this message
Wayne Stambaugh (stambaughw) wrote :

@Ian, I noticed that you are using the long ago deprecated idea of using ToggleToolbar to maintain tool states. In the past it has caused us nothing but grief an I see it creeping it's way back into KiCad which I am not thrilled about. We should always use wxUpdateUIEvents for maintaining control states. Using wxUpdateUIEvents allows you to use a single function for handling command event IDs used in common menu and toolbar commands. Handling toolbar states separate from menu states is a recipe for disaster. Once you make this change, I will approve your merge request.

review: Needs Fixing
Revision history for this message
Jeff Young (jeyjey) wrote :

@Wayne, commands by and large are no longer based on event IDs, but ACTIONs. This makes wxUpdateUIEvents difficult to use.

The menus now inherit from CONDITIONAL_MENU, which stores lamdas which are used to render the item states just before the menu is opened.

Since we can't use just-in-time processing for toolbars, Tom introduced SyncToolbars() which performs the lamda processing for toolbars after dispatching each event.

Revision history for this message
Wayne Stambaugh (stambaughw) wrote :

@Ian, do you no longer create toolbars with command IDs? If not, I consider this a design flaw. I have seen instances in both Pcbnew and Eeschema where the save menu entry and toolbar button states are out of sync. I'm sure this is directly attributable to this design decision. We used to do the same thing a long time ago and had the exact same issue. I really want to avoid these creeping back into KiCad.

Revision history for this message
Jeff Young (jeyjey) wrote :

I think that was for me, not Ian, so I'll answer.

That's correct, we don't use command IDs anymore for most stuff. (Or, rather, the command IDs we use are auto-generated and by-and-large aren't exposed.)

As long as the same lamda is used for the menu and toolbar they shouldn't get out of sync. (Yes, you could accidentally use different lamdas, but many of our old commands used different IDs between menu and toolbar so they had the same issue.)

The new architecture does significantly reduce the amount of duplicated info that is spread around the app (and liable to get out-of-sync).

Revision history for this message
Wayne Stambaugh (stambaughw) wrote :

@Jeff, it was aimed a everyone. This is a lesson learned in the past that still applies. If the same ID is used for the toolbar, the menu entry, and optionally a context menu entry, wxUpdateUIEvent reduces the UI update code to a single event handler. If we weren't using a common event ID, shame on us. There was really no excuse for not doing it this correctly since it is one of the more well documented parts of wxWidgets. I would suggest using EnableTool() rather than ToggleTool(). If you inadvertently use ToggleTool() somewhere else, your tool states are more likely to be broken. This was the primary issue in the past. I will tolerate it for now but if I start to see broken toolbar and menu states, I will be grumbling about it on the mailing list.

review: Approve
Revision history for this message
Ian McInerney (imcinerney) wrote :

@Wayne, ToggleTool() and EnableTool() control two different aspects of the menu item, so they are not interchangeable. The ToggleTool() function controls the checked state of the menu item, and it takes a bool as input, so the state is explicitly set (the checked state is not actually subjected to an XOR operation). Whether an item is checked will affect if the button looks to be depressed or not. If it is checked, then it is depressed. Yes, it is a terribly named function because it doesn't actually XOR anything, it just sets the state of the checkmark.

The EnableTool() function controls the enabled/disabled state of the menu item. If it is disabled, the user is not able to click on the menu item at all.

Revision history for this message
Wayne Stambaugh (stambaughw) wrote :

@Ian, I merged your changes into the master branch. Thanks.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/common/wildcards_and_files_ext.cpp b/common/wildcards_and_files_ext.cpp
2index 7ecf555..7f724b3 100644
3--- a/common/wildcards_and_files_ext.cpp
4+++ b/common/wildcards_and_files_ext.cpp
5@@ -101,6 +101,7 @@ const std::string ComponentFileExtension( "cmp" );
6 const std::string GerberFileExtension( "gbr" );
7 const std::string GerberJobFileExtension( "gbrjob" );
8 const std::string HtmlFileExtension( "html" );
9+const std::string EquFileExtension( "equ" );
10
11 const std::string LegacyPcbFileExtension( "brd" );
12 const std::string KiCadPcbFileExtension( "kicad_pcb" );
13diff --git a/cvpcb/CMakeLists.txt b/cvpcb/CMakeLists.txt
14index be34e41..b779f66 100644
15--- a/cvpcb/CMakeLists.txt
16+++ b/cvpcb/CMakeLists.txt
17@@ -24,16 +24,10 @@ set( CVPCB_DIALOGS
18 dialogs/dialog_display_options_base.cpp
19 dialogs/dialog_config_equfiles_base.cpp
20 dialogs/dialog_config_equfiles.cpp
21- ../pcbnew/dialogs/dialog_fp_plugin_options.cpp
22- ../pcbnew/dialogs/dialog_fp_plugin_options_base.cpp
23 )
24
25 set( CVPCB_SRCS
26 ../common/base_units.cpp
27- ../pcbnew/board_items_to_polygon_shape_transform.cpp
28- ../pcbnew/pcb_general_settings.cpp
29- ../pcbnew/drc_item.cpp
30- ../pcbnew/tools/pcb_actions.cpp
31 ../pcbnew/tools/grid_helper.cpp
32 auto_associate.cpp
33 cfg.cpp
34@@ -47,8 +41,10 @@ set( CVPCB_SRCS
35 readwrite_dlgs.cpp
36 toolbars_cvpcb.cpp
37 tools/cvpcb_actions.cpp
38+ tools/cvpcb_association_tool.cpp
39 tools/cvpcb_control.cpp
40- tools/cvpcb_selection_tool.cpp
41+ tools/cvpcb_fpviewer_control.cpp
42+ tools/cvpcb_fpviewer_selection_tool.cpp
43 )
44
45
46@@ -75,62 +71,6 @@ if( false )
47 endif()
48
49
50-if( false ) # no CVPCB exe any more, only the *.kiface
51- add_executable( cvpcb WIN32 MACOSX_BUNDLE
52- ../common/single_top.cpp
53- ../common/pgm_base.cpp
54- ${CVPCB_RESOURCES}
55- )
56- set_source_files_properties( ../common/single_top.cpp PROPERTIES
57- COMPILE_DEFINITIONS "TOP_FRAME=FRAME_CVPCB;PGM_DATA_FILE_EXT=\"net\";BUILD_KIWAY_DLL"
58- )
59- target_link_libraries( cvpcb
60- #singletop # replaces common, giving us restrictive control and link warnings.
61- # There's way too much crap coming in from common yet.
62- common
63- ${wxWidgets_LIBRARIES}
64- )
65- if( MAKE_LINK_MAPS )
66- set_target_properties( cvpcb PROPERTIES
67- LINK_FLAGS "-Wl,-cref,-Map=cvpcb.map" )
68- endif()
69-
70- if( APPLE )
71- include( ${CMAKE_MODULE_PATH}/KiCadVersion.cmake )
72- configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist.in ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist @ONLY )
73-
74- set_target_properties( cvpcb PROPERTIES
75- MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist
76- )
77-
78- # put individual bundle outside of main bundle as a first step
79- # will be pulled into the main bundle when creating main bundle
80- install( TARGETS cvpcb
81- DESTINATION ${KICAD_BIN}
82- COMPONENT binary
83- )
84- install( CODE "
85- # override default embedded path settings
86- ${OSX_BUNDLE_OVERRIDE_PATHS}
87-
88- # do all the work
89- include( BundleUtilities )
90- fixup_bundle( ${KICAD_BIN}/cvpcb.app/Contents/MacOS/cvpcb
91- \"\"
92- \"\"
93- )
94- " COMPONENT Runtime
95- )
96- else()
97- install( TARGETS cvpcb
98- DESTINATION ${KICAD_BIN}
99- COMPONENT binary
100- )
101- endif()
102-
103-endif() # no CVPCB exe
104-
105-
106 # the main cvpcb program, in DSO form.
107 add_library( cvpcb_kiface MODULE
108 cvpcb.cpp
109diff --git a/cvpcb/auto_associate.cpp b/cvpcb/auto_associate.cpp
110index c3757a2..f06790c 100644
111--- a/cvpcb/auto_associate.cpp
112+++ b/cvpcb/auto_associate.cpp
113@@ -31,19 +31,14 @@
114 // 'FT232BL' 'QFP:LQFP-32_7x7mm_Pitch0.8mm'
115
116
117-#include <fctsys.h>
118-#include <common.h>
119 #include <kiface_i.h>
120-#include <project.h>
121-#include <gestfich.h>
122-#include <pgm_base.h>
123 #include <kicad_string.h>
124 #include <macros.h>
125
126-#include <cvpcb.h>
127+#include <auto_associate.h>
128+#include <cvpcb_association.h>
129 #include <cvpcb_mainframe.h>
130 #include <listboxes.h>
131-#include <auto_associate.h>
132
133 #define QUOTE '\''
134
135@@ -167,7 +162,7 @@ int CVPCB_MAINFRAME::buildEquivalenceList( FOOTPRINT_EQUIVALENCE_LIST& aList, wx
136 }
137
138
139-void CVPCB_MAINFRAME::AutomaticFootprintMatching( wxCommandEvent& event )
140+void CVPCB_MAINFRAME::AutomaticFootprintMatching()
141 {
142 FOOTPRINT_EQUIVALENCE_LIST equiv_List;
143 wxString msg, error_msg;
144@@ -192,6 +187,7 @@ void CVPCB_MAINFRAME::AutomaticFootprintMatching( wxCommandEvent& event )
145 m_skipComponentSelect = true;
146 error_msg.Empty();
147
148+ bool firstAssoc = true;
149 for( unsigned kk = 0; kk < m_netlist.GetCount(); kk++ )
150 {
151 COMPONENT* component = m_netlist.GetComponent( kk );
152@@ -231,7 +227,9 @@ void CVPCB_MAINFRAME::AutomaticFootprintMatching( wxCommandEvent& event )
153 // If the equivalence is unique, no ambiguity: use the association
154 if( module && equ_is_unique )
155 {
156- SetNewPkg( equivItem.m_FootprintFPID, kk );
157+ AssociateFootprint( CVPCB_ASSOCIATION( kk, equivItem.m_FootprintFPID ),
158+ firstAssoc );
159+ firstAssoc = false;
160 found = true;
161 break;
162 }
163@@ -269,7 +267,8 @@ void CVPCB_MAINFRAME::AutomaticFootprintMatching( wxCommandEvent& event )
164
165 if( found )
166 {
167- SetNewPkg( equivItem.m_FootprintFPID, kk );
168+ AssociateFootprint( CVPCB_ASSOCIATION( kk, equivItem.m_FootprintFPID ), firstAssoc );
169+ firstAssoc = false;
170 break;
171 }
172 }
173@@ -278,7 +277,8 @@ void CVPCB_MAINFRAME::AutomaticFootprintMatching( wxCommandEvent& event )
174 continue;
175 else if( !fpid_candidate.IsEmpty() )
176 {
177- SetNewPkg( fpid_candidate, kk );
178+ AssociateFootprint( CVPCB_ASSOCIATION( kk, fpid_candidate ), firstAssoc );
179+ firstAssoc = false;
180 continue;
181 }
182
183@@ -291,7 +291,9 @@ void CVPCB_MAINFRAME::AutomaticFootprintMatching( wxCommandEvent& event )
184
185 if( module )
186 {
187- SetNewPkg( component->GetFootprintFilters()[0], kk );
188+ AssociateFootprint( CVPCB_ASSOCIATION( kk, component->GetFootprintFilters()[0] ),
189+ firstAssoc );
190+ firstAssoc = false;
191 }
192 }
193 }
194diff --git a/cvpcb/auto_associate.h b/cvpcb/auto_associate.h
195index e307695..c83fc95 100644
196--- a/cvpcb/auto_associate.h
197+++ b/cvpcb/auto_associate.h
198@@ -30,6 +30,7 @@
199 // 'FT232BL' 'QFP:LQFP-32_7x7mm_Pitch0.8mm'
200 //
201
202+#include <boost/ptr_container/ptr_vector.hpp>
203
204 class FOOTPRINT_EQUIVALENCE
205 {
206diff --git a/cvpcb/cfg.cpp b/cvpcb/cfg.cpp
207index 4ce1b7f..fd83b80 100644
208--- a/cvpcb/cfg.cpp
209+++ b/cvpcb/cfg.cpp
210@@ -26,20 +26,11 @@
211 * @file cfg.cpp
212 */
213
214-#include <fctsys.h>
215-#include <kiface_i.h>
216-#include <fp_lib_table.h>
217-#include <id.h>
218-#include <common.h>
219-#include <gestfich.h>
220 #include <config_params.h>
221-#include <wildcards_and_files_ext.h>
222-#include <fp_lib_table.h>
223-#include <confirm.h>
224+#include <kiface_i.h>
225+#include <project.h>
226
227-#include <cvpcb.h>
228 #include <cvpcb_mainframe.h>
229-#include <display_footprints_frame.h>
230
231
232 PARAM_CFG_ARRAY& CVPCB_MAINFRAME::GetProjectFileParameters()
233diff --git a/cvpcb/components_listbox.cpp b/cvpcb/components_listbox.cpp
234index f8a9719..13bcc9d 100644
235--- a/cvpcb/components_listbox.cpp
236+++ b/cvpcb/components_listbox.cpp
237@@ -25,9 +25,8 @@
238 * @file class_components_listbox.cpp
239 */
240
241-#include <fctsys.h>
242+#include <trace_helpers.h>
243
244-#include <cvpcb.h>
245 #include <cvpcb_mainframe.h>
246 #include <listboxes.h>
247 #include <cvpcb_id.h>
248@@ -111,21 +110,12 @@ void COMPONENTS_LISTBOX::SetSelection( int index, bool State )
249
250 void COMPONENTS_LISTBOX::OnChar( wxKeyEvent& event )
251 {
252+ wxLogTrace( kicadTraceKeyEvent, "COMPONENTS_LISTBOX::OnChar %s", dump( event ) );
253+
254 int key = event.GetKeyCode();
255
256 switch( key )
257 {
258- case WXK_TAB:
259- case WXK_RIGHT:
260- case WXK_NUMPAD_RIGHT:
261- GetParent()->ChangeFocus( true );
262- return;
263-
264- case WXK_LEFT:
265- case WXK_NUMPAD_LEFT:
266- GetParent()->ChangeFocus( false );
267- return;
268-
269 case WXK_HOME:
270 case WXK_END:
271 case WXK_UP:
272diff --git a/cvpcb/cvpcb.cpp b/cvpcb/cvpcb.cpp
273index c81dfd6..3308039 100644
274--- a/cvpcb/cvpcb.cpp
275+++ b/cvpcb/cvpcb.cpp
276@@ -27,24 +27,13 @@
277 * @file cvpcb.cpp
278 */
279
280-#include <fctsys.h>
281-#include <macros.h>
282+#include <confirm.h>
283 #include <fp_lib_table.h>
284 #include <kiface_i.h>
285 #include <pgm_base.h>
286-#include <confirm.h>
287
288-#include <cvpcb.h>
289 #include <cvpcb_mainframe.h>
290 #include <display_footprints_frame.h>
291-#include <cvpcb_id.h>
292-
293-#include <build_version.h>
294-
295-#include <wx/snglinst.h>
296-
297-// Constant string definitions for CvPcb
298-const wxString EquFileExtension( wxT( "equ" ) );
299
300
301 namespace CV {
302diff --git a/cvpcb/cvpcb_association.h b/cvpcb/cvpcb_association.h
303new file mode 100644
304index 0000000..e9978d5
305--- /dev/null
306+++ b/cvpcb/cvpcb_association.h
307@@ -0,0 +1,127 @@
308+/*
309+ * This program source code file is part of KiCad, a free EDA CAD application.
310+ *
311+ * Copyright (C) 2019 Ian McInerney <Ian.S.McInerney@ieee.org>
312+ * Copyright (C) 2019 KiCad Developers, see AUTHORS.txt for contributors.
313+ *
314+ * This program is free software: you can redistribute it and/or modify it
315+ * under the terms of the GNU General Public License as published by the
316+ * Free Software Foundation, either version 3 of the License, or (at your
317+ * option) any later version.
318+ *
319+ * This program is distributed in the hope that it will be useful, but
320+ * WITHOUT ANY WARRANTY; without even the implied warranty of
321+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
322+ * General Public License for more details.
323+ *
324+ * You should have received a copy of the GNU General Public License along
325+ * with this program. If not, see <http://www.gnu.org/licenses/>.
326+ */
327+
328+#ifndef CVPCB_ASSOCIATION_H
329+#define CVPCB_ASSOCIATION_H
330+
331+#include <lib_id.h>
332+#include <utf8.h>
333+
334+/**
335+ * A class to define a footprint association to be made in cvpcb.
336+ */
337+class CVPCB_ASSOCIATION
338+{
339+
340+public:
341+
342+ /**
343+ * Create an association event that contains all the information needed to modify the footprint
344+ * association of a component in cvpcb.
345+ *
346+ * @param aComponentIndex is the index of the component to change
347+ * @param aNewFootprint is the new footprint to give to the component
348+ * @param aOldFootprint is the old footprint from the component
349+ */
350+ CVPCB_ASSOCIATION(
351+ unsigned int aComponentIndex, LIB_ID aNewFootprint, LIB_ID aOldFootprint = LIB_ID() ) :
352+ m_componentIndex( aComponentIndex ),
353+ m_newFootprint( aNewFootprint ),
354+ m_oldFootprint( aOldFootprint )
355+ {}
356+
357+ CVPCB_ASSOCIATION(
358+ unsigned int aComponentIndex, wxString aNewFootprint, wxString aOldFootprint = "" ) :
359+ m_componentIndex( aComponentIndex )
360+ {
361+ m_newFootprint.Parse( aNewFootprint, LIB_ID::ID_PCB );
362+ m_oldFootprint.Parse( aOldFootprint, LIB_ID::ID_PCB );
363+ }
364+
365+ /**
366+ * Reverse the association.
367+ *
368+ * @return the reversed association
369+ */
370+ CVPCB_ASSOCIATION Reverse() const
371+ {
372+ return CVPCB_ASSOCIATION( m_componentIndex, m_oldFootprint, m_newFootprint );
373+ }
374+
375+ /**
376+ * Get the index of the component to modify the association of.
377+ *
378+ * @return the index of the component
379+ */
380+ unsigned int GetComponentIndex() const
381+ {
382+ return m_componentIndex;
383+ }
384+
385+ /**
386+ * Get the new footprint to associate to the component.
387+ *
388+ * @return the LIB_ID of the new footprint
389+ */
390+ LIB_ID GetNewFootprint() const
391+ {
392+ return m_newFootprint;
393+ }
394+
395+ /**
396+ * Get the old footprint of the component
397+ *
398+ * @return the LIB_ID of the old footprint
399+ */
400+ LIB_ID GetOldFootprint() const
401+ {
402+ return m_oldFootprint;
403+ }
404+
405+ /**
406+ * Set the footprint that should be associated with the component
407+ *
408+ * @param aNewFootprint is the LIB_ID of the new footprint
409+ */
410+ void SetNewFootprint( const LIB_ID& aNewFootprint )
411+ {
412+ m_newFootprint = aNewFootprint;
413+ }
414+
415+ /**
416+ * Set the footprint that was associated with the component before this association event
417+ *
418+ * @param aOldFootprint is the LIB_ID of the old footprint
419+ */
420+ void SetOldFootprint( const LIB_ID& aOldFootprint )
421+ {
422+ m_oldFootprint = aOldFootprint;
423+ }
424+
425+
426+private:
427+ unsigned int m_componentIndex;
428+ LIB_ID m_newFootprint;
429+ LIB_ID m_oldFootprint;
430+
431+};
432+
433+
434+#endif
435diff --git a/cvpcb/cvpcb_id.h b/cvpcb/cvpcb_id.h
436index 07197b0..8df4dbb 100644
437--- a/cvpcb/cvpcb_id.h
438+++ b/cvpcb/cvpcb_id.h
439@@ -39,21 +39,8 @@
440 // specific IDs
441 enum id_cvpcb_frm
442 {
443- ID_CVPCB_CREATE_SCREENCMP = ID_END_LIST,
444- ID_CVPCB_GOTO_FIRSTNA,
445- ID_CVPCB_GOTO_PREVIOUSNA,
446- ID_CVPCB_DEL_ASSOCIATIONS,
447- ID_CVPCB_AUTO_ASSOCIE,
448- ID_CVPCB_COMPONENT_LIST,
449+ ID_CVPCB_COMPONENT_LIST = ID_END_LIST,
450 ID_CVPCB_FOOTPRINT_LIST,
451- ID_CVPCB_FOOTPRINT_DISPLAY_FULL_LIST,
452- ID_CVPCB_FOOTPRINT_DISPLAY_FILTERED_LIST,
453- ID_CVPCB_FOOTPRINT_DISPLAY_PIN_FILTERED_LIST,
454- ID_CVPCB_FOOTPRINT_DISPLAY_BY_LIBRARY_LIST,
455- ID_CVPCB_FOOTPRINT_DISPLAY_BY_NAME,
456 ID_CVPCB_LIBRARY_LIST,
457- ID_CVPCB_EQUFILES_LIST_EDIT,
458- ID_CVPCB_LIB_TABLE_EDIT,
459 ID_CVPCB_FILTER_TEXT_EDIT,
460- ID_TB_MEASUREMENT_TOOL
461 };
462diff --git a/cvpcb/cvpcb_mainframe.cpp b/cvpcb/cvpcb_mainframe.cpp
463index 3b3576d..40f012f 100644
464--- a/cvpcb/cvpcb_mainframe.cpp
465+++ b/cvpcb/cvpcb_mainframe.cpp
466@@ -23,29 +23,30 @@
467 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
468 */
469
470-#include <fctsys.h>
471-#include <build_version.h>
472-#include <kiway_express.h>
473-#include <kiface_i.h>
474-#include <kiface_ids.h>
475-#include <macros.h>
476+#include <bitmaps.h>
477 #include <confirm.h>
478 #include <eda_dde.h>
479-#include <html_messagebox.h>
480 #include <fp_lib_table.h>
481+#include <kiface_i.h>
482+#include <kiway_express.h>
483+#include <macros.h>
484 #include <netlist_reader.h>
485-#include <bitmaps.h>
486+#include <numeric>
487+#include <tool/action_toolbar.h>
488+#include <tool/common_control.h>
489+#include <tool/tool_dispatcher.h>
490+#include <tool/tool_manager.h>
491 #include <widgets/progress_reporter.h>
492-#include <cvpcb.h>
493-#include <listboxes.h>
494 #include <wx/statline.h>
495-#include <invoke_pcb_dialog.h>
496-#include <display_footprints_frame.h>
497+
498+#include <cvpcb_association.h>
499 #include <cvpcb_id.h>
500-#include <tool/tool_manager.h>
501-#include <tool/action_toolbar.h>
502 #include <cvpcb_mainframe.h>
503-#include <tool/common_control.h>
504+#include <display_footprints_frame.h>
505+#include <listboxes.h>
506+#include <tools/cvpcb_actions.h>
507+#include <tools/cvpcb_association_tool.h>
508+#include <tools/cvpcb_control.h>
509
510 wxSize const FRAME_MIN_SIZE_DU( 350, 250 );
511 wxSize const FRAME_DEFAULT_SIZE_DU( 450, 300 );
512@@ -56,49 +57,6 @@ wxSize const FRAME_DEFAULT_SIZE_DU( 450, 300 );
513 static const wxString FilterFootprintEntry = "FilterFootprint";
514 ///@}
515
516-BEGIN_EVENT_TABLE( CVPCB_MAINFRAME, KIWAY_PLAYER )
517-
518- // Menu events
519- EVT_MENU( ID_SAVE_PROJECT, CVPCB_MAINFRAME::OnSaveAndContinue )
520- EVT_MENU( wxID_EXIT, CVPCB_MAINFRAME::OnQuit )
521- EVT_MENU( ID_CVPCB_EQUFILES_LIST_EDIT, CVPCB_MAINFRAME::OnEditEquFilesList )
522-
523- // Toolbar events
524- EVT_TOOL( ID_CVPCB_LIB_TABLE_EDIT, CVPCB_MAINFRAME::OnEditFootprintLibraryTable )
525- EVT_TOOL( ID_CVPCB_CREATE_SCREENCMP, CVPCB_MAINFRAME::DisplayModule )
526- EVT_TOOL( ID_CVPCB_GOTO_FIRSTNA, CVPCB_MAINFRAME::ToFirstNA )
527- EVT_TOOL( ID_CVPCB_GOTO_PREVIOUSNA, CVPCB_MAINFRAME::ToPreviousNA )
528- EVT_TOOL( ID_CVPCB_DEL_ASSOCIATIONS, CVPCB_MAINFRAME::DelAssociations )
529- EVT_TOOL( ID_CVPCB_AUTO_ASSOCIE, CVPCB_MAINFRAME::AutomaticFootprintMatching )
530- EVT_TOOL( ID_CVPCB_FOOTPRINT_DISPLAY_FILTERED_LIST,
531- CVPCB_MAINFRAME::OnSelectFilteringFootprint )
532- EVT_TOOL( ID_CVPCB_FOOTPRINT_DISPLAY_PIN_FILTERED_LIST,
533- CVPCB_MAINFRAME::OnSelectFilteringFootprint )
534- EVT_TOOL( ID_CVPCB_FOOTPRINT_DISPLAY_BY_LIBRARY_LIST,
535- CVPCB_MAINFRAME::OnSelectFilteringFootprint )
536- EVT_TOOL( ID_CVPCB_FOOTPRINT_DISPLAY_BY_NAME,
537- CVPCB_MAINFRAME::OnSelectFilteringFootprint )
538- EVT_TEXT( ID_CVPCB_FILTER_TEXT_EDIT, CVPCB_MAINFRAME::OnEnterFilteringText )
539-
540- // Button events
541- EVT_BUTTON( wxID_OK, CVPCB_MAINFRAME::OnOK )
542- EVT_BUTTON( wxID_CANCEL, CVPCB_MAINFRAME::OnCancel )
543-
544- // Frame events
545- EVT_CLOSE( CVPCB_MAINFRAME::OnCloseWindow )
546- EVT_SIZE( CVPCB_MAINFRAME::OnSize )
547-
548- // UI event handlers
549- EVT_UPDATE_UI( ID_CVPCB_FOOTPRINT_DISPLAY_FILTERED_LIST, CVPCB_MAINFRAME::OnFilterFPbyKeywords )
550- EVT_UPDATE_UI( ID_CVPCB_FOOTPRINT_DISPLAY_PIN_FILTERED_LIST,
551- CVPCB_MAINFRAME::OnFilterFPbyPinCount )
552- EVT_UPDATE_UI( ID_CVPCB_FOOTPRINT_DISPLAY_BY_LIBRARY_LIST,
553- CVPCB_MAINFRAME::OnFilterFPbyLibrary )
554- EVT_UPDATE_UI( ID_CVPCB_FOOTPRINT_DISPLAY_BY_NAME, CVPCB_MAINFRAME::OnFilterFPbyKeyName )
555-
556-END_EVENT_TABLE()
557-
558-
559 #define CVPCB_MAINFRAME_NAME wxT( "CvpcbFrame" )
560
561
562@@ -112,7 +70,7 @@ CVPCB_MAINFRAME::CVPCB_MAINFRAME( KIWAY* aKiway, wxWindow* aParent ) :
563 m_mainToolBar = NULL;
564 m_modified = false;
565 m_skipComponentSelect = false;
566- m_filteringOptions = 0;
567+ m_filteringOptions = FOOTPRINTS_LISTBOX::UNFILTERED_FP_LIST;
568 m_tcFilterString = NULL;
569 m_FootprintsList = FOOTPRINT_LIST::GetInstance( Kiway() );
570 m_initialized = false;
571@@ -133,14 +91,7 @@ CVPCB_MAINFRAME::CVPCB_MAINFRAME( KIWAY* aKiway, wxWindow* aParent ) :
572 // Frame size and position
573 SetSize( m_FramePos.x, m_FramePos.y, m_FrameSize.x, m_FrameSize.y );
574
575- // Create the manager
576- m_toolManager = new TOOL_MANAGER;
577- m_toolManager->SetEnvironment( nullptr, nullptr, nullptr, this );
578-
579- // Register tools
580- m_toolManager->RegisterTool( new COMMON_CONTROL );
581- m_toolManager->InitTools();
582-
583+ setupTools();
584 ReCreateMenuBar();
585 ReCreateHToolbar();
586
587@@ -168,7 +119,7 @@ CVPCB_MAINFRAME::CVPCB_MAINFRAME( KIWAY* aKiway, wxWindow* aParent ) :
588 auto bottomPanel = new wxPanel( this );
589 auto panelSizer = new wxBoxSizer( wxVERTICAL );
590
591- wxFlexGridSizer* fgSizerStatus = new wxFlexGridSizer( 2, 1, 0, 0 );
592+ wxFlexGridSizer* fgSizerStatus = new wxFlexGridSizer( 3, 1, 0, 0 );
593 fgSizerStatus->SetFlexibleDirection( wxBOTH );
594 fgSizerStatus->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
595
596@@ -176,7 +127,10 @@ CVPCB_MAINFRAME::CVPCB_MAINFRAME( KIWAY* aKiway, wxWindow* aParent ) :
597 fgSizerStatus->Add( m_statusLine1, 0, 0, 5 );
598
599 m_statusLine2 = new wxStaticText( bottomPanel, wxID_ANY, wxEmptyString );
600- fgSizerStatus->Add( m_statusLine2, 0, wxBOTTOM, 3 );
601+ fgSizerStatus->Add( m_statusLine2, 0, 0, 5 );
602+
603+ m_statusLine3 = new wxStaticText( bottomPanel, wxID_ANY, wxEmptyString );
604+ fgSizerStatus->Add( m_statusLine3, 0, wxBOTTOM, 3 );
605
606 panelSizer->Add( fgSizerStatus, 1, wxEXPAND|wxLEFT, 2 );
607
608@@ -187,6 +141,7 @@ CVPCB_MAINFRAME::CVPCB_MAINFRAME( KIWAY* aKiway, wxWindow* aParent ) :
609 statusFont.SetSymbolicSize( wxFONTSIZE_SMALL );
610 m_statusLine1->SetFont( statusFont );
611 m_statusLine2->SetFont( statusFont );
612+ m_statusLine3->SetFont( statusFont );
613
614 // Add buttons:
615 auto buttonsSizer = new wxBoxSizer( wxHORIZONTAL );
616@@ -216,56 +171,128 @@ CVPCB_MAINFRAME::CVPCB_MAINFRAME( KIWAY* aKiway, wxWindow* aParent ) :
617 m_initialized = true;
618
619 // Connect Events
620- m_saveAndContinue->Connect( wxEVT_COMMAND_BUTTON_CLICKED,
621- wxCommandEventHandler( CVPCB_MAINFRAME::OnSaveAndContinue ),
622- NULL, this );
623- m_footprintListBox->Connect( wxEVT_RIGHT_DOWN,
624- wxMouseEventHandler( CVPCB_MAINFRAME::OnFootprintRightClick ),
625- NULL, this );
626- m_compListBox->Connect( wxEVT_RIGHT_DOWN,
627- wxMouseEventHandler( CVPCB_MAINFRAME::OnComponentRightClick ),
628- NULL, this );
629+ setupEventHandlers();
630+
631+ // Start the main processing loop
632+ m_toolManager->InvokeTool( "cvpcb.Control" );
633+
634+ // Ensure the toolbars are sync'd properly so the filtering options display correct
635+ SyncToolbars();
636 }
637
638
639 CVPCB_MAINFRAME::~CVPCB_MAINFRAME()
640 {
641- // Disconnect Events
642- m_saveAndContinue->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED,
643- wxCommandEventHandler( CVPCB_MAINFRAME::OnSaveAndContinue ),
644- NULL, this );
645- m_footprintListBox->Disconnect( wxEVT_RIGHT_DOWN,
646- wxMouseEventHandler( CVPCB_MAINFRAME::OnFootprintRightClick ),
647- NULL, this );
648+ // Be sure a active tool (if exists) is deactivated:
649+ if( m_toolManager )
650+ m_toolManager->DeactivateTool();
651+
652+ // Clean up the tool infrastructure
653+ delete m_actions;
654+ delete m_toolManager;
655+ delete m_toolDispatcher;
656
657 m_auimgr.UnInit();
658 }
659
660
661-void CVPCB_MAINFRAME::LoadSettings( wxConfigBase* aCfg )
662+void CVPCB_MAINFRAME::setupTools()
663 {
664- EDA_BASE_FRAME::LoadSettings( aCfg );
665-
666- wxSize const frame_default( ConvertDialogToPixels( FRAME_DEFAULT_SIZE_DU ) );
667+ // Create the manager
668+ m_actions = new CVPCB_ACTIONS();
669+ m_toolManager = new TOOL_MANAGER;
670+ m_toolManager->SetEnvironment( nullptr, nullptr, nullptr, this );
671+ m_toolDispatcher = new TOOL_DISPATCHER( m_toolManager, m_actions );
672
673- if( m_FrameSize == wxDefaultSize )
674- m_FrameSize = frame_default;
675+ // Register tools
676+ m_toolManager->RegisterTool( new COMMON_CONTROL );
677+ m_toolManager->RegisterTool( new CVPCB_CONTROL );
678+ m_toolManager->RegisterTool( new CVPCB_ASSOCIATION_TOOL );
679+ m_toolManager->InitTools();
680
681- aCfg->Read( FilterFootprintEntry, &m_filteringOptions, FOOTPRINTS_LISTBOX::UNFILTERED_FP_LIST );
682+ CVPCB_CONTROL* tool = m_toolManager->GetTool<CVPCB_CONTROL>();
683+
684+ // Create the context menu for the component list box
685+ m_componentContextMenu = new ACTION_MENU( true );
686+ m_componentContextMenu->SetTool( tool );
687+ m_componentContextMenu->Add( CVPCB_ACTIONS::showFootprintViewer );
688+ m_componentContextMenu->AppendSeparator();
689+ m_componentContextMenu->Add( ACTIONS::cut );
690+ m_componentContextMenu->Add( ACTIONS::copy );
691+ m_componentContextMenu->Add( ACTIONS::paste );
692+ m_componentContextMenu->AppendSeparator();
693+ m_componentContextMenu->Add( CVPCB_ACTIONS::deleteAssoc );
694+
695+ // Create the context menu for the footprint list box
696+ m_footprintContextMenu = new ACTION_MENU( true );
697+ m_footprintContextMenu->SetTool( tool );
698+ m_footprintContextMenu->Add( CVPCB_ACTIONS::showFootprintViewer );
699 }
700
701-
702-void CVPCB_MAINFRAME::SaveSettings( wxConfigBase* aCfg )
703+void CVPCB_MAINFRAME::setupEventHandlers()
704 {
705- EDA_BASE_FRAME::SaveSettings( aCfg );
706+ // Connect the handlers to launch the context menus in the listboxes
707+ m_footprintListBox->Bind( wxEVT_RIGHT_DOWN,
708+ [this]( wxMouseEvent& )
709+ {
710+ PopupMenu( m_footprintContextMenu );
711+ } );
712
713- aCfg->Write( FilterFootprintEntry, m_filteringOptions );
714-}
715+ m_compListBox->Bind( wxEVT_RIGHT_DOWN,
716+ [this]( wxMouseEvent& )
717+ {
718+ PopupMenu( m_componentContextMenu );
719+ } );
720
721+ // Connect the handler for the save button
722+ m_saveAndContinue->Bind( wxEVT_COMMAND_BUTTON_CLICKED,
723+ [this]( wxCommandEvent& )
724+ {
725+ this->GetToolManager()->RunAction( CVPCB_ACTIONS::saveAssociations );
726+ } );
727
728-void CVPCB_MAINFRAME::OnSize( wxSizeEvent& event )
729-{
730- event.Skip();
731+ // Connect the handlers for the ok/cancel buttons
732+ Bind( wxEVT_BUTTON,
733+ [this]( wxCommandEvent& )
734+ {
735+ this->GetToolManager()->RunAction( CVPCB_ACTIONS::saveAssociations );
736+ Close( true );
737+ }, wxID_OK );
738+ Bind( wxEVT_BUTTON,
739+ [this]( wxCommandEvent& )
740+ {
741+ // Throw away modifications on a Cancel
742+ m_modified = false;
743+ Close( false );
744+ }, wxID_CANCEL );
745+
746+ // Connect the handlers for the close events
747+ Bind( wxEVT_CLOSE_WINDOW, &CVPCB_MAINFRAME::OnCloseWindow, this );
748+ Bind( wxEVT_MENU,
749+ [this]( wxCommandEvent& )
750+ {
751+ Close( false );
752+ }, wxID_CLOSE );
753+ Bind( wxEVT_MENU,
754+ [this]( wxCommandEvent& )
755+ {
756+ Close( false );
757+ }, wxID_EXIT );
758+
759+ // Toolbar events
760+ Bind( wxEVT_TEXT, &CVPCB_MAINFRAME::OnEnterFilteringText, this, ID_CVPCB_FILTER_TEXT_EDIT );
761+
762+ // Just skip the resize events
763+ Bind( wxEVT_SIZE,
764+ []( wxSizeEvent& aEvent )
765+ {
766+ aEvent.Skip();
767+ } );
768+
769+ // Attach the events to the tool dispatcher
770+ Bind( wxEVT_TOOL, &TOOL_DISPATCHER::DispatchWxCommand, m_toolDispatcher );
771+ Bind( wxEVT_CHAR, &TOOL_DISPATCHER::DispatchWxEvent, m_toolDispatcher );
772+ Bind( wxEVT_CHAR_HOOK, &TOOL_DISPATCHER::DispatchWxEvent, m_toolDispatcher );
773 }
774
775
776@@ -296,213 +323,169 @@ void CVPCB_MAINFRAME::OnCloseWindow( wxCloseEvent& Event )
777 }
778
779
780-void CVPCB_MAINFRAME::ChangeFocus( bool aMoveRight )
781+void CVPCB_MAINFRAME::OnEnterFilteringText( wxCommandEvent& aEvent )
782 {
783- wxWindow* hasFocus = wxWindow::FindFocus();
784-
785- if( aMoveRight )
786- {
787- if( hasFocus == m_libListBox )
788- m_compListBox->SetFocus();
789- else if( hasFocus == m_compListBox )
790- m_footprintListBox->SetFocus();
791- else if( hasFocus == m_footprintListBox )
792- m_libListBox->SetFocus();
793- }
794- else
795- {
796- if( hasFocus == m_libListBox )
797- m_footprintListBox->SetFocus();
798- else if( hasFocus == m_compListBox )
799- m_libListBox->SetFocus();
800- else if( hasFocus == m_footprintListBox )
801- m_compListBox->SetFocus();
802- }
803-}
804+ // Called when changing the filter string in main toolbar.
805+ // If the option FOOTPRINTS_LISTBOX::FILTERING_BY_NAME is set, update the list of
806+ // available footprints which match the filter
807
808+ m_currentSearchPattern = m_tcFilterString->GetValue();
809
810-void CVPCB_MAINFRAME::ToFirstNA( wxCommandEvent& event )
811-{
812- if( m_netlist.IsEmpty() )
813+ if( ( m_filteringOptions & FOOTPRINTS_LISTBOX::FILTERING_BY_NAME ) == 0 )
814 return;
815
816- int first_selected = m_compListBox->GetFirstSelected();
817-
818- if( first_selected < 0 )
819- first_selected = -1; // We will start to 0 for the first search , if no item selected
820-
821- int candidate = -1;
822-
823- for( int jj = first_selected+1; jj < (int)m_netlist.GetCount(); jj++ )
824- {
825- if( m_netlist.GetComponent( jj )->GetFPID().empty() )
826- {
827- candidate = jj;
828- break;
829- }
830- }
831-
832- if( candidate >= 0 )
833- {
834- m_compListBox->DeselectAll();
835- m_compListBox->SetSelection( candidate );
836- SendMessageToEESCHEMA();
837- }
838+ wxListEvent l_event;
839+ OnSelectComponent( l_event );
840 }
841
842
843-void CVPCB_MAINFRAME::ToPreviousNA( wxCommandEvent& event )
844+void CVPCB_MAINFRAME::OnSelectComponent( wxListEvent& event )
845 {
846- if( m_netlist.IsEmpty() )
847+ if( m_skipComponentSelect )
848 return;
849
850- int first_selected = m_compListBox->GetFirstSelected();
851-
852- if( first_selected < 0 )
853- first_selected = m_compListBox->GetCount();
854+ wxString libraryName;
855+ COMPONENT* component = GetSelectedComponent();
856+ libraryName = m_libListBox->GetSelectedLibrary();
857
858- int candidate = -1;
859+ m_footprintListBox->SetFootprints( *m_FootprintsList, libraryName, component,
860+ m_currentSearchPattern, m_filteringOptions);
861
862- for( int jj = first_selected-1; jj >= 0; jj-- )
863- {
864- if( m_netlist.GetComponent( jj )->GetFPID().empty() )
865- {
866- candidate = jj;
867- break;
868- }
869- }
870+ if( component && component->GetFPID().IsValid() )
871+ m_footprintListBox->SetSelectedFootprint( component->GetFPID() );
872+ else
873+ m_footprintListBox->SetSelection( m_footprintListBox->GetSelection(), false );
874
875- if( candidate >= 0 )
876- {
877- m_compListBox->DeselectAll();
878- m_compListBox->SetSelection( candidate );
879- SendMessageToEESCHEMA();
880- }
881+ refreshAfterComponentSearch( component );
882 }
883
884
885-void CVPCB_MAINFRAME::OnOK( wxCommandEvent& aEvent )
886+void CVPCB_MAINFRAME::LoadSettings( wxConfigBase* aCfg )
887 {
888- SaveFootprintAssociation( false );
889- m_modified = false;
890+ EDA_BASE_FRAME::LoadSettings( aCfg );
891
892- Close( true );
893-}
894+ wxSize const frame_default( ConvertDialogToPixels( FRAME_DEFAULT_SIZE_DU ) );
895
896+ if( m_FrameSize == wxDefaultSize )
897+ m_FrameSize = frame_default;
898
899-void CVPCB_MAINFRAME::OnSaveAndContinue( wxCommandEvent& aEvent )
900-{
901- SaveFootprintAssociation( true );
902- m_modified = false;
903+ aCfg->Read( FilterFootprintEntry, &m_filteringOptions, FOOTPRINTS_LISTBOX::UNFILTERED_FP_LIST );
904 }
905
906
907-void CVPCB_MAINFRAME::OnCancel( wxCommandEvent& event )
908+void CVPCB_MAINFRAME::SaveSettings( wxConfigBase* aCfg )
909 {
910- // Throw away modifications on a Cancel
911- m_modified = false;
912+ EDA_BASE_FRAME::SaveSettings( aCfg );
913
914- Close( false );
915+ aCfg->Write( FilterFootprintEntry, m_filteringOptions );
916 }
917
918
919-void CVPCB_MAINFRAME::OnQuit( wxCommandEvent& event )
920+void CVPCB_MAINFRAME::UndoAssociation()
921 {
922- Close( false );
923-}
924+ if( m_undoList.size() == 0 )
925+ return;
926
927+ CVPCB_UNDO_REDO_ENTRIES redoEntries;
928+ CVPCB_UNDO_REDO_ENTRIES curEntry = m_undoList.back();
929+ m_undoList.pop_back();
930
931-void CVPCB_MAINFRAME::DelAssociations( wxCommandEvent& event )
932-{
933- if( IsOK( this, _( "Delete selections" ) ) )
934+ // Iterate over the entries to undo
935+ for( auto assoc : curEntry )
936 {
937- m_skipComponentSelect = true;
938-
939- // Remove all selections to avoid issues when setting the fpids
940- m_compListBox->DeselectAll();
941-
942- for( unsigned i = 0; i < m_netlist.GetCount(); i++ )
943- {
944- LIB_ID fpid;
945-
946- m_netlist.GetComponent( i )->SetFPID( fpid );
947- SetNewPkg( wxEmptyString );
948- }
949-
950- // Remove all selections after setting the fpids
951- m_compListBox->DeselectAll();
952-
953- m_skipComponentSelect = false;
954- m_compListBox->SetSelection( 0 );
955+ AssociateFootprint( assoc, true, false );
956+ redoEntries.emplace_back( assoc.Reverse() );
957 }
958
959- DisplayStatus();
960+ // Add the redo entries to the redo stack
961+ m_redoList.emplace_back( redoEntries );
962 }
963
964
965-bool CVPCB_MAINFRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, int aCtl )
966+void CVPCB_MAINFRAME::RedoAssociation()
967 {
968- return true;
969-}
970-
971+ if( m_redoList.size() == 0 )
972+ return;
973
974-void CVPCB_MAINFRAME::OnEditFootprintLibraryTable( wxCommandEvent& aEvent )
975-{
976- KIFACE* kiface = Kiway().KiFACE( KIWAY::FACE_PCB );
977- kiface->CreateWindow( this, DIALOG_PCB_LIBRARY_TABLE, &Kiway() );
978+ CVPCB_UNDO_REDO_ENTRIES curEntry = m_redoList.back();
979+ m_redoList.pop_back();
980
981- wxBusyCursor dummy;
982- BuildLIBRARY_LISTBOX();
983- m_FootprintsList->ReadFootprintFiles( Prj().PcbFootprintLibs( Kiway() ) );
984+ // Iterate over the entries to undo
985+ bool firstAssoc = true;
986+ for( auto assoc : curEntry )
987+ {
988+ AssociateFootprint( assoc, firstAssoc );
989+ firstAssoc = false;
990+ }
991 }
992
993
994-void CVPCB_MAINFRAME::DisplayModule( wxCommandEvent& event )
995+void CVPCB_MAINFRAME::AssociateFootprint( const CVPCB_ASSOCIATION& aAssociation,
996+ bool aNewEntry, bool aAddUndoItem )
997 {
998- CreateScreenCmp();
999-}
1000+ // Ensure there is data to work with
1001+ COMPONENT* component;
1002
1003+ if( m_netlist.IsEmpty() )
1004+ return;
1005
1006-void CVPCB_MAINFRAME::OnComponentRightClick( wxMouseEvent& event )
1007-{
1008- wxMenu menu;
1009+ component = m_netlist.GetComponent( aAssociation.GetComponentIndex() );
1010
1011- menu.Append( ID_CVPCB_CREATE_SCREENCMP, _( "View Footprint" ),
1012- _( "Show the assigned footprint in the footprint viewer" ) );
1013+ if( component == NULL )
1014+ return;
1015
1016- PopupMenu( &menu );
1017-}
1018+ LIB_ID fpid = aAssociation.GetNewFootprint();
1019+ LIB_ID oldFpid = component->GetFPID();
1020
1021+ // Test for validity of the requested footprint
1022+ if( !fpid.empty() && !fpid.IsValid() )
1023+ {
1024+ wxString msg =
1025+ wxString::Format( _( "\"%s\" is not a valid footprint." ), fpid.Format().wx_str() );
1026+ DisplayErrorMessage( this, msg );
1027+ }
1028
1029-void CVPCB_MAINFRAME::OnFootprintRightClick( wxMouseEvent& event )
1030-{
1031- wxMenu menu;
1032+ // Set the new footprint
1033+ component->SetFPID( fpid );
1034
1035- menu.Append( ID_CVPCB_CREATE_SCREENCMP, _( "View Footprint" ),
1036- _( "Show the current footprint in the footprint viewer" ) );
1037+ // create the new component description and set it
1038+ wxString description = wxString::Format( CMP_FORMAT, aAssociation.GetComponentIndex() + 1,
1039+ GetChars( component->GetReference() ), GetChars( component->GetValue() ),
1040+ GetChars( FROM_UTF8( component->GetFPID().Format().c_str() ) ) );
1041+ m_compListBox->SetString( aAssociation.GetComponentIndex(), description );
1042
1043- PopupMenu( &menu );
1044-}
1045+ // Mark the data as being modified
1046+ m_modified = true;
1047
1048+ // Update the statusbar and refresh the list
1049+ DisplayStatus();
1050+ m_compListBox->Refresh();
1051
1052-void CVPCB_MAINFRAME::OnSelectComponent( wxListEvent& event )
1053-{
1054- if( m_skipComponentSelect )
1055+ if( !aAddUndoItem )
1056 return;
1057
1058- wxString libraryName;
1059- COMPONENT* component = GetSelectedComponent();
1060- libraryName = m_libListBox->GetSelectedLibrary();
1061+ // Update the undo list
1062+ if ( aNewEntry )
1063+ {
1064+ // Create a new entry for this association
1065+ CVPCB_UNDO_REDO_ENTRIES newEntry;
1066+ newEntry.emplace_back( CVPCB_ASSOCIATION( aAssociation.GetComponentIndex(), oldFpid,
1067+ aAssociation.GetNewFootprint() ) );
1068+ m_undoList.emplace_back( newEntry );
1069+
1070+ // Clear the redo list
1071+ m_redoList.clear();
1072+ }
1073+ else
1074+ m_undoList.back().emplace_back( CVPCB_ASSOCIATION( aAssociation.GetComponentIndex(),
1075+ oldFpid, aAssociation.GetNewFootprint() ) );
1076
1077- m_footprintListBox->SetFootprints( *m_FootprintsList, libraryName, component,
1078- m_currentSearchPattern, m_filteringOptions);
1079+}
1080
1081- if( component && component->GetFPID().IsValid() )
1082- m_footprintListBox->SetSelectedFootprint( component->GetFPID() );
1083- else
1084- m_footprintListBox->SetSelection( m_footprintListBox->GetSelection(), false );
1085
1086- refreshAfterComponentSearch (component);
1087+bool CVPCB_MAINFRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, int aCtl )
1088+{
1089+ return true;
1090 }
1091
1092
1093@@ -546,7 +529,7 @@ void CVPCB_MAINFRAME::refreshAfterComponentSearch( COMPONENT* component )
1094 }
1095
1096 if( GetFootprintViewerFrame() )
1097- CreateScreenCmp();
1098+ m_toolManager->RunAction( CVPCB_ACTIONS::showFootprintViewer, true );
1099 }
1100
1101 SendMessageToEESCHEMA();
1102@@ -554,79 +537,46 @@ void CVPCB_MAINFRAME::refreshAfterComponentSearch( COMPONENT* component )
1103 }
1104
1105
1106-void CVPCB_MAINFRAME::OnSelectFilteringFootprint( wxCommandEvent& event )
1107+void CVPCB_MAINFRAME::SetFootprintFilter(
1108+ FOOTPRINTS_LISTBOX::FP_FILTER_T aFilter, CVPCB_MAINFRAME::CVPCB_FILTER_ACTION aAction )
1109 {
1110- int option = 0;
1111+ int option = FOOTPRINTS_LISTBOX::UNFILTERED_FP_LIST;
1112
1113- switch( event.GetId() )
1114+ // Extract the needed information about the filter
1115+ switch( aFilter )
1116 {
1117- case ID_CVPCB_FOOTPRINT_DISPLAY_FILTERED_LIST:
1118- option = FOOTPRINTS_LISTBOX::FILTERING_BY_COMPONENT_KEYWORD;
1119- break;
1120+ case FOOTPRINTS_LISTBOX::FILTERING_BY_NAME:
1121+ // Extract the current search patten when needed
1122+ m_currentSearchPattern = m_tcFilterString->GetValue();
1123+
1124+ case FOOTPRINTS_LISTBOX::UNFILTERED_FP_LIST:
1125+ case FOOTPRINTS_LISTBOX::FILTERING_BY_PIN_COUNT:
1126+ case FOOTPRINTS_LISTBOX::FILTERING_BY_LIBRARY:
1127+ case FOOTPRINTS_LISTBOX::FILTERING_BY_COMPONENT_KEYWORD:
1128+ option = aFilter;
1129+ }
1130
1131- case ID_CVPCB_FOOTPRINT_DISPLAY_PIN_FILTERED_LIST:
1132- option = FOOTPRINTS_LISTBOX::FILTERING_BY_PIN_COUNT;
1133+ // Apply the filter accordingly
1134+ switch( aAction )
1135+ {
1136+ case CVPCB_MAINFRAME::FILTER_DISABLE:
1137+ m_filteringOptions &= ~option;
1138 break;
1139
1140- case ID_CVPCB_FOOTPRINT_DISPLAY_BY_LIBRARY_LIST:
1141- option = FOOTPRINTS_LISTBOX::FILTERING_BY_LIBRARY;
1142+ case CVPCB_MAINFRAME::FILTER_ENABLE:
1143+ m_filteringOptions |= option;
1144 break;
1145
1146- case ID_CVPCB_FOOTPRINT_DISPLAY_BY_NAME:
1147- m_currentSearchPattern = m_tcFilterString->GetValue();
1148- option = FOOTPRINTS_LISTBOX::FILTERING_BY_NAME;
1149+ case CVPCB_MAINFRAME::FILTER_TOGGLE:
1150+ m_filteringOptions ^= option;
1151 break;
1152 }
1153
1154- if( event.IsChecked() )
1155- m_filteringOptions |= option;
1156- else
1157- m_filteringOptions &= ~option;
1158-
1159 wxListEvent l_event;
1160 OnSelectComponent( l_event );
1161 }
1162
1163
1164-void CVPCB_MAINFRAME::OnFilterFPbyKeywords( wxUpdateUIEvent& event )
1165-{
1166- event.Check( m_filteringOptions & FOOTPRINTS_LISTBOX::FILTERING_BY_COMPONENT_KEYWORD );
1167-}
1168-
1169-
1170-void CVPCB_MAINFRAME::OnFilterFPbyPinCount( wxUpdateUIEvent& event )
1171-{
1172- event.Check( m_filteringOptions & FOOTPRINTS_LISTBOX::FILTERING_BY_PIN_COUNT );
1173-}
1174-
1175-
1176-void CVPCB_MAINFRAME::OnFilterFPbyLibrary( wxUpdateUIEvent& event )
1177-{
1178- event.Check( m_filteringOptions & FOOTPRINTS_LISTBOX::FILTERING_BY_LIBRARY );
1179-}
1180-
1181-
1182-void CVPCB_MAINFRAME::OnFilterFPbyKeyName( wxUpdateUIEvent& event )
1183-{
1184- event.Check( m_filteringOptions & FOOTPRINTS_LISTBOX::FILTERING_BY_NAME );
1185-}
1186-
1187-
1188-void CVPCB_MAINFRAME::OnEnterFilteringText( wxCommandEvent& aEvent )
1189-{
1190- // Called when changing the filter string in main toolbar.
1191- // If the option FOOTPRINTS_LISTBOX::FILTERING_BY_NAME is set, update the list of
1192- // available footprints which match the filter
1193-
1194- m_currentSearchPattern = m_tcFilterString->GetValue();
1195-
1196- if( ( m_filteringOptions & FOOTPRINTS_LISTBOX::FILTERING_BY_NAME ) == 0 )
1197- return;
1198-
1199- OnSelectFilteringFootprint( aEvent );
1200-}
1201-
1202-
1203 void CVPCB_MAINFRAME::DisplayStatus()
1204 {
1205 if( !m_initialized )
1206@@ -707,6 +657,37 @@ void CVPCB_MAINFRAME::DisplayStatus()
1207 }
1208
1209 SetStatusText( msg, 1 );
1210+
1211+ msg.Empty();
1212+ wxString lib;
1213+
1214+ // Choose the footprint to get the information on
1215+ if( module )
1216+ {
1217+ // Use the footprint in the footprint viewer
1218+ lib = module->GetLibNickname();
1219+ }
1220+ else if( GetFocusedControl() == CVPCB_MAINFRAME::CONTROL_COMPONENT )
1221+ {
1222+ // Use the footprint of the selected component
1223+ if( component )
1224+ lib = component->GetFPID().GetLibNickname();
1225+ }
1226+ else if( GetFocusedControl() == CVPCB_MAINFRAME::CONTROL_LIBRARY )
1227+ {
1228+ // Use the library that is selected
1229+ lib = m_libListBox->GetSelectedLibrary();
1230+ }
1231+
1232+ // Extract the library information
1233+ FP_LIB_TABLE* fptbl = Prj().PcbFootprintLibs( Kiway() );
1234+
1235+ if( fptbl->HasLibrary( lib ) )
1236+ msg = wxString::Format( _( "Library location: %s" ), fptbl->GetFullURI( lib ) );
1237+ else
1238+ msg = wxString::Format( _( "Library location: unknown" ) );
1239+
1240+ SetStatusText( msg, 2 );
1241 }
1242
1243
1244@@ -806,39 +787,6 @@ int CVPCB_MAINFRAME::ReadSchematicNetlist( const std::string& aNetlist )
1245 }
1246
1247
1248-void CVPCB_MAINFRAME::CreateScreenCmp()
1249-{
1250- DISPLAY_FOOTPRINTS_FRAME* fpframe = GetFootprintViewerFrame();
1251-
1252- if( !fpframe )
1253- {
1254- fpframe = (DISPLAY_FOOTPRINTS_FRAME*) Kiway().Player( FRAME_CVPCB_DISPLAY, true, this );
1255- fpframe->Show( true );
1256- }
1257- else
1258- {
1259- if( fpframe->IsIconized() )
1260- fpframe->Iconize( false );
1261-
1262- // The display footprint window might be buried under some other
1263- // windows, so CreateScreenCmp() on an existing window would not
1264- // show any difference, leaving the user confused.
1265- // So we want to put it to front, second after our CVPCB_MAINFRAME.
1266- // We do this by a little dance of bringing it to front then the main
1267- // frame back.
1268- wxWindow* focus = FindFocus();
1269-
1270- fpframe->Raise(); // Make sure that is visible.
1271- Raise(); // .. but still we want the focus.
1272-
1273- if( focus )
1274- focus->SetFocus();
1275- }
1276-
1277- fpframe->InitDisplay();
1278-}
1279-
1280-
1281 void CVPCB_MAINFRAME::BuildFOOTPRINTS_LISTBOX()
1282 {
1283 wxFont guiFont = wxSystemSettings::GetFont( wxSYS_DEFAULT_GUI_FONT );
1284@@ -939,6 +887,83 @@ COMPONENT* CVPCB_MAINFRAME::GetSelectedComponent()
1285 }
1286
1287
1288+void CVPCB_MAINFRAME::SetSelectedComponent( int aIndex, bool aSkipUpdate )
1289+{
1290+ m_skipComponentSelect = aSkipUpdate;
1291+
1292+ if( aIndex < 0 )
1293+ {
1294+ m_compListBox->DeselectAll();
1295+ }
1296+ else if( aIndex < m_compListBox->GetCount() )
1297+ {
1298+ m_compListBox->DeselectAll();
1299+ m_compListBox->SetSelection( aIndex );
1300+ SendMessageToEESCHEMA();
1301+ }
1302+
1303+ m_skipComponentSelect = false;
1304+}
1305+
1306+
1307+std::vector<unsigned int> CVPCB_MAINFRAME::GetComponentIndices(
1308+ CVPCB_MAINFRAME::CRITERIA aCriteria )
1309+{
1310+ std::vector<unsigned int> idx;
1311+
1312+ // Make sure a netlist has been loaded and the box has contents
1313+ if( m_netlist.IsEmpty() || m_compListBox->GetCount() == 0 )
1314+ return idx;
1315+
1316+ switch( aCriteria )
1317+ {
1318+ case CVPCB_MAINFRAME::ALL_COMPONENTS:
1319+ idx.resize( m_netlist.GetCount() );
1320+ std::iota( idx.begin(), idx.end(), 0 );
1321+ break;
1322+
1323+ case CVPCB_MAINFRAME::SEL_COMPONENTS:
1324+ {
1325+ // Check to see if anything is selected
1326+ if( m_compListBox->GetSelectedItemCount() < 1 )
1327+ break;
1328+
1329+ // Get the components
1330+ int lastIdx = m_compListBox->GetFirstSelected();
1331+ idx.emplace_back( lastIdx );
1332+
1333+ lastIdx = m_compListBox->GetNextSelected( lastIdx );
1334+ while( lastIdx > 0 )
1335+ {
1336+ idx.emplace_back( lastIdx );
1337+ lastIdx = m_compListBox->GetNextSelected( lastIdx );
1338+ }
1339+ break;
1340+ }
1341+ case CVPCB_MAINFRAME::NA_COMPONENTS:
1342+ for( unsigned int i = 0; i < m_netlist.GetCount(); i++ )
1343+ {
1344+ if( m_netlist.GetComponent( i )->GetFPID().empty() )
1345+ idx.emplace_back( i );
1346+ }
1347+ break;
1348+
1349+ case CVPCB_MAINFRAME::ASOC_COMPONENTS:
1350+ for( unsigned int i = 0; i < m_netlist.GetCount(); i++ )
1351+ {
1352+ if( !m_netlist.GetComponent( i )->GetFPID().empty() )
1353+ idx.emplace_back( i );
1354+ }
1355+ break;
1356+
1357+ default:
1358+ wxASSERT_MSG( false, "Invalid component selection criteria" );
1359+ }
1360+
1361+ return idx;
1362+}
1363+
1364+
1365 DISPLAY_FOOTPRINTS_FRAME* CVPCB_MAINFRAME::GetFootprintViewerFrame()
1366 {
1367 // returns the Footprint Viewer frame, if exists, or NULL
1368@@ -947,6 +972,54 @@ DISPLAY_FOOTPRINTS_FRAME* CVPCB_MAINFRAME::GetFootprintViewerFrame()
1369 }
1370
1371
1372+CVPCB_MAINFRAME::CONTROL_TYPE CVPCB_MAINFRAME::GetFocusedControl()
1373+{
1374+ if( m_libListBox->HasFocus() )
1375+ return CVPCB_MAINFRAME::CONTROL_LIBRARY;
1376+ else if( m_compListBox->HasFocus() )
1377+ return CVPCB_MAINFRAME::CONTROL_COMPONENT;
1378+ else if( m_footprintListBox->HasFocus() )
1379+ return CVPCB_MAINFRAME::CONTROL_FOOTPRINT;
1380+
1381+ return CVPCB_MAINFRAME::CONTROL_NONE;
1382+}
1383+
1384+
1385+wxControl* CVPCB_MAINFRAME::GetFocusedControlObject()
1386+{
1387+ if( m_libListBox->HasFocus() )
1388+ return m_libListBox;
1389+ else if( m_compListBox->HasFocus() )
1390+ return m_compListBox;
1391+ else if( m_footprintListBox->HasFocus() )
1392+ return m_footprintListBox;
1393+
1394+ return nullptr;
1395+}
1396+
1397+
1398+void CVPCB_MAINFRAME::SetFocusedControl( CVPCB_MAINFRAME::CONTROL_TYPE aLB )
1399+{
1400+ switch( aLB )
1401+ {
1402+ case CVPCB_MAINFRAME::CONTROL_LIBRARY:
1403+ m_libListBox->SetFocus();
1404+ break;
1405+
1406+ case CVPCB_MAINFRAME::CONTROL_COMPONENT:
1407+ m_compListBox->SetFocus();
1408+ break;
1409+
1410+ case CVPCB_MAINFRAME::CONTROL_FOOTPRINT:
1411+ m_footprintListBox->SetFocus();
1412+ break;
1413+
1414+ default:
1415+ break;
1416+ }
1417+}
1418+
1419+
1420 wxString CVPCB_MAINFRAME::GetSelectedFootprint()
1421 {
1422 // returns the LIB_ID of the selected footprint in footprint listview
1423@@ -957,12 +1030,23 @@ wxString CVPCB_MAINFRAME::GetSelectedFootprint()
1424
1425 void CVPCB_MAINFRAME::SetStatusText( const wxString& aText, int aNumber )
1426 {
1427- wxASSERT( aNumber < 2 );
1428+ switch( aNumber )
1429+ {
1430+ case 0:
1431+ m_statusLine1->SetLabel( aText );
1432+ break;
1433
1434- if( aNumber == 1 )
1435+ case 1:
1436 m_statusLine2->SetLabel( aText );
1437- else
1438- m_statusLine1->SetLabel( aText );
1439+ break;
1440+
1441+ case 2:
1442+ m_statusLine3->SetLabel( aText );
1443+ break;
1444+
1445+ default:
1446+ wxASSERT_MSG( false, "Invalid status row number" );
1447+ }
1448 }
1449
1450
1451diff --git a/cvpcb/cvpcb_mainframe.h b/cvpcb/cvpcb_mainframe.h
1452index 4925e51..6c821d9 100644
1453--- a/cvpcb/cvpcb_mainframe.h
1454+++ b/cvpcb/cvpcb_mainframe.h
1455@@ -25,28 +25,35 @@
1456 #ifndef _CVPCB_MAINFRAME_H_
1457 #define _CVPCB_MAINFRAME_H_
1458
1459-#include <wx/listctrl.h>
1460-#include <wx/filename.h>
1461+#include <config_params.h>
1462+#include <kiway_player.h>
1463 #include <pcb_netlist.h>
1464-#include <footprint_info.h>
1465
1466-#include <pcb_base_frame.h>
1467-#include <config_params.h>
1468 #include <auto_associate.h>
1469-#include <memory>
1470-
1471+#include <cvpcb_association.h>
1472+#include <listboxes.h>
1473
1474-/* Forward declarations of all top-level window classes. */
1475+/* Forward declarations */
1476+class ACTION_TOOLBAR;
1477+class ACTION_MENU;
1478+class TOOL_DISPATCHER;
1479 class wxAuiToolBar;
1480-class FOOTPRINTS_LISTBOX;
1481-class COMPONENTS_LISTBOX;
1482-class LIBRARY_LISTBOX;
1483 class DISPLAY_FOOTPRINTS_FRAME;
1484-class COMPONENT;
1485-class FP_LIB_TABLE;
1486
1487 namespace CV { struct IFACE; }
1488
1489+// The undo/redo list is composed of vectors of associations
1490+typedef std::vector< CVPCB_ASSOCIATION > CVPCB_UNDO_REDO_ENTRIES;
1491+
1492+// The undo list is a vector of undo entries
1493+typedef std::vector< CVPCB_UNDO_REDO_ENTRIES > CVPCB_UNDO_REDO_LIST;
1494+
1495+/**
1496+ * The print format to display a schematic component line.
1497+ * format: idx reference - value : footprint_id
1498+ */
1499+#define CMP_FORMAT wxT( "%3d %8s - %16s : %s" )
1500+
1501 /**
1502 * The CvPcb application main window.
1503 */
1504@@ -57,13 +64,14 @@ class CVPCB_MAINFRAME : public KIWAY_PLAYER
1505 wxString m_currentSearchPattern;
1506 NETLIST m_netlist;
1507 int m_filteringOptions;
1508- wxAuiToolBar* m_mainToolBar;
1509+ ACTION_TOOLBAR* m_mainToolBar;
1510 FOOTPRINTS_LISTBOX* m_footprintListBox;
1511 LIBRARY_LISTBOX* m_libListBox;
1512 COMPONENTS_LISTBOX* m_compListBox;
1513 wxTextCtrl* m_tcFilterString;
1514 wxStaticText* m_statusLine1;
1515 wxStaticText* m_statusLine2;
1516+ wxStaticText* m_statusLine3;
1517 wxButton* m_saveAndContinue;
1518
1519 public:
1520@@ -90,59 +98,93 @@ public:
1521 void KiwayMailIn( KIWAY_EXPRESS& aEvent ) override;
1522
1523 /**
1524- * @return a pointer on the Footprint Viewer frame, if exists, or NULL
1525+ * The action to apply to a footprint filter when it is modified.
1526 */
1527- DISPLAY_FOOTPRINTS_FRAME* GetFootprintViewerFrame();
1528+ enum CVPCB_FILTER_ACTION
1529+ {
1530+ FILTER_DISABLE, ///< Turn off the filter
1531+ FILTER_ENABLE, ///< Turn on the filter
1532+ FILTER_TOGGLE ///< Toggle the filter state
1533+ };
1534
1535 /**
1536- * Function OnSelectComponent
1537- * Called when clicking on a component in component list window
1538- * * Updates the filtered footprint list, if the filtered list option is selected
1539- * * Updates the current selected footprint in footprint list
1540- * * Updates the footprint shown in footprint display window (if opened)
1541+ * The type of the controls present in the application
1542 */
1543- void OnSelectComponent( wxListEvent& event );
1544+ enum CONTROL_TYPE
1545+ {
1546+ CONTROL_NONE, ///< No controls have focus
1547+ CONTROL_LIBRARY, ///< Library listbox
1548+ CONTROL_COMPONENT, ///< Component listbox
1549+ CONTROL_FOOTPRINT ///< Footprint listbox
1550+ };
1551
1552 /**
1553- * Function OnEditFootprintLibraryTable
1554- * displays the footprint library table editing dialog and updates the global and local
1555- * footprint tables accordingly.
1556+ * Directions to rotate the focus through the listboxes is
1557 */
1558- void OnEditFootprintLibraryTable( wxCommandEvent& event );
1559+ enum FOCUS_DIR
1560+ {
1561+ CHANGE_FOCUS_RIGHT,
1562+ CHANGE_FOCUS_LEFT
1563+ };
1564
1565- void OnCancel( wxCommandEvent& aEvent );
1566- void OnOK( wxCommandEvent& aEvent );
1567- void OnSaveAndContinue( wxCommandEvent& aEvent );
1568- void OnQuit( wxCommandEvent& event );
1569- void OnCloseWindow( wxCloseEvent& Event );
1570- void OnSize( wxSizeEvent& SizeEvent );
1571- void OnKeyDown( wxKeyEvent& aEvent );
1572- void ReCreateHToolbar();
1573- void ReCreateMenuBar() override;
1574- void ShowChangedLanguage() override;
1575+ /**
1576+ * Directions to move when selecting items
1577+ */
1578+ enum ITEM_DIR
1579+ {
1580+ ITEM_NEXT, ///< The next item
1581+ ITEM_PREV ///< The previous item
1582+ };
1583
1584- void ChangeFocus( bool aMoveRight );
1585+ /**
1586+ * @return a pointer on the Footprint Viewer frame, if exists, or NULL
1587+ */
1588+ DISPLAY_FOOTPRINTS_FRAME* GetFootprintViewerFrame();
1589
1590- void ToFirstNA( wxCommandEvent& event );
1591- void ToPreviousNA( wxCommandEvent& event );
1592+ /**
1593+ * Find out which control currently has focus.
1594+ *
1595+ * @return the contorl that currently has focus
1596+ */
1597+ CVPCB_MAINFRAME::CONTROL_TYPE GetFocusedControl();
1598
1599 /**
1600- * Function DelAssociations
1601- * removes all component footprint associations already made
1602+ * Get a pointer to the currently focused control
1603+ *
1604+ * @return the control that currently has focus
1605 */
1606- void DelAssociations( wxCommandEvent& event );
1607+ wxControl* GetFocusedControlObject();
1608
1609 /**
1610- * Function OnEditEquFilesList
1611- * envokes the equ files list edit dialog.
1612+ * Set the focus to a specific control.
1613+ *
1614+ * @param aControl the contorl to set focus to
1615 */
1616- void OnEditEquFilesList( wxCommandEvent& aEvent );
1617+ void SetFocusedControl( CVPCB_MAINFRAME::CONTROL_TYPE aControl );
1618
1619- void DisplayModule( wxCommandEvent& event );
1620+ /**
1621+ * Function OnSelectComponent
1622+ * Called when clicking on a component in component list window
1623+ * * Updates the filtered footprint list, if the filtered list option is selected
1624+ * * Updates the current selected footprint in footprint list
1625+ * * Updates the footprint shown in footprint display window (if opened)
1626+ */
1627+ void OnSelectComponent( wxListEvent& event );
1628+
1629+ /**
1630+ * OnCloseWindow
1631+ *
1632+ * Called by a close event to close the window
1633+ */
1634+ void OnCloseWindow( wxCloseEvent& Event );
1635
1636- void OnComponentRightClick( wxMouseEvent& event );
1637+ /*
1638+ * Functions to rebuild the toolbars and menubars
1639+ */
1640+ void ReCreateHToolbar();
1641+ void ReCreateMenuBar() override;
1642
1643- void OnFootprintRightClick( wxMouseEvent& event );
1644+ void ShowChangedLanguage() override;
1645
1646 /**
1647 * Called by the automatic association button
1648@@ -152,46 +194,55 @@ public:
1649 * format of a line:
1650 * 'cmp_ref' 'footprint_name'
1651 */
1652- void AutomaticFootprintMatching( wxCommandEvent& event );
1653+ void AutomaticFootprintMatching();
1654
1655 /**
1656- * Function OnSelectFilteringFootprint
1657- * is the command event handler for enabling and disabling footprint filtering.
1658+ * Function SetFootprintFilter
1659+ * Set a filter criteria to either on/off or toggle the criteria.
1660+ *
1661+ * @param aFilter The filter to modify
1662+ * @param aAction What action (on, off or toggle) to take
1663 */
1664- void OnSelectFilteringFootprint( wxCommandEvent& event );
1665+ void SetFootprintFilter(
1666+ FOOTPRINTS_LISTBOX::FP_FILTER_T aFilter, CVPCB_MAINFRAME::CVPCB_FILTER_ACTION aAction );
1667
1668 /**
1669 * Function OnEnterFilteringText
1670 * Is called each time the text of m_tcFilterString is changed.
1671 */
1672- void OnEnterFilteringText( wxCommandEvent& event );
1673+ void OnEnterFilteringText( wxCommandEvent& event );
1674+
1675
1676 /**
1677- * Function SetNewPkg
1678- * set the footprint name for all selected components in component list
1679- * and selects the next component.
1680- * @param aFootprintName = the new footprint name
1681+ * Undo the most recent associations that were performed.
1682 */
1683- void SetNewPkg( const wxString& aFootprintName );
1684+ void UndoAssociation();
1685
1686 /**
1687- * Function SetNewPkg
1688- * Set the footprint name for the component of position aIndex in the component list
1689- *
1690- * @param aFootprintName = the new footprint name
1691- * @param aIndex = the index of the component to modify in the component list
1692+ * Redo the most recently undone association
1693 */
1694- void SetNewPkg( const wxString& aFootprintName, int aIndex );
1695-
1696- void BuildCmpListBox();
1697- void BuildFOOTPRINTS_LISTBOX();
1698- void BuildLIBRARY_LISTBOX();
1699+ void RedoAssociation();
1700
1701 /**
1702- * Create or Update the frame showing the current highlighted footprint
1703- * and (if showed) the 3D display frame
1704+ * Associate a footprint with a specific component in the list.
1705+ *
1706+ * Associations can be chained into a single undo/redo step by setting aNewEntry to false
1707+ * for every association other than the first one. This will create a new list entry for
1708+ * the first association, and add the subsequent associations to that list.
1709+ *
1710+ * @param aAssociation is the association to perform
1711+ * @param aNewEntry specifies if this association should be a new entry in the undo list
1712+ * @param aAddUndoItem specifies if an undo item should be created for this association
1713 */
1714- void CreateScreenCmp();
1715+ void AssociateFootprint( const CVPCB_ASSOCIATION& aAssociation, bool aNewEntry = true,
1716+ bool aAddUndoItem = true );
1717+
1718+ /*
1719+ * Functions to build the listboxes and their contents
1720+ */
1721+ void BuildCmpListBox();
1722+ void BuildFOOTPRINTS_LISTBOX();
1723+ void BuildLIBRARY_LISTBOX();
1724
1725 /**
1726 * Function SaveFootprintAssociation
1727@@ -208,7 +259,7 @@ public:
1728 * @param aNetlist is the netlist from eeschema in kicad s-expr format.
1729 * (see CVPCB_MAINFRAME::KiwayMailIn() to know how to get this netlist)
1730 */
1731- bool ReadNetListAndFpFiles( const std::string& aNetlist );
1732+ bool ReadNetListAndFpFiles( const std::string& aNetlist );
1733
1734 /**
1735 * Function ReadSchematicNetlist
1736@@ -217,7 +268,7 @@ public:
1737 * It is the same netlist as the .net file created by Eeschema.
1738 * (This method is called by ReadNetListAndFpFiles)
1739 */
1740- int ReadSchematicNetlist( const std::string& aNetlist );
1741+ int ReadSchematicNetlist( const std::string& aNetlist );
1742
1743 /**
1744 * Function LoadProjectFile
1745@@ -247,7 +298,7 @@ public:
1746 * displayed in the second status bar pane. The third status bar pane always displays the
1747 * current footprint list filtering.
1748 */
1749- void DisplayStatus();
1750+ void DisplayStatus();
1751
1752 /**
1753 * Function LoadFootprintFiles
1754@@ -260,7 +311,7 @@ public:
1755 * fills m_footprints
1756 * @return true if libraries are found, false otherwise.
1757 */
1758- bool LoadFootprintFiles();
1759+ bool LoadFootprintFiles();
1760
1761 /**
1762 * Function GetProjectFileParameters
1763@@ -287,9 +338,43 @@ public:
1764 */
1765 void SendMessageToEESCHEMA( bool aClearHighligntOnly = false );
1766
1767+ /**
1768+ * Get the selected component from the component listbox.
1769+ *
1770+ * @return the selected component
1771+ */
1772 COMPONENT* GetSelectedComponent();
1773
1774 /**
1775+ * Set the currently selected component in the components listbox
1776+ *
1777+ * @param aIndex the index of the component to select, -1 to clear selection
1778+ * @param aSkipUpdate skips running the OnSelectComponent event to update the other windows
1779+ */
1780+ void SetSelectedComponent( int aIndex, bool aSkipUpdate = false );
1781+
1782+ /**
1783+ * Criteria to use to identify sets of components
1784+ */
1785+ enum CRITERIA
1786+ {
1787+ ALL_COMPONENTS, ///< All components
1788+ SEL_COMPONENTS, ///< Selected components
1789+ NA_COMPONENTS, ///< Not associated components
1790+ ASOC_COMPONENTS ///< Associated components
1791+ };
1792+
1793+ /**
1794+ * Get the indices for all the components meeting the specified criteria in the components
1795+ * listbox.
1796+ *
1797+ * @param aCriteria is the criteria to use for finding the indices
1798+ * @return a vector containing all the indices
1799+ */
1800+ std::vector<unsigned int> GetComponentIndices(
1801+ CVPCB_MAINFRAME::CRITERIA aCriteria = CVPCB_MAINFRAME::ALL_COMPONENTS );
1802+
1803+ /**
1804 * @return the LIB_ID of the selected footprint in footprint listview
1805 * or a empty string if no selection
1806 */
1807@@ -297,13 +382,21 @@ public:
1808
1809 void SetStatusText( const wxString& aText, int aNumber = 0 ) override;
1810
1811+ /**
1812+ * Syncronize the toolbar state with the current tool state.
1813+ */
1814+ void SyncToolbars() override;
1815+
1816 private:
1817- // UI event handlers.
1818- // Keep consistent the display state of toggle menus or tools in toolbar
1819- void OnFilterFPbyKeywords( wxUpdateUIEvent& event );
1820- void OnFilterFPbyPinCount( wxUpdateUIEvent& event );
1821- void OnFilterFPbyLibrary( wxUpdateUIEvent& event );
1822- void OnFilterFPbyKeyName( wxUpdateUIEvent& event );
1823+ /**
1824+ * Setup the tool system for the CVPCB main frame.
1825+ */
1826+ void setupTools();
1827+
1828+ /**
1829+ * Setup event handlers
1830+ */
1831+ void setupEventHandlers();
1832
1833 /**
1834 * read the .equ files and populate the list of equvalents
1835@@ -316,7 +409,16 @@ private:
1836
1837 void refreshAfterComponentSearch (COMPONENT* component);
1838
1839- DECLARE_EVENT_TABLE()
1840+ // Tool dispatcher
1841+ TOOL_DISPATCHER* m_toolDispatcher;
1842+
1843+ // Context menus for the list boxes
1844+ ACTION_MENU* m_footprintContextMenu;
1845+ ACTION_MENU* m_componentContextMenu;
1846+
1847+ // Undo/Redo item lists
1848+ CVPCB_UNDO_REDO_LIST m_undoList;
1849+ CVPCB_UNDO_REDO_LIST m_redoList;
1850 };
1851
1852 #endif //#ifndef _CVPCB_MAINFRAME_H_
1853diff --git a/cvpcb/dialogs/dialog_config_equfiles.cpp b/cvpcb/dialogs/dialog_config_equfiles.cpp
1854index d9aa80a..f5e2754 100644
1855--- a/cvpcb/dialogs/dialog_config_equfiles.cpp
1856+++ b/cvpcb/dialogs/dialog_config_equfiles.cpp
1857@@ -26,18 +26,14 @@
1858 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
1859 */
1860
1861-#include <fctsys.h>
1862 #include <pgm_base.h>
1863-#include <common.h>
1864 #include <confirm.h>
1865 #include <gestfich.h>
1866 #include <id.h>
1867 #include <project.h> // For PROJECT_VAR_NAME definition
1868 #include <fp_lib_table.h> // For KISYSMOD definition
1869
1870-#include <cvpcb.h>
1871 #include <cvpcb_mainframe.h>
1872-
1873 #include <dialog_config_equfiles.h>
1874 #include <wildcards_and_files_ext.h>
1875
1876@@ -59,14 +55,6 @@ DIALOG_CONFIG_EQUFILES::DIALOG_CONFIG_EQUFILES( CVPCB_MAINFRAME* aParent ) :
1877 }
1878
1879
1880-void CVPCB_MAINFRAME::OnEditEquFilesList( wxCommandEvent& aEvent )
1881-{
1882- DIALOG_CONFIG_EQUFILES dlg( this );
1883-
1884- dlg.ShowModal();
1885-}
1886-
1887-
1888 void DIALOG_CONFIG_EQUFILES::Init()
1889 {
1890 m_sdbSizerOK->SetDefault();
1891diff --git a/cvpcb/dialogs/dialog_display_options.cpp b/cvpcb/dialogs/dialog_display_options.cpp
1892index a809c00..91dec0c 100644
1893--- a/cvpcb/dialogs/dialog_display_options.cpp
1894+++ b/cvpcb/dialogs/dialog_display_options.cpp
1895@@ -21,9 +21,6 @@
1896 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
1897 */
1898
1899-#include <fctsys.h>
1900-#include <common.h>
1901-#include <cvpcb.h>
1902 #include <display_footprints_frame.h>
1903 #include <dialog_display_options.h>
1904
1905diff --git a/cvpcb/display_footprints_frame.cpp b/cvpcb/display_footprints_frame.cpp
1906index 2362126..e2b89fe 100644
1907--- a/cvpcb/display_footprints_frame.cpp
1908+++ b/cvpcb/display_footprints_frame.cpp
1909@@ -23,33 +23,30 @@
1910 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
1911 */
1912
1913-#include <fctsys.h>
1914+#include <bitmaps.h>
1915+#include <class_board.h>
1916+#include <class_module.h>
1917 #include <common.h>
1918-#include <pcb_draw_panel_gal.h>
1919 #include <confirm.h>
1920+#include <eda_dockart.h>
1921+#include <fp_lib_table.h>
1922+#include <id.h>
1923+#include <lib_id.h>
1924 #include <macros.h>
1925-#include <bitmaps.h>
1926 #include <msgpanel.h>
1927-#include <wildcards_and_files_ext.h>
1928-#include <lib_id.h>
1929-#include <fp_lib_table.h>
1930-#include <eda_dockart.h>
1931-#include <class_module.h>
1932-#include <class_board.h>
1933+#include <pcb_draw_panel_gal.h>
1934 #include <pcb_painter.h>
1935-#include <cvpcb_mainframe.h>
1936-#include <display_footprints_frame.h>
1937-#include <cvpcb_id.h>
1938-#include <listboxes.h>
1939-#include <view/view.h>
1940-#include <tool/tool_manager.h>
1941-#include <tool/tool_dispatcher.h>
1942 #include <tool/action_toolbar.h>
1943 #include <tool/common_tools.h>
1944+#include <tool/tool_dispatcher.h>
1945+#include <tool/tool_manager.h>
1946 #include <tool/zoom_tool.h>
1947+
1948+#include <cvpcb_mainframe.h>
1949+#include <display_footprints_frame.h>
1950 #include <tools/cvpcb_actions.h>
1951-#include <tools/cvpcb_selection_tool.h>
1952-#include <tools/cvpcb_control.h>
1953+#include <tools/cvpcb_fpviewer_control.h>
1954+#include <tools/cvpcb_fpviewer_selection_tool.h>
1955
1956 // Colors for layers and items
1957 COLORS_DESIGN_SETTINGS g_ColorsSettings( FRAME_CVPCB_DISPLAY );
1958@@ -119,8 +116,8 @@ DISPLAY_FOOTPRINTS_FRAME::DISPLAY_FOOTPRINTS_FRAME( KIWAY* aKiway, wxWindow* aPa
1959
1960 m_toolManager->RegisterTool( new COMMON_TOOLS );
1961 m_toolManager->RegisterTool( new ZOOM_TOOL );
1962- m_toolManager->RegisterTool( new CVPCB_SELECTION_TOOL );
1963- m_toolManager->RegisterTool( new CVPCB_CONTROL );
1964+ m_toolManager->RegisterTool( new CVPCB_FOOTPRINT_VIEWER_CONTROL );
1965+ m_toolManager->RegisterTool( new CVPCB_FOOTPRINT_VIEWER_SELECTION_TOOL );
1966 m_toolManager->InitTools();
1967
1968 // Run the control tool, it is supposed to be always active
1969@@ -157,12 +154,13 @@ DISPLAY_FOOTPRINTS_FRAME::DISPLAY_FOOTPRINTS_FRAME( KIWAY* aKiway, wxWindow* aPa
1970
1971 DISPLAY_FOOTPRINTS_FRAME::~DISPLAY_FOOTPRINTS_FRAME()
1972 {
1973+ GetBoard()->DeleteAllModules();
1974 GetCanvas()->StopDrawing();
1975 GetCanvas()->GetView()->Clear();
1976 // Be sure any event cannot be fired after frame deletion:
1977 GetCanvas()->SetEvtHandlerEnabled( false );
1978
1979- // Be sure a active tool (if exists) is desactivated:
1980+ // Be sure a active tool (if exists) is deactivated:
1981 if( m_toolManager )
1982 m_toolManager->DeactivateTool();
1983
1984diff --git a/cvpcb/display_footprints_frame.h b/cvpcb/display_footprints_frame.h
1985index cc8e8c3..50f709e 100644
1986--- a/cvpcb/display_footprints_frame.h
1987+++ b/cvpcb/display_footprints_frame.h
1988@@ -33,8 +33,6 @@
1989 // The name (for wxWidgets) of the footprint viewer frame
1990 #define FOOTPRINTVIEWER_FRAME_NAME wxT( "FootprintViewerFrame" )
1991
1992-class CVPCB_MAINFRAME;
1993-
1994
1995 /**
1996 * Class DISPLAY_FOOTPRINTS_FRAME
1997diff --git a/cvpcb/footprints_listbox.cpp b/cvpcb/footprints_listbox.cpp
1998index a30df9a..71c50fd 100644
1999--- a/cvpcb/footprints_listbox.cpp
2000+++ b/cvpcb/footprints_listbox.cpp
2001@@ -27,16 +27,15 @@
2002 * class to display the list of available footprints
2003 */
2004
2005-#include <fctsys.h>
2006+#include <footprint_filter.h>
2007+#include <tool/tool_manager.h>
2008+#include <trace_helpers.h>
2009 #include <wx/wupdlock.h>
2010
2011-#include <cvpcb.h>
2012+#include <cvpcb_id.h>
2013 #include <cvpcb_mainframe.h>
2014 #include <listboxes.h>
2015-#include <cvpcb_id.h>
2016-#include <eda_pattern_match.h>
2017-#include <footprint_filter.h>
2018-
2019+#include <tools/cvpcb_actions.h>
2020
2021 FOOTPRINTS_LISTBOX::FOOTPRINTS_LISTBOX( CVPCB_MAINFRAME* parent,
2022 wxWindowID id, const wxPoint& loc,
2023@@ -215,7 +214,7 @@ void FOOTPRINTS_LISTBOX::OnLeftClick( wxListEvent& event )
2024
2025 // If the footprint view window is displayed, update the footprint.
2026 if( GetParent()->GetFootprintViewerFrame() )
2027- GetParent()->CreateScreenCmp();
2028+ GetParent()->GetToolManager()->RunAction( CVPCB_ACTIONS::showFootprintViewer, true );
2029
2030 GetParent()->DisplayStatus();
2031
2032@@ -226,29 +225,18 @@ void FOOTPRINTS_LISTBOX::OnLeftClick( wxListEvent& event )
2033
2034 void FOOTPRINTS_LISTBOX::OnLeftDClick( wxListEvent& event )
2035 {
2036- wxString footprintName = GetSelectedFootprint();
2037-
2038- GetParent()->SetNewPkg( footprintName );
2039+ GetParent()->GetToolManager()->RunAction( CVPCB_ACTIONS::associate, true );
2040 }
2041
2042
2043 void FOOTPRINTS_LISTBOX::OnChar( wxKeyEvent& event )
2044 {
2045+ wxLogTrace( kicadTraceKeyEvent, "FOOTPRINTS_LISTBOX::OnChar %s", dump( event ) );
2046+
2047 int key = event.GetKeyCode();
2048
2049 switch( key )
2050 {
2051- case WXK_TAB:
2052- case WXK_RIGHT:
2053- case WXK_NUMPAD_RIGHT:
2054- GetParent()->ChangeFocus( true );
2055- return;
2056-
2057- case WXK_LEFT:
2058- case WXK_NUMPAD_LEFT:
2059- GetParent()->ChangeFocus( false );
2060- return;
2061-
2062 case WXK_HOME:
2063 case WXK_END:
2064 case WXK_UP:
2065diff --git a/cvpcb/library_listbox.cpp b/cvpcb/library_listbox.cpp
2066index 0113e60..bfbee50 100644
2067--- a/cvpcb/library_listbox.cpp
2068+++ b/cvpcb/library_listbox.cpp
2069@@ -26,10 +26,8 @@
2070 * class to display used library and selecting it
2071 */
2072
2073-#include <fctsys.h>
2074-#include <macros.h>
2075+#include <trace_helpers.h>
2076
2077-#include <cvpcb.h>
2078 #include <cvpcb_mainframe.h>
2079 #include <listboxes.h>
2080 #include <cvpcb_id.h>
2081@@ -144,21 +142,12 @@ END_EVENT_TABLE()
2082
2083 void LIBRARY_LISTBOX::OnChar( wxKeyEvent& event )
2084 {
2085+ wxLogTrace( kicadTraceKeyEvent, "LIBRARY_LISTBOX::OnChar %s", dump( event ) );
2086+
2087 int key = event.GetKeyCode();
2088
2089 switch( key )
2090 {
2091- case WXK_TAB:
2092- case WXK_RIGHT:
2093- case WXK_NUMPAD_RIGHT:
2094- GetParent()->ChangeFocus( true );
2095- return;
2096-
2097- case WXK_LEFT:
2098- case WXK_NUMPAD_LEFT:
2099- GetParent()->ChangeFocus( false );
2100- return;
2101-
2102 case WXK_HOME:
2103 case WXK_END:
2104 case WXK_UP:
2105@@ -211,10 +200,9 @@ void LIBRARY_LISTBOX::OnChar( wxKeyEvent& event )
2106
2107 void LIBRARY_LISTBOX::OnSelectLibrary( wxListEvent& event )
2108 {
2109- wxCommandEvent setLibraryFilterEvent;
2110- setLibraryFilterEvent.SetId( ID_CVPCB_FOOTPRINT_DISPLAY_BY_LIBRARY_LIST );
2111- setLibraryFilterEvent.SetInt( 1 );
2112- GetParent()->OnSelectFilteringFootprint( setLibraryFilterEvent );
2113+ // Apply the filter
2114+ GetParent()->SetFootprintFilter(
2115+ FOOTPRINTS_LISTBOX::FILTERING_BY_LIBRARY, CVPCB_MAINFRAME::FILTER_ENABLE );
2116
2117 SetFocus();
2118 GetParent()->OnSelectComponent( event );
2119diff --git a/cvpcb/listbox_base.cpp b/cvpcb/listbox_base.cpp
2120index d2c42d3..24256af 100644
2121--- a/cvpcb/listbox_base.cpp
2122+++ b/cvpcb/listbox_base.cpp
2123@@ -26,13 +26,8 @@
2124 * @brief Implementation of class for displaying footprint list and component lists.
2125 */
2126
2127-#include <fctsys.h>
2128-#include <macros.h>
2129-
2130-#include <cvpcb.h>
2131 #include <cvpcb_mainframe.h>
2132 #include <listboxes.h>
2133-#include <cvpcb_id.h>
2134
2135
2136 /******************************************************************************
2137diff --git a/cvpcb/menubar.cpp b/cvpcb/menubar.cpp
2138index ef8db00..5ecae29 100644
2139--- a/cvpcb/menubar.cpp
2140+++ b/cvpcb/menubar.cpp
2141@@ -22,15 +22,15 @@
2142 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
2143 */
2144
2145-#include <pgm_base.h>
2146 #include <bitmaps.h>
2147-#include <tool/conditional_menu.h>
2148+#include <menus_helpers.h>
2149 #include <tool/actions.h>
2150-#include <tool/tool_manager.h>
2151 #include <tool/common_control.h>
2152-#include "cvpcb_id.h"
2153-#include "cvpcb_mainframe.h"
2154-#include <menus_helpers.h>
2155+#include <tool/conditional_menu.h>
2156+#include <tool/tool_manager.h>
2157+
2158+#include <cvpcb_mainframe.h>
2159+#include <tools/cvpcb_actions.h>
2160
2161
2162 void CVPCB_MAINFRAME::ReCreateMenuBar()
2163@@ -45,30 +45,46 @@ void CVPCB_MAINFRAME::ReCreateMenuBar()
2164 //
2165 CONDITIONAL_MENU* fileMenu = new CONDITIONAL_MENU( false, tool );
2166
2167- fileMenu->AddItem( ID_SAVE_PROJECT,
2168- _( "&Save Schematic\tCtrl+S" ),
2169- _( "Save footprint associations in schematic symbol footprint fields" ),
2170- save_xpm, SELECTION_CONDITIONS::ShowAlways );
2171+ fileMenu->AddItem( CVPCB_ACTIONS::saveAssociations, SELECTION_CONDITIONS::ShowAlways );
2172+ fileMenu->AddSeparator();
2173+ fileMenu->AddItem( wxID_CLOSE, _( "Close" ), "", exit_xpm, SELECTION_CONDITIONS::ShowAlways );
2174
2175 fileMenu->Resolve();
2176
2177 //-- Preferences menu -----------------------------------------------
2178 //
2179+ CONDITIONAL_MENU* editMenu = new CONDITIONAL_MENU( false, tool );
2180+
2181+ auto enableUndoCondition = [ this ] ( const SELECTION& sel )
2182+ {
2183+ return m_undoList.size() > 0;
2184+ };
2185+ auto enableRedoCondition = [ this ] ( const SELECTION& sel )
2186+ {
2187+ return m_redoList.size() > 0;
2188+ };
2189+
2190+ editMenu->AddItem( ACTIONS::undo, enableUndoCondition );
2191+ editMenu->AddItem( ACTIONS::redo, enableRedoCondition );
2192+ editMenu->AddSeparator();
2193+ editMenu->AddItem( ACTIONS::cut, SELECTION_CONDITIONS::ShowAlways );
2194+ editMenu->AddItem( ACTIONS::copy, SELECTION_CONDITIONS::ShowAlways );
2195+ editMenu->AddItem( ACTIONS::paste, SELECTION_CONDITIONS::ShowAlways );
2196+
2197+ editMenu->Resolve();
2198+
2199+ //-- Preferences menu -----------------------------------------------
2200+ //
2201 CONDITIONAL_MENU* prefsMenu = new CONDITIONAL_MENU( false, tool );
2202
2203- prefsMenu->AddItem( ACTIONS::configurePaths, SELECTION_CONDITIONS::ShowAlways );
2204- prefsMenu->AddItem( ACTIONS::showFootprintLibTable, SELECTION_CONDITIONS::ShowAlways );
2205+ prefsMenu->AddItem( ACTIONS::configurePaths, SELECTION_CONDITIONS::ShowAlways );
2206+ prefsMenu->AddItem( ACTIONS::showFootprintLibTable, SELECTION_CONDITIONS::ShowAlways );
2207 prefsMenu->AddItem( wxID_PREFERENCES,
2208 _( "Preferences...\tCTRL+," ),
2209 _( "Show preferences for all open tools" ),
2210- preference_xpm, SELECTION_CONDITIONS::ShowAlways );
2211-
2212+ preference_xpm, SELECTION_CONDITIONS::ShowAlways );
2213 prefsMenu->AddSeparator();
2214- prefsMenu->AddItem( ID_CVPCB_EQUFILES_LIST_EDIT,
2215- _( "Footprint &Association Files..." ),
2216- _( "Configure footprint association file (.equ) list. These files are "
2217- "used to automatically assign footprint names from symbol values." ),
2218- library_table_xpm, SELECTION_CONDITIONS::ShowAlways );
2219+ prefsMenu->AddItem( CVPCB_ACTIONS::showEquFileTable, SELECTION_CONDITIONS::ShowAlways );
2220
2221 prefsMenu->AddSeparator();
2222 AddMenuLanguageList( prefsMenu, tool );
2223@@ -78,6 +94,7 @@ void CVPCB_MAINFRAME::ReCreateMenuBar()
2224 //-- Menubar -------------------------------------------------------------
2225 //
2226 menuBar->Append( fileMenu, _( "&File" ) );
2227+ menuBar->Append( editMenu, _( "&Edit" ) );
2228 menuBar->Append( prefsMenu, _( "&Preferences" ) );
2229 AddStandardHelpMenu( menuBar );
2230
2231diff --git a/cvpcb/readwrite_dlgs.cpp b/cvpcb/readwrite_dlgs.cpp
2232index f0d3ff5..fb95859 100644
2233--- a/cvpcb/readwrite_dlgs.cpp
2234+++ b/cvpcb/readwrite_dlgs.cpp
2235@@ -1,7 +1,3 @@
2236-/**
2237- * @file cvpcb/readwrite_dlgs.cpp
2238- */
2239-
2240 /*
2241 * This program source code file is part of KiCad, a free EDA CAD application.
2242 *
2243@@ -26,102 +22,20 @@
2244 * or you may write to the Free Software Foundation, Inc.,
2245 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
2246 */
2247-#include <fctsys.h>
2248-#include <kiway.h>
2249-#include <common.h>
2250+
2251 #include <confirm.h>
2252-#include <build_version.h>
2253-#include <macros.h>
2254-#include <lib_id.h>
2255+#include <fctsys.h>
2256 #include <fp_lib_table.h>
2257 #include <html_messagebox.h>
2258+#include <kiway.h>
2259+#include <lib_id.h>
2260+#include <macros.h>
2261
2262-#include <cvpcb.h>
2263 #include <cvpcb_mainframe.h>
2264 #include <listboxes.h>
2265 #include <fp_conflict_assignment_selector.h>
2266
2267
2268-void CVPCB_MAINFRAME::SetNewPkg( const wxString& aFootprintName )
2269-{
2270- COMPONENT* component;
2271- int componentIndex;
2272-
2273- if( m_netlist.IsEmpty() )
2274- return;
2275-
2276- // If no component is selected, select the first one
2277- if( m_compListBox->GetFirstSelected() < 0 )
2278- {
2279- componentIndex = 0;
2280- m_compListBox->SetSelection( componentIndex, true );
2281- }
2282-
2283- // iterate over the selection
2284- while( m_compListBox->GetFirstSelected() != -1 )
2285- {
2286- // Get the component for the current iteration
2287- componentIndex = m_compListBox->GetFirstSelected();
2288- component = m_netlist.GetComponent( componentIndex );
2289-
2290- if( component == NULL )
2291- return;
2292-
2293- SetNewPkg( aFootprintName, componentIndex );
2294-
2295- m_compListBox->SetSelection( componentIndex, false );
2296- }
2297-
2298- // select the next component, if there is one
2299- if( componentIndex < (m_compListBox->GetCount() - 1) )
2300- componentIndex++;
2301-
2302- m_compListBox->SetSelection( componentIndex, true );
2303-
2304- // update the statusbar
2305- DisplayStatus();
2306-}
2307-
2308-
2309-void CVPCB_MAINFRAME::SetNewPkg( const wxString& aFootprintName, int aIndex )
2310-{
2311- COMPONENT* component;
2312-
2313- if( m_netlist.IsEmpty() )
2314- return;
2315-
2316- component = m_netlist.GetComponent( aIndex );
2317-
2318- if( component == NULL )
2319- return;
2320-
2321- LIB_ID fpid;
2322-
2323- if( !aFootprintName.IsEmpty() )
2324- {
2325- wxCHECK_RET( fpid.Parse( aFootprintName, LIB_ID::ID_PCB ) < 0,
2326- wxString::Format( _( "\"%s\" is not a valid LIB_ID." ), aFootprintName ) );
2327- }
2328-
2329- component->SetFPID( fpid );
2330-
2331- // create the new component description
2332- wxString description = wxString::Format( CMP_FORMAT, aIndex + 1,
2333- GetChars( component->GetReference() ),
2334- GetChars( component->GetValue() ),
2335- GetChars( FROM_UTF8( component->GetFPID().Format().c_str() ) ) );
2336-
2337- // Set the new description and deselect the processed component
2338- m_compListBox->SetString( aIndex, description );
2339-
2340- // Mark this "session" as modified
2341- m_modified = true;
2342-
2343- // update the statusbar
2344- DisplayStatus();
2345-}
2346-
2347-
2348 /// Return true if the resultant LIB_ID has a certain nickname. The guess
2349 /// is only made if this footprint resides in only one library.
2350 /// @return int - 0 on success, 1 on not found, 2 on ambiguous i.e. multiple matches
2351@@ -390,5 +304,8 @@ bool CVPCB_MAINFRAME::SaveFootprintAssociation( bool doSaveSchematic )
2352 SetStatusText( _( "Schematic saved" ), 1 );
2353 }
2354
2355+ // Changes are saved, so reset the flag
2356+ m_modified = false;
2357+
2358 return true;
2359 }
2360diff --git a/cvpcb/toolbars_cvpcb.cpp b/cvpcb/toolbars_cvpcb.cpp
2361index 6334c53..e998af1 100644
2362--- a/cvpcb/toolbars_cvpcb.cpp
2363+++ b/cvpcb/toolbars_cvpcb.cpp
2364@@ -23,13 +23,13 @@
2365 * @file tool_cvpcb.cpp
2366 */
2367
2368-#include <fctsys.h>
2369-#include <kiface_i.h>
2370-#include <common.h>
2371-
2372 #include <bitmaps.h>
2373-#include <cvpcb_mainframe.h>
2374+#include <tool/action_toolbar.h>
2375+#include <tool/actions.h>
2376+
2377 #include <cvpcb_id.h>
2378+#include <cvpcb_mainframe.h>
2379+#include <tools/cvpcb_actions.h>
2380
2381
2382 void CVPCB_MAINFRAME::ReCreateHToolbar()
2383@@ -37,35 +37,24 @@ void CVPCB_MAINFRAME::ReCreateHToolbar()
2384 if( m_mainToolBar )
2385 m_mainToolBar->Clear();
2386 else
2387- m_mainToolBar = new wxAuiToolBar( this, ID_H_TOOLBAR, wxDefaultPosition, wxDefaultSize,
2388- KICAD_AUI_TB_STYLE | wxAUI_TB_HORZ_LAYOUT );
2389-
2390- m_mainToolBar->AddTool( ID_CVPCB_LIB_TABLE_EDIT, wxEmptyString,
2391- KiScaledBitmap( config_xpm, this ),
2392- _( "Edit footprint library table" ) );
2393+ m_mainToolBar = new ACTION_TOOLBAR( this, ID_H_TOOLBAR, wxDefaultPosition, wxDefaultSize,
2394+ KICAD_AUI_TB_STYLE | wxAUI_TB_HORZ_LAYOUT );
2395
2396- KiScaledSeparator( m_mainToolBar, this );
2397- m_mainToolBar->AddTool( ID_CVPCB_CREATE_SCREENCMP, wxEmptyString,
2398- KiScaledBitmap( show_footprint_xpm, this ),
2399- _( "View selected footprint" ) );
2400+ m_mainToolBar->Add( ACTIONS::showFootprintLibTable );
2401
2402 KiScaledSeparator( m_mainToolBar, this );
2403- m_mainToolBar->AddTool( ID_CVPCB_GOTO_PREVIOUSNA, wxEmptyString,
2404- KiScaledBitmap( left_xpm, this ),
2405- _( "Select previous unlinked symbol" ) );
2406+ m_mainToolBar->Add( CVPCB_ACTIONS::showFootprintViewer );
2407
2408- m_mainToolBar->AddTool( ID_CVPCB_GOTO_FIRSTNA, wxEmptyString,
2409- KiScaledBitmap( right_xpm, this ),
2410- _( "Select next unlinked symbol" ) );
2411
2412 KiScaledSeparator( m_mainToolBar, this );
2413- m_mainToolBar->AddTool( ID_CVPCB_AUTO_ASSOCIE, wxEmptyString,
2414- KiScaledBitmap( auto_associe_xpm, this ),
2415- _( "Perform automatic footprint association" ) );
2416+ m_mainToolBar->Add( CVPCB_ACTIONS::gotoPreviousNA );
2417+ m_mainToolBar->Add( CVPCB_ACTIONS::gotoNextNA );
2418
2419- m_mainToolBar->AddTool( ID_CVPCB_DEL_ASSOCIATIONS, wxEmptyString,
2420- KiScaledBitmap( delete_association_xpm, this ),
2421- _( "Delete all footprint associations" ) );
2422+ KiScaledSeparator( m_mainToolBar, this );
2423+ m_mainToolBar->Add( ACTIONS::undo );
2424+ m_mainToolBar->Add( ACTIONS::redo );
2425+ m_mainToolBar->Add( CVPCB_ACTIONS::autoAssociate );
2426+ m_mainToolBar->Add( CVPCB_ACTIONS::deleteAll );
2427
2428 // Add tools for footprint names filtering:
2429 KiScaledSeparator( m_mainToolBar, this );
2430@@ -75,32 +64,12 @@ void CVPCB_MAINFRAME::ReCreateHToolbar()
2431 text->SetFont( m_mainToolBar->GetFont().Bold() );
2432 m_mainToolBar->AddControl( text );
2433
2434- m_mainToolBar->AddTool( ID_CVPCB_FOOTPRINT_DISPLAY_FILTERED_LIST,
2435- KiScaledBitmap( module_filtered_list_xpm, this ),
2436- wxNullBitmap,
2437- true, NULL,
2438- _( "Filter footprint list by schematic symbol keywords" ),
2439- wxEmptyString );
2440-
2441- m_mainToolBar->AddTool( ID_CVPCB_FOOTPRINT_DISPLAY_PIN_FILTERED_LIST,
2442- KiScaledBitmap( module_pin_filtered_list_xpm, this ),
2443- wxNullBitmap,
2444- true, NULL,
2445- _( "Filter footprint list by pin count" ),
2446- wxEmptyString );
2447-
2448- m_mainToolBar->AddTool( ID_CVPCB_FOOTPRINT_DISPLAY_BY_LIBRARY_LIST,
2449- KiScaledBitmap( module_library_list_xpm, this ),
2450- wxNullBitmap, true, NULL,
2451- _( "Filter footprint list by library" ),
2452- wxEmptyString );
2453+ m_mainToolBar->Add( CVPCB_ACTIONS::filterFPbyKeywords, true );
2454+ m_mainToolBar->Add( CVPCB_ACTIONS::filterFPbyPin, true );
2455+ m_mainToolBar->Add( CVPCB_ACTIONS::filterFPbyLibrary, true );
2456
2457 KiScaledSeparator( m_mainToolBar, this );
2458- m_mainToolBar->AddTool( ID_CVPCB_FOOTPRINT_DISPLAY_BY_NAME,
2459- KiScaledBitmap( module_name_filtered_list_xpm, this ),
2460- wxNullBitmap, true, NULL,
2461- _( "Filter footprint list using a partial name or a pattern" ),
2462- wxEmptyString );
2463+ m_mainToolBar->Add( CVPCB_ACTIONS::filterFPbyDisplayName, true );
2464
2465 m_tcFilterString = new wxTextCtrl( m_mainToolBar, ID_CVPCB_FILTER_TEXT_EDIT );
2466
2467@@ -110,3 +79,22 @@ void CVPCB_MAINFRAME::ReCreateHToolbar()
2468 // after adding the buttons to the toolbar, must call Realize() to reflect the changes
2469 m_mainToolBar->Realize();
2470 }
2471+
2472+
2473+void CVPCB_MAINFRAME::SyncToolbars()
2474+{
2475+#define filterActive( filt ) ( m_filteringOptions & filt )
2476+
2477+ m_mainToolBar->Toggle( ACTIONS::undo, m_undoList.size() > 0 );
2478+ m_mainToolBar->Toggle( ACTIONS::redo, m_redoList.size() > 0 );
2479+
2480+ m_mainToolBar->Toggle( CVPCB_ACTIONS::filterFPbyKeywords,
2481+ filterActive( FOOTPRINTS_LISTBOX::FILTERING_BY_COMPONENT_KEYWORD ) );
2482+ m_mainToolBar->Toggle( CVPCB_ACTIONS::filterFPbyLibrary,
2483+ filterActive( FOOTPRINTS_LISTBOX::FILTERING_BY_LIBRARY ) );
2484+ m_mainToolBar->Toggle( CVPCB_ACTIONS::filterFPbyPin,
2485+ filterActive( FOOTPRINTS_LISTBOX::FILTERING_BY_PIN_COUNT ) );
2486+ m_mainToolBar->Toggle( CVPCB_ACTIONS::filterFPbyDisplayName,
2487+ filterActive( FOOTPRINTS_LISTBOX::FILTERING_BY_NAME ) );
2488+ m_mainToolBar->Refresh();
2489+}
2490diff --git a/cvpcb/tools/cvpcb_actions.cpp b/cvpcb/tools/cvpcb_actions.cpp
2491index 4dc8505..13a5b0e 100644
2492--- a/cvpcb/tools/cvpcb_actions.cpp
2493+++ b/cvpcb/tools/cvpcb_actions.cpp
2494@@ -18,10 +18,11 @@
2495 * with this program. If not, see <http://www.gnu.org/licenses/>.
2496 */
2497
2498-#include <tool/tool_manager.h>
2499 #include <bitmaps.h>
2500-#include "cvpcb_actions.h"
2501
2502+#include <cvpcb_mainframe.h>
2503+#include <listboxes.h>
2504+#include <tools/cvpcb_actions.h>
2505
2506 // Actions, being statically-defined, require specialized I18N handling. We continue to
2507 // use the _() macro so that string harvesting by the I18N framework doesn't have to be
2508@@ -31,10 +32,124 @@
2509 #define _(s) s
2510
2511
2512-// CVPCB_SELECTION_TOOL
2513-//
2514-TOOL_ACTION CVPCB_ACTIONS::selectionActivate( "cvpcb.InteractiveSelection",
2515- AS_GLOBAL, 0, "",
2516- "", "", NULL, AF_ACTIVATE ); // No description, it is not supposed to be shown anywhere
2517+// Selection tool action for the footprint viewer window
2518+TOOL_ACTION CVPCB_ACTIONS::selectionActivate( "cvpcb.InteractiveSelection", AS_GLOBAL,
2519+ 0, "",
2520+ "",
2521+ "",
2522+ NULL, AF_ACTIVATE ); // No description, it is not supposed to be shown anywhere
2523
2524+TOOL_ACTION CVPCB_ACTIONS::controlActivate( "cvpcb.Control", AS_GLOBAL,
2525+ 0, "",
2526+ "",
2527+ "",
2528+ NULL, AF_ACTIVATE ); // No description, it is not supposed to be shown anywhere
2529
2530+
2531+// Action to show the footprint viewer window
2532+TOOL_ACTION CVPCB_ACTIONS::showFootprintViewer( "cvpcb.Control.ShowFootprintViewer", AS_GLOBAL,
2533+ 0, "",
2534+ _( "View selected footprint" ),
2535+ _( "View the selected footprint in the footprint viewer" ),
2536+ show_footprint_xpm );
2537+
2538+
2539+// Actions to handle management tasks
2540+TOOL_ACTION CVPCB_ACTIONS::showEquFileTable( "cvpcb.Control.ShowEquFileTable", AS_GLOBAL,
2541+ 0, "",
2542+ _( "Manage Footprint Association Files" ),
2543+ _( "Configure footprint association file (.equ) list. These files are "
2544+ "used to automatically assign footprint names from symbol values." ),
2545+ library_table_xpm );
2546+
2547+TOOL_ACTION CVPCB_ACTIONS::saveAssociations( "cvpcb.Control.SaveAssocations", AS_GLOBAL,
2548+ MD_CTRL + 'S', LEGACY_HK_NAME( "Save" ),
2549+ _( "Save to Schematic" ),
2550+ _( "Save footprint associations in schematic symbol footprint fields" ),
2551+ save_xpm );
2552+
2553+// Actions to navigate the display
2554+TOOL_ACTION CVPCB_ACTIONS::changeFocusRight( "cvpcb.Control.changeFocusRight", AS_GLOBAL,
2555+ WXK_TAB, "",
2556+ "",
2557+ "",
2558+ nullptr, AF_NONE,
2559+ (void*) CVPCB_MAINFRAME::CHANGE_FOCUS_RIGHT );
2560+
2561+TOOL_ACTION CVPCB_ACTIONS::changeFocusLeft( "cvpcb.Control.changeFocusLeft", AS_GLOBAL,
2562+ MD_SHIFT + WXK_TAB, "",
2563+ "",
2564+ "",
2565+ nullptr, AF_NONE,
2566+ (void*) CVPCB_MAINFRAME::CHANGE_FOCUS_LEFT );
2567+
2568+// Actions to navigate the component list
2569+TOOL_ACTION CVPCB_ACTIONS::gotoNextNA( "cvpcb.Control.GotoNextNA", AS_GLOBAL,
2570+ 0, "",
2571+ _( "Select next unassociated symbol" ),
2572+ _( "Select next unassociated symbol" ),
2573+ right_xpm, AF_NONE,
2574+ (void*) CVPCB_MAINFRAME::ITEM_NEXT );
2575+
2576+TOOL_ACTION CVPCB_ACTIONS::gotoPreviousNA( "cvpcb.Control.GotoPreviousNA", AS_GLOBAL,
2577+ 0, "",
2578+ _( "Select previous unassociated symbol" ),
2579+ _( "Select previous unassociated symbol" ),
2580+ left_xpm, AF_NONE,
2581+ (void*) CVPCB_MAINFRAME::ITEM_PREV );
2582+
2583+
2584+// Actions to modify component associations
2585+TOOL_ACTION CVPCB_ACTIONS::associate( "cvpcb.Association.Associate", AS_GLOBAL,
2586+ WXK_RETURN, "",
2587+ _( "Associate footprint" ),
2588+ _( "Associate selected footprint with selected components" ),
2589+ auto_associe_xpm );
2590+
2591+TOOL_ACTION CVPCB_ACTIONS::autoAssociate( "cvpcb.Association.AutoAssociate", AS_GLOBAL,
2592+ 0, "",
2593+ _( "Automatically associate footprints" ),
2594+ _( "Perform automatic footprint association" ),
2595+ auto_associe_xpm );
2596+
2597+TOOL_ACTION CVPCB_ACTIONS::deleteAssoc( "cvpcb.Association.Delete", AS_GLOBAL,
2598+ WXK_DELETE, "",
2599+ _( "Delete association" ),
2600+ _( "Delete selected footprint associations" ),
2601+ delete_association_xpm );
2602+
2603+TOOL_ACTION CVPCB_ACTIONS::deleteAll( "cvpcb.Association.DeleteAll", AS_GLOBAL,
2604+ 0, "",
2605+ _( "Delete all footprint associations" ),
2606+ _( "Delete all footprint associations" ),
2607+ delete_association_xpm );
2608+
2609+
2610+// Actions to filter the footprint list
2611+TOOL_ACTION CVPCB_ACTIONS::filterFPbyKeywords( "cvpcb.Control.FilterFPByKeyword", AS_GLOBAL,
2612+ 0, "",
2613+ _( "Filter by keyword" ),
2614+ _( "Filter footprint list by schematic symbol keywords" ),
2615+ module_filtered_list_xpm, AF_NONE,
2616+ (void*) FOOTPRINTS_LISTBOX::FILTERING_BY_COMPONENT_KEYWORD );
2617+
2618+TOOL_ACTION CVPCB_ACTIONS::filterFPbyPin( "cvpcb.Control.FilterFPByPin", AS_GLOBAL,
2619+ 0, "",
2620+ _( "Filter by pin count" ),
2621+ _( "Filter footprint list by pin count" ),
2622+ module_pin_filtered_list_xpm, AF_NONE,
2623+ (void*) FOOTPRINTS_LISTBOX::FILTERING_BY_PIN_COUNT );
2624+
2625+TOOL_ACTION CVPCB_ACTIONS::filterFPbyLibrary( "cvpcb.Control.FilterFPByLibrary", AS_GLOBAL,
2626+ 0, "",
2627+ _( "Filter by library" ),
2628+ _( "Filter footprint list by library" ),
2629+ module_library_list_xpm, AF_NONE,
2630+ (void*) FOOTPRINTS_LISTBOX::FILTERING_BY_LIBRARY );
2631+
2632+TOOL_ACTION CVPCB_ACTIONS::filterFPbyDisplayName( "cvpcb.Control.FilterFPByDisplayName", AS_GLOBAL,
2633+ 0, "",
2634+ _( "Filter by display name" ),
2635+ _( "Filter footprint list using a partial name or a pattern" ),
2636+ module_name_filtered_list_xpm, AF_NONE,
2637+ (void*) FOOTPRINTS_LISTBOX::FILTERING_BY_NAME );
2638diff --git a/cvpcb/tools/cvpcb_actions.h b/cvpcb/tools/cvpcb_actions.h
2639index 9fb8759..a600cc8 100644
2640--- a/cvpcb/tools/cvpcb_actions.h
2641+++ b/cvpcb/tools/cvpcb_actions.h
2642@@ -2,7 +2,7 @@
2643 * This program source code file is part of KiCad, a free EDA CAD application.
2644 *
2645 * Copyright (C) 2013-2016 CERN
2646- * Copyright (C) 2018 KiCad Developers, see AUTHORS.txt for contributors.
2647+ * Copyright (C) 2018-2019 KiCad Developers, see AUTHORS.txt for contributors.
2648 * @author Maciej Suminski <maciej.suminski@cern.ch>
2649 *
2650 * This program is free software; you can redistribute it and/or
2651@@ -26,12 +26,10 @@
2652 #ifndef CVPCB_ACTIONS_H
2653 #define CVPCB_ACTIONS_H
2654
2655-#include <tool/tool_action.h>
2656-#include <tool/actions.h>
2657 #include <core/optional.h>
2658-
2659-class TOOL_EVENT;
2660-class TOOL_MANAGER;
2661+#include <tool/actions.h>
2662+#include <tool/tool_event.h>
2663+class TOOL_ACTION;
2664
2665 /**
2666 * Class CVPCB_ACTIONS
2667@@ -42,9 +40,36 @@ class TOOL_MANAGER;
2668 class CVPCB_ACTIONS : public ACTIONS
2669 {
2670 public:
2671- // Selection Tool
2672- /// Activation of the selection tool
2673+ /// Activation actions
2674 static TOOL_ACTION selectionActivate;
2675+ static TOOL_ACTION controlActivate;
2676+
2677+ /// Window control actions
2678+ static TOOL_ACTION changeFocusRight;
2679+ static TOOL_ACTION changeFocusLeft;
2680+
2681+ /// Open the footprint viewer
2682+ static TOOL_ACTION showFootprintViewer;
2683+
2684+ /// Navigate the component tree
2685+ static TOOL_ACTION gotoPreviousNA;
2686+ static TOOL_ACTION gotoNextNA;
2687+
2688+ /// Management actions
2689+ static TOOL_ACTION saveAssociations;
2690+ static TOOL_ACTION showEquFileTable;
2691+
2692+ /// Footprint Association actions
2693+ static TOOL_ACTION autoAssociate;
2694+ static TOOL_ACTION associate;
2695+ static TOOL_ACTION deleteAll;
2696+ static TOOL_ACTION deleteAssoc;
2697+
2698+ /// Footprint Filtering actions
2699+ static TOOL_ACTION filterFPbyKeywords;
2700+ static TOOL_ACTION filterFPbyPin;
2701+ static TOOL_ACTION filterFPbyLibrary;
2702+ static TOOL_ACTION filterFPbyDisplayName;
2703
2704 ///> @copydoc COMMON_ACTIONS::TranslateLegacyId()
2705 virtual OPT<TOOL_EVENT> TranslateLegacyId( int aId ) override { return OPT<TOOL_EVENT>(); }
2706diff --git a/cvpcb/tools/cvpcb_association_tool.cpp b/cvpcb/tools/cvpcb_association_tool.cpp
2707new file mode 100644
2708index 0000000..d9fb66d
2709--- /dev/null
2710+++ b/cvpcb/tools/cvpcb_association_tool.cpp
2711@@ -0,0 +1,296 @@
2712+/*
2713+ * This program source code file is part of KiCad, a free EDA CAD application.
2714+ *
2715+ * Copyright (C) 2019 Ian McInerney <Ian.S.McInerney@ieee.org>
2716+ * Copyright (C) 2019 KiCad Developers, see AUTHORS.txt for contributors.
2717+ *
2718+ * This program is free software: you can redistribute it and/or modify it
2719+ * under the terms of the GNU General Public License as published by the
2720+ * Free Software Foundation, either version 3 of the License, or (at your
2721+ * option) any later version.
2722+ *
2723+ * This program is distributed in the hope that it will be useful, but
2724+ * WITHOUT ANY WARRANTY; without even the implied warranty of
2725+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2726+ * General Public License for more details.
2727+ *
2728+ * You should have received a copy of the GNU General Public License along
2729+ * with this program. If not, see <http://www.gnu.org/licenses/>.
2730+ */
2731+
2732+#include <confirm.h>
2733+#include <cstdint>
2734+#include <functional>
2735+#include <kiface_i.h>
2736+#include <kiway_express.h>
2737+#include <lib_id.h>
2738+#include <tool/actions.h>
2739+#include <tool/tool_manager.h>
2740+#include <wx/clipbrd.h>
2741+
2742+#include <cvpcb_association.h>
2743+#include <cvpcb_mainframe.h>
2744+#include <dialogs/dialog_config_equfiles.h>
2745+#include <display_footprints_frame.h>
2746+#include <listboxes.h>
2747+#include <tools/cvpcb_actions.h>
2748+#include <tools/cvpcb_association_tool.h>
2749+
2750+using namespace std::placeholders;
2751+
2752+
2753+CVPCB_ASSOCIATION_TOOL::CVPCB_ASSOCIATION_TOOL() :
2754+ TOOL_INTERACTIVE( "cvpcb.Association" ),
2755+ m_frame( nullptr )
2756+{
2757+}
2758+
2759+
2760+int CVPCB_ASSOCIATION_TOOL::CopyAssoc( const TOOL_EVENT& aEvent )
2761+{
2762+ COMPONENT* comp;
2763+ LIB_ID fpid;
2764+ switch( m_frame->GetFocusedControl() )
2765+ {
2766+ case CVPCB_MAINFRAME::CONTROL_FOOTPRINT:
2767+ fpid.Parse( m_frame->GetSelectedFootprint(), LIB_ID::ID_PCB );
2768+ break;
2769+
2770+ case CVPCB_MAINFRAME::CONTROL_COMPONENT:
2771+ // Get the selection
2772+ comp = m_frame->GetSelectedComponent();
2773+
2774+ if( !comp )
2775+ return 0;
2776+
2777+ // Get the fpid and save it to the clipboard
2778+ fpid = comp->GetFPID();
2779+ break;
2780+
2781+ default:
2782+ // Do nothing
2783+ break;
2784+ }
2785+
2786+ // if no valid fpid, then skip
2787+ if( !fpid.IsValid() )
2788+ return 0;
2789+
2790+ if( wxTheClipboard->Open() )
2791+ {
2792+ if( !wxTheClipboard->SetData( new wxTextDataObject( fpid.GetUniStringLibId() ) ) )
2793+ wxLogDebug( "Failed to copy data to clipboard" );
2794+
2795+ wxTheClipboard->Flush();
2796+ wxTheClipboard->Close();
2797+ }
2798+
2799+ return 0;
2800+}
2801+
2802+
2803+int CVPCB_ASSOCIATION_TOOL::CutAssoc( const TOOL_EVENT& aEvent )
2804+{
2805+ // Only cut when in the component frame
2806+ if( m_frame->GetFocusedControl() != CVPCB_MAINFRAME::CONTROL_COMPONENT )
2807+ return 0;
2808+
2809+ // Get the selection, but only use the first one
2810+ COMPONENT* comp = m_frame->GetSelectedComponent();
2811+ std::vector<unsigned int> idx = m_frame->GetComponentIndices( CVPCB_MAINFRAME::SEL_COMPONENTS );
2812+
2813+ if( idx.empty() || !comp )
2814+ return 0;
2815+
2816+ // Get the fpid
2817+ LIB_ID fpid;
2818+ fpid = comp->GetFPID();
2819+
2820+ // if no valid fpid, then skip
2821+ if( !fpid.IsValid() )
2822+ return 0;
2823+
2824+ // Save it to the clipboard
2825+ if( wxTheClipboard->Open() )
2826+ {
2827+ if( !wxTheClipboard->SetData( new wxTextDataObject( fpid.GetUniStringLibId() ) ) )
2828+ {
2829+ wxLogDebug( "Failed to cut data to clipboard" );
2830+ wxTheClipboard->Close();
2831+ return 0;
2832+ }
2833+
2834+ wxTheClipboard->Flush();
2835+ wxTheClipboard->Close();
2836+ }
2837+
2838+ // Remove the association
2839+ m_frame->AssociateFootprint( CVPCB_ASSOCIATION( idx.front(), "" ) );
2840+
2841+ return 0;
2842+}
2843+
2844+
2845+int CVPCB_ASSOCIATION_TOOL::PasteAssoc( const TOOL_EVENT& aEvent )
2846+{
2847+ // Get the selection
2848+ std::vector<unsigned int> idx = m_frame->GetComponentIndices( CVPCB_MAINFRAME::SEL_COMPONENTS );
2849+
2850+ if( idx.empty() )
2851+ return 0;
2852+
2853+ // Get the clipboard data and ensure it is valid
2854+ LIB_ID fpid;
2855+ wxTextDataObject data;
2856+
2857+ if( wxTheClipboard->Open() )
2858+ {
2859+ wxTheClipboard->GetData( data );
2860+ wxTheClipboard->Close();
2861+ }
2862+
2863+ if( fpid.Parse( data.GetText(), LIB_ID::ID_PCB ) >= 0 )
2864+ return 0;
2865+
2866+ // Assign the fpid to the selections
2867+ bool firstAssoc = true;
2868+ for( auto i : idx )
2869+ {
2870+ m_frame->AssociateFootprint( CVPCB_ASSOCIATION( i, fpid ), firstAssoc );
2871+ firstAssoc = false;
2872+ }
2873+
2874+ return 0;
2875+}
2876+
2877+void CVPCB_ASSOCIATION_TOOL::Reset( RESET_REASON aReason )
2878+{
2879+ m_frame = getEditFrame<CVPCB_MAINFRAME>();
2880+}
2881+
2882+
2883+int CVPCB_ASSOCIATION_TOOL::Undo( const TOOL_EVENT& aEvent )
2884+{
2885+ m_frame->UndoAssociation();
2886+
2887+ return 0;
2888+}
2889+
2890+
2891+int CVPCB_ASSOCIATION_TOOL::Redo( const TOOL_EVENT& aEvent )
2892+{
2893+ m_frame->RedoAssociation();
2894+
2895+ return 0;
2896+}
2897+
2898+
2899+int CVPCB_ASSOCIATION_TOOL::Associate( const TOOL_EVENT& aEvent )
2900+{
2901+ // Get the currently selected footprint
2902+ LIB_ID fpid;
2903+ wxString fp = m_frame->GetSelectedFootprint();
2904+ fpid.Parse( fp, LIB_ID::ID_PCB );
2905+
2906+ // Ignore the action if the footprint is empty (nothing selected)
2907+ if( fpid.empty() )
2908+ return 0;
2909+
2910+ // Test for validity of the requested footprint
2911+ if( !fpid.IsValid() )
2912+ {
2913+ wxString msg =
2914+ wxString::Format( _( "\"%s\" is not a valid footprint." ), fpid.Format().wx_str() );
2915+ DisplayErrorMessage( m_frame, msg );
2916+ }
2917+
2918+ // Get all the components that are selected and associate them with the current footprint
2919+ std::vector<unsigned int> sel = m_frame->GetComponentIndices( CVPCB_MAINFRAME::SEL_COMPONENTS );
2920+
2921+ bool firstAssoc = true;
2922+ for( auto i : sel )
2923+ {
2924+ CVPCB_ASSOCIATION newfp( i, fpid );
2925+ m_frame->AssociateFootprint( newfp, firstAssoc );
2926+ firstAssoc = false;
2927+ }
2928+
2929+ // Move to the next not associated component
2930+ m_toolMgr->RunAction( CVPCB_ACTIONS::gotoNextNA );
2931+
2932+ return 0;
2933+}
2934+
2935+
2936+int CVPCB_ASSOCIATION_TOOL::AutoAssociate( const TOOL_EVENT& aEvent )
2937+{
2938+ m_frame->AutomaticFootprintMatching();
2939+
2940+ return 0;
2941+}
2942+
2943+
2944+int CVPCB_ASSOCIATION_TOOL::DeleteAssoc( const TOOL_EVENT& aEvent )
2945+{
2946+ // Get all the components that are selected
2947+ std::vector<unsigned int> sel = m_frame->GetComponentIndices( CVPCB_MAINFRAME::SEL_COMPONENTS );
2948+
2949+ // Delete the association
2950+ bool firstAssoc = true;
2951+ for( auto i : sel )
2952+ {
2953+ m_frame->AssociateFootprint( CVPCB_ASSOCIATION( i, LIB_ID() ), firstAssoc );
2954+ firstAssoc = false;
2955+ }
2956+
2957+ return 0;
2958+}
2959+
2960+
2961+int CVPCB_ASSOCIATION_TOOL::DeleteAll( const TOOL_EVENT& aEvent )
2962+{
2963+ if( IsOK( m_frame, _( "Delete all associations?" ) ) )
2964+ {
2965+ // Remove all selections to avoid issues when setting the fpids
2966+ m_frame->SetSelectedComponent( -1, true );
2967+ std::vector<unsigned int> idx =
2968+ m_frame->GetComponentIndices( CVPCB_MAINFRAME::ALL_COMPONENTS );
2969+
2970+ bool firstAssoc = true;
2971+ for( auto i : idx )
2972+ {
2973+ m_frame->AssociateFootprint( CVPCB_ASSOCIATION( i, LIB_ID() ), firstAssoc );
2974+ firstAssoc = false;
2975+ }
2976+
2977+ // Remove all selections after setting the fpids and select the first component
2978+ m_frame->SetSelectedComponent( -1, true );
2979+ m_frame->SetSelectedComponent( 0 );
2980+ }
2981+
2982+ // Update the status display
2983+ m_frame->DisplayStatus();
2984+
2985+ return 0;
2986+}
2987+
2988+
2989+void CVPCB_ASSOCIATION_TOOL::setTransitions()
2990+{
2991+ // Association
2992+ Go( &CVPCB_ASSOCIATION_TOOL::Associate, CVPCB_ACTIONS::associate.MakeEvent() );
2993+ Go( &CVPCB_ASSOCIATION_TOOL::AutoAssociate, CVPCB_ACTIONS::autoAssociate.MakeEvent() );
2994+
2995+ // Deletion
2996+ Go( &CVPCB_ASSOCIATION_TOOL::DeleteAll, CVPCB_ACTIONS::deleteAll.MakeEvent() );
2997+ Go( &CVPCB_ASSOCIATION_TOOL::DeleteAssoc, CVPCB_ACTIONS::deleteAssoc.MakeEvent() );
2998+
2999+ // Helpers
3000+ Go( &CVPCB_ASSOCIATION_TOOL::Undo, ACTIONS::undo.MakeEvent() );
3001+ Go( &CVPCB_ASSOCIATION_TOOL::Redo, ACTIONS::redo.MakeEvent() );
3002+
3003+ // Clipboard
3004+ Go( &CVPCB_ASSOCIATION_TOOL::CutAssoc, ACTIONS::cut.MakeEvent() );
3005+ Go( &CVPCB_ASSOCIATION_TOOL::CopyAssoc, ACTIONS::copy.MakeEvent() );
3006+ Go( &CVPCB_ASSOCIATION_TOOL::PasteAssoc, ACTIONS::paste.MakeEvent() );
3007+}
3008diff --git a/cvpcb/tools/cvpcb_association_tool.h b/cvpcb/tools/cvpcb_association_tool.h
3009new file mode 100644
3010index 0000000..4c73fbe
3011--- /dev/null
3012+++ b/cvpcb/tools/cvpcb_association_tool.h
3013@@ -0,0 +1,116 @@
3014+/*
3015+ * This program source code file is part of KiCad, a free EDA CAD application.
3016+ *
3017+ * Copyright (C) 2019 Ian McInerney <Ian.S.McInerney@ieee.org>
3018+ * Copyright (C) 2019 KiCad Developers, see AUTHORS.txt for contributors.
3019+ *
3020+ * This program is free software: you can redistribute it and/or modify it
3021+ * under the terms of the GNU General Public License as published by the
3022+ * Free Software Foundation, either version 3 of the License, or (at your
3023+ * option) any later version.
3024+ *
3025+ * This program is distributed in the hope that it will be useful, but
3026+ * WITHOUT ANY WARRANTY; without even the implied warranty of
3027+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3028+ * General Public License for more details.
3029+ *
3030+ * You should have received a copy of the GNU General Public License along
3031+ * with this program. If not, see <http://www.gnu.org/licenses/>.
3032+ */
3033+
3034+#ifndef CVPCB_ASSOCIATION_TOOL_H_
3035+#define CVPCB_ASSOCIATION_TOOL_H_
3036+
3037+#include <tool/tool_interactive.h>
3038+
3039+#include <cvpcb_mainframe.h>
3040+
3041+
3042+/**
3043+ * Class CVPCB_CONTROL
3044+ *
3045+ * Handles actions in main cvpcb window.
3046+ */
3047+
3048+class CVPCB_ASSOCIATION_TOOL : public TOOL_INTERACTIVE
3049+{
3050+public:
3051+ CVPCB_ASSOCIATION_TOOL();
3052+ ~CVPCB_ASSOCIATION_TOOL() {}
3053+
3054+ /// @copydoc TOOL_INTERACTIVE::Reset()
3055+ void Reset( RESET_REASON aReason ) override;
3056+
3057+ /**
3058+ * Undo the footprint associations most recently done.
3059+ *
3060+ * @param aEvent is the event generated by the tool framework
3061+ */
3062+ int Undo( const TOOL_EVENT& aEvent );
3063+
3064+ /**
3065+ * Redo the footprint associations most recently done.
3066+ *
3067+ * @param aEvent is the event generated by the tool framework
3068+ */
3069+ int Redo( const TOOL_EVENT& aEvent );
3070+
3071+ /**
3072+ * Associate the selected footprint with the currently selected components.
3073+ *
3074+ * @param aEvent is the event generated by the tool framework
3075+ */
3076+ int Associate( const TOOL_EVENT& aEvent );
3077+
3078+ /**
3079+ * Perform automatic footprint association.
3080+ *
3081+ * @param aEvent is the event generated by the tool framework
3082+ */
3083+ int AutoAssociate( const TOOL_EVENT& aEvent );
3084+
3085+ /**
3086+ * Delete all associations.
3087+ *
3088+ * @param aEvent is the event generated by the tool framework
3089+ */
3090+ int DeleteAll( const TOOL_EVENT& aEvent );
3091+
3092+ /**
3093+ * Delete the selected associations.
3094+ *
3095+ * @param aEvent is the event generated by the tool framework
3096+ */
3097+ int DeleteAssoc( const TOOL_EVENT& aEvent );
3098+
3099+ /**
3100+ * Copy the selected associations to the clipboard.
3101+ *
3102+ * @param aEvent is the event generated by the tool framework
3103+ */
3104+ int CopyAssoc( const TOOL_EVENT& aEvent );
3105+
3106+ /**
3107+ * Cut the selected associations to the clipboard.
3108+ *
3109+ * @param aEvent is the event generated by the tool framework
3110+ */
3111+ int CutAssoc( const TOOL_EVENT& aEvent );
3112+
3113+ /**
3114+ * Paste the clipboard onto the current selection.
3115+ *
3116+ * @param aEvent is the event generated by the tool framework
3117+ */
3118+ int PasteAssoc( const TOOL_EVENT& aEvent );
3119+
3120+ /*
3121+ * Sets up handlers for various events.
3122+ */
3123+ void setTransitions() override;
3124+
3125+private:
3126+ CVPCB_MAINFRAME* m_frame;
3127+};
3128+
3129+#endif
3130diff --git a/cvpcb/tools/cvpcb_control.cpp b/cvpcb/tools/cvpcb_control.cpp
3131index 8e3eebe..28077cc 100644
3132--- a/cvpcb/tools/cvpcb_control.cpp
3133+++ b/cvpcb/tools/cvpcb_control.cpp
3134@@ -1,57 +1,327 @@
3135 /*
3136 * This program source code file is part of KiCad, a free EDA CAD application.
3137 *
3138- * Copyright (C) 2014-2016 CERN
3139- * @author Maciej Suminski <maciej.suminski@cern.ch>
3140- * Copyright (C) 2007-2019 KiCad Developers, see AUTHORS.txt for contributors.
3141+ * Copyright (C) 2019 Ian McInerney <Ian.S.McInerney@ieee.org>
3142+ * Copyright (C) 2019 KiCad Developers, see AUTHORS.txt for contributors.
3143 *
3144- * This program is free software; you can redistribute it and/or
3145- * modify it under the terms of the GNU General Public License
3146- * as published by the Free Software Foundation; either version 2
3147- * of the License, or (at your option) any later version.
3148+ * This program is free software: you can redistribute it and/or modify it
3149+ * under the terms of the GNU General Public License as published by the
3150+ * Free Software Foundation, either version 3 of the License, or (at your
3151+ * option) any later version.
3152 *
3153- * This program is distributed in the hope that it will be useful,
3154- * but WITHOUT ANY WARRANTY; without even the implied warranty of
3155- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3156- * GNU General Public License for more details.
3157+ * This program is distributed in the hope that it will be useful, but
3158+ * WITHOUT ANY WARRANTY; without even the implied warranty of
3159+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3160+ * General Public License for more details.
3161 *
3162- * You should have received a copy of the GNU General Public License
3163- * along with this program; if not, you may find one here:
3164- * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
3165- * or you may search the http://www.gnu.org website for the version 2 license,
3166- * or you may write to the Free Software Foundation, Inc.,
3167- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
3168+ * You should have received a copy of the GNU General Public License along
3169+ * with this program. If not, see <http://www.gnu.org/licenses/>.
3170 */
3171
3172+#include <confirm.h>
3173 #include <cstdint>
3174 #include <functional>
3175+#include <kiface_i.h>
3176+#include <kiway_express.h>
3177+#include <lib_id.h>
3178 #include <tool/actions.h>
3179+#include <tool/tool_manager.h>
3180+
3181+#include <cvpcb_mainframe.h>
3182+#include <dialogs/dialog_config_equfiles.h>
3183+#include <display_footprints_frame.h>
3184+#include <listboxes.h>
3185+#include <tools/cvpcb_actions.h>
3186 #include <tools/cvpcb_control.h>
3187+
3188 using namespace std::placeholders;
3189
3190
3191 CVPCB_CONTROL::CVPCB_CONTROL() :
3192- TOOL_INTERACTIVE( "cvpcb.Control" ),
3193- m_frame( nullptr )
3194+ TOOL_INTERACTIVE( "cvpcb.Control" ),
3195+ m_frame( nullptr )
3196 {
3197 }
3198
3199
3200 void CVPCB_CONTROL::Reset( RESET_REASON aReason )
3201 {
3202- m_frame = getEditFrame<DISPLAY_FOOTPRINTS_FRAME>();
3203+ m_frame = getEditFrame<CVPCB_MAINFRAME>();
3204+}
3205+
3206+
3207+int CVPCB_CONTROL::Main( const TOOL_EVENT& aEvent )
3208+{
3209+ // Main loop: keep receiving events
3210+ while( TOOL_EVENT* evt = Wait() )
3211+ {
3212+ bool handled = false;
3213+
3214+ // The escape key maps to the cancel event, which is used to close the window
3215+ if( evt->IsCancel() )
3216+ {
3217+ wxCloseEvent dummy;
3218+ m_frame->OnCloseWindow( dummy );
3219+ handled = true;
3220+ }
3221+ else if( evt->IsKeyPressed() )
3222+ {
3223+ switch( evt->KeyCode() )
3224+ {
3225+ // The right arrow moves focus to the focusable object to the right
3226+ case WXK_RIGHT:
3227+ m_toolMgr->RunAction( CVPCB_ACTIONS::changeFocusRight );
3228+ handled = true;
3229+ break;
3230+
3231+ // The left arrow moves focus to the focusable object to the left
3232+ case WXK_LEFT:
3233+ m_toolMgr->RunAction( CVPCB_ACTIONS::changeFocusLeft );
3234+ handled = true;
3235+ break;
3236+
3237+ default:
3238+ // Let every other key continue processing to the controls of the window
3239+ break;
3240+ }
3241+ }
3242+
3243+ if( !handled )
3244+ evt->SetPassEvent();
3245+ }
3246+
3247+ // This tool is supposed to be active forever
3248+ wxASSERT( false );
3249+
3250+ return 0;
3251+}
3252+
3253+
3254+int CVPCB_CONTROL::ChangeFocus( const TOOL_EVENT& aEvent )
3255+{
3256+ int tmp = aEvent.Parameter<intptr_t>();
3257+ CVPCB_MAINFRAME::FOCUS_DIR dir =
3258+ static_cast<CVPCB_MAINFRAME::FOCUS_DIR>( tmp );
3259+
3260+ switch( dir )
3261+ {
3262+ case CVPCB_MAINFRAME::CHANGE_FOCUS_RIGHT:
3263+ switch( m_frame->GetFocusedControl() )
3264+ {
3265+ case CVPCB_MAINFRAME::CONTROL_LIBRARY:
3266+ m_frame->SetFocusedControl( CVPCB_MAINFRAME::CONTROL_COMPONENT );
3267+ break;
3268+
3269+ case CVPCB_MAINFRAME::CONTROL_COMPONENT:
3270+ m_frame->SetFocusedControl( CVPCB_MAINFRAME::CONTROL_FOOTPRINT );
3271+ break;
3272+
3273+ case CVPCB_MAINFRAME::CONTROL_FOOTPRINT:
3274+ m_frame->SetFocusedControl( CVPCB_MAINFRAME::CONTROL_LIBRARY );
3275+ break;
3276+
3277+ case CVPCB_MAINFRAME::CONTROL_NONE:
3278+ default:
3279+ break;
3280+ }
3281+
3282+ break;
3283+
3284+ case CVPCB_MAINFRAME::CHANGE_FOCUS_LEFT:
3285+ switch( m_frame->GetFocusedControl() )
3286+ {
3287+ case CVPCB_MAINFRAME::CONTROL_LIBRARY:
3288+ m_frame->SetFocusedControl( CVPCB_MAINFRAME::CONTROL_FOOTPRINT );
3289+ break;
3290+
3291+ case CVPCB_MAINFRAME::CONTROL_COMPONENT:
3292+ m_frame->SetFocusedControl( CVPCB_MAINFRAME::CONTROL_LIBRARY );
3293+ break;
3294+
3295+ case CVPCB_MAINFRAME::CONTROL_FOOTPRINT:
3296+ m_frame->SetFocusedControl( CVPCB_MAINFRAME::CONTROL_COMPONENT );
3297+ break;
3298+
3299+ case CVPCB_MAINFRAME::CONTROL_NONE:
3300+ default:
3301+ break;
3302+ }
3303+
3304+ break;
3305+
3306+ default:
3307+ break;
3308+ }
3309+
3310+ return 0;
3311+}
3312+
3313+
3314+int CVPCB_CONTROL::ShowFootprintViewer( const TOOL_EVENT& aEvent )
3315+{
3316+
3317+ DISPLAY_FOOTPRINTS_FRAME* fpframe = m_frame->GetFootprintViewerFrame();
3318+
3319+ if( !fpframe )
3320+ {
3321+ fpframe = (DISPLAY_FOOTPRINTS_FRAME*) m_frame->Kiway().Player(
3322+ FRAME_CVPCB_DISPLAY, true, m_frame );
3323+ fpframe->Show( true );
3324+ }
3325+ else
3326+ {
3327+ if( fpframe->IsIconized() )
3328+ fpframe->Iconize( false );
3329+
3330+ // The display footprint window might be buried under some other
3331+ // windows, so CreateScreenCmp() on an existing window would not
3332+ // show any difference, leaving the user confused.
3333+ // So we want to put it to front, second after our CVPCB_MAINFRAME.
3334+ // We do this by a little dance of bringing it to front then the main
3335+ // frame back.
3336+ wxWindow* focus = m_frame->FindFocus();
3337+
3338+ fpframe->Raise(); // Make sure that is visible.
3339+ m_frame->Raise(); // .. but still we want the focus.
3340+
3341+ if( focus )
3342+ focus->SetFocus();
3343+ }
3344+
3345+ fpframe->InitDisplay();
3346+
3347+ return 0;
3348+}
3349+
3350+
3351+int CVPCB_CONTROL::ToggleFootprintFilter( const TOOL_EVENT& aEvent )
3352+{
3353+ m_frame->SetFootprintFilter(
3354+ static_cast<FOOTPRINTS_LISTBOX::FP_FILTER_T>( aEvent.Parameter<intptr_t>() ),
3355+ CVPCB_MAINFRAME::FILTER_TOGGLE );
3356+
3357+ return 0;
3358 }
3359
3360
3361-int CVPCB_CONTROL::Show3DViewer( const TOOL_EVENT& aEvent )
3362+int CVPCB_CONTROL::ShowEquFileTable( const TOOL_EVENT& aEvent )
3363 {
3364- m_frame->CreateAndShow3D_Frame();
3365+ DIALOG_CONFIG_EQUFILES dlg( m_frame );
3366+ dlg.ShowModal();
3367+
3368+ return 0;
3369+}
3370+
3371+
3372+int CVPCB_CONTROL::SaveAssociations( const TOOL_EVENT& aEvent )
3373+{
3374+ m_frame->SaveFootprintAssociation( true );
3375+ return 0;
3376+}
3377+
3378+
3379+int CVPCB_CONTROL::ToNA( const TOOL_EVENT& aEvent )
3380+{
3381+ int tmp = aEvent.Parameter<intptr_t>();
3382+ CVPCB_MAINFRAME::ITEM_DIR dir =
3383+ static_cast<CVPCB_MAINFRAME::ITEM_DIR>( tmp );
3384+
3385+ std::vector<unsigned int> naComp = m_frame->GetComponentIndices( CVPCB_MAINFRAME::NA_COMPONENTS );
3386+ std::vector<unsigned int> tempSel = m_frame->GetComponentIndices( CVPCB_MAINFRAME::SEL_COMPONENTS );
3387+
3388+ // No unassociated components
3389+ if( naComp.empty() )
3390+ return 0;
3391+
3392+ // Extract the current selection
3393+ unsigned int curSel = -1;
3394+ unsigned int newSel = -1;
3395+ switch( dir )
3396+ {
3397+ case CVPCB_MAINFRAME::ITEM_NEXT:
3398+ if( !tempSel.empty() )
3399+ newSel = tempSel.front();
3400+
3401+ // Find the next index in the component list
3402+ for( unsigned int i : naComp )
3403+ {
3404+ if( i > newSel )
3405+ {
3406+ newSel = i;
3407+ break;
3408+ }
3409+ }
3410+
3411+ break;
3412+
3413+ case CVPCB_MAINFRAME::ITEM_PREV:
3414+ if( !tempSel.empty() )
3415+ {
3416+ newSel = tempSel.front();
3417+ curSel = newSel - 1; // Break one before the current selection
3418+ }
3419+
3420+ break;
3421+
3422+ default:
3423+ wxASSERT_MSG( false, "Invalid direction" );
3424+ }
3425+
3426+ // Find the next index in the component list
3427+ for( unsigned int i : naComp )
3428+ {
3429+ if( i >= curSel )
3430+ {
3431+ newSel = i;
3432+ break;
3433+ }
3434+ }
3435+
3436+ // Set the component selection
3437+ m_frame->SetSelectedComponent( newSel );
3438+
3439+ return 0;
3440+}
3441+
3442+
3443+int CVPCB_CONTROL::UpdateMenu( const TOOL_EVENT& aEvent )
3444+{
3445+ ACTION_MENU* actionMenu = aEvent.Parameter<ACTION_MENU*>();
3446+ CONDITIONAL_MENU* conditionalMenu = dynamic_cast<CONDITIONAL_MENU*>( actionMenu );
3447+ SELECTION dummySel;
3448+
3449+ if( conditionalMenu )
3450+ conditionalMenu->Evaluate( dummySel );
3451+
3452+ if( actionMenu )
3453+ actionMenu->UpdateAll();
3454+
3455 return 0;
3456 }
3457
3458
3459 void CVPCB_CONTROL::setTransitions()
3460 {
3461- // Miscellaneous
3462- Go( &CVPCB_CONTROL::Show3DViewer, ACTIONS::show3DViewer.MakeEvent() );
3463+ // Control actions
3464+ Go( &CVPCB_CONTROL::UpdateMenu, ACTIONS::updateMenu.MakeEvent() );
3465+ Go( &CVPCB_CONTROL::Main, CVPCB_ACTIONS::controlActivate.MakeEvent() );
3466+ Go( &CVPCB_CONTROL::ChangeFocus, CVPCB_ACTIONS::changeFocusRight.MakeEvent() );
3467+ Go( &CVPCB_CONTROL::ChangeFocus, CVPCB_ACTIONS::changeFocusLeft.MakeEvent() );
3468+
3469+ // Run the footprint viewer
3470+ Go( &CVPCB_CONTROL::ShowFootprintViewer, CVPCB_ACTIONS::showFootprintViewer.MakeEvent() );
3471+
3472+ // Management actions
3473+ Go( &CVPCB_CONTROL::ShowEquFileTable, CVPCB_ACTIONS::showEquFileTable.MakeEvent() );
3474+ Go( &CVPCB_CONTROL::SaveAssociations, CVPCB_ACTIONS::saveAssociations.MakeEvent() );
3475+
3476+ // Navigation actions
3477+ Go( &CVPCB_CONTROL::ToNA, CVPCB_ACTIONS::gotoNextNA.MakeEvent() );
3478+ Go( &CVPCB_CONTROL::ToNA, CVPCB_ACTIONS::gotoPreviousNA.MakeEvent() );
3479+
3480+ // Filter the footprints
3481+ Go( &CVPCB_CONTROL::ToggleFootprintFilter, CVPCB_ACTIONS::filterFPbyKeywords.MakeEvent() );
3482+ Go( &CVPCB_CONTROL::ToggleFootprintFilter, CVPCB_ACTIONS::filterFPbyLibrary.MakeEvent() );
3483+ Go( &CVPCB_CONTROL::ToggleFootprintFilter, CVPCB_ACTIONS::filterFPbyPin.MakeEvent() );
3484+ Go( &CVPCB_CONTROL::ToggleFootprintFilter, CVPCB_ACTIONS::filterFPbyDisplayName.MakeEvent() );
3485 }
3486diff --git a/cvpcb/tools/cvpcb_control.h b/cvpcb/tools/cvpcb_control.h
3487index 469d084..6cc134e 100644
3488--- a/cvpcb/tools/cvpcb_control.h
3489+++ b/cvpcb/tools/cvpcb_control.h
3490@@ -1,58 +1,113 @@
3491 /*
3492 * This program source code file is part of KiCad, a free EDA CAD application.
3493 *
3494- * Copyright (C) 2014-2016 CERN
3495- * @author Maciej Suminski <maciej.suminski@cern.ch>
3496- * Copyright (C) 2007-2018 KiCad Developers, see AUTHORS.txt for contributors.
3497+ * Copyright (C) 2019 Ian McInerney <Ian.S.McInerney@ieee.org>
3498+ * Copyright (C) 2019 KiCad Developers, see AUTHORS.txt for contributors.
3499 *
3500- * This program is free software; you can redistribute it and/or
3501- * modify it under the terms of the GNU General Public License
3502- * as published by the Free Software Foundation; either version 2
3503- * of the License, or (at your option) any later version.
3504+ * This program is free software: you can redistribute it and/or modify it
3505+ * under the terms of the GNU General Public License as published by the
3506+ * Free Software Foundation, either version 3 of the License, or (at your
3507+ * option) any later version.
3508 *
3509- * This program is distributed in the hope that it will be useful,
3510- * but WITHOUT ANY WARRANTY; without even the implied warranty of
3511- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3512- * GNU General Public License for more details.
3513+ * This program is distributed in the hope that it will be useful, but
3514+ * WITHOUT ANY WARRANTY; without even the implied warranty of
3515+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3516+ * General Public License for more details.
3517 *
3518- * You should have received a copy of the GNU General Public License
3519- * along with this program; if not, you may find one here:
3520- * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
3521- * or you may search the http://www.gnu.org website for the version 2 license,
3522- * or you may write to the Free Software Foundation, Inc.,
3523- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
3524+ * You should have received a copy of the GNU General Public License along
3525+ * with this program. If not, see <http://www.gnu.org/licenses/>.
3526 */
3527
3528-#ifndef CVPCB_CONTROL_H
3529-#define CVPCB_CONTROL_H
3530+#ifndef CVPCB_CONTROL_H_
3531+#define CVPCB_CONTROL_H_
3532
3533 #include <tool/tool_interactive.h>
3534-#include <display_footprints_frame.h>
3535+
3536+#include <cvpcb_mainframe.h>
3537
3538
3539 /**
3540 * Class CVPCB_CONTROL
3541 *
3542- * Handles actions in cvpcb display frame.
3543+ * Handles actions in main cvpcb window.
3544 */
3545
3546 class CVPCB_CONTROL : public TOOL_INTERACTIVE
3547 {
3548 public:
3549 CVPCB_CONTROL();
3550- ~CVPCB_CONTROL() { }
3551+ ~CVPCB_CONTROL() {}
3552
3553 /// @copydoc TOOL_INTERACTIVE::Reset()
3554 void Reset( RESET_REASON aReason ) override;
3555
3556- int Show3DViewer( const TOOL_EVENT& aEvent );
3557+ /**
3558+ * Main processing loop for the CVPCB window. This function will constantly loop and
3559+ * to process various actions taken in the window.
3560+ *
3561+ * @param aEvent is the event generated by the tool framework
3562+ */
3563+ int Main( const TOOL_EVENT& aEvent );
3564+
3565+ /**
3566+ * Rotate focus in the CVPCB window
3567+ *
3568+ * @param aEvent is the event generated by the tool framework
3569+ */
3570+ int ChangeFocus( const TOOL_EVENT& aEvent );
3571+
3572+ /**
3573+ * Move the selected component to the not associated one in the specified direction.
3574+ *
3575+ * @param aEvent is the event generated by the tool framework
3576+ */
3577+ int ToNA( const TOOL_EVENT& aEvent );
3578+
3579+ /**
3580+ * Show the dialog to modify the included footprint association files (.equ)
3581+ *
3582+ * @param aEvent is the event generated by the tool framework
3583+ */
3584+ int ShowEquFileTable( const TOOL_EVENT& aEvent );
3585+
3586+ /**
3587+ * Save the associations to the schematic.
3588+ *
3589+ * @param aEvent is the event generated by the tool framework
3590+ */
3591+ int SaveAssociations( const TOOL_EVENT& aEvent );
3592+
3593+ /**
3594+ * Create or Update the frame showing the current highlighted footprint
3595+ * and (if showed) the 3D display frame.
3596+ *
3597+ * @param aEvent is the event generated by the tool framework
3598+ */
3599+ int ShowFootprintViewer( const TOOL_EVENT& aEvent );
3600+
3601+ /**
3602+ * Filter the footprint list by toggling the given filter type.
3603+ * The event parameter corresponds to the filter type (using the FP_FILTER_T from the
3604+ * FOOTPRINTS_LISTBOX class)
3605+ *
3606+ * @param aEvent is the event generated by the tool framework
3607+ */
3608+ int ToggleFootprintFilter( const TOOL_EVENT& aEvent );
3609+
3610+ /**
3611+ * Update the menu to reflect the current tool states.
3612+ *
3613+ * @param aEvent is the event generated by the tool framework
3614+ */
3615+ int UpdateMenu( const TOOL_EVENT& aEvent );
3616
3617- ///> Sets up handlers for various events.
3618+ /*
3619+ * Sets up handlers for various events.
3620+ */
3621 void setTransitions() override;
3622
3623 private:
3624- ///> Pointer to the currently used edit/draw frame.
3625- DISPLAY_FOOTPRINTS_FRAME* m_frame;
3626+ CVPCB_MAINFRAME* m_frame;
3627 };
3628
3629 #endif
3630diff --git a/cvpcb/cvpcb.h b/cvpcb/tools/cvpcb_fpviewer_control.cpp
3631similarity index 53%
3632rename from cvpcb/cvpcb.h
3633rename to cvpcb/tools/cvpcb_fpviewer_control.cpp
3634index 5592125..f1f83b1 100644
3635--- a/cvpcb/cvpcb.h
3636+++ b/cvpcb/tools/cvpcb_fpviewer_control.cpp
3637@@ -1,8 +1,9 @@
3638 /*
3639 * This program source code file is part of KiCad, a free EDA CAD application.
3640 *
3641- * Copyright (C) 2018 Jean-Pierre Charras, jp.charras at wanadoo.fr
3642- * Copyright (C) 2018 KiCad Developers, see AUTHORS.txt for contributors.
3643+ * Copyright (C) 2014-2016 CERN
3644+ * @author Maciej Suminski <maciej.suminski@cern.ch>
3645+ * Copyright (C) 2007-2019 KiCad Developers, see AUTHORS.txt for contributors.
3646 *
3647 * This program is free software; you can redistribute it and/or
3648 * modify it under the terms of the GNU General Public License
3649@@ -22,15 +23,34 @@
3650 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
3651 */
3652
3653-#ifndef __CVPCB_H__
3654-#define __CVPCB_H__
3655+#include <functional>
3656+using namespace std::placeholders;
3657
3658-// Define print format to display a schematic component line. format:
3659-// idx reference - value : footprint_id
3660-#define CMP_FORMAT wxT( "%3d %8s - %16s : %s" )
3661+#include <tool/actions.h>
3662+#include <tools/cvpcb_fpviewer_control.h>
3663
3664-extern const wxString EquFileExtension;
3665-extern const wxString EquFilesWildcard;
3666
3667+CVPCB_FOOTPRINT_VIEWER_CONTROL::CVPCB_FOOTPRINT_VIEWER_CONTROL() :
3668+ TOOL_INTERACTIVE( "cvpcb.FootprintViewerControl" ),
3669+ m_frame( nullptr )
3670+{
3671+}
3672
3673-#endif /* __CVPCB_H__ */
3674+
3675+void CVPCB_FOOTPRINT_VIEWER_CONTROL::Reset( RESET_REASON aReason )
3676+{
3677+ m_frame = getEditFrame<DISPLAY_FOOTPRINTS_FRAME>();
3678+}
3679+
3680+
3681+int CVPCB_FOOTPRINT_VIEWER_CONTROL::Show3DViewer( const TOOL_EVENT& aEvent )
3682+{
3683+ m_frame->CreateAndShow3D_Frame();
3684+ return 0;
3685+}
3686+
3687+
3688+void CVPCB_FOOTPRINT_VIEWER_CONTROL::setTransitions()
3689+{
3690+ Go( &CVPCB_FOOTPRINT_VIEWER_CONTROL::Show3DViewer, ACTIONS::show3DViewer.MakeEvent() );
3691+}
3692diff --git a/cvpcb/tools/cvpcb_fpviewer_control.h b/cvpcb/tools/cvpcb_fpviewer_control.h
3693new file mode 100644
3694index 0000000..4caeaa3
3695--- /dev/null
3696+++ b/cvpcb/tools/cvpcb_fpviewer_control.h
3697@@ -0,0 +1,59 @@
3698+/*
3699+ * This program source code file is part of KiCad, a free EDA CAD application.
3700+ *
3701+ * Copyright (C) 2014-2016 CERN
3702+ * @author Maciej Suminski <maciej.suminski@cern.ch>
3703+ * Copyright (C) 2007-2019 KiCad Developers, see AUTHORS.txt for contributors.
3704+ *
3705+ * This program is free software; you can redistribute it and/or
3706+ * modify it under the terms of the GNU General Public License
3707+ * as published by the Free Software Foundation; either version 2
3708+ * of the License, or (at your option) any later version.
3709+ *
3710+ * This program is distributed in the hope that it will be useful,
3711+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3712+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3713+ * GNU General Public License for more details.
3714+ *
3715+ * You should have received a copy of the GNU General Public License
3716+ * along with this program; if not, you may find one here:
3717+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
3718+ * or you may search the http://www.gnu.org website for the version 2 license,
3719+ * or you may write to the Free Software Foundation, Inc.,
3720+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
3721+ */
3722+
3723+#ifndef CVPCB_FOOTPRINT_VIEWER_CONTROL_H_
3724+#define CVPCB_FOOTPRINT_VIEWER_CONTROL_H_
3725+
3726+#include <display_footprints_frame.h>
3727+#include <tool/tool_interactive.h>
3728+
3729+
3730+/**
3731+ * Class CVPCB_FOOTPRINT_VIEWER_CONTROL
3732+ *
3733+ * Handles control actions for the cvpcb footprint display frame.
3734+ */
3735+
3736+class CVPCB_FOOTPRINT_VIEWER_CONTROL : public TOOL_INTERACTIVE
3737+{
3738+public:
3739+ CVPCB_FOOTPRINT_VIEWER_CONTROL();
3740+ ~CVPCB_FOOTPRINT_VIEWER_CONTROL() {}
3741+
3742+ /// @copydoc TOOL_INTERACTIVE::Reset()
3743+ void Reset( RESET_REASON aReason ) override;
3744+
3745+ ///> Show the 3D viewer with the currently selected footprint
3746+ int Show3DViewer( const TOOL_EVENT& aEvent );
3747+
3748+ ///> Sets up handlers for various events.
3749+ void setTransitions() override;
3750+
3751+private:
3752+ ///> Pointer to the currently used edit/draw frame.
3753+ DISPLAY_FOOTPRINTS_FRAME* m_frame;
3754+};
3755+
3756+#endif
3757diff --git a/cvpcb/tools/cvpcb_selection_tool.cpp b/cvpcb/tools/cvpcb_fpviewer_selection_tool.cpp
3758similarity index 84%
3759rename from cvpcb/tools/cvpcb_selection_tool.cpp
3760rename to cvpcb/tools/cvpcb_fpviewer_selection_tool.cpp
3761index df974dc..2a09c61 100644
3762--- a/cvpcb/tools/cvpcb_selection_tool.cpp
3763+++ b/cvpcb/tools/cvpcb_fpviewer_selection_tool.cpp
3764@@ -17,41 +17,38 @@
3765 * with this program. If not, see <http://www.gnu.org/licenses/>.
3766 */
3767
3768-#include <limits>
3769 #include <functional>
3770 using namespace std::placeholders;
3771-#include <class_draw_panel_gal.h>
3772-#include <view/view.h>
3773+
3774 #include <bitmaps.h>
3775+#include <preview_items/ruler_item.h>
3776 #include <tool/tool_event.h>
3777-#include <tool/tool_manager.h>
3778 #include <tools/cvpcb_actions.h>
3779-#include <tools/cvpcb_selection_tool.h>
3780-#include <preview_items/ruler_item.h>
3781-#include <cvpcb_id.h>
3782-
3783+#include <tools/cvpcb_fpviewer_selection_tool.h>
3784+#include <view/view.h>
3785+#include <view/view_controls.h>
3786
3787-CVPCB_SELECTION_TOOL::CVPCB_SELECTION_TOOL() :
3788- TOOL_INTERACTIVE( "cvpcb.InteractiveSelection" ),
3789+CVPCB_FOOTPRINT_VIEWER_SELECTION_TOOL::CVPCB_FOOTPRINT_VIEWER_SELECTION_TOOL() :
3790+ TOOL_INTERACTIVE( "cvpcb.FootprintViewerInteractiveSelection" ),
3791 m_frame( nullptr )
3792 {
3793 }
3794
3795
3796-bool CVPCB_SELECTION_TOOL::Init()
3797+bool CVPCB_FOOTPRINT_VIEWER_SELECTION_TOOL::Init()
3798 {
3799 getEditFrame<DISPLAY_FOOTPRINTS_FRAME>()->AddStandardSubMenus( m_menu );
3800 return true;
3801 }
3802
3803
3804-void CVPCB_SELECTION_TOOL::Reset( RESET_REASON aReason )
3805+void CVPCB_FOOTPRINT_VIEWER_SELECTION_TOOL::Reset( RESET_REASON aReason )
3806 {
3807 m_frame = getEditFrame<DISPLAY_FOOTPRINTS_FRAME>();
3808 }
3809
3810
3811-int CVPCB_SELECTION_TOOL::Main( const TOOL_EVENT& aEvent )
3812+int CVPCB_FOOTPRINT_VIEWER_SELECTION_TOOL::Main( const TOOL_EVENT& aEvent )
3813 {
3814 // Main loop: keep receiving events
3815 while( TOOL_EVENT* evt = Wait() )
3816@@ -102,18 +99,18 @@ int CVPCB_SELECTION_TOOL::Main( const TOOL_EVENT& aEvent )
3817 }
3818
3819
3820-int CVPCB_SELECTION_TOOL::MeasureTool( const TOOL_EVENT& aEvent )
3821+int CVPCB_FOOTPRINT_VIEWER_SELECTION_TOOL::MeasureTool( const TOOL_EVENT& aEvent )
3822 {
3823 auto& view = *getView();
3824 auto& controls = *getViewControls();
3825- auto previous_settings = controls.GetSettings();
3826+ auto previous_settings = controls.GetSettings();
3827
3828 std::string tool = aEvent.GetCommandStr().get();
3829 m_frame->PushTool( tool );
3830 Activate();
3831
3832 KIGFX::PREVIEW::TWO_POINT_GEOMETRY_MANAGER twoPtMgr;
3833- KIGFX::PREVIEW::RULER_ITEM ruler( twoPtMgr, m_frame->GetUserUnits() );
3834+ KIGFX::PREVIEW::RULER_ITEM ruler( twoPtMgr, m_frame->GetUserUnits() );
3835
3836 view.Add( &ruler );
3837 view.SetVisible( &ruler, false );
3838@@ -129,7 +126,7 @@ int CVPCB_SELECTION_TOOL::MeasureTool( const TOOL_EVENT& aEvent )
3839 m_frame->GetCanvas()->SetCurrentCursor( wxCURSOR_ARROW );
3840 const VECTOR2I cursorPos = controls.GetCursorPosition();
3841
3842- auto clearRuler = [&] () {
3843+ auto clearRuler = [&]() {
3844 view.SetVisible( &ruler, false );
3845 controls.SetAutoPan( false );
3846 controls.CaptureCursor( false );
3847@@ -223,9 +220,9 @@ int CVPCB_SELECTION_TOOL::MeasureTool( const TOOL_EVENT& aEvent )
3848 return 0;
3849 }
3850
3851-void CVPCB_SELECTION_TOOL::setTransitions()
3852+void CVPCB_FOOTPRINT_VIEWER_SELECTION_TOOL::setTransitions()
3853 {
3854- Go( &CVPCB_SELECTION_TOOL::Main, CVPCB_ACTIONS::selectionActivate.MakeEvent() );
3855- Go( &CVPCB_SELECTION_TOOL::MeasureTool, ACTIONS::measureTool.MakeEvent() );
3856+ Go( &CVPCB_FOOTPRINT_VIEWER_SELECTION_TOOL::Main,
3857+ CVPCB_ACTIONS::selectionActivate.MakeEvent() );
3858+ Go( &CVPCB_FOOTPRINT_VIEWER_SELECTION_TOOL::MeasureTool, ACTIONS::measureTool.MakeEvent() );
3859 }
3860-
3861diff --git a/cvpcb/tools/cvpcb_selection_tool.h b/cvpcb/tools/cvpcb_fpviewer_selection_tool.h
3862similarity index 82%
3863rename from cvpcb/tools/cvpcb_selection_tool.h
3864rename to cvpcb/tools/cvpcb_fpviewer_selection_tool.h
3865index 55fb973..b85f6c3 100644
3866--- a/cvpcb/tools/cvpcb_selection_tool.h
3867+++ b/cvpcb/tools/cvpcb_fpviewer_selection_tool.h
3868@@ -17,25 +17,27 @@
3869 * with this program. If not, see <http://www.gnu.org/licenses/>.
3870 */
3871
3872-#ifndef CVPCB_SELECTION_TOOL_H
3873-#define CVPCB_SELECTION_TOOL_H
3874+#ifndef CVPCB_FOOTPRINT_VIEWER_SELECTION_TOOL_H_
3875+#define CVPCB_FOOTPRINT_VIEWER_SELECTION_TOOL_H_
3876
3877+#include <display_footprints_frame.h>
3878
3879-#include <tool/tool_interactive.h>
3880 #include <tool/action_menu.h>
3881 #include <tool/selection.h>
3882+#include <tool/tool_interactive.h>
3883 #include <tool/tool_menu.h>
3884-#include <display_footprints_frame.h>
3885
3886
3887 /**
3888- * Class CVPCB_SELECTION_TOOL
3889+ * Class CVPCB_FOOTPRINT_VIEWER_SELECTION_TOOL
3890+ *
3891+ * Selection tool for the footprint viewer in cvpcb.
3892 */
3893-class CVPCB_SELECTION_TOOL : public TOOL_INTERACTIVE
3894+class CVPCB_FOOTPRINT_VIEWER_SELECTION_TOOL : public TOOL_INTERACTIVE
3895 {
3896 public:
3897- CVPCB_SELECTION_TOOL();
3898- ~CVPCB_SELECTION_TOOL() { }
3899+ CVPCB_FOOTPRINT_VIEWER_SELECTION_TOOL();
3900+ ~CVPCB_FOOTPRINT_VIEWER_SELECTION_TOOL() {}
3901
3902 /// @copydoc TOOL_BASE::Init()
3903 bool Init() override;
3904@@ -53,8 +55,12 @@ public:
3905 /**
3906 * Selections aren't currently supported in the footprint viewer.
3907 */
3908- SELECTION& GetSelection() { return m_selection; }
3909- void clearSelection() {};
3910+ SELECTION& GetSelection()
3911+ {
3912+ return m_selection;
3913+ }
3914+
3915+ void clearSelection() {}
3916
3917 ///> Launches a tool to measure between points
3918 int MeasureTool( const TOOL_EVENT& aEvent );
3919@@ -63,6 +69,7 @@ public:
3920 void setTransitions() override;
3921
3922 private:
3923+ /// Pointer to the parent frame.
3924 DISPLAY_FOOTPRINTS_FRAME* m_frame;
3925
3926 /// Current state of selection (not really used: no selection in display footprints frame).
3927diff --git a/include/tool/action_toolbar.h b/include/tool/action_toolbar.h
3928index 7e78ad3..3258962 100644
3929--- a/include/tool/action_toolbar.h
3930+++ b/include/tool/action_toolbar.h
3931@@ -25,6 +25,7 @@
3932 #define ACTION_TOOLBAR_H
3933
3934 #include <map>
3935+#include <wx/bitmap.h> // Needed for the auibar include
3936 #include <wx/aui/auibar.h>
3937 #include <tool/tool_event.h>
3938
3939@@ -52,11 +53,11 @@ public:
3940 * a TOOL_EVENT command containing name of the action is sent.
3941 */
3942 void Add( const TOOL_ACTION& aAction, bool aIsToggleEntry = false );
3943-
3944+
3945 /**
3946 * Function AddButton()
3947 * Adds a large button such as used in the Kicad Manager Frame's launch bar.
3948- * @param aAction
3949+ * @param aAction
3950 */
3951 void AddButton( const TOOL_ACTION& aAction );
3952
3953@@ -66,7 +67,7 @@ public:
3954 * for the custom-drawn layer pair bitmap.
3955 */
3956 void SetToolBitmap( const TOOL_ACTION& aAction, const wxBitmap& aBitmap );
3957-
3958+
3959 /**
3960 * Applies the default toggle action. For checked items this is check/uncheck; for
3961 * non-checked items it's enable/disable.
3962diff --git a/include/wildcards_and_files_ext.h b/include/wildcards_and_files_ext.h
3963index a8692ab..907a684 100644
3964--- a/include/wildcards_and_files_ext.h
3965+++ b/include/wildcards_and_files_ext.h
3966@@ -104,6 +104,7 @@ extern const std::string NetlistFileExtension;
3967 extern const std::string GerberFileExtension;
3968 extern const std::string GerberJobFileExtension;
3969 extern const std::string HtmlFileExtension;
3970+extern const std::string EquFileExtension;
3971
3972 extern const std::string LegacyPcbFileExtension;
3973 extern const std::string KiCadPcbFileExtension;

Subscribers

People subscribed via source and target branches

to status/vote changes: