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 The 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 <pgm_base.h>
29#include <board.h>
31#include <footprint.h>
32#include <lset.h>
33#include <pcb_group.h>
34#include <pcb_track.h>
35#include <pcb_shape.h>
36#include <tool/tool_manager.h>
39#include <view/view.h>
40#include <board_commit.h>
41#include <tools/pcb_tool_base.h>
42#include <tools/pcb_actions.h>
45#include <teardrop/teardrop.h>
46#include <pcb_board_outline.h>
47
48#include <functional>
50using namespace std::placeholders;
51
52
54 COMMIT(),
55 m_toolMgr( aTool->GetManager() ),
56 m_isBoardEditor( false ),
57 m_isFootprintEditor( false )
58{
59 if( PCB_TOOL_BASE* pcb_tool = dynamic_cast<PCB_TOOL_BASE*>( aTool ) )
60 {
61 m_isBoardEditor = pcb_tool->IsBoardEditor();
62 m_isFootprintEditor = pcb_tool->IsFootprintEditor();
63 }
64}
65
66
68 COMMIT(),
69 m_toolMgr( aFrame->GetToolManager() ),
70 m_isBoardEditor( aFrame->IsType( FRAME_PCB_EDITOR ) ),
72{
73}
74
75
77 COMMIT(),
78 m_toolMgr( aMgr ),
79 m_isBoardEditor( false ),
80 m_isFootprintEditor( false )
81{
82 EDA_DRAW_FRAME* frame = dynamic_cast<EDA_DRAW_FRAME*>( aMgr->GetToolHolder() );
83
84 if( frame && frame->IsType( FRAME_PCB_EDITOR ) )
85 m_isBoardEditor = true;
86 else if( frame && frame->IsType( FRAME_FOOTPRINT_EDITOR ) )
88}
89
90
91BOARD_COMMIT::BOARD_COMMIT( TOOL_MANAGER* aMgr, bool aIsBoardEditor, bool aIsFootprintEditor ) :
92 COMMIT(),
93 m_toolMgr( aMgr ),
94 m_isBoardEditor( aIsBoardEditor ),
95 m_isFootprintEditor( aIsFootprintEditor )
96{
97}
98
99
101{
102 return static_cast<BOARD*>( m_toolMgr->GetModel() );
103}
104
105
106COMMIT& BOARD_COMMIT::Stage( EDA_ITEM* aItem, CHANGE_TYPE aChangeType, BASE_SCREEN* aScreen, RECURSE_MODE aRecurse )
107{
108 if( aRecurse == RECURSE_MODE::RECURSE )
109 {
110 if( PCB_GROUP* group = dynamic_cast<PCB_GROUP*>( aItem ) )
111 {
112 for( EDA_ITEM* member : group->GetItems() )
113 Stage( member, aChangeType, aScreen, aRecurse );
114 }
115 }
116
117 return COMMIT::Stage( aItem, aChangeType );
118}
119
120
121COMMIT& BOARD_COMMIT::Stage( std::vector<EDA_ITEM*>& container, CHANGE_TYPE aChangeType, BASE_SCREEN* aScreen )
122{
123 return COMMIT::Stage( container, aChangeType, aScreen );
124}
125
126
128{
129 return COMMIT::Stage( aItems, aModFlag, aScreen );
130}
131
132
133void BOARD_COMMIT::propagateDamage( BOARD_ITEM* aChangedItem, std::vector<ZONE*>* aStaleZones,
134 std::vector<BOX2I>& aStaleRuleAreas )
135{
136 wxCHECK( aChangedItem, /* void */ );
137
138 if( aStaleZones && aChangedItem->Type() == PCB_ZONE_T )
139 aStaleZones->push_back( static_cast<ZONE*>( aChangedItem ) );
140
141 aChangedItem->RunOnChildren( std::bind( &BOARD_COMMIT::propagateDamage, this, _1, aStaleZones, aStaleRuleAreas ),
143
144 BOARD* board = static_cast<BOARD*>( m_toolMgr->GetModel() );
145 BOX2I damageBBox = aChangedItem->GetBoundingBox();
146 LSET damageLayers = aChangedItem->GetLayerSet();
147
148 if( m_isBoardEditor && aChangedItem->Type() == PCB_ZONE_T )
149 {
150 // A named zone can have custom DRC rules targetting it.
151 if( !static_cast<ZONE*>( aChangedItem )->GetZoneName().IsEmpty() )
152 aStaleRuleAreas.push_back( damageBBox );
153 }
154
155 if( aStaleZones )
156 {
157 if( damageLayers.test( Edge_Cuts ) || damageLayers.test( Margin ) )
158 damageLayers = LSET::PhysicalLayersMask();
159 else
160 damageLayers &= LSET::AllCuMask();
161
162 if( damageLayers.any() )
163 {
164 for( ZONE* zone : board->Zones() )
165 {
166 if( zone->GetIsRuleArea() )
167 continue;
168
169 if( ( zone->GetLayerSet() & damageLayers ).any() && zone->GetBoundingBox().Intersects( damageBBox ) )
170 aStaleZones->push_back( zone );
171 }
172 }
173 }
174}
175
176
177void BOARD_COMMIT::Push( const wxString& aMessage, int aCommitFlags )
178{
179 KIGFX::PCB_VIEW* view = static_cast<KIGFX::PCB_VIEW*>( m_toolMgr->GetView() );
180 BOARD* board = static_cast<BOARD*>( m_toolMgr->GetModel() );
181 PCB_BASE_FRAME* frame = dynamic_cast<PCB_BASE_FRAME*>( m_toolMgr->GetToolHolder() );
182 PCB_SELECTION_TOOL* selTool = m_toolMgr->GetTool<PCB_SELECTION_TOOL>();
183 PCB_GROUP* enteredGroup = selTool && !( aCommitFlags & SKIP_ENTERED_GROUP ) ? selTool->GetEnteredGroup()
184 : nullptr;
185 // Notification info
186 PICKED_ITEMS_LIST undoList;
187 bool itemsDeselected = false;
188 bool selectedModified = false;
189
190 // Dirty flags and lists
191 bool solderMaskDirty = false;
192 bool autofillZones = false;
193 bool updateBoardBoundingBox = false;
194 std::vector<BOARD_ITEM*> staleTeardropPadsAndVias;
195 std::set<PCB_TRACK*> staleTeardropTracks;
196 std::vector<ZONE*> staleZonesStorage;
197 std::vector<ZONE*>* staleZones = nullptr;
198 std::vector<BOX2I> staleRuleAreas;
199
200 if( Empty() )
201 return;
202
203 undoList.SetDescription( aMessage );
204
205 TEARDROP_MANAGER teardropMgr( board, m_toolMgr );
206 std::shared_ptr<CONNECTIVITY_DATA> connectivity = board->GetConnectivity();
207
208 // Note: frame == nullptr happens in QA tests
209
210 std::vector<BOARD_ITEM*> bulkAddedItems;
211 std::vector<BOARD_ITEM*> bulkRemovedItems;
212 std::vector<BOARD_ITEM*> itemsChanged;
213
214 if( m_isBoardEditor && !( aCommitFlags & ZONE_FILL_OP )
215 && ( frame && frame->GetPcbNewSettings()->m_AutoRefillZones ) )
216 {
217 autofillZones = true;
218 staleZones = &staleZonesStorage;
219
220 for( ZONE* zone : board->Zones() )
221 zone->CacheBoundingBox();
222 }
223
224 for( COMMIT_LINE& entry : m_entries )
225 {
226 if( !entry.m_item || !entry.m_item->IsBOARD_ITEM() )
227 continue;
228
229 BOARD_ITEM* boardItem = static_cast<BOARD_ITEM*>( entry.m_item );
230
231 if( m_isBoardEditor )
232 {
233 if( boardItem->Type() == PCB_VIA_T || boardItem->Type() == PCB_FOOTPRINT_T
234 || boardItem->IsOnLayer( F_Mask ) || boardItem->IsOnLayer( B_Mask ) )
235 {
236 solderMaskDirty = true;
237 }
238
239 if( boardItem->GetLayer() == Edge_Cuts )
240 {
241 updateBoardBoundingBox = true;
242 }
243
244 if( !( aCommitFlags & SKIP_TEARDROPS ) )
245 {
246 if( boardItem->Type() == PCB_FOOTPRINT_T )
247 {
248 for( PAD* pad : static_cast<FOOTPRINT*>( boardItem )->Pads() )
249 staleTeardropPadsAndVias.push_back( pad );
250 }
251 else if( boardItem->Type() == PCB_PAD_T || boardItem->Type() == PCB_VIA_T )
252 {
253 staleTeardropPadsAndVias.push_back( boardItem );
254 }
255 else if( boardItem->Type() == PCB_TRACE_T || boardItem->Type() == PCB_ARC_T )
256 {
257 PCB_TRACK* track = static_cast<PCB_TRACK*>( boardItem );
258
259 staleTeardropTracks.insert( track );
260
261 std::vector<PAD*> connectedPads;
262 std::vector<PCB_VIA*> connectedVias;
263
264 connectivity->GetConnectedPadsAndVias( track, &connectedPads, &connectedVias );
265
266 for( PAD* pad : connectedPads )
267 staleTeardropPadsAndVias.push_back( pad );
268
269 for( PCB_VIA* via : connectedVias )
270 staleTeardropPadsAndVias.push_back( via );
271 }
272 }
273 }
274
275 if( boardItem->IsSelected() || ( m_isFootprintEditor && boardItem == board->GetFirstFootprint() ) )
276 selectedModified = true;
277 }
278
279 // Old teardrops must be removed before connectivity is rebuilt
280 if( !staleTeardropPadsAndVias.empty() || !staleTeardropTracks.empty() )
281 teardropMgr.RemoveTeardrops( *this, &staleTeardropPadsAndVias, &staleTeardropTracks );
282
283 auto updateComponentClasses =
284 [this]( BOARD_ITEM* boardItem )
285 {
286 if( boardItem->Type() != PCB_FOOTPRINT_T )
287 return;
288
289 FOOTPRINT* footprint = static_cast<FOOTPRINT*>( boardItem );
291 };
292
293 // We don't know that anything will be added to the entered group, but it does no harm to
294 // add it to the commit anyway.
295 if( enteredGroup )
296 Modify( enteredGroup );
297
298
299 for( COMMIT_LINE& entry : m_entries )
300 {
301 if( !entry.m_item || !entry.m_item->IsBOARD_ITEM() )
302 continue;
303
304 BOARD_ITEM* boardItem = static_cast<BOARD_ITEM*>( entry.m_item );
305 int changeType = entry.m_type & CHT_TYPE;
306 int changeFlags = entry.m_type & CHT_FLAGS;
307
308 switch( changeType )
309 {
310 case CHT_ADD:
311 if( enteredGroup && boardItem->IsGroupableType() && !boardItem->GetParentGroup() )
312 enteredGroup->AddItem( boardItem );
313
314 if( !( aCommitFlags & SKIP_UNDO ) )
315 undoList.PushItem( ITEM_PICKER( nullptr, boardItem, UNDO_REDO::NEWITEM ) );
316
317 if( !( changeFlags & CHT_DONE ) )
318 {
320 {
321 if( FOOTPRINT* parentFP = board->GetFirstFootprint() )
322 parentFP->Add( boardItem );
323 }
324 else
325 {
326 board->Add( boardItem, ADD_MODE::BULK_INSERT ); // handles connectivity
327 bulkAddedItems.push_back( boardItem );
328 }
329 }
330
331 if( boardItem->Type() != PCB_MARKER_T )
332 propagateDamage( boardItem, staleZones, staleRuleAreas );
333
334 if( view && boardItem->Type() != PCB_NETINFO_T )
335 view->Add( boardItem );
336
337 updateComponentClasses( boardItem );
338
339 break;
340
341 case CHT_REMOVE:
342 {
343 EDA_GROUP* parentGroup = boardItem->GetParentGroup();
344
345 if( !( aCommitFlags & SKIP_UNDO ) )
346 {
347 ITEM_PICKER itemWrapper( nullptr, boardItem, UNDO_REDO::DELETED );
348 itemWrapper.SetLink( entry.m_copy );
349 entry.m_copy = nullptr; // We've transferred ownership to the undo list
350 undoList.PushItem( itemWrapper );
351 }
352
353 if( boardItem->IsSelected() )
354 {
355 if( selTool )
356 selTool->RemoveItemFromSel( boardItem, true /* quiet mode */ );
357
358 itemsDeselected = true;
359 }
360
361 if( parentGroup && !( parentGroup->AsEdaItem()->GetFlags() & STRUCT_DELETED ) )
362 parentGroup->RemoveItem( boardItem );
363
364 if( boardItem->Type() != PCB_MARKER_T )
365 propagateDamage( boardItem, staleZones, staleRuleAreas );
366
367 switch( boardItem->Type() )
368 {
369 case PCB_FIELD_T:
370 static_cast<PCB_FIELD*>( boardItem )->SetVisible( false );
371 break;
372
373 case PCB_TEXT_T:
374 case PCB_PAD_T:
375 case PCB_SHAPE_T:
377 case PCB_GENERATOR_T:
378 case PCB_TEXTBOX_T:
379 case PCB_BARCODE_T:
380 case PCB_TABLE_T:
381 case PCB_TRACE_T:
382 case PCB_ARC_T:
383 case PCB_VIA_T:
385 case PCB_DIM_CENTER_T:
386 case PCB_DIM_RADIAL_T:
388 case PCB_DIM_LEADER_T:
389 case PCB_TARGET_T:
390 case PCB_MARKER_T:
391 case PCB_POINT_T:
392 case PCB_ZONE_T:
393 case PCB_FOOTPRINT_T:
394 case PCB_GROUP_T:
395 if( view )
396 view->Remove( boardItem );
397
398 if( !( changeFlags & CHT_DONE ) )
399 {
401 {
402 if( FOOTPRINT* parentFP = board->GetFirstFootprint() )
403 parentFP->Remove( boardItem );
404 }
405 else
406 {
407 board->Remove( boardItem, REMOVE_MODE::BULK );
408 bulkRemovedItems.push_back( boardItem );
409 }
410 }
411
412 break;
413
414 // Metadata items
415 case PCB_NETINFO_T:
416 board->Remove( boardItem, REMOVE_MODE::BULK );
417 bulkRemovedItems.push_back( boardItem );
418 break;
419
420 default: // other types do not need to (or should not) be handled
421 wxASSERT( false );
422 break;
423 }
424
425 // The item has been removed from the board; it is now owned by undo/redo.
426 boardItem->SetFlags( UR_TRANSIENT );
427 break;
428 }
429
430 case CHT_MODIFY:
431 {
432 BOARD_ITEM* boardItemCopy = static_cast<BOARD_ITEM*>( entry.m_copy );
433
434 if( !( aCommitFlags & SKIP_UNDO ) )
435 {
436 ITEM_PICKER itemWrapper( nullptr, boardItem, UNDO_REDO::CHANGED );
437 itemWrapper.SetLink( entry.m_copy );
438 entry.m_copy = nullptr; // We've transferred ownership to the undo list
439 undoList.PushItem( itemWrapper );
440 }
441
442 if( !( aCommitFlags & SKIP_CONNECTIVITY ) )
443 {
444 connectivity->MarkItemNetAsDirty( boardItemCopy );
445 connectivity->Update( boardItem );
446 }
447
448 if( boardItem->Type() != PCB_MARKER_T )
449 {
450 propagateDamage( boardItemCopy, staleZones, staleRuleAreas ); // before
451 propagateDamage( boardItem, staleZones, staleRuleAreas ); // after
452 }
453
454 updateComponentClasses( boardItem );
455
456 if( view && boardItem->Type() != PCB_NETINFO_T )
457 view->Update( boardItem );
458
459 itemsChanged.push_back( boardItem );
460 break;
461 }
462
463 default:
464 UNIMPLEMENTED_FOR( boardItem->GetClass() );
465 break;
466 }
467
468 // Delete any copies we still have ownership of
469 delete entry.m_copy;
470 entry.m_copy = nullptr;
471
472 boardItem->ClearEditFlags();
473 boardItem->RunOnChildren(
474 [&]( BOARD_ITEM* item )
475 {
476 item->ClearEditFlags();
477 },
479 } // ... and regenerate them.
480
481 // Invalidate component classes
483
484 if( m_isBoardEditor )
485 {
486 size_t originalCount = m_entries.size();
487
488 if( aCommitFlags & SKIP_CONNECTIVITY )
489 {
490 connectivity->ClearRatsnest();
491 connectivity->ClearLocalRatsnest();
492 }
493 else
494 {
495 connectivity->RecalculateRatsnest( this );
497 connectivity->ClearLocalRatsnest();
498
499 if( frame )
500 frame->GetCanvas()->RedrawRatsnest();
501
502 board->OnRatsnestChanged();
503 }
504
505 if( solderMaskDirty )
506 {
507 if( frame )
508 frame->HideSolderMask();
509 }
510
511 if( updateBoardBoundingBox && view )
512 {
513 if( PCB_BOARD_OUTLINE* outline = board->BoardOutline() )
514 {
515 board->UpdateBoardOutline();
516
517 if( view->HasItem( outline ) )
518 view->Update( outline );
519 else
520 view->Add( outline );
521 }
522 }
523
524 if( PCBNEW_SETTINGS* cfg = GetAppSettings<PCBNEW_SETTINGS>( "pcbnew" ) )
525 {
526 if( !staleRuleAreas.empty() && ( cfg->m_Display.m_TrackClearance == SHOW_WITH_VIA_ALWAYS
527 || cfg->m_Display.m_PadClearance ) )
528 {
529 if( view )
530 view->UpdateCollidingItems( staleRuleAreas, { PCB_TRACE_T, PCB_ARC_T, PCB_VIA_T, PCB_PAD_T } );
531 }
532 }
533
534 if( !staleTeardropPadsAndVias.empty() || !staleTeardropTracks.empty() )
535 {
536 teardropMgr.UpdateTeardrops( *this, &staleTeardropPadsAndVias, &staleTeardropTracks );
537
538 // UpdateTeardrops() can modify the ratsnest data. So rebuild this ratsnest data
539 connectivity->RecalculateRatsnest( this );
540 }
541
542 // Log undo items for any connectivity or teardrop changes
543 for( size_t i = originalCount; i < m_entries.size(); ++i )
544 {
545 COMMIT_LINE& entry = m_entries[i];
546 BOARD_ITEM* boardItem = nullptr;
547 BOARD_ITEM* boardItemCopy = nullptr;
548
549 if( entry.m_item && entry.m_item->IsBOARD_ITEM() )
550 boardItem = static_cast<BOARD_ITEM*>( entry.m_item );
551
552 if( entry.m_copy && entry.m_copy->IsBOARD_ITEM() )
553 boardItemCopy = static_cast<BOARD_ITEM*>( entry.m_copy );
554
555 wxCHECK2( boardItem, continue );
556
557 if( !( aCommitFlags & SKIP_UNDO ) )
558 {
559 ITEM_PICKER itemWrapper( nullptr, boardItem, convert( entry.m_type & CHT_TYPE ) );
560 itemWrapper.SetLink( boardItemCopy );
561 undoList.PushItem( itemWrapper );
562 }
563 else
564 {
565 delete entry.m_copy;
566 }
567
568 if( view && boardItem->Type() != PCB_NETINFO_T )
569 {
570 if( ( entry.m_type & CHT_TYPE ) == CHT_ADD )
571 view->Add( boardItem );
572 else if( ( entry.m_type & CHT_TYPE ) == CHT_REMOVE )
573 view->Remove( boardItem );
574 else
575 view->Update( boardItem );
576 }
577 }
578 }
579
580 if( bulkAddedItems.size() > 0 || bulkRemovedItems.size() > 0 || itemsChanged.size() > 0 )
581 board->OnItemsCompositeUpdate( bulkAddedItems, bulkRemovedItems, itemsChanged );
582
583 if( frame )
584 {
585 if( !( aCommitFlags & SKIP_UNDO ) )
586 {
587 if( aCommitFlags & APPEND_UNDO )
589 else
590 frame->SaveCopyInUndoList( undoList, UNDO_REDO::UNSPECIFIED );
591 }
592 }
593
594 m_toolMgr->PostEvent( { TC_MESSAGE, TA_MODEL_CHANGE, AS_GLOBAL } );
595
596 if( itemsDeselected )
598
599 if( autofillZones )
600 {
601 ZONE_FILLER_TOOL* zoneFillerTool = m_toolMgr->GetTool<ZONE_FILLER_TOOL>();
602
603 for( ZONE* zone : *staleZones )
604 zoneFillerTool->DirtyZone( zone );
605
607 }
608
610
611 if( selectedModified )
613
614 if( frame )
615 {
616 if( !( aCommitFlags & SKIP_SET_DIRTY ) )
617 frame->OnModify();
618 else
620
621 // Ensure the message panel is updated after committing changes.
622 // By default (i.e. if no event posted), display the updated board info
623 if( !itemsDeselected && !autofillZones && !selectedModified )
624 {
625 std::vector<MSG_PANEL_ITEM> msg_list;
626 board->GetMsgPanelInfo( frame, msg_list );
627 frame->SetMsgPanel( msg_list );
628 }
629 }
630
631 clear();
632}
633
634
636{
637 // Easiest way to disallow both a parent and one of its children appearing in the list
638 // is to only ever add the parent when either can be legal (ie: in the board editor).
639 if( m_isBoardEditor && aItem->IsBOARD_ITEM() )
640 {
641 if( FOOTPRINT* footprint = static_cast<BOARD_ITEM*>( aItem )->GetParentFootprint() )
642 return footprint;
643 }
644
645 EDA_ITEM* parent = aItem->GetParent();
646
647 if( parent && parent->Type() == PCB_TABLE_T )
648 return parent;
649
650 return aItem;
651}
652
653
655{
656 return MakeImage( aItem );
657}
658
659
661{
662 EDA_ITEM* clone = aItem->Clone();
663 clone->SetFlags( UR_TRANSIENT );
664
665 return clone;
666}
667
668
670{
671 PICKED_ITEMS_LIST undoList;
672 KIGFX::VIEW* view = m_toolMgr->GetView();
673 BOARD* board = (BOARD*) m_toolMgr->GetModel();
674 std::shared_ptr<CONNECTIVITY_DATA> connectivity = board->GetConnectivity();
675
676 board->IncrementTimeStamp(); // clear caches
677
678 auto updateComponentClasses =
679 [this]( BOARD_ITEM* boardItem )
680 {
681 if( boardItem->Type() != PCB_FOOTPRINT_T )
682 return;
683
684 FOOTPRINT* footprint = static_cast<FOOTPRINT*>( boardItem );
686 };
687
688 std::vector<BOARD_ITEM*> bulkAddedItems;
689 std::vector<BOARD_ITEM*> bulkRemovedItems;
690 std::vector<BOARD_ITEM*> itemsChanged;
691 std::vector<BOARD_ITEM*> itemsToDelete;
692
693 for( COMMIT_LINE& entry : m_entries )
694 {
695 if( !entry.m_item || !entry.m_item->IsBOARD_ITEM() )
696 continue;
697
698 BOARD_ITEM* boardItem = static_cast<BOARD_ITEM*>( entry.m_item );
699 int changeType = entry.m_type & CHT_TYPE;
700 int changeFlags = entry.m_type & CHT_FLAGS;
701
702 switch( changeType )
703 {
704 case CHT_ADD:
705 if( changeFlags & CHT_DONE )
706 {
707 if( boardItem->Type() != PCB_NETINFO_T )
708 view->Remove( boardItem );
709
710 connectivity->Remove( boardItem );
711
713 {
714 if( FOOTPRINT* parentFP = board->GetFirstFootprint() )
715 parentFP->Remove( boardItem );
716 }
717 else
718 {
719 board->Remove( boardItem, REMOVE_MODE::BULK );
720 bulkRemovedItems.push_back( boardItem );
721 }
722 }
723
724 // Defer deletion until after OnItemsCompositeUpdate so that
725 // board listeners do not receive dangling pointers.
726 itemsToDelete.push_back( boardItem );
727 entry.m_item = nullptr;
728 continue;
729
730 case CHT_REMOVE:
731 {
732 if( !( changeFlags & CHT_DONE ) )
733 break;
734
735 if( boardItem->Type() != PCB_NETINFO_T )
736 view->Add( boardItem );
737
739 {
740 if( FOOTPRINT* parentFP = board->GetFirstFootprint() )
741 parentFP->Add( boardItem, ADD_MODE::INSERT );
742 }
743 else
744 {
745 board->Add( boardItem, ADD_MODE::INSERT );
746 bulkAddedItems.push_back( boardItem );
747 }
748
749 updateComponentClasses( boardItem );
750 break;
751 }
752
753 case CHT_MODIFY:
754 {
755 if( boardItem->Type() != PCB_NETINFO_T )
756 view->Remove( boardItem );
757
758 connectivity->Remove( boardItem );
759
760 wxASSERT( entry.m_copy && entry.m_copy->IsBOARD_ITEM() );
761 BOARD_ITEM* boardItemCopy = static_cast<BOARD_ITEM*>( entry.m_copy );
762 boardItem->SwapItemData( boardItemCopy );
763
764 if( boardItem->Type() != PCB_NETINFO_T )
765 view->Add( boardItem );
766
767 connectivity->Add( boardItem );
768 itemsChanged.push_back( boardItem );
769
770 updateComponentClasses( boardItem );
771 break;
772 }
773
774 default:
775 UNIMPLEMENTED_FOR( boardItem->GetClass() );
776 break;
777 }
778
779 // Delete any copies we still have ownership of
780 delete entry.m_copy;
781 entry.m_copy = nullptr;
782
783 boardItem->ClearEditFlags();
784 }
785
786 // Invalidate component classes
788
789 if( bulkAddedItems.size() > 0 || bulkRemovedItems.size() > 0 || itemsChanged.size() > 0 )
790 board->OnItemsCompositeUpdate( bulkAddedItems, bulkRemovedItems, itemsChanged );
791
792 for( BOARD_ITEM* item : itemsToDelete )
793 delete item;
794
795 if( m_isBoardEditor )
796 {
797 connectivity->RecalculateRatsnest();
799 board->OnRatsnestChanged();
800 }
801
802 PCB_SELECTION_TOOL* selTool = m_toolMgr->GetTool<PCB_SELECTION_TOOL>();
803 selTool->RebuildSelection();
804
805 // Property panel needs to know about the reselect
807
808 clear();
809}
#define SKIP_CONNECTIVITY
#define SKIP_SET_DIRTY
#define APPEND_UNDO
#define SKIP_UNDO
#define ZONE_FILL_OP
#define SKIP_ENTERED_GROUP
#define SKIP_TEARDROPS
BOX2< VECTOR2I > BOX2I
Definition box2.h:922
Handles how to draw a screen (a board, a schematic ...)
Definition base_screen.h:41
virtual void Push(const wxString &aMessage=wxEmptyString, int aCommitFlags=0) override
Execute the changes.
COMMIT & Stage(EDA_ITEM *aItem, CHANGE_TYPE aChangeType, BASE_SCREEN *aScreen=nullptr, RECURSE_MODE aRecurse=RECURSE_MODE::NO_RECURSE) override
Add a change of the item aItem of type aChangeType to the change list.
BOARD * GetBoard() const
virtual void Revert() override
Revert the commit by restoring the modified items state.
static EDA_ITEM * MakeImage(EDA_ITEM *aItem)
EDA_ITEM * undoLevelItem(EDA_ITEM *aItem) const override
bool m_isBoardEditor
EDA_ITEM * makeImage(EDA_ITEM *aItem) const override
void propagateDamage(BOARD_ITEM *aItem, std::vector< ZONE * > *aStaleZones, std::vector< BOX2I > &aStaleRuleAreas)
TOOL_MANAGER * m_toolMgr
bool m_isFootprintEditor
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:84
virtual PCB_LAYER_ID GetLayer() const
Return the primary layer this item is on.
Definition board_item.h:237
bool IsGroupableType() const
void SwapItemData(BOARD_ITEM *aImage)
Swap data between aItem and aImage.
virtual bool IsOnLayer(PCB_LAYER_ID aLayer) const
Test to see if this object is on the given layer.
Definition board_item.h:319
virtual LSET GetLayerSet() const
Return a std::bitset of all layers on which the item physically resides.
Definition board_item.h:257
virtual void RunOnChildren(const std::function< void(BOARD_ITEM *)> &aFunction, RECURSE_MODE aMode) const
Invoke a function on all children.
Definition board_item.h:213
Information pertinent to a Pcbnew printed circuit board.
Definition board.h:322
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT, bool aSkipConnectivity=false) override
Removes an item from the container.
Definition board.cpp:1222
PCB_BOARD_OUTLINE * BoardOutline()
Definition board.h:371
void UpdateBoardOutline()
Definition board.cpp:3642
const ZONES & Zones() const
Definition board.h:367
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:3255
FOOTPRINT * GetFirstFootprint() const
Get the first footprint on the board or nullptr.
Definition board.h:530
void IncrementTimeStamp()
Definition board.cpp:258
void OnRatsnestChanged()
Notify the board and its listeners that the ratsnest has been recomputed.
Definition board.cpp:3262
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:2182
void UpdateRatsnestExclusions()
Update the visibility flags on the current unconnected ratsnest lines.
Definition board.cpp:298
COMPONENT_CLASS_MANAGER & GetComponentClassManager()
Gets the component class manager.
Definition board.h:1407
void Remove(BOARD_ITEM *aBoardItem, REMOVE_MODE aMode=REMOVE_MODE::NORMAL) override
Removes an item from the container.
Definition board.cpp:1381
std::shared_ptr< CONNECTIVITY_DATA > GetConnectivity() const
Return a list of missing connections between components/tracks.
Definition board.h:563
bool Empty() const
Definition commit.h:137
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
COMMIT()
Definition commit.cpp:34
std::vector< COMMIT_LINE > m_entries
Definition commit.h:185
void clear()
Should be called in Push() & Revert() methods.
Definition commit.h:157
virtual COMMIT & Stage(EDA_ITEM *aItem, CHANGE_TYPE aChangeType, BASE_SCREEN *aScreen=nullptr, RECURSE_MODE aRecurse=RECURSE_MODE::NO_RECURSE)
Add a change of the item aItem of type aChangeType to the change list.
Definition commit.cpp:46
void InvalidateComponentClasses()
Invalidates any caches component classes and recomputes caches if required.
void RebuildRequiredCaches(FOOTPRINT *aFootprint=nullptr) const
Rebuilds any caches that may be required by custom assignment rules.
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 set of EDA_ITEMs (i.e., without duplicates).
Definition eda_group.h:46
void RemoveItem(EDA_ITEM *aItem)
Remove item from group.
Definition eda_group.cpp:40
virtual EDA_ITEM * AsEdaItem()=0
A base class for most all the KiCad significant classes used in schematics and boards.
Definition eda_item.h:99
virtual void ClearEditFlags()
Definition eda_item.h:162
virtual const BOX2I GetBoundingBox() const
Return the orthogonal bounding box of this object for display purposes.
Definition eda_item.cpp:120
void SetFlags(EDA_ITEM_FLAGS aMask)
Definition eda_item.h:148
virtual EDA_GROUP * GetParentGroup() const
Definition eda_item.h:117
KICAD_T Type() const
Returns the type of object.
Definition eda_item.h:111
bool IsSelected() const
Definition eda_item.h:128
EDA_ITEM * GetParent() const
Definition eda_item.h:113
virtual EDA_ITEM * Clone() const
Create a duplicate of this item with linked list members set to NULL.
Definition eda_item.cpp:128
EDA_ITEM_FLAGS GetFlags() const
Definition eda_item.h:151
static const TOOL_EVENT SelectedItemsModified
Selected items were moved, this can be very high frequency on the canvas, use with care.
Definition actions.h:352
static const TOOL_EVENT UnselectedEvent
Definition actions.h:346
void SetLink(EDA_ITEM *aItem)
virtual void Update(const VIEW_ITEM *aItem, int aUpdateFlags) const override
For dynamic VIEWs, inform the associated VIEW that the graphical representation of this item has chan...
Definition pcb_view.cpp:91
virtual void Add(VIEW_ITEM *aItem, int aDrawPriority=-1) override
Add a VIEW_ITEM to the view.
Definition pcb_view.cpp:57
void UpdateCollidingItems(const std::vector< BOX2I > &aStaleAreas, std::initializer_list< KICAD_T > aTypes)
Sets the KIGFX::REPAINT on all items matching aTypes which intersect aStaleAreas.
Definition pcb_view.cpp:122
virtual void Remove(VIEW_ITEM *aItem) override
Remove a VIEW_ITEM from the view.
Definition pcb_view.cpp:74
bool IsBOARD_ITEM() const
Definition view_item.h:102
virtual wxString GetClass() const =0
Return the class name.
Hold a (potentially large) number of VIEW_ITEMs and renders them on a graphics device provided by the...
Definition view.h:67
virtual void Add(VIEW_ITEM *aItem, int aDrawPriority=-1)
Add a VIEW_ITEM to the view.
Definition view.cpp:299
virtual void Remove(VIEW_ITEM *aItem)
Remove a VIEW_ITEM from the view.
Definition view.cpp:342
bool HasItem(const VIEW_ITEM *aItem) const
Indicates whether or not the given item has been added to the view.
Definition view.cpp:1686
LSET is a set of PCB_LAYER_IDs.
Definition lset.h:37
static LSET AllCuMask()
return AllCuMask( MAX_CU_LAYERS );
Definition lset.cpp:608
static const LSET & PhysicalLayersMask()
Return a mask holding all layers which are physically realized.
Definition lset.cpp:697
Definition pad.h:55
DISPLAY_OPTIONS m_Display
static TOOL_ACTION rehatchShapes
static TOOL_ACTION zoneFillDirty
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:53
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.
void PushItem(const ITEM_PICKER &aItem)
Push aItem to the top of the list.
void SetDescription(const wxString &aDescription)
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:95
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:230
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:185
Base abstract interface for all kinds of tools.
Definition tool_base.h:66
Master controller class:
TOOLS_HOLDER * GetToolHolder() const
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_REMOVE
Definition commit.h:43
@ CHT_DONE
Flag to indicate the change is already applied.
Definition commit.h:47
@ CHT_TYPE
Definition commit.h:45
@ CHT_ADD
Definition commit.h:42
@ CHT_FLAGS
Definition commit.h:48
RECURSE_MODE
Definition eda_item.h:51
@ RECURSE
Definition eda_item.h:52
@ NO_RECURSE
Definition eda_item.h:53
#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.
@ SHOW_WITH_VIA_ALWAYS
see class PGM_BASE
T * GetAppSettings(const char *aFilename)
EDA_ITEM * m_copy
Optional copy of the item.
Definition commit.h:151
CHANGE_TYPE m_type
Modification type.
Definition commit.h:152
EDA_ITEM * m_item
Main item that is added/deleted/modified.
Definition commit.h:150
@ AS_GLOBAL
Global action (toolbar/main menu event, global shortcut)
Definition tool_action.h:49
@ TA_MODEL_CHANGE
Model has changed (partial update).
Definition tool_event.h:121
@ TC_MESSAGE
Definition tool_event.h:58
@ 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:106
@ PCB_DIM_LEADER_T
class PCB_DIM_LEADER, a leader dimension (graphic item)
Definition typeinfo.h:103
@ 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:104
@ PCB_GROUP_T
class PCB_GROUP, a set of BOARD_ITEMs
Definition typeinfo.h:111
@ 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:108
@ 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_BARCODE_T
class PCB_BARCODE, a barcode (graphic item)
Definition typeinfo.h:101
@ PCB_TARGET_T
class PCB_TARGET, a target (graphic item)
Definition typeinfo.h:107
@ 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:102
@ 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:110
@ PCB_POINT_T
class PCB_POINT, a 0-dimensional point
Definition typeinfo.h:113
@ 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:105
UNDO_REDO
Undo Redo considerations: Basically we have 3 cases New item Deleted item Modified item there is also...