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>
40#include <pcb_edit_frame.h>
41
42
44 PCB_TOOL_BASE( "pcbnew.GlobalEdit" ),
45 m_selectionTool( nullptr )
46{
47}
48
49
51{
52 if( aReason != RUN )
53 m_commit = std::make_unique<BOARD_COMMIT>( this );
54}
55
56
58{
59 // Find the selection tool, so they can cooperate
61
62 return true;
63}
64
65
67{
69 PCB_SELECTION& selection = m_selectionTool->GetSelection();
70 FOOTPRINT* footprint = nullptr;
71 bool updateMode = false;
72 bool currentMode = false;
73
74 if( aEvent.HasPosition() )
75 selection = m_selectionTool->RequestSelection( EDIT_TOOL::FootprintFilter );
76
77 if( !selection.Empty() )
78 footprint = selection.FirstOfKind<FOOTPRINT>();
79
81 {
82 updateMode = true;
83 currentMode = true;
84 }
85 else if( aEvent.IsAction( &PCB_ACTIONS::updateFootprints ) )
86 {
87 updateMode = true;
88 currentMode = selection.CountType( PCB_FOOTPRINT_T ) > 0;
89 }
90 else if( aEvent.IsAction( &PCB_ACTIONS::changeFootprint ) )
91 {
92 updateMode = false;
93 currentMode = true;
94 }
95 else if( aEvent.IsAction( &PCB_ACTIONS::changeFootprints ) )
96 {
97 updateMode = false;
98 currentMode = selection.CountType( PCB_FOOTPRINT_T ) > 0;
99 }
100 else
101 {
102 wxFAIL_MSG( wxT( "ExchangeFootprints: unexpected action" ) );
103 }
104
105 DIALOG_EXCHANGE_FOOTPRINTS dialog( editFrame, footprint, updateMode, currentMode );
106 dialog.ShowQuasiModal();
107
108 return 0;
109}
110
111
112bool GLOBAL_EDIT_TOOL::swapBoardItem( BOARD_ITEM* aItem, std::map<PCB_LAYER_ID, PCB_LAYER_ID>& aLayerMap )
113{
114 LSET originalLayers = aItem->GetLayerSet();
115 LSET newLayers;
116
117 for( PCB_LAYER_ID original : originalLayers )
118 {
119 if( aLayerMap.count( original ) )
120 newLayers.set( aLayerMap[ original ] );
121 else
122 newLayers.set( original );
123 }
124
125 if( originalLayers != newLayers )
126 {
127 m_commit->Modify( aItem );
128 aItem->SetLayerSet( newLayers );
129 frame()->GetCanvas()->GetView()->Update( aItem, KIGFX::GEOMETRY );
130 return true;
131 }
132
133 return false;
134}
135
136
138{
139 std::map<PCB_LAYER_ID, PCB_LAYER_ID> layerMap;
140
141 DIALOG_SWAP_LAYERS dlg( frame(), layerMap );
142
143 if( dlg.ShowModal() != wxID_OK )
144 return 0;
145
146 bool hasChanges = false;
147
148 // Change tracks.
149 for( PCB_TRACK* segm : frame()->GetBoard()->Tracks() )
150 {
151 if( segm->Type() == PCB_VIA_T )
152 {
153 PCB_VIA* via = static_cast<PCB_VIA*>( segm );
154 PCB_LAYER_ID top_layer, bottom_layer;
155
156 if( via->GetViaType() == VIATYPE::THROUGH )
157 continue;
158
159 via->LayerPair( &top_layer, &bottom_layer );
160
161 if( layerMap[bottom_layer] != bottom_layer || layerMap[top_layer] != top_layer )
162 {
163 m_commit->Modify( via );
164 via->SetLayerPair( layerMap[top_layer], layerMap[bottom_layer] );
165 frame()->GetCanvas()->GetView()->Update( via, KIGFX::GEOMETRY );
166 hasChanges = true;
167 }
168 }
169 else
170 {
171 hasChanges |= swapBoardItem( segm, layerMap );
172 }
173 }
174
175 for( PCB_GENERATOR* generator : frame()->GetBoard()->Generators() )
176 hasChanges |= swapBoardItem( generator, layerMap );
177
178 for( BOARD_ITEM* zone : frame()->GetBoard()->Zones() )
179 hasChanges |= swapBoardItem( zone, layerMap );
180
181 for( BOARD_ITEM* drawing : frame()->GetBoard()->Drawings() )
182 hasChanges |= swapBoardItem( drawing, layerMap );
183
184 if( hasChanges )
185 {
186 frame()->OnModify();
187 m_commit->Push( _( "Swap Layers" ) );
188 frame()->GetCanvas()->Refresh();
189 }
190
191 return 0;
192}
193
194
196{
198 DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS dlg( editFrame );
199
200 dlg.ShowQuasiModal(); // QuasiModal required for NET_SELECTOR
201 return 0;
202}
203
204
206{
208 DIALOG_CLEANUP_TRACKS_AND_VIAS dlg( editFrame );
209
210 dlg.ShowModal();
211 return 0;
212}
213
214
216{
218 DIALOG_CLEANUP_GRAPHICS dlg( editFrame, false );
219
220 dlg.ShowModal();
221 return 0;
222}
223
224
226{
228 PCB_SELECTION& selection = m_selectionTool->RequestSelection(
229 []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector, PCB_SELECTION_TOOL* sTool )
230 {
231 sTool->FilterCollectorForHierarchy( aCollector, true );
232 } );
233 DIALOG_UNUSED_PAD_LAYERS dlg( editFrame, selection, *m_commit );
234
235 dlg.ShowModal();
236
237 return 0;
238}
239
241{
243 BOARD_COMMIT commit( editFrame );
244 BOARD* board = editFrame->GetBoard();
245
246 for( ZONE* zone : board->Zones() )
247 commit.Modify( zone );
248
249 DIALOG_ZONE_MANAGER dlg( editFrame );
250
251 int dialogResult = dlg.ShowQuasiModal();
252
253 if( dialogResult == wxID_OK && dlg.GetRepourOnClose() )
254 dialogResult = ZONE_MANAGER_REPOUR;
255
256 if( dialogResult == wxID_CANCEL )
257 return 0;
258
259 // Ensure all zones are deselected before make any change in view, to avoid
260 // dangling pointers in EDIT_POINT
262 selTool->ClearSelection();
263
264 wxBusyCursor dummy;
265
266 // Clear the zone bounding box cache before Push() updates the VIEW, otherwise
267 // View->Update() will query stale cached values and the VIEW's R-Tree will be
268 // indexed with incorrect bounding boxes, causing single-click zone selection to fail.
269 board->IncrementTimeStamp();
270
271 commit.Push( _( "Zone Manager" ), SKIP_CONNECTIVITY );
272
273 board->BuildConnectivity();
274
275 if( TOOL_MANAGER* manager = GetManager() )
276 manager->PostEvent( EVENTS::ConnectivityChangedEvent );
277
278 editFrame->GetCanvas()->RedrawRatsnest();
279
280 if( dialogResult == ZONE_MANAGER_REPOUR )
281 {
282 if( TOOL_MANAGER* manager = GetManager() )
283 manager->PostAction( PCB_ACTIONS::zoneFillAll );
284 }
285
286 return 0;
287}
288
289
290
292{
294
295 if( !editFrame )
296 return 0;
297
298 DIALOG_MIGRATE_3D_MODELS dlg( editFrame );
299 dlg.ShowModal();
300 return 0;
301}
302
303
323
324
#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
Dialog that offers to migrate obsolete WRL 3D model references on a loaded board to current STEP mode...
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 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)
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
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