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, you may find one here:
18 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
19 * or you may search the http://www.gnu.org website for the version 2 license,
20 * or you may write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22 */
23
25#include <footprint.h>
26#include <pcb_track.h>
27#include <pcb_generator.h>
28#include <tool/tool_manager.h>
29#include <tools/pcb_actions.h>
30#include <tools/edit_tool.h>
39
40
42 PCB_TOOL_BASE( "pcbnew.GlobalEdit" ),
43 m_selectionTool( nullptr )
44{
45}
46
47
49{
50 if( aReason != RUN )
51 m_commit = std::make_unique<BOARD_COMMIT>( this );
52}
53
54
56{
57 // Find the selection tool, so they can cooperate
59
60 return true;
61}
62
63
65{
67 PCB_SELECTION& selection = m_selectionTool->GetSelection();
68 FOOTPRINT* footprint = nullptr;
69 bool updateMode = false;
70 bool currentMode = false;
71
72 if( aEvent.HasPosition() )
73 selection = m_selectionTool->RequestSelection( EDIT_TOOL::FootprintFilter );
74
75 if( !selection.Empty() )
76 footprint = selection.FirstOfKind<FOOTPRINT>();
77
79 {
80 updateMode = true;
81 currentMode = true;
82 }
83 else if( aEvent.IsAction( &PCB_ACTIONS::updateFootprints ) )
84 {
85 updateMode = true;
86 currentMode = selection.CountType( PCB_FOOTPRINT_T ) > 0;
87 }
88 else if( aEvent.IsAction( &PCB_ACTIONS::changeFootprint ) )
89 {
90 updateMode = false;
91 currentMode = true;
92 }
93 else if( aEvent.IsAction( &PCB_ACTIONS::changeFootprints ) )
94 {
95 updateMode = false;
96 currentMode = selection.CountType( PCB_FOOTPRINT_T ) > 0;
97 }
98 else
99 {
100 wxFAIL_MSG( wxT( "ExchangeFootprints: unexpected action" ) );
101 }
102
103 DIALOG_EXCHANGE_FOOTPRINTS dialog( editFrame, footprint, updateMode, currentMode );
104 dialog.ShowQuasiModal();
105
106 return 0;
107}
108
109
110bool GLOBAL_EDIT_TOOL::swapBoardItem( BOARD_ITEM* aItem, std::map<PCB_LAYER_ID, PCB_LAYER_ID>& aLayerMap )
111{
112 LSET originalLayers = aItem->GetLayerSet();
113 LSET newLayers;
114
115 for( PCB_LAYER_ID original : originalLayers )
116 {
117 if( aLayerMap.count( original ) )
118 newLayers.set( aLayerMap[ original ] );
119 else
120 newLayers.set( original );
121 }
122
123 if( originalLayers != newLayers )
124 {
125 m_commit->Modify( aItem );
126 aItem->SetLayerSet( newLayers );
127 frame()->GetCanvas()->GetView()->Update( aItem, KIGFX::GEOMETRY );
128 return true;
129 }
130
131 return false;
132}
133
134
136{
137 std::map<PCB_LAYER_ID, PCB_LAYER_ID> layerMap;
138
139 DIALOG_SWAP_LAYERS dlg( frame(), layerMap );
140
141 if( dlg.ShowModal() != wxID_OK )
142 return 0;
143
144 bool hasChanges = false;
145
146 // Change tracks.
147 for( PCB_TRACK* segm : frame()->GetBoard()->Tracks() )
148 {
149 if( segm->Type() == PCB_VIA_T )
150 {
151 PCB_VIA* via = static_cast<PCB_VIA*>( segm );
152 PCB_LAYER_ID top_layer, bottom_layer;
153
154 if( via->GetViaType() == VIATYPE::THROUGH )
155 continue;
156
157 via->LayerPair( &top_layer, &bottom_layer );
158
159 if( layerMap[bottom_layer] != bottom_layer || layerMap[top_layer] != top_layer )
160 {
161 m_commit->Modify( via );
162 via->SetLayerPair( layerMap[top_layer], layerMap[bottom_layer] );
163 frame()->GetCanvas()->GetView()->Update( via, KIGFX::GEOMETRY );
164 hasChanges = true;
165 }
166 }
167 else
168 {
169 hasChanges |= swapBoardItem( segm, layerMap );
170 }
171 }
172
173 for( PCB_GENERATOR* generator : frame()->GetBoard()->Generators() )
174 hasChanges |= swapBoardItem( generator, layerMap );
175
176 for( BOARD_ITEM* zone : frame()->GetBoard()->Zones() )
177 hasChanges |= swapBoardItem( zone, layerMap );
178
179 for( BOARD_ITEM* drawing : frame()->GetBoard()->Drawings() )
180 hasChanges |= swapBoardItem( drawing, layerMap );
181
182 if( hasChanges )
183 {
184 frame()->OnModify();
185 m_commit->Push( _( "Swap Layers" ) );
186 frame()->GetCanvas()->Refresh();
187 }
188
189 return 0;
190}
191
192
194{
196 DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS dlg( editFrame );
197
198 dlg.ShowQuasiModal(); // QuasiModal required for NET_SELECTOR
199 return 0;
200}
201
202
204{
206 DIALOG_CLEANUP_TRACKS_AND_VIAS dlg( editFrame );
207
208 dlg.ShowModal();
209 return 0;
210}
211
212
214{
216 DIALOG_CLEANUP_GRAPHICS dlg( editFrame, false );
217
218 dlg.ShowModal();
219 return 0;
220}
221
222
224{
226 PCB_SELECTION& selection = m_selectionTool->RequestSelection(
227 []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector, PCB_SELECTION_TOOL* sTool )
228 {
229 sTool->FilterCollectorForHierarchy( aCollector, true );
230 } );
231 DIALOG_UNUSED_PAD_LAYERS dlg( editFrame, selection, *m_commit );
232
233 dlg.ShowModal();
234
235 return 0;
236}
237
239{
241 BOARD_COMMIT commit( editFrame );
242 BOARD* board = editFrame->GetBoard();
243
244 for( ZONE* zone : board->Zones() )
245 commit.Modify( zone );
246
247 DIALOG_ZONE_MANAGER dlg( editFrame );
248
249 int dialogResult = dlg.ShowQuasiModal();
250
251 if( dialogResult == wxID_OK && dlg.GetRepourOnClose() )
252 dialogResult = ZONE_MANAGER_REPOUR;
253
254 if( dialogResult == wxID_CANCEL )
255 return 0;
256
257 // Ensure all zones are deselected before make any change in view, to avoid
258 // dangling pointers in EDIT_POINT
260 selTool->ClearSelection();
261
262 wxBusyCursor dummy;
263
264 // Clear the zone bounding box cache before Push() updates the VIEW, otherwise
265 // View->Update() will query stale cached values and the VIEW's R-Tree will be
266 // indexed with incorrect bounding boxes, causing single-click zone selection to fail.
267 board->IncrementTimeStamp();
268
269 commit.Push( _( "Zone Manager" ), SKIP_CONNECTIVITY );
270
271 board->BuildConnectivity();
272
273 if( TOOL_MANAGER* manager = GetManager() )
274 manager->PostEvent( EVENTS::ConnectivityChangedEvent );
275
276 editFrame->GetCanvas()->RedrawRatsnest();
277
278 if( dialogResult == ZONE_MANAGER_REPOUR )
279 {
280 if( TOOL_MANAGER* manager = GetManager() )
281 manager->PostAction( PCB_ACTIONS::zoneFillAll );
282 }
283
284 return 0;
285}
286
287
288
307
308
#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:84
virtual void SetLayerSet(const LSET &aLayers)
Definition board_item.h:296
virtual LSET GetLayerSet() const
Return a std::bitset of all layers on which the item physically resides.
Definition board_item.h:288
Information pertinent to a Pcbnew printed circuit board.
Definition board.h:323
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:106
int ShowModal() override
static const TOOL_EVENT ConnectivityChangedEvent
Selected item had a property changed (except movement)
Definition actions.h:349
Used when the right click button is pressed, or when the select tool is in effect.
Definition collectors.h:207
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 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)
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 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
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
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:146
T * getEditFrame() const
Return the application window object, casted to requested user type.
Definition tool_base.h:186
TOOL_MANAGER * m_toolMgr
Definition tool_base.h:220
RESET_REASON
Determine the reason of reset for a tool.
Definition tool_base.h:78
@ RUN
Tool is invoked after being inactive.
Definition tool_base.h:79
Generic, UI-independent tool event.
Definition tool_event.h:171
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:260
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:74
#define _(s)
PCB_LAYER_ID
A quick note on layer IDs:
Definition layer_ids.h:60
@ GEOMETRY
Position or shape has changed.
Definition view_item.h:55
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:94
@ PCB_FOOTPRINT_T
class FOOTPRINT, a footprint
Definition typeinfo.h:83
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:687
#define ZONE_MANAGER_REPOUR
Definition zones.h:43