KiCad PCB EDA Suite
Loading...
Searching...
No Matches
global_edit_tool.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright The KiCad Developers, see AUTHORS.TXT for contributors.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <https://www.gnu.org/licenses/>.
18 */
19
21#include <footprint.h>
22#include <pcb_track.h>
23#include <pcb_generator.h>
24#include <tool/tool_manager.h>
25#include <tools/pcb_actions.h>
26#include <tools/edit_tool.h>
36#include <pcb_edit_frame.h>
37
38
40 PCB_TOOL_BASE( "pcbnew.GlobalEdit" ),
41 m_selectionTool( nullptr )
42{
43}
44
45
47{
48 if( aReason != RUN )
49 m_commit = std::make_unique<BOARD_COMMIT>( this );
50}
51
52
54{
55 // Find the selection tool, so they can cooperate
57
58 return true;
59}
60
61
63{
65 PCB_SELECTION& selection = m_selectionTool->GetSelection();
66 FOOTPRINT* footprint = nullptr;
67 bool updateMode = false;
68 bool currentMode = false;
69
70 if( aEvent.HasPosition() )
71 selection = m_selectionTool->RequestSelection( EDIT_TOOL::FootprintFilter );
72
73 if( !selection.Empty() )
74 footprint = selection.FirstOfKind<FOOTPRINT>();
75
77 {
78 updateMode = true;
79 currentMode = true;
80 }
81 else if( aEvent.IsAction( &PCB_ACTIONS::updateFootprints ) )
82 {
83 updateMode = true;
84 currentMode = selection.CountType( PCB_FOOTPRINT_T ) > 0;
85 }
86 else if( aEvent.IsAction( &PCB_ACTIONS::changeFootprint ) )
87 {
88 updateMode = false;
89 currentMode = true;
90 }
91 else if( aEvent.IsAction( &PCB_ACTIONS::changeFootprints ) )
92 {
93 updateMode = false;
94 currentMode = selection.CountType( PCB_FOOTPRINT_T ) > 0;
95 }
96 else
97 {
98 wxFAIL_MSG( wxT( "ExchangeFootprints: unexpected action" ) );
99 }
100
101 DIALOG_EXCHANGE_FOOTPRINTS dialog( editFrame, footprint, updateMode, currentMode );
102 dialog.ShowQuasiModal();
103
104 return 0;
105}
106
107
108bool GLOBAL_EDIT_TOOL::swapBoardItem( BOARD_ITEM* aItem, std::map<PCB_LAYER_ID, PCB_LAYER_ID>& aLayerMap )
109{
110 LSET originalLayers = aItem->GetLayerSet();
111 LSET newLayers;
112
113 for( PCB_LAYER_ID original : originalLayers )
114 {
115 if( aLayerMap.count( original ) )
116 newLayers.set( aLayerMap[ original ] );
117 else
118 newLayers.set( original );
119 }
120
121 if( originalLayers != newLayers )
122 {
123 m_commit->Modify( aItem, nullptr, RECURSE_MODE::RECURSE );
124 aItem->SetLayerSet( newLayers );
125 frame()->GetCanvas()->GetView()->Update( aItem, KIGFX::GEOMETRY );
126 return true;
127 }
128
129 return false;
130}
131
132
134{
135 std::map<PCB_LAYER_ID, PCB_LAYER_ID> layerMap;
136
137 DIALOG_SWAP_LAYERS dlg( frame(), layerMap );
138
139 if( dlg.ShowModal() != wxID_OK )
140 return 0;
141
142 bool hasChanges = false;
143
144 // Change tracks.
145 for( PCB_TRACK* segm : frame()->GetBoard()->Tracks() )
146 {
147 if( dynamic_cast<PCB_GENERATOR*>( segm->GetParentGroup() ) )
148 continue;
149
150 if( segm->Type() == PCB_VIA_T )
151 {
152 PCB_VIA* via = static_cast<PCB_VIA*>( segm );
153 PCB_LAYER_ID top_layer, bottom_layer;
154
155 if( via->GetViaType() == VIATYPE::THROUGH )
156 continue;
157
158 via->LayerPair( &top_layer, &bottom_layer );
159
160 if( layerMap[bottom_layer] != bottom_layer || layerMap[top_layer] != top_layer )
161 {
162 m_commit->Modify( via );
163 via->SetLayerPair( layerMap[top_layer], layerMap[bottom_layer] );
164 frame()->GetCanvas()->GetView()->Update( via, KIGFX::GEOMETRY );
165 hasChanges = true;
166 }
167 }
168 else
169 {
170 hasChanges |= swapBoardItem( segm, layerMap );
171 }
172 }
173
174 for( PCB_GENERATOR* generator : frame()->GetBoard()->Generators() )
175 hasChanges |= swapBoardItem( generator, layerMap );
176
177 for( BOARD_ITEM* zone : frame()->GetBoard()->Zones() )
178 hasChanges |= swapBoardItem( zone, layerMap );
179
180 for( BOARD_ITEM* drawing : frame()->GetBoard()->Drawings() )
181 hasChanges |= swapBoardItem( drawing, layerMap );
182
183 if( hasChanges )
184 {
185 frame()->OnModify();
186 m_commit->Push( _( "Swap Layers" ) );
187 frame()->GetCanvas()->Refresh();
188 }
189
190 return 0;
191}
192
193
195{
197 DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS dlg( editFrame );
198
199 dlg.ShowQuasiModal(); // QuasiModal required for NET_SELECTOR
200 return 0;
201}
202
203
205{
207 DIALOG_CLEANUP_TRACKS_AND_VIAS dlg( editFrame );
208
209 dlg.ShowModal();
210 return 0;
211}
212
213
215{
217 DIALOG_CLEANUP_GRAPHICS dlg( editFrame, false );
218
219 dlg.ShowModal();
220 return 0;
221}
222
223
225{
227 PCB_SELECTION& selection = m_selectionTool->RequestSelection(
228 []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector, PCB_SELECTION_TOOL* sTool )
229 {
230 sTool->FilterCollectorForHierarchy( aCollector, true );
231 } );
232 DIALOG_UNUSED_PAD_LAYERS dlg( editFrame, selection, *m_commit );
233
234 dlg.ShowModal();
235
236 return 0;
237}
238
240{
242 BOARD_COMMIT commit( editFrame );
243 BOARD* board = editFrame->GetBoard();
244
245 for( ZONE* zone : board->Zones() )
246 commit.Modify( zone );
247
248 DIALOG_ZONE_MANAGER dlg( editFrame );
249
250 int dialogResult = dlg.ShowQuasiModal();
251
252 if( dialogResult == wxID_OK && dlg.GetRepourOnClose() )
253 dialogResult = ZONE_MANAGER_REPOUR;
254
255 if( dialogResult == wxID_CANCEL )
256 {
257 // The dialog hides zones in the view when they are marked for deletion
258 if( KIGFX::VIEW* view = editFrame->GetCanvas()->GetView() )
259 {
260 for( ZONE* zone : dlg.GetZonesToDelete() )
261 view->Hide( zone, false );
262 }
263
264 editFrame->GetCanvas()->Refresh();
265 return 0;
266 }
267
268 // Promote the pre-staged CHT_MODIFY entries for any zone the user marked for deletion
269 if( KIGFX::VIEW* view = editFrame->GetCanvas()->GetView() )
270 {
271 for( ZONE* zone : dlg.GetZonesToDelete() )
272 {
273 view->Hide( zone, false );
274
275 commit.Unmodify( zone, nullptr );
276 commit.Remove( zone );
277 }
278 }
279
280 // Ensure all zones are deselected before make any change in view, to avoid
281 // dangling pointers in EDIT_POINT
283 selTool->ClearSelection();
284
285 wxBusyCursor dummy;
286
287 // Clear the zone bounding box cache before Push() updates the VIEW, otherwise
288 // View->Update() will query stale cached values and the VIEW's R-Tree will be
289 // indexed with incorrect bounding boxes, causing single-click zone selection to fail.
290 board->IncrementTimeStamp();
291
292 commit.Push( _( "Zone Manager" ), SKIP_CONNECTIVITY );
293
294 board->BuildConnectivity();
295
296 if( TOOL_MANAGER* manager = GetManager() )
297 manager->PostEvent( EVENTS::ConnectivityChangedEvent );
298
299 editFrame->GetCanvas()->RedrawRatsnest();
300
301 if( dialogResult == ZONE_MANAGER_REPOUR )
302 {
303 if( TOOL_MANAGER* manager = GetManager() )
304 manager->PostAction( PCB_ACTIONS::zoneFillAll );
305 }
306
307 return 0;
308}
309
310
311
313{
315
316 if( !editFrame )
317 return 0;
318
319 DIALOG_MIGRATE_3D_MODELS dlg( editFrame );
320 dlg.ShowModal();
321 return 0;
322}
323
324
344
345
BASE_SET & set(size_t pos)
Definition base_set.h:126
void Push(const wxString &aMessage=wxEmptyString, int aCommitFlags=0) override
Execute the changes.
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition board_item.h:84
virtual void SetLayerSet(const LSET &aLayers)
Definition board_item.h:354
virtual LSET GetLayerSet() const
Return a std::bitset of all layers on which the item physically resides.
Definition board_item.h:346
Information pertinent to a Pcbnew printed circuit board.
Definition board.h:410
COMMIT & Remove(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Remove a new item from the model.
Definition commit.h:86
void Unmodify(EDA_ITEM *aItem, BASE_SCREEN *aScreen)
Definition commit.cpp:200
COMMIT & Modify(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr, RECURSE_MODE aRecurse=RECURSE_MODE::NO_RECURSE)
Modify a given item in the model.
Definition commit.h:102
Dialog that offers to migrate obsolete WRL 3D model references on a loaded board to current STEP mode...
int ShowModal() override
const std::vector< ZONE * > & GetZonesToDelete() const
virtual void Refresh(bool aEraseBackground=true, const wxRect *aRect=nullptr) override
static const TOOL_EVENT ConnectivityChangedEvent
Definition actions.h:349
Used when the right click button is pressed, or when the select tool is in effect.
Definition collectors.h:203
int ZonesManager(const TOOL_EVENT &aEvent)
int EditTracksAndVias(const TOOL_EVENT &aEvent)
int CleanupGraphics(const TOOL_EVENT &aEvent)
bool Init() override
Init() is called once upon a registration of the tool.
bool swapBoardItem(BOARD_ITEM *aItem, std::map< PCB_LAYER_ID, PCB_LAYER_ID > &aLayerMap)
Set up handlers for various events.
int ExchangeFootprints(const TOOL_EVENT &aEvent)
Invoke the dialog used to update or exchange the footprint definitions used for footprints.
std::unique_ptr< BOARD_COMMIT > m_commit
void setTransitions() override
This method is meant to be overridden in order to specify handlers for events.
void Reset(RESET_REASON aReason) override
Bring the tool to a known, initial state.
int GlobalDeletions(const TOOL_EVENT &aEvent)
int Migrate3DModels(const TOOL_EVENT &aEvent)
int CleanupTracksAndVias(const TOOL_EVENT &aEvent)
int SwapLayers(const TOOL_EVENT &aEvent)
int EditTeardrops(const TOOL_EVENT &aEvent)
PCB_SELECTION_TOOL * m_selectionTool
int RemoveUnusedPads(const TOOL_EVENT &aEvent)
Hold a (potentially large) number of VIEW_ITEMs and renders them on a graphics device provided by the...
Definition view.h:63
LSET is a set of PCB_LAYER_IDs.
Definition lset.h:37
static TOOL_ACTION editTracksAndVias
static TOOL_ACTION swapLayers
static TOOL_ACTION zonesManager
static TOOL_ACTION zoneFillAll
static TOOL_ACTION updateFootprint
static TOOL_ACTION migrate3DModels
static TOOL_ACTION cleanupTracksAndVias
static TOOL_ACTION editTextAndGraphics
static TOOL_ACTION globalDeletions
static TOOL_ACTION updateFootprints
static TOOL_ACTION removeUnusedPads
static TOOL_ACTION changeFootprints
static TOOL_ACTION changeFootprint
static TOOL_ACTION editTeardrops
static TOOL_ACTION cleanupGraphics
PCB_DRAW_PANEL_GAL * GetCanvas() const override
Return a pointer to GAL-based canvas of given EDA draw frame.
BOARD * GetBoard() const
virtual KIGFX::PCB_VIEW * GetView() const override
Return a pointer to the KIGFX::VIEW instance used in the panel.
void RedrawRatsnest()
Force refresh of the ratsnest visual representation.
The main frame for Pcbnew.
The selection tool: currently supports:
void FilterCollectorForHierarchy(GENERAL_COLLECTOR &aCollector, bool aMultiselect) const
In general we don't want to select both a parent and any of it's children.
int ClearSelection(const TOOL_EVENT &aEvent)
Clear current selection event handler.
T * frame() const
KIGFX::PCB_VIEW * view() const
PCB_TOOL_BASE(TOOL_ID aId, const std::string &aName)
Constructor.
BOARD * board() const
const PCB_SELECTION & selection() const
FOOTPRINT * footprint() const
TOOL_MANAGER * GetToolManager() const
Return the MVC controller.
TOOL_MANAGER * GetManager() const
Return the instance of TOOL_MANAGER that takes care of the tool.
Definition tool_base.h:142
T * getEditFrame() const
Return the application window object, casted to requested user type.
Definition tool_base.h:182
TOOL_MANAGER * m_toolMgr
Definition tool_base.h:220
RESET_REASON
Determine the reason of reset for a tool.
Definition tool_base.h:74
@ RUN
Tool is invoked after being inactive.
Definition tool_base.h:75
Generic, UI-independent tool event.
Definition tool_event.h:167
bool HasPosition() const
Returns if it this event has a valid position (true for mouse events and context-menu or hotkey-based...
Definition tool_event.h:256
bool IsAction(const TOOL_ACTION *aAction) const
Test if the event contains an action issued upon activation of the given TOOL_ACTION.
void Go(int(T::*aStateFunc)(const TOOL_EVENT &), const TOOL_EVENT_LIST &aConditions=TOOL_EVENT(TC_ANY, TA_ANY))
Define which state (aStateFunc) to go when a certain event arrives (aConditions).
friend class TOOL_MANAGER
T * GetTool()
Return the tool of given type or nullptr if there is no such tool registered.
Handle a list of polygons defining a copper zone.
Definition zone.h:70
#define _(s)
@ RECURSE
Definition eda_item.h:51
PCB_LAYER_ID
A quick note on layer IDs:
Definition layer_ids.h:56
@ GEOMETRY
Position or shape has changed.
Definition view_item.h:51
#define SKIP_CONNECTIVITY
Definition sch_commit.h:41
std::vector< FAB_LAYER_COLOR > dummy
@ PCB_VIA_T
class PCB_VIA, a via (like a track segment on a copper layer)
Definition typeinfo.h:89
@ PCB_FOOTPRINT_T
class FOOTPRINT, a footprint
Definition typeinfo.h:78
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:708
#define ZONE_MANAGER_REPOUR
Definition zones.h:39