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 );
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( segm->Type() == PCB_VIA_T )
148 {
149 PCB_VIA* via = static_cast<PCB_VIA*>( segm );
150 PCB_LAYER_ID top_layer, bottom_layer;
151
152 if( via->GetViaType() == VIATYPE::THROUGH )
153 continue;
154
155 via->LayerPair( &top_layer, &bottom_layer );
156
157 if( layerMap[bottom_layer] != bottom_layer || layerMap[top_layer] != top_layer )
158 {
159 m_commit->Modify( via );
160 via->SetLayerPair( layerMap[top_layer], layerMap[bottom_layer] );
161 frame()->GetCanvas()->GetView()->Update( via, KIGFX::GEOMETRY );
162 hasChanges = true;
163 }
164 }
165 else
166 {
167 hasChanges |= swapBoardItem( segm, layerMap );
168 }
169 }
170
171 for( PCB_GENERATOR* generator : frame()->GetBoard()->Generators() )
172 hasChanges |= swapBoardItem( generator, layerMap );
173
174 for( BOARD_ITEM* zone : frame()->GetBoard()->Zones() )
175 hasChanges |= swapBoardItem( zone, layerMap );
176
177 for( BOARD_ITEM* drawing : frame()->GetBoard()->Drawings() )
178 hasChanges |= swapBoardItem( drawing, layerMap );
179
180 if( hasChanges )
181 {
182 frame()->OnModify();
183 m_commit->Push( _( "Swap Layers" ) );
184 frame()->GetCanvas()->Refresh();
185 }
186
187 return 0;
188}
189
190
192{
194 DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS dlg( editFrame );
195
196 dlg.ShowQuasiModal(); // QuasiModal required for NET_SELECTOR
197 return 0;
198}
199
200
202{
204 DIALOG_CLEANUP_TRACKS_AND_VIAS dlg( editFrame );
205
206 dlg.ShowModal();
207 return 0;
208}
209
210
212{
214 DIALOG_CLEANUP_GRAPHICS dlg( editFrame, false );
215
216 dlg.ShowModal();
217 return 0;
218}
219
220
222{
224 PCB_SELECTION& selection = m_selectionTool->RequestSelection(
225 []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector, PCB_SELECTION_TOOL* sTool )
226 {
227 sTool->FilterCollectorForHierarchy( aCollector, true );
228 } );
229 DIALOG_UNUSED_PAD_LAYERS dlg( editFrame, selection, *m_commit );
230
231 dlg.ShowModal();
232
233 return 0;
234}
235
237{
239 BOARD_COMMIT commit( editFrame );
240 BOARD* board = editFrame->GetBoard();
241
242 for( ZONE* zone : board->Zones() )
243 commit.Modify( zone );
244
245 DIALOG_ZONE_MANAGER dlg( editFrame );
246
247 int dialogResult = dlg.ShowQuasiModal();
248
249 if( dialogResult == wxID_OK && dlg.GetRepourOnClose() )
250 dialogResult = ZONE_MANAGER_REPOUR;
251
252 if( dialogResult == wxID_CANCEL )
253 {
254 // The dialog hides zones in the view when they are marked for deletion
255 if( KIGFX::VIEW* view = editFrame->GetCanvas()->GetView() )
256 {
257 for( ZONE* zone : dlg.GetZonesToDelete() )
258 view->Hide( zone, false );
259 }
260
261 editFrame->GetCanvas()->Refresh();
262 return 0;
263 }
264
265 // Promote the pre-staged CHT_MODIFY entries for any zone the user marked for deletion
266 if( KIGFX::VIEW* view = editFrame->GetCanvas()->GetView() )
267 {
268 for( ZONE* zone : dlg.GetZonesToDelete() )
269 {
270 view->Hide( zone, false );
271
272 commit.Unmodify( zone, nullptr );
273 commit.Remove( zone );
274 }
275 }
276
277 // Ensure all zones are deselected before make any change in view, to avoid
278 // dangling pointers in EDIT_POINT
280 selTool->ClearSelection();
281
282 wxBusyCursor dummy;
283
284 // Clear the zone bounding box cache before Push() updates the VIEW, otherwise
285 // View->Update() will query stale cached values and the VIEW's R-Tree will be
286 // indexed with incorrect bounding boxes, causing single-click zone selection to fail.
287 board->IncrementTimeStamp();
288
289 commit.Push( _( "Zone Manager" ), SKIP_CONNECTIVITY );
290
291 board->BuildConnectivity();
292
293 if( TOOL_MANAGER* manager = GetManager() )
294 manager->PostEvent( EVENTS::ConnectivityChangedEvent );
295
296 editFrame->GetCanvas()->RedrawRatsnest();
297
298 if( dialogResult == ZONE_MANAGER_REPOUR )
299 {
300 if( TOOL_MANAGER* manager = GetManager() )
301 manager->PostAction( PCB_ACTIONS::zoneFillAll );
302 }
303
304 return 0;
305}
306
307
308
310{
312
313 if( !editFrame )
314 return 0;
315
316 DIALOG_MIGRATE_3D_MODELS dlg( editFrame );
317 dlg.ShowModal();
318 return 0;
319}
320
321
341
342
#define SKIP_CONNECTIVITY
BASE_SET & set(size_t pos)
Definition base_set.h:116
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:81
virtual void SetLayerSet(const LSET &aLayers)
Definition board_item.h:293
virtual LSET GetLayerSet() const
Return a std::bitset of all layers on which the item physically resides.
Definition board_item.h:285
Information pertinent to a Pcbnew printed circuit board.
Definition board.h:372
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:156
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:345
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)
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
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:90
@ PCB_FOOTPRINT_T
class FOOTPRINT, a footprint
Definition typeinfo.h:79
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:683
#define ZONE_MANAGER_REPOUR
Definition zones.h:39