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 <pad.h>
34#include <pcb_group.h>
35#include <pcb_track.h>
36#include <pcb_shape.h>
37#include <tool/tool_manager.h>
40#include <view/view.h>
41#include <board_commit.h>
42#include <tools/pcb_tool_base.h>
43#include <tools/pcb_actions.h>
46#include <teardrop/teardrop.h>
47#include <pcb_board_outline.h>
48
49#include <functional>
51using namespace std::placeholders;
52
53
55 COMMIT(),
56 m_toolMgr( aTool->GetManager() ),
57 m_isBoardEditor( false ),
58 m_isFootprintEditor( false )
59{
60 if( PCB_TOOL_BASE* pcb_tool = dynamic_cast<PCB_TOOL_BASE*>( aTool ) )
61 {
62 m_isBoardEditor = pcb_tool->IsBoardEditor();
63 m_isFootprintEditor = pcb_tool->IsFootprintEditor();
64 }
65}
66
67
69 COMMIT(),
70 m_toolMgr( aFrame->GetToolManager() ),
71 m_isBoardEditor( aFrame->IsType( FRAME_PCB_EDITOR ) ),
73{
74}
75
76
78 COMMIT(),
79 m_toolMgr( aMgr ),
80 m_isBoardEditor( false ),
81 m_isFootprintEditor( false )
82{
83 EDA_DRAW_FRAME* frame = dynamic_cast<EDA_DRAW_FRAME*>( aMgr->GetToolHolder() );
84
85 if( frame && frame->IsType( FRAME_PCB_EDITOR ) )
86 m_isBoardEditor = true;
87 else if( frame && frame->IsType( FRAME_FOOTPRINT_EDITOR ) )
89}
90
91
92BOARD_COMMIT::BOARD_COMMIT( TOOL_MANAGER* aMgr, bool aIsBoardEditor, bool aIsFootprintEditor ) :
93 COMMIT(),
94 m_toolMgr( aMgr ),
95 m_isBoardEditor( aIsBoardEditor ),
96 m_isFootprintEditor( aIsFootprintEditor )
97{
98}
99
100
102{
103 return static_cast<BOARD*>( m_toolMgr->GetModel() );
104}
105
106
107COMMIT& BOARD_COMMIT::Stage( EDA_ITEM* aItem, CHANGE_TYPE aChangeType, BASE_SCREEN* aScreen, RECURSE_MODE aRecurse )
108{
109 if( aRecurse == RECURSE_MODE::RECURSE )
110 {
111 if( PCB_GROUP* group = dynamic_cast<PCB_GROUP*>( aItem ) )
112 {
113 for( EDA_ITEM* member : group->GetItems() )
114 Stage( member, aChangeType, aScreen, aRecurse );
115 }
116 }
117
118 return COMMIT::Stage( aItem, aChangeType );
119}
120
121
122COMMIT& BOARD_COMMIT::Stage( std::vector<EDA_ITEM*>& container, CHANGE_TYPE aChangeType, BASE_SCREEN* aScreen )
123{
124 return COMMIT::Stage( container, aChangeType, aScreen );
125}
126
127
129{
130 return COMMIT::Stage( aItems, aModFlag, aScreen );
131}
132
133
134void BOARD_COMMIT::propagateDamage( BOARD_ITEM* aChangedItem, std::vector<ZONE*>* aStaleZones,
135 std::vector<BOX2I>& aStaleRuleAreas )
136{
137 wxCHECK( aChangedItem, /* void */ );
138
139 if( aStaleZones && aChangedItem->Type() == PCB_ZONE_T )
140 aStaleZones->push_back( static_cast<ZONE*>( aChangedItem ) );
141
142 aChangedItem->RunOnChildren( std::bind( &BOARD_COMMIT::propagateDamage, this, _1, aStaleZones, aStaleRuleAreas ),
144
145 BOARD* board = static_cast<BOARD*>( m_toolMgr->GetModel() );
146 BOX2I damageBBox = aChangedItem->GetBoundingBox();
147 LSET damageLayers = aChangedItem->GetLayerSet();
148
149 if( m_isBoardEditor && aChangedItem->Type() == PCB_ZONE_T )
150 {
151 // A named zone can have custom DRC rules targetting it.
152 if( !static_cast<ZONE*>( aChangedItem )->GetZoneName().IsEmpty() )
153 aStaleRuleAreas.push_back( damageBBox );
154 }
155
156 if( aStaleZones )
157 {
158 if( damageLayers.test( Edge_Cuts ) || damageLayers.test( Margin ) )
159 damageLayers = LSET::PhysicalLayersMask();
160 else
161 damageLayers &= LSET::AllCuMask();
162
163 if( damageLayers.any() )
164 {
165 for( ZONE* zone : board->Zones() )
166 {
167 if( zone->GetIsRuleArea() )
168 continue;
169
170 if( ( zone->GetLayerSet() & damageLayers ).any() && zone->GetBoundingBox().Intersects( damageBBox ) )
171 aStaleZones->push_back( zone );
172 }
173 }
174 }
175}
176
177
178void BOARD_COMMIT::Push( const wxString& aMessage, int aCommitFlags )
179{
180 KIGFX::PCB_VIEW* view = static_cast<KIGFX::PCB_VIEW*>( m_toolMgr->GetView() );
181 BOARD* board = static_cast<BOARD*>( m_toolMgr->GetModel() );
182 PCB_BASE_FRAME* frame = dynamic_cast<PCB_BASE_FRAME*>( m_toolMgr->GetToolHolder() );
183 PCB_SELECTION_TOOL* selTool = m_toolMgr->GetTool<PCB_SELECTION_TOOL>();
184 PCB_GROUP* enteredGroup = selTool && !( aCommitFlags & SKIP_ENTERED_GROUP ) ? selTool->GetEnteredGroup()
185 : nullptr;
186 // Notification info
187 PICKED_ITEMS_LIST undoList;
188 bool itemsDeselected = false;
189 bool selectedModified = false;
190
191 // Dirty flags and lists
192 bool solderMaskDirty = false;
193 bool autofillZones = false;
194 bool updateBoardBoundingBox = false;
195 std::vector<BOARD_ITEM*> staleTeardropPadsAndVias;
196 std::set<PCB_TRACK*> staleTeardropTracks;
197 std::vector<ZONE*> staleZonesStorage;
198 std::vector<ZONE*>* staleZones = nullptr;
199 std::vector<BOX2I> staleRuleAreas;
200
201 if( Empty() )
202 return;
203
204 undoList.SetDescription( aMessage );
205
206 TEARDROP_MANAGER teardropMgr( board, m_toolMgr );
207 std::shared_ptr<CONNECTIVITY_DATA> connectivity = board->GetConnectivity();
208
209 // Note: frame == nullptr happens in QA tests
210
211 std::vector<BOARD_ITEM*> bulkAddedItems;
212 std::vector<BOARD_ITEM*> bulkRemovedItems;
213 std::vector<BOARD_ITEM*> itemsChanged;
214
215 if( m_isBoardEditor && !( aCommitFlags & ZONE_FILL_OP )
216 && ( frame && frame->GetPcbNewSettings()->m_AutoRefillZones ) )
217 {
218 autofillZones = true;
219 staleZones = &staleZonesStorage;
220
221 for( ZONE* zone : board->Zones() )
222 zone->CacheBoundingBox();
223 }
224
225 for( COMMIT_LINE& entry : m_entries )
226 {
227 if( !entry.m_item || !entry.m_item->IsBOARD_ITEM() )
228 continue;
229
230 BOARD_ITEM* boardItem = static_cast<BOARD_ITEM*>( entry.m_item );
231
232 if( m_isBoardEditor )
233 {
234 if( boardItem->Type() == PCB_VIA_T || boardItem->Type() == PCB_FOOTPRINT_T
235 || boardItem->IsOnLayer( F_Mask ) || boardItem->IsOnLayer( B_Mask ) )
236 {
237 solderMaskDirty = true;
238 }
239
240 if( boardItem->GetLayer() == Edge_Cuts )
241 {
242 updateBoardBoundingBox = true;
243 }
244
245 if( !( aCommitFlags & SKIP_TEARDROPS ) )
246 {
247 if( boardItem->Type() == PCB_FOOTPRINT_T )
248 {
249 for( PAD* pad : static_cast<FOOTPRINT*>( boardItem )->Pads() )
250 staleTeardropPadsAndVias.push_back( pad );
251 }
252 else if( boardItem->Type() == PCB_PAD_T || boardItem->Type() == PCB_VIA_T )
253 {
254 staleTeardropPadsAndVias.push_back( boardItem );
255 }
256 else if( boardItem->Type() == PCB_TRACE_T || boardItem->Type() == PCB_ARC_T )
257 {
258 PCB_TRACK* track = static_cast<PCB_TRACK*>( boardItem );
259
260 staleTeardropTracks.insert( track );
261
262 std::vector<PAD*> connectedPads;
263 std::vector<PCB_VIA*> connectedVias;
264
265 connectivity->GetConnectedPadsAndVias( track, &connectedPads, &connectedVias );
266
267 for( PAD* pad : connectedPads )
268 staleTeardropPadsAndVias.push_back( pad );
269
270 for( PCB_VIA* via : connectedVias )
271 staleTeardropPadsAndVias.push_back( via );
272 }
273 }
274 }
275
276 if( boardItem->IsSelected() || ( m_isFootprintEditor && boardItem == board->GetFirstFootprint() ) )
277 selectedModified = true;
278 }
279
280 // Old teardrops must be removed before connectivity is rebuilt
281 if( !staleTeardropPadsAndVias.empty() || !staleTeardropTracks.empty() )
282 teardropMgr.RemoveTeardrops( *this, &staleTeardropPadsAndVias, &staleTeardropTracks );
283
284 auto updateComponentClasses =
285 [this]( BOARD_ITEM* boardItem )
286 {
287 if( boardItem->Type() != PCB_FOOTPRINT_T )
288 return;
289
290 FOOTPRINT* footprint = static_cast<FOOTPRINT*>( boardItem );
292 };
293
294 // We don't know that anything will be added to the entered group, but it does no harm to
295 // add it to the commit anyway.
296 if( enteredGroup )
297 Modify( enteredGroup );
298
299
300 for( COMMIT_LINE& entry : m_entries )
301 {
302 if( !entry.m_item || !entry.m_item->IsBOARD_ITEM() )
303 continue;
304
305 BOARD_ITEM* boardItem = static_cast<BOARD_ITEM*>( entry.m_item );
306 int changeType = entry.m_type & CHT_TYPE;
307 int changeFlags = entry.m_type & CHT_FLAGS;
308
309 switch( changeType )
310 {
311 case CHT_ADD:
312 if( enteredGroup && boardItem->IsGroupableType() && !boardItem->GetParentGroup() )
313 enteredGroup->AddItem( boardItem );
314
315 if( !( aCommitFlags & SKIP_UNDO ) )
316 undoList.PushItem( ITEM_PICKER( nullptr, boardItem, UNDO_REDO::NEWITEM ) );
317
318 if( !( changeFlags & CHT_DONE ) )
319 {
321 {
322 if( FOOTPRINT* parentFP = board->GetFirstFootprint() )
323 parentFP->Add( boardItem );
324 }
325 else
326 {
327 board->Add( boardItem, ADD_MODE::BULK_INSERT ); // handles connectivity
328 bulkAddedItems.push_back( boardItem );
329 }
330 }
331
332 if( boardItem->Type() != PCB_MARKER_T )
333 propagateDamage( boardItem, staleZones, staleRuleAreas );
334
335 if( view && boardItem->Type() != PCB_NETINFO_T )
336 view->Add( boardItem );
337
338 updateComponentClasses( boardItem );
339
340 break;
341
342 case CHT_REMOVE:
343 {
344 EDA_GROUP* parentGroup = boardItem->GetParentGroup();
345
346 if( !( aCommitFlags & SKIP_UNDO ) )
347 {
348 ITEM_PICKER itemWrapper( nullptr, boardItem, UNDO_REDO::DELETED );
349 itemWrapper.SetLink( entry.m_copy );
350 entry.m_copy = nullptr; // We've transferred ownership to the undo list
351 undoList.PushItem( itemWrapper );
352 }
353
354 if( boardItem->IsSelected() )
355 {
356 if( selTool )
357 selTool->RemoveItemFromSel( boardItem, true /* quiet mode */ );
358
359 itemsDeselected = true;
360 }
361
362 if( parentGroup && !( parentGroup->AsEdaItem()->GetFlags() & STRUCT_DELETED ) )
363 parentGroup->RemoveItem( boardItem );
364
365 if( boardItem->Type() != PCB_MARKER_T )
366 propagateDamage( boardItem, staleZones, staleRuleAreas );
367
368 switch( boardItem->Type() )
369 {
370 case PCB_FIELD_T:
371 static_cast<PCB_FIELD*>( boardItem )->SetVisible( false );
372 break;
373
374 case PCB_TEXT_T:
375 case PCB_PAD_T:
376 case PCB_SHAPE_T:
378 case PCB_GENERATOR_T:
379 case PCB_TEXTBOX_T:
380 case PCB_BARCODE_T:
381 case PCB_TABLE_T:
382 case PCB_TRACE_T:
383 case PCB_ARC_T:
384 case PCB_VIA_T:
386 case PCB_DIM_CENTER_T:
387 case PCB_DIM_RADIAL_T:
389 case PCB_DIM_LEADER_T:
390 case PCB_TARGET_T:
391 case PCB_MARKER_T:
392 case PCB_POINT_T:
393 case PCB_ZONE_T:
394 case PCB_FOOTPRINT_T:
395 case PCB_GROUP_T:
396 if( view )
397 view->Remove( boardItem );
398
399 if( !( changeFlags & CHT_DONE ) )
400 {
402 {
403 if( FOOTPRINT* parentFP = board->GetFirstFootprint() )
404 parentFP->Remove( boardItem );
405 }
406 else
407 {
408 board->Remove( boardItem, REMOVE_MODE::BULK );
409 bulkRemovedItems.push_back( boardItem );
410 }
411 }
412
413 break;
414
415 // Metadata items
416 case PCB_NETINFO_T:
417 board->Remove( boardItem, REMOVE_MODE::BULK );
418 bulkRemovedItems.push_back( boardItem );
419 break;
420
421 default: // other types do not need to (or should not) be handled
422 wxASSERT( false );
423 break;
424 }
425
426 // The item has been removed from the board; it is now owned by undo/redo.
427 boardItem->SetFlags( UR_TRANSIENT );
428 break;
429 }
430
431 case CHT_MODIFY:
432 {
433 BOARD_ITEM* boardItemCopy = static_cast<BOARD_ITEM*>( entry.m_copy );
434
435 if( !( aCommitFlags & SKIP_UNDO ) )
436 {
437 ITEM_PICKER itemWrapper( nullptr, boardItem, UNDO_REDO::CHANGED );
438 itemWrapper.SetLink( entry.m_copy );
439 entry.m_copy = nullptr; // We've transferred ownership to the undo list
440 undoList.PushItem( itemWrapper );
441 }
442
443 if( !( aCommitFlags & SKIP_CONNECTIVITY ) )
444 {
445 connectivity->MarkItemNetAsDirty( boardItemCopy );
446 connectivity->Update( boardItem );
447 }
448
449 if( boardItem->Type() != PCB_MARKER_T )
450 {
451 propagateDamage( boardItemCopy, staleZones, staleRuleAreas ); // before
452 propagateDamage( boardItem, staleZones, staleRuleAreas ); // after
453 }
454
455 updateComponentClasses( boardItem );
456
457 if( view && boardItem->Type() != PCB_NETINFO_T )
458 view->Update( boardItem );
459
460 itemsChanged.push_back( boardItem );
461 break;
462 }
463
464 default:
465 UNIMPLEMENTED_FOR( boardItem->GetClass() );
466 break;
467 }
468
469 // Delete any copies we still have ownership of
470 delete entry.m_copy;
471 entry.m_copy = nullptr;
472
473 boardItem->ClearEditFlags();
474 boardItem->RunOnChildren(
475 [&]( BOARD_ITEM* item )
476 {
477 item->ClearEditFlags();
478 },
480 } // ... and regenerate them.
481
482 // Invalidate component classes
484
485 if( m_isBoardEditor )
486 {
487 size_t originalCount = m_entries.size();
488
489 if( aCommitFlags & SKIP_CONNECTIVITY )
490 {
491 connectivity->ClearRatsnest();
492 connectivity->ClearLocalRatsnest();
493 }
494 else
495 {
496 connectivity->RecalculateRatsnest( this );
498 connectivity->ClearLocalRatsnest();
499
500 if( frame )
501 frame->GetCanvas()->RedrawRatsnest();
502
503 board->OnRatsnestChanged();
504 }
505
506 if( solderMaskDirty )
507 {
508 if( frame )
509 frame->HideSolderMask();
510 }
511
512 if( updateBoardBoundingBox && view )
513 {
514 if( PCB_BOARD_OUTLINE* outline = board->BoardOutline() )
515 {
516 board->UpdateBoardOutline();
517
518 if( view->HasItem( outline ) )
519 view->Update( outline );
520 else
521 view->Add( outline );
522 }
523 }
524
525 if( PCBNEW_SETTINGS* cfg = GetAppSettings<PCBNEW_SETTINGS>( "pcbnew" ) )
526 {
527 if( !staleRuleAreas.empty() && ( cfg->m_Display.m_TrackClearance == SHOW_WITH_VIA_ALWAYS
528 || cfg->m_Display.m_PadClearance ) )
529 {
530 if( view )
531 view->UpdateCollidingItems( staleRuleAreas, { PCB_TRACE_T, PCB_ARC_T, PCB_VIA_T, PCB_PAD_T } );
532 }
533 }
534
535 if( !staleTeardropPadsAndVias.empty() || !staleTeardropTracks.empty() )
536 {
537 teardropMgr.UpdateTeardrops( *this, &staleTeardropPadsAndVias, &staleTeardropTracks );
538
539 // UpdateTeardrops() can modify the ratsnest data. So rebuild this ratsnest data
540 connectivity->RecalculateRatsnest( this );
541 }
542
543 // Log undo items for any connectivity or teardrop changes
544 for( size_t i = originalCount; i < m_entries.size(); ++i )
545 {
546 COMMIT_LINE& entry = m_entries[i];
547 BOARD_ITEM* boardItem = nullptr;
548 BOARD_ITEM* boardItemCopy = nullptr;
549
550 if( entry.m_item && entry.m_item->IsBOARD_ITEM() )
551 boardItem = static_cast<BOARD_ITEM*>( entry.m_item );
552
553 if( entry.m_copy && entry.m_copy->IsBOARD_ITEM() )
554 boardItemCopy = static_cast<BOARD_ITEM*>( entry.m_copy );
555
556 wxCHECK2( boardItem, continue );
557
558 if( !( aCommitFlags & SKIP_UNDO ) )
559 {
560 ITEM_PICKER itemWrapper( nullptr, boardItem, convert( entry.m_type & CHT_TYPE ) );
561 itemWrapper.SetLink( boardItemCopy );
562 undoList.PushItem( itemWrapper );
563 }
564 else
565 {
566 delete entry.m_copy;
567 }
568
569 if( view && boardItem->Type() != PCB_NETINFO_T )
570 {
571 if( ( entry.m_type & CHT_TYPE ) == CHT_ADD )
572 view->Add( boardItem );
573 else if( ( entry.m_type & CHT_TYPE ) == CHT_REMOVE )
574 view->Remove( boardItem );
575 else
576 view->Update( boardItem );
577 }
578 }
579 }
580
581 if( bulkAddedItems.size() > 0 || bulkRemovedItems.size() > 0 || itemsChanged.size() > 0 )
582 board->OnItemsCompositeUpdate( bulkAddedItems, bulkRemovedItems, itemsChanged );
583
584 if( frame )
585 {
586 if( !( aCommitFlags & SKIP_UNDO ) )
587 {
588 if( aCommitFlags & APPEND_UNDO )
590 else
591 frame->SaveCopyInUndoList( undoList, UNDO_REDO::UNSPECIFIED );
592 }
593 }
594
595 m_toolMgr->PostEvent( { TC_MESSAGE, TA_MODEL_CHANGE, AS_GLOBAL } );
596
597 if( itemsDeselected )
599
600 if( autofillZones )
601 {
602 ZONE_FILLER_TOOL* zoneFillerTool = m_toolMgr->GetTool<ZONE_FILLER_TOOL>();
603
604 for( ZONE* zone : *staleZones )
605 zoneFillerTool->DirtyZone( zone );
606
608 }
609
611
612 if( selectedModified )
614
615 if( frame )
616 {
617 if( !( aCommitFlags & SKIP_SET_DIRTY ) )
618 frame->OnModify();
619 else
621
622 // Ensure the message panel is updated after committing changes.
623 // By default (i.e. if no event posted), display the updated board info
624 if( !itemsDeselected && !autofillZones && !selectedModified )
625 {
626 std::vector<MSG_PANEL_ITEM> msg_list;
627 board->GetMsgPanelInfo( frame, msg_list );
628 frame->SetMsgPanel( msg_list );
629 }
630 }
631
632 clear();
633}
634
635
637{
638 // Easiest way to disallow both a parent and one of its children appearing in the list
639 // is to only ever add the parent when either can be legal (ie: in the board editor).
640 if( m_isBoardEditor && aItem->IsBOARD_ITEM() )
641 {
642 if( FOOTPRINT* footprint = static_cast<BOARD_ITEM*>( aItem )->GetParentFootprint() )
643 return footprint;
644 }
645
646 EDA_ITEM* parent = aItem->GetParent();
647
648 if( parent && parent->Type() == PCB_TABLE_T )
649 return parent;
650
651 return aItem;
652}
653
654
656{
657 return MakeImage( aItem );
658}
659
660
662{
663 EDA_ITEM* clone = aItem->Clone();
664 clone->SetFlags( UR_TRANSIENT );
665
666 return clone;
667}
668
669
671{
672 PICKED_ITEMS_LIST undoList;
673 KIGFX::VIEW* view = m_toolMgr->GetView();
674 BOARD* board = (BOARD*) m_toolMgr->GetModel();
675 std::shared_ptr<CONNECTIVITY_DATA> connectivity = board->GetConnectivity();
676
677 board->IncrementTimeStamp(); // clear caches
678
679 auto updateComponentClasses =
680 [this]( BOARD_ITEM* boardItem )
681 {
682 if( boardItem->Type() != PCB_FOOTPRINT_T )
683 return;
684
685 FOOTPRINT* footprint = static_cast<FOOTPRINT*>( boardItem );
687 };
688
689 std::vector<BOARD_ITEM*> bulkAddedItems;
690 std::vector<BOARD_ITEM*> bulkRemovedItems;
691 std::vector<BOARD_ITEM*> itemsChanged;
692 std::vector<BOARD_ITEM*> itemsToDelete;
693
694 for( COMMIT_LINE& entry : m_entries )
695 {
696 if( !entry.m_item || !entry.m_item->IsBOARD_ITEM() )
697 continue;
698
699 BOARD_ITEM* boardItem = static_cast<BOARD_ITEM*>( entry.m_item );
700 int changeType = entry.m_type & CHT_TYPE;
701 int changeFlags = entry.m_type & CHT_FLAGS;
702
703 switch( changeType )
704 {
705 case CHT_ADD:
706 if( changeFlags & CHT_DONE )
707 {
708 if( boardItem->Type() != PCB_NETINFO_T )
709 view->Remove( boardItem );
710
711 connectivity->Remove( boardItem );
712
714 {
715 if( FOOTPRINT* parentFP = board->GetFirstFootprint() )
716 parentFP->Remove( boardItem );
717 }
718 else
719 {
720 board->Remove( boardItem, REMOVE_MODE::BULK );
721 bulkRemovedItems.push_back( boardItem );
722 }
723 }
724
725 // Defer deletion until after OnItemsCompositeUpdate so that
726 // board listeners do not receive dangling pointers.
727 itemsToDelete.push_back( boardItem );
728 entry.m_item = nullptr;
729 continue;
730
731 case CHT_REMOVE:
732 {
733 if( !( changeFlags & CHT_DONE ) )
734 break;
735
736 if( boardItem->Type() != PCB_NETINFO_T )
737 view->Add( boardItem );
738
740 {
741 if( FOOTPRINT* parentFP = board->GetFirstFootprint() )
742 parentFP->Add( boardItem, ADD_MODE::INSERT );
743 }
744 else
745 {
746 board->Add( boardItem, ADD_MODE::INSERT );
747 bulkAddedItems.push_back( boardItem );
748 }
749
750 updateComponentClasses( boardItem );
751 break;
752 }
753
754 case CHT_MODIFY:
755 {
756 if( boardItem->Type() != PCB_NETINFO_T )
757 view->Remove( boardItem );
758
759 connectivity->Remove( boardItem );
760
761 wxASSERT( entry.m_copy && entry.m_copy->IsBOARD_ITEM() );
762 BOARD_ITEM* boardItemCopy = static_cast<BOARD_ITEM*>( entry.m_copy );
763 boardItem->SwapItemData( boardItemCopy );
764
765 if( boardItem->Type() != PCB_NETINFO_T )
766 view->Add( boardItem );
767
768 connectivity->Add( boardItem );
769 itemsChanged.push_back( boardItem );
770
771 updateComponentClasses( boardItem );
772 break;
773 }
774
775 default:
776 UNIMPLEMENTED_FOR( boardItem->GetClass() );
777 break;
778 }
779
780 // Delete any copies we still have ownership of
781 delete entry.m_copy;
782 entry.m_copy = nullptr;
783
784 boardItem->ClearEditFlags();
785 }
786
787 // Invalidate component classes
789
790 if( bulkAddedItems.size() > 0 || bulkRemovedItems.size() > 0 || itemsChanged.size() > 0 )
791 board->OnItemsCompositeUpdate( bulkAddedItems, bulkRemovedItems, itemsChanged );
792
793 for( BOARD_ITEM* item : itemsToDelete )
794 delete item;
795
796 if( m_isBoardEditor )
797 {
798 connectivity->RecalculateRatsnest();
800 board->OnRatsnestChanged();
801 }
802
803 PCB_SELECTION_TOOL* selTool = m_toolMgr->GetTool<PCB_SELECTION_TOOL>();
804 selTool->RebuildSelection();
805
806 // Property panel needs to know about the reselect
808
809 clear();
810}
#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:1223
PCB_BOARD_OUTLINE * BoardOutline()
Definition board.h:371
void UpdateBoardOutline()
Definition board.cpp:3646
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:3259
FOOTPRINT * GetFirstFootprint() const
Get the first footprint on the board or nullptr.
Definition board.h:530
void IncrementTimeStamp()
Definition board.cpp:259
void OnRatsnestChanged()
Notify the board and its listeners that the ratsnest has been recomputed.
Definition board.cpp:3266
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:2186
void UpdateRatsnestExclusions()
Update the visibility flags on the current unconnected ratsnest lines.
Definition board.cpp:299
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:1382
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:300
virtual void Remove(VIEW_ITEM *aItem)
Remove a VIEW_ITEM from the view.
Definition view.cpp:343
bool HasItem(const VIEW_ITEM *aItem) const
Indicates whether or not the given item has been added to the view.
Definition view.cpp:1713
LSET is a set of PCB_LAYER_IDs.
Definition lset.h:37
static const 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:94
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...