KiCad PCB EDA Suite
Loading...
Searching...
No Matches
board_commit.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 (C) 2016 CERN
5 * Copyright (C) 2020-2024 KiCad Developers, see AUTHORS.txt for contributors.
6 * @author Tomasz Wlostowski <[email protected]>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, you may find one here:
20 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
21 * or you may search the http://www.gnu.org website for the version 2 license,
22 * or you may write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
24 */
25
26#include <macros.h>
27#include <board.h>
28#include <footprint.h>
29#include <lset.h>
30#include <pcb_group.h>
31#include <pcb_track.h>
32#include <tool/tool_manager.h>
35#include <view/view.h>
36#include <board_commit.h>
37#include <tools/pcb_tool_base.h>
38#include <tools/pcb_actions.h>
40#include <teardrop/teardrop.h>
41
42#include <functional>
43using namespace std::placeholders;
44
45
47 m_toolMgr( aTool->GetManager() ),
48 m_isBoardEditor( false ),
49 m_isFootprintEditor( false )
50{
51 if( PCB_TOOL_BASE* pcb_tool = dynamic_cast<PCB_TOOL_BASE*>( aTool ) )
52 {
53 m_isBoardEditor = pcb_tool->IsBoardEditor();
54 m_isFootprintEditor = pcb_tool->IsFootprintEditor();
55 }
56}
57
58
60 m_toolMgr( aFrame->GetToolManager() ),
61 m_isBoardEditor( aFrame->IsType( FRAME_PCB_EDITOR ) ),
62 m_isFootprintEditor( aFrame->IsType( FRAME_FOOTPRINT_EDITOR ) )
63{
64}
65
66
68 m_toolMgr( aMgr ),
69 m_isBoardEditor( false ),
70 m_isFootprintEditor( false )
71{
72 EDA_DRAW_FRAME* frame = dynamic_cast<EDA_DRAW_FRAME*>( aMgr->GetToolHolder() );
73
74 if( frame && frame->IsType( FRAME_PCB_EDITOR ) )
75 m_isBoardEditor = true;
76 else if( frame && frame->IsType( FRAME_FOOTPRINT_EDITOR ) )
78}
79
80BOARD_COMMIT::BOARD_COMMIT( TOOL_MANAGER* aMgr, bool aIsBoardEditor ) :
81 m_toolMgr( aMgr ),
82 m_isBoardEditor( aIsBoardEditor ),
83 m_isFootprintEditor( false )
84{
85}
86
87
89{
90 return static_cast<BOARD*>( m_toolMgr->GetModel() );
91}
92
93
95{
96 // Many operations (move, rotate, etc.) are applied directly to a group's children, so they
97 // must be staged as well.
98 if( aChangeType == CHT_MODIFY )
99 {
100 if( PCB_GROUP* group = dynamic_cast<PCB_GROUP*>( aItem ) )
101 {
102 group->RunOnChildren(
103 [&]( BOARD_ITEM* child )
104 {
105 Stage( child, aChangeType );
106 } );
107 }
108 }
109
110 return COMMIT::Stage( aItem, aChangeType );
111}
112
113
114COMMIT& BOARD_COMMIT::Stage( std::vector<EDA_ITEM*>& container, CHANGE_TYPE aChangeType,
115 BASE_SCREEN* aScreen )
116{
117 return COMMIT::Stage( container, aChangeType, aScreen );
118}
119
120
122 BASE_SCREEN* aScreen )
123{
124 return COMMIT::Stage( aItems, aModFlag, aScreen );
125}
126
127
129{
130 wxCHECK( item, /* void */ );
131
133
134 if( item->Type() == PCB_ZONE_T )
135 zoneFillerTool->DirtyZone( static_cast<ZONE*>( item ) );
136
137 item->RunOnChildren( std::bind( &BOARD_COMMIT::dirtyIntersectingZones, this, _1, aChangeType ) );
138
139 BOARD* board = static_cast<BOARD*>( m_toolMgr->GetModel() );
140 BOX2I bbox = item->GetBoundingBox();
141 LSET layers = item->GetLayerSet();
142
143 if( layers.test( Edge_Cuts ) || layers.test( Margin ) )
144 layers = LSET::PhysicalLayersMask();
145 else
146 layers &= LSET::AllCuMask();
147
148 if( layers.any() )
149 {
150 for( ZONE* zone : board->Zones() )
151 {
152 if( zone->GetIsRuleArea() )
153 continue;
154
155 if( ( zone->GetLayerSet() & layers ).any()
156 && zone->GetBoundingBox().Intersects( bbox ) )
157 {
158 zoneFillerTool->DirtyZone( zone );
159 }
160 }
161 }
162}
163
164
165void BOARD_COMMIT::Push( const wxString& aMessage, int aCommitFlags )
166{
167 KIGFX::VIEW* view = m_toolMgr->GetView();
168 BOARD* board = static_cast<BOARD*>( m_toolMgr->GetModel() );
169 PCB_BASE_FRAME* frame = dynamic_cast<PCB_BASE_FRAME*>( m_toolMgr->GetToolHolder() );
171
172 // Notification info
173 PICKED_ITEMS_LIST undoList;
174 bool itemsDeselected = false;
175 bool selectedModified = false;
176
177 // Dirty flags and lists
178 bool solderMaskDirty = false;
179 bool autofillZones = false;
180 std::vector<BOARD_ITEM*> staleTeardropPadsAndVias;
181 std::set<PCB_TRACK*> staleTeardropTracks;
182 PCB_GROUP* addedGroup = nullptr;
183
184 if( Empty() )
185 return;
186
187 undoList.SetDescription( aMessage );
188
189 TEARDROP_MANAGER teardropMgr( board, m_toolMgr );
190 std::shared_ptr<CONNECTIVITY_DATA> connectivity = board->GetConnectivity();
191
192 // Note: frame == nullptr happens in QA tests
193
194 std::vector<BOARD_ITEM*> bulkAddedItems;
195 std::vector<BOARD_ITEM*> bulkRemovedItems;
196 std::vector<BOARD_ITEM*> itemsChanged;
197
199 && !( aCommitFlags & ZONE_FILL_OP )
200 && ( frame && frame->GetPcbNewSettings()->m_AutoRefillZones ) )
201 {
202 autofillZones = true;
203
204 for( ZONE* zone : board->Zones() )
205 zone->CacheBoundingBox();
206 }
207
208 for( COMMIT_LINE& ent : m_changes )
209 {
210 if( !ent.m_item || !ent.m_item->IsBOARD_ITEM() )
211 continue;
212
213 BOARD_ITEM* boardItem = static_cast<BOARD_ITEM*>( ent.m_item );
214
215 if( m_isBoardEditor )
216 {
217 if( boardItem->Type() == PCB_VIA_T || boardItem->Type() == PCB_FOOTPRINT_T
218 || boardItem->IsOnLayer( F_Mask ) || boardItem->IsOnLayer( B_Mask ) )
219 {
220 solderMaskDirty = true;
221 }
222
223 if( !( aCommitFlags & SKIP_TEARDROPS ) )
224 {
225 if( boardItem->Type() == PCB_FOOTPRINT_T )
226 {
227 for( PAD* pad : static_cast<FOOTPRINT*>( boardItem )->Pads() )
228 staleTeardropPadsAndVias.push_back( pad );
229 }
230 else if( boardItem->Type() == PCB_PAD_T || boardItem->Type() == PCB_VIA_T )
231 {
232 staleTeardropPadsAndVias.push_back( boardItem );
233 }
234 else if( boardItem->Type() == PCB_TRACE_T || boardItem->Type() == PCB_ARC_T )
235 {
236 PCB_TRACK* track = static_cast<PCB_TRACK*>( boardItem );
237
238 staleTeardropTracks.insert( track );
239
240 std::vector<PAD*> connectedPads;
241 std::vector<PCB_VIA*> connectedVias;
242
243 connectivity->GetConnectedPadsAndVias( track, &connectedPads, &connectedVias );
244
245 for( PAD* pad : connectedPads )
246 staleTeardropPadsAndVias.push_back( pad );
247
248 for( PCB_VIA* via : connectedVias )
249 staleTeardropPadsAndVias.push_back( via );
250 }
251 }
252 }
253
254 if( boardItem->IsSelected() )
255 selectedModified = true;
256 }
257
258 // Old teardrops must be removed before connectivity is rebuilt
259 if( !staleTeardropPadsAndVias.empty() || !staleTeardropTracks.empty() )
260 teardropMgr.RemoveTeardrops( *this, &staleTeardropPadsAndVias, &staleTeardropTracks );
261
262 for( COMMIT_LINE& ent : m_changes )
263 {
264 if( !ent.m_item || !ent.m_item->IsBOARD_ITEM() )
265 continue;
266
267 BOARD_ITEM* boardItem = static_cast<BOARD_ITEM*>( ent.m_item );
268 int changeType = ent.m_type & CHT_TYPE;
269 int changeFlags = ent.m_type & CHT_FLAGS;
270
271 switch( changeType )
272 {
273 case CHT_ADD:
274 if( selTool && selTool->GetEnteredGroup() && !boardItem->GetParentGroup()
275 && PCB_GROUP::IsGroupableType( boardItem->Type() ) )
276 {
277 selTool->GetEnteredGroup()->AddItem( boardItem );
278 }
279
280 if( !( aCommitFlags & SKIP_UNDO ) )
281 undoList.PushItem( ITEM_PICKER( nullptr, boardItem, UNDO_REDO::NEWITEM ) );
282
283 if( !( changeFlags & CHT_DONE ) )
284 {
286 {
287 FOOTPRINT* parentFP = board->GetFirstFootprint();
288 wxCHECK2_MSG( parentFP, continue, "Commit thinks this is footprint editor, but "
289 "there is no first footprint!" );
290 parentFP->Add( boardItem );
291 }
292 else if( FOOTPRINT* parentFP = boardItem->GetParentFootprint() )
293 {
294 parentFP->Add( boardItem );
295 }
296 else
297 {
298 board->Add( boardItem, ADD_MODE::BULK_INSERT ); // handles connectivity
299 bulkAddedItems.push_back( boardItem );
300 }
301 }
302
303 if( boardItem->Type() == PCB_GROUP_T || boardItem->Type() == PCB_GENERATOR_T )
304 addedGroup = static_cast<PCB_GROUP*>( boardItem );
305
306 if( m_isBoardEditor && autofillZones && boardItem->Type() != PCB_MARKER_T )
307 dirtyIntersectingZones( boardItem, changeType );
308
309 if( view && boardItem->Type() != PCB_NETINFO_T )
310 view->Add( boardItem );
311
312 break;
313
314 case CHT_REMOVE:
315 {
316 FOOTPRINT* parentFP = boardItem->GetParentFootprint();
317 PCB_GROUP* parentGroup = boardItem->GetParentGroup();
318
319 if( !( aCommitFlags & SKIP_UNDO ) )
320 undoList.PushItem( ITEM_PICKER( nullptr, boardItem, UNDO_REDO::DELETED ) );
321
322 if( boardItem->IsSelected() )
323 {
324 if( selTool )
325 selTool->RemoveItemFromSel( boardItem, true /* quiet mode */ );
326
327 itemsDeselected = true;
328 }
329
330 if( parentGroup && !( parentGroup->GetFlags() & STRUCT_DELETED ) )
331 parentGroup->RemoveItem( boardItem );
332
333 if( parentFP && !( parentFP->GetFlags() & STRUCT_DELETED ) )
334 ent.m_parent = parentFP->m_Uuid;
335
336 if( m_isBoardEditor && autofillZones && boardItem->Type() != PCB_MARKER_T )
337 dirtyIntersectingZones( boardItem, changeType );
338
339 switch( boardItem->Type() )
340 {
341 case PCB_FIELD_T:
342 static_cast<PCB_FIELD*>( boardItem )->SetVisible( false );
343 break;
344
345 case PCB_TEXT_T:
346 case PCB_PAD_T:
347 case PCB_SHAPE_T: // a shape (normally not on copper layers)
348 case PCB_REFERENCE_IMAGE_T: // a bitmap on an associated layer
349 case PCB_GENERATOR_T: // a generator on a layer
350 case PCB_TEXTBOX_T: // a line-wrapped (and optionally bordered) text item
351 case PCB_TABLE_T: // rows and columns of tablecells
352 case PCB_TRACE_T: // a track segment (segment on a copper layer)
353 case PCB_ARC_T: // an arced track segment (segment on a copper layer)
354 case PCB_VIA_T: // a via (like track segment on a copper layer)
355 case PCB_DIM_ALIGNED_T: // a dimension (graphic item)
356 case PCB_DIM_CENTER_T:
357 case PCB_DIM_RADIAL_T:
359 case PCB_DIM_LEADER_T: // a leader dimension
360 case PCB_TARGET_T: // a target (graphic item)
361 case PCB_MARKER_T: // a marker used to show something
362 case PCB_ZONE_T:
363 case PCB_FOOTPRINT_T:
364 case PCB_GROUP_T:
365 if( view )
366 view->Remove( boardItem );
367
368 if( !( changeFlags & CHT_DONE ) )
369 {
370 if( parentFP )
371 {
372 parentFP->Remove( boardItem );
373 }
374 else
375 {
376 board->Remove( boardItem, REMOVE_MODE::BULK );
377 bulkRemovedItems.push_back( boardItem );
378 }
379 }
380
381 break;
382
383 // Metadata items
384 case PCB_NETINFO_T:
385 board->Remove( boardItem, REMOVE_MODE::BULK );
386 bulkRemovedItems.push_back( boardItem );
387 break;
388
389 default: // other types do not need to (or should not) be handled
390 wxASSERT( false );
391 break;
392 }
393
394 // The item has been removed from the board; it is now owned by undo/redo.
395 boardItem->SetFlags( UR_TRANSIENT );
396
397 break;
398 }
399
400 case CHT_UNGROUP:
401 if( PCB_GROUP* group = boardItem->GetParentGroup() )
402 {
403 if( !( aCommitFlags & SKIP_UNDO ) )
404 {
405 ITEM_PICKER itemWrapper( nullptr, boardItem, UNDO_REDO::UNGROUP );
406 itemWrapper.SetGroupId( group->m_Uuid );
407 undoList.PushItem( itemWrapper );
408 }
409
410 group->RemoveItem( boardItem );
411 }
412
413 break;
414
415 case CHT_GROUP:
416 if( addedGroup )
417 {
418 addedGroup->AddItem( boardItem );
419
420 if( !( aCommitFlags & SKIP_UNDO ) )
421 undoList.PushItem( ITEM_PICKER( nullptr, boardItem, UNDO_REDO::REGROUP ) );
422 }
423
424 break;
425
426 case CHT_MODIFY:
427 {
428 BOARD_ITEM* boardItemCopy = nullptr;
429
430 if( ent.m_copy && ent.m_copy->IsBOARD_ITEM() )
431 boardItemCopy = static_cast<BOARD_ITEM*>( ent.m_copy );
432
433 if( !( aCommitFlags & SKIP_UNDO ) )
434 {
435 ITEM_PICKER itemWrapper( nullptr, boardItem, UNDO_REDO::CHANGED );
436 wxASSERT( boardItemCopy );
437 itemWrapper.SetLink( boardItemCopy );
438 undoList.PushItem( itemWrapper );
439 }
440
441 if( !( aCommitFlags & SKIP_CONNECTIVITY ) )
442 {
443 if( boardItemCopy )
444 connectivity->MarkItemNetAsDirty( boardItemCopy );
445
446 connectivity->Update( boardItem );
447 }
448
449 if( m_isBoardEditor && autofillZones && boardItem->Type() != PCB_MARKER_T )
450 {
451 dirtyIntersectingZones( boardItemCopy, changeType ); // before
452 dirtyIntersectingZones( boardItem, changeType ); // after
453 }
454
455 if( view )
456 view->Update( boardItem );
457
458 itemsChanged.push_back( boardItem );
459
460 // if no undo entry is needed, the copy would create a memory leak
461 if( aCommitFlags & SKIP_UNDO )
462 delete ent.m_copy;
463
464 break;
465 }
466
467 default:
468 UNIMPLEMENTED_FOR( boardItem->GetClass() );
469 break;
470 }
471
472 boardItem->ClearEditFlags();
473 boardItem->RunOnDescendants(
474 [&]( BOARD_ITEM* item )
475 {
476 item->ClearEditFlags();
477 } );
478 }
479
480 if( m_isBoardEditor )
481 {
482 size_t num_changes = m_changes.size();
483
484 if( aCommitFlags & SKIP_CONNECTIVITY )
485 {
486 connectivity->ClearRatsnest();
487 connectivity->ClearLocalRatsnest();
488 }
489 else
490 {
491 connectivity->RecalculateRatsnest( this );
493 connectivity->ClearLocalRatsnest();
494
495 if( frame )
496 frame->GetCanvas()->RedrawRatsnest();
497
498 board->OnRatsnestChanged();
499 }
500
501 if( solderMaskDirty )
502 {
503 if( frame )
504 frame->HideSolderMask();
505 }
506
507 if( !staleTeardropPadsAndVias.empty() || !staleTeardropTracks.empty() )
508 {
509 teardropMgr.UpdateTeardrops( *this, &staleTeardropPadsAndVias, &staleTeardropTracks );
510
511 // UpdateTeardrops() can modify the ratsnest data. So rebuild this ratsnest data
512 connectivity->RecalculateRatsnest( this );
513 }
514
515 // Log undo items for any connectivity or teardrop changes
516 for( size_t i = num_changes; i < m_changes.size(); ++i )
517 {
518 COMMIT_LINE& ent = m_changes[i];
519 BOARD_ITEM* boardItem = nullptr;
520 BOARD_ITEM* boardItemCopy = nullptr;
521
522 if( ent.m_item && ent.m_item->IsBOARD_ITEM() )
523 boardItem = static_cast<BOARD_ITEM*>( ent.m_item );
524
525 if( ent.m_copy && ent.m_copy->IsBOARD_ITEM() )
526 boardItemCopy = static_cast<BOARD_ITEM*>( ent.m_copy );
527
528 wxCHECK2( boardItem, continue );
529
530 if( !( aCommitFlags & SKIP_UNDO ) )
531 {
532 ITEM_PICKER itemWrapper( nullptr, boardItem, convert( ent.m_type & CHT_TYPE ) );
533 itemWrapper.SetLink( boardItemCopy );
534 undoList.PushItem( itemWrapper );
535 }
536 else
537 {
538 delete ent.m_copy;
539 }
540
541 if( view )
542 {
543 if( ( ent.m_type & CHT_TYPE ) == CHT_ADD )
544 view->Add( boardItem );
545 else if( ( ent.m_type & CHT_TYPE ) == CHT_REMOVE )
546 view->Remove( boardItem );
547 else
548 view->Update( boardItem );
549 }
550 }
551 }
552
553 if( bulkAddedItems.size() > 0 || bulkRemovedItems.size() > 0 || itemsChanged.size() > 0 )
554 board->OnItemsCompositeUpdate( bulkAddedItems, bulkRemovedItems, itemsChanged );
555
556 if( frame )
557 {
558 if( !( aCommitFlags & SKIP_UNDO ) )
559 {
560 if( aCommitFlags & APPEND_UNDO )
561 frame->AppendCopyToUndoList( undoList, UNDO_REDO::UNSPECIFIED );
562 else
563 frame->SaveCopyInUndoList( undoList, UNDO_REDO::UNSPECIFIED );
564 }
565 }
566
568
569 if( itemsDeselected )
571
572 if( autofillZones )
574
575 if( selectedModified )
577
578 if( frame )
579 {
580 if( !( aCommitFlags & SKIP_SET_DIRTY ) )
581 frame->OnModify();
582 else
584
585 // Ensure the message panel is updated after committing changes.
586 // By default (i.e. if no event posted), display the updated board info
587 if( !itemsDeselected && !autofillZones && !selectedModified )
588 {
589 std::vector<MSG_PANEL_ITEM> msg_list;
590 board->GetMsgPanelInfo( frame, msg_list );
591 frame->SetMsgPanel( msg_list );
592 }
593 }
594
595 clear();
596}
597
598
600{
601 return aItem;
602}
603
604
606{
607 return MakeImage( aItem );
608}
609
610
612{
613 EDA_ITEM* clone = aItem->Clone();
614
615 if( clone->IsBOARD_ITEM() )
616 static_cast<BOARD_ITEM*>( clone )->SetParentGroup( nullptr );
617
618 clone->SetFlags( UR_TRANSIENT );
619
620 return clone;
621}
622
623
625{
626 PICKED_ITEMS_LIST undoList;
627 KIGFX::VIEW* view = m_toolMgr->GetView();
628 BOARD* board = (BOARD*) m_toolMgr->GetModel();
629 std::shared_ptr<CONNECTIVITY_DATA> connectivity = board->GetConnectivity();
630
631 board->IncrementTimeStamp(); // clear caches
632
633 std::vector<BOARD_ITEM*> bulkAddedItems;
634 std::vector<BOARD_ITEM*> bulkRemovedItems;
635 std::vector<BOARD_ITEM*> itemsChanged;
636
637 for( auto it = m_changes.rbegin(); it != m_changes.rend(); ++it )
638 {
639 COMMIT_LINE& ent = *it;
640
641 if( !ent.m_item || !ent.m_item->IsBOARD_ITEM() )
642 continue;
643
644 BOARD_ITEM* boardItem = static_cast<BOARD_ITEM*>( ent.m_item );
645 int changeType = ent.m_type & CHT_TYPE;
646 int changeFlags = ent.m_type & CHT_FLAGS;
647
648 switch( changeType )
649 {
650 case CHT_ADD:
651 // Items are auto-added to the parent group by BOARD_ITEM::Duplicate(), not when
652 // the commit is pushed.
653 if( PCB_GROUP* parentGroup = boardItem->GetParentGroup() )
654 {
655 if( GetStatus( parentGroup ) == 0 )
656 parentGroup->RemoveItem( boardItem );
657 }
658
659 if( !( changeFlags & CHT_DONE ) )
660 break;
661
662 view->Remove( boardItem );
663 connectivity->Remove( boardItem );
664
665 if( FOOTPRINT* parentFP = boardItem->GetParentFootprint() )
666 {
667 parentFP->Remove( boardItem );
668 }
669 else
670 {
671 board->Remove( boardItem, REMOVE_MODE::BULK );
672 bulkRemovedItems.push_back( boardItem );
673 }
674
675 break;
676
677 case CHT_REMOVE:
678 {
679 if( !( changeFlags & CHT_DONE ) )
680 break;
681
682 view->Add( boardItem );
683 connectivity->Add( boardItem );
684
685 // Note: parent can be nullptr, because ent.m_parent is not
686 // initialized for every ent.m_item, only for some.
687 BOARD_ITEM* parent = board->GetItem( ent.m_parent );
688
689 if( parent && parent->Type() == PCB_FOOTPRINT_T )
690 {
691 static_cast<FOOTPRINT*>( parent )->Add( boardItem, ADD_MODE::INSERT );
692 }
693 else
694 {
695 board->Add( boardItem, ADD_MODE::INSERT );
696 bulkAddedItems.push_back( boardItem );
697 }
698
699 break;
700 }
701
702 case CHT_MODIFY:
703 {
704 view->Remove( boardItem );
705 connectivity->Remove( boardItem );
706
707 wxASSERT( ent.m_copy && ent.m_copy->IsBOARD_ITEM() );
708 BOARD_ITEM* boardItemCopy = static_cast<BOARD_ITEM*>( ent.m_copy );
709 boardItem->SwapItemData( boardItemCopy );
710
711 if( PCB_GROUP* group = dynamic_cast<PCB_GROUP*>( boardItem ) )
712 {
713 group->RunOnChildren(
714 [&]( BOARD_ITEM* child )
715 {
716 child->SetParentGroup( group );
717 } );
718 }
719
720 view->Add( boardItem );
721 connectivity->Add( boardItem );
722 itemsChanged.push_back( boardItem );
723
724 delete ent.m_copy;
725 break;
726 }
727
728 default:
729 UNIMPLEMENTED_FOR( boardItem->GetClass() );
730 break;
731 }
732
733 boardItem->ClearEditFlags();
734 }
735
736 if( bulkAddedItems.size() > 0 || bulkRemovedItems.size() > 0 || itemsChanged.size() > 0 )
737 board->OnItemsCompositeUpdate( bulkAddedItems, bulkRemovedItems, itemsChanged );
738
739 if( m_isBoardEditor )
740 {
741 connectivity->RecalculateRatsnest();
743 board->OnRatsnestChanged();
744 }
745
747 selTool->RebuildSelection();
748
749 // Property panel needs to know about the reselect
751
752 clear();
753}
754
#define SKIP_CONNECTIVITY
Definition: board_commit.h:42
#define SKIP_SET_DIRTY
Definition: board_commit.h:41
#define APPEND_UNDO
Definition: board_commit.h:40
#define SKIP_UNDO
Definition: board_commit.h:39
#define ZONE_FILL_OP
Definition: board_commit.h:43
#define SKIP_TEARDROPS
Definition: board_commit.h:44
Handles how to draw a screen (a board, a schematic ...)
Definition: base_screen.h:41
void dirtyIntersectingZones(BOARD_ITEM *item, int aChangeType)
virtual void Push(const wxString &aMessage=wxEmptyString, int aCommitFlags=0) override
Revert the commit by restoring the modified items state.
COMMIT & Stage(EDA_ITEM *aItem, CHANGE_TYPE aChangeType, BASE_SCREEN *aScreen=nullptr) override
EDA_ITEM * parentObject(EDA_ITEM *aItem) const override
BOARD * GetBoard() const
virtual void Revert() override
static EDA_ITEM * MakeImage(EDA_ITEM *aItem)
bool m_isBoardEditor
Definition: board_commit.h:80
EDA_ITEM * makeImage(EDA_ITEM *aItem) const override
TOOL_MANAGER * m_toolMgr
Definition: board_commit.h:79
bool m_isFootprintEditor
Definition: board_commit.h:81
BOARD_COMMIT(EDA_DRAW_FRAME *aFrame)
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition: board_item.h:79
void SetParentGroup(PCB_GROUP *aGroup)
Definition: board_item.h:89
void SwapItemData(BOARD_ITEM *aImage)
Swap data between aItem and aImage.
Definition: board_item.cpp:226
PCB_GROUP * GetParentGroup() const
Definition: board_item.h:90
virtual bool IsOnLayer(PCB_LAYER_ID aLayer) const
Test to see if this object is on the given layer.
Definition: board_item.h:319
FOOTPRINT * GetParentFootprint() const
Definition: board_item.cpp:299
virtual LSET GetLayerSet() const
Return a std::bitset of all layers on which the item physically resides.
Definition: board_item.h:257
virtual void RunOnDescendants(const std::function< void(BOARD_ITEM *)> &aFunction, int aDepth=0) const
Invoke a function on all descendants.
Definition: board_item.h:212
virtual void RunOnChildren(const std::function< void(BOARD_ITEM *)> &aFunction) const
Invoke a function on all children.
Definition: board_item.h:206
Information pertinent to a Pcbnew printed circuit board.
Definition: board.h:290
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT, bool aSkipConnectivity=false) override
Removes an item from the container.
Definition: board.cpp:1000
BOARD_ITEM * GetItem(const KIID &aID) const
Definition: board.cpp:1408
const ZONES & Zones() const
Definition: board.h:335
void OnItemsCompositeUpdate(std::vector< BOARD_ITEM * > &aAddedItems, std::vector< BOARD_ITEM * > &aRemovedItems, std::vector< BOARD_ITEM * > &aChangedItems)
Notify the board and its listeners that items on the board have been modified in a composite operatio...
Definition: board.cpp:2702
FOOTPRINT * GetFirstFootprint() const
Get the first footprint on the board or nullptr.
Definition: board.h:448
void IncrementTimeStamp()
Definition: board.cpp:255
void OnRatsnestChanged()
Notify the board and its listeners that the ratsnest has been recomputed.
Definition: board.cpp:2711
void GetMsgPanelInfo(EDA_DRAW_FRAME *aFrame, std::vector< MSG_PANEL_ITEM > &aList) override
Populate aList of MSG_PANEL_ITEM objects with it's internal state for display purposes.
Definition: board.cpp:1731
void UpdateRatsnestExclusions()
Update the visibility flags on the current unconnected ratsnest lines.
Definition: board.cpp:296
void Remove(BOARD_ITEM *aBoardItem, REMOVE_MODE aMode=REMOVE_MODE::NORMAL) override
Removes an item from the container.
Definition: board.cpp:1138
std::shared_ptr< CONNECTIVITY_DATA > GetConnectivity() const
Return a list of missing connections between components/tracks.
Definition: board.h:475
Represent a set of changes (additions, deletions or modifications) of a data model (e....
Definition: commit.h:74
virtual COMMIT & Stage(EDA_ITEM *aItem, CHANGE_TYPE aChangeType, BASE_SCREEN *aScreen=nullptr)
Definition: commit.cpp:48
bool Empty() const
Returns status of an item.
Definition: commit.h:144
COMMIT & Add(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Notify observers that aItem has been added.
Definition: commit.h:80
int GetStatus(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Definition: commit.cpp:130
void clear()
Definition: commit.h:165
std::vector< COMMIT_LINE > m_changes
Definition: commit.h:195
bool IsType(FRAME_T aType) const
The base class for create windows for drawing purpose.
void SetMsgPanel(const std::vector< MSG_PANEL_ITEM > &aList)
Clear the message panel and populates it with the contents of aList.
A base class for most all the KiCad significant classes used in schematics and boards.
Definition: eda_item.h:89
virtual void ClearEditFlags()
Definition: eda_item.h:141
virtual const BOX2I GetBoundingBox() const
Return the orthogonal bounding box of this object for display purposes.
Definition: eda_item.cpp:77
void SetFlags(EDA_ITEM_FLAGS aMask)
Definition: eda_item.h:127
const KIID m_Uuid
Definition: eda_item.h:489
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:101
bool IsSelected() const
Definition: eda_item.h:110
virtual EDA_ITEM * Clone() const
Create a duplicate of this item with linked list members set to NULL.
Definition: eda_item.cpp:85
virtual wxString GetClass() const =0
Return the class name.
EDA_ITEM_FLAGS GetFlags() const
Definition: eda_item.h:130
static const TOOL_EVENT SelectedItemsModified
Selected items were moved, this can be very high frequency on the canvas, use with care.
Definition: actions.h:299
static const TOOL_EVENT UnselectedEvent
Definition: actions.h:293
void Remove(BOARD_ITEM *aItem, REMOVE_MODE aMode=REMOVE_MODE::NORMAL) override
Removes an item from the container.
Definition: footprint.cpp:1045
std::deque< PAD * > & Pads()
Definition: footprint.h:206
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT, bool aSkipConnectivity=false) override
Removes an item from the container.
Definition: footprint.cpp:982
void SetGroupId(KIID aId)
void SetLink(EDA_ITEM *aItem)
bool IsBOARD_ITEM() const
Definition: view_item.h:100
Hold a (potentially large) number of VIEW_ITEMs and renders them on a graphics device provided by the...
Definition: view.h:68
virtual void Add(VIEW_ITEM *aItem, int aDrawPriority=-1)
Add a VIEW_ITEM to the view.
Definition: view.cpp:317
virtual void Remove(VIEW_ITEM *aItem)
Remove a VIEW_ITEM from the view.
Definition: view.cpp:357
virtual void Update(const VIEW_ITEM *aItem, int aUpdateFlags) const
For dynamic VIEWs, inform the associated VIEW that the graphical representation of this item has chan...
Definition: view.cpp:1687
LSET is a set of PCB_LAYER_IDs.
Definition: lset.h:36
static LSET AllCuMask(int aCuLayerCount=MAX_CU_LAYERS)
Return a mask holding the requested number of Cu PCB_LAYER_IDs.
Definition: lset.cpp:676
static LSET PhysicalLayersMask()
Return a mask holding all layers which are physically realized.
Definition: lset.cpp:756
Definition: pad.h:54
DISPLAY_OPTIONS m_Display
static TOOL_ACTION zoneFillDirty
Definition: pcb_actions.h:409
Base PCB main window class for Pcbnew, Gerbview, and CvPcb footprint viewer.
PCBNEW_SETTINGS * GetPcbNewSettings() const
void OnModify() override
Must be called after a change in order to set the "modify" flag and update other data structures and ...
virtual void SaveCopyInUndoList(EDA_ITEM *aItemToCopy, UNDO_REDO aTypeCommand)
Create a new entry in undo list of commands.
PCB_DRAW_PANEL_GAL * GetCanvas() const override
Return a pointer to GAL-based canvas of given EDA draw frame.
virtual void Update3DView(bool aMarkDirty, bool aRefresh, const wxString *aTitle=nullptr)
Update the 3D view, if the viewer is opened by this frame.
virtual void AppendCopyToUndoList(const PICKED_ITEMS_LIST &aItemsList, UNDO_REDO aTypeCommand)
As SaveCopyInUndoList, but appends the changes to the last undo item on the stack.
void RedrawRatsnest()
Return the bounding box of the view that should be used if model is not valid.
A set of BOARD_ITEMs (i.e., without duplicates).
Definition: pcb_group.h:52
static bool IsGroupableType(KICAD_T aType)
Check if the proposed type can be added to a group.
Definition: pcb_group.cpp:50
virtual bool RemoveItem(BOARD_ITEM *aItem)
Remove item from group.
Definition: pcb_group.cpp:96
virtual bool AddItem(BOARD_ITEM *aItem)
Add item to group.
Definition: pcb_group.cpp:81
The selection tool: currently supports:
PCB_GROUP * GetEnteredGroup()
void RebuildSelection()
Rebuild the selection from the EDA_ITEMs' selection flags.
A holder to handle information on schematic or board items.
int RemoveItemFromSel(const TOOL_EVENT &aEvent)
TEARDROP_MANAGER manage and build teardrop areas A teardrop area is a polygonal area (a copper ZONE) ...
Definition: teardrop.h:97
void UpdateTeardrops(BOARD_COMMIT &aCommit, const std::vector< BOARD_ITEM * > *dirtyPadsAndVias, const std::set< PCB_TRACK * > *dirtyTracks, bool aForceFullUpdate=false)
Update teardrops on a list of items.
Definition: teardrop.cpp:151
void RemoveTeardrops(BOARD_COMMIT &aCommit, const std::vector< BOARD_ITEM * > *dirtyPadsAndVias, const std::set< PCB_TRACK * > *dirtyTracks)
Remove teardrops connected to any dirty pads, vias or tracks.
Definition: teardrop.cpp:99
Base abstract interface for all kinds of tools.
Definition: tool_base.h:66
Master controller class:
Definition: tool_manager.h:62
bool ProcessEvent(const TOOL_EVENT &aEvent)
Propagate an event to tools that requested events of matching type(s).
void PostEvent(const TOOL_EVENT &aEvent)
Put an event to the event queue to be processed at the end of event processing cycle.
TOOLS_HOLDER * GetToolHolder() const
Definition: tool_manager.h:402
bool PostAction(const std::string &aActionName, T aParam)
Run the specified action after the current action (coroutine) ends.
Definition: tool_manager.h:235
EDA_ITEM * GetModel() const
Definition: tool_manager.h:398
KIGFX::VIEW * GetView() const
Definition: tool_manager.h:391
Handle actions specific to filling copper zones.
void DirtyZone(ZONE *aZone)
Handle a list of polygons defining a copper zone.
Definition: zone.h:73
CHANGE_TYPE
Types of changes.
Definition: commit.h:41
@ CHT_MODIFY
Definition: commit.h:44
@ CHT_GROUP
Definition: commit.h:45
@ CHT_REMOVE
Definition: commit.h:43
@ CHT_DONE
Flag to indicate the change is already applied.
Definition: commit.h:49
@ CHT_TYPE
Definition: commit.h:47
@ CHT_ADD
Definition: commit.h:42
@ CHT_UNGROUP
Definition: commit.h:46
@ CHT_FLAGS
Definition: commit.h:50
#define STRUCT_DELETED
flag indication structures to be erased
#define UR_TRANSIENT
indicates the item is owned by the undo/redo stack
@ FRAME_PCB_EDITOR
Definition: frame_type.h:42
@ FRAME_FOOTPRINT_EDITOR
Definition: frame_type.h:43
@ Edge_Cuts
Definition: layer_ids.h:112
@ B_Mask
Definition: layer_ids.h:98
@ F_Mask
Definition: layer_ids.h:97
@ Margin
Definition: layer_ids.h:113
This file contains miscellaneous commonly used macros and functions.
#define UNIMPLEMENTED_FOR(type)
Definition: macros.h:96
Class to handle a set of BOARD_ITEMs.
EDA_ITEM * m_copy
Optional copy of the item.
Definition: commit.h:158
CHANGE_TYPE m_type
Modification type.
Definition: commit.h:159
KIID m_parent
Parent item (primarily for undo of deleted items)
Definition: commit.h:160
EDA_ITEM * m_item
Main item that is added/deleted/modified.
Definition: commit.h:157
@ AS_GLOBAL
Global action (toolbar/main menu event, global shortcut)
Definition: tool_action.h:48
@ TA_MODEL_CHANGE
Definition: tool_event.h:120
@ TC_MESSAGE
Definition: tool_event.h:57
@ PCB_SHAPE_T
class PCB_SHAPE, a segment not on copper layers
Definition: typeinfo.h:88
@ PCB_DIM_ORTHOGONAL_T
class PCB_DIM_ORTHOGONAL, a linear dimension constrained to x/y
Definition: typeinfo.h:105
@ PCB_DIM_LEADER_T
class PCB_DIM_LEADER, a leader dimension (graphic item)
Definition: typeinfo.h:102
@ PCB_GENERATOR_T
class PCB_GENERATOR, generator on a layer
Definition: typeinfo.h:91
@ PCB_VIA_T
class PCB_VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:97
@ PCB_DIM_CENTER_T
class PCB_DIM_CENTER, a center point marking (graphic item)
Definition: typeinfo.h:103
@ PCB_GROUP_T
class PCB_GROUP, a set of BOARD_ITEMs
Definition: typeinfo.h:110
@ PCB_TEXTBOX_T
class PCB_TEXTBOX, wrapped text on a layer
Definition: typeinfo.h:93
@ PCB_ZONE_T
class ZONE, a copper pour area
Definition: typeinfo.h:107
@ PCB_TEXT_T
class PCB_TEXT, text on a layer
Definition: typeinfo.h:92
@ PCB_REFERENCE_IMAGE_T
class PCB_REFERENCE_IMAGE, bitmap on a layer
Definition: typeinfo.h:89
@ PCB_FIELD_T
class PCB_FIELD, text associated with a footprint property
Definition: typeinfo.h:90
@ PCB_MARKER_T
class PCB_MARKER, a marker used to show something
Definition: typeinfo.h:99
@ PCB_TARGET_T
class PCB_TARGET, a target (graphic item)
Definition: typeinfo.h:106
@ PCB_FOOTPRINT_T
class FOOTPRINT, a footprint
Definition: typeinfo.h:86
@ PCB_DIM_ALIGNED_T
class PCB_DIM_ALIGNED, a linear dimension (graphic item)
Definition: typeinfo.h:101
@ PCB_PAD_T
class PAD, a pad in a footprint
Definition: typeinfo.h:87
@ PCB_ARC_T
class PCB_ARC, an arc track segment on a copper layer
Definition: typeinfo.h:98
@ PCB_TABLE_T
class PCB_TABLE, table of PCB_TABLECELLs
Definition: typeinfo.h:94
@ PCB_NETINFO_T
class NETINFO_ITEM, a description of a net
Definition: typeinfo.h:109
@ PCB_TRACE_T
class PCB_TRACK, a track segment (segment on a copper layer)
Definition: typeinfo.h:96
@ PCB_DIM_RADIAL_T
class PCB_DIM_RADIAL, a radius or diameter dimension
Definition: typeinfo.h:104
UNDO_REDO
Undo Redo considerations: Basically we have 3 cases New item Deleted item Modified item there is also...