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
virtual 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:409
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:197
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
Selected item had a property changed (except movement)
Definition actions.h:347
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 #VIEW instance used in the panel.
void RedrawRatsnest()
Return the bounding box of the view that should be used if model is not valid.
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)
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
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:683
#define ZONE_MANAGER_REPOUR
Definition zones.h:39