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