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 m_toolMgr( aTool->GetManager() ),
54 m_isBoardEditor( false ),
55 m_isFootprintEditor( false )
56{
57 if( PCB_TOOL_BASE* pcb_tool = dynamic_cast<PCB_TOOL_BASE*>( aTool ) )
58 {
59 m_isBoardEditor = pcb_tool->IsBoardEditor();
60 m_isFootprintEditor = pcb_tool->IsFootprintEditor();
61 }
62}
63
64
66 m_toolMgr( aFrame->GetToolManager() ),
67 m_isBoardEditor( aFrame->IsType( FRAME_PCB_EDITOR ) ),
68 m_isFootprintEditor( aFrame->IsType( FRAME_FOOTPRINT_EDITOR ) )
69{
70}
71
72
74 m_toolMgr( aMgr ),
75 m_isBoardEditor( false ),
76 m_isFootprintEditor( false )
77{
78 EDA_DRAW_FRAME* frame = dynamic_cast<EDA_DRAW_FRAME*>( aMgr->GetToolHolder() );
79
80 if( frame && frame->IsType( FRAME_PCB_EDITOR ) )
81 m_isBoardEditor = true;
82 else if( frame && frame->IsType( FRAME_FOOTPRINT_EDITOR ) )
84}
85
86BOARD_COMMIT::BOARD_COMMIT( TOOL_MANAGER* aMgr, bool aIsBoardEditor ) :
87 m_toolMgr( aMgr ),
88 m_isBoardEditor( aIsBoardEditor ),
89 m_isFootprintEditor( false )
90{
91}
92
93
95{
96 return static_cast<BOARD*>( m_toolMgr->GetModel() );
97}
98
99
101 RECURSE_MODE aRecurse )
102{
103 if( aRecurse == RECURSE_MODE::RECURSE )
104 {
105 if( PCB_GROUP* group = dynamic_cast<PCB_GROUP*>( aItem ) )
106 {
107 for( EDA_ITEM* member : group->GetItems() )
108 Stage( member, aChangeType, aScreen, aRecurse );
109 }
110 }
111
112 return COMMIT::Stage( aItem, aChangeType );
113}
114
115
116COMMIT& BOARD_COMMIT::Stage( std::vector<EDA_ITEM*>& container, CHANGE_TYPE aChangeType,
117 BASE_SCREEN* aScreen )
118{
119 return COMMIT::Stage( container, aChangeType, aScreen );
120}
121
122
124 BASE_SCREEN* aScreen )
125{
126 return COMMIT::Stage( aItems, aModFlag, aScreen );
127}
128
129
130void BOARD_COMMIT::propagateDamage( BOARD_ITEM* aChangedItem, std::vector<ZONE*>* aStaleZones,
131 std::vector<BOX2I>& aStaleRuleAreas )
132{
133 wxCHECK( aChangedItem, /* void */ );
134
135 if( aStaleZones && aChangedItem->Type() == PCB_ZONE_T )
136 aStaleZones->push_back( static_cast<ZONE*>( aChangedItem ) );
137
138 aChangedItem->RunOnChildren( std::bind( &BOARD_COMMIT::propagateDamage, this, _1, aStaleZones, aStaleRuleAreas ),
139 RECURSE_MODE::NO_RECURSE );
140
141 BOARD* board = static_cast<BOARD*>( m_toolMgr->GetModel() );
142 BOX2I damageBBox = aChangedItem->GetBoundingBox();
143 LSET damageLayers = aChangedItem->GetLayerSet();
144
145 if( m_isBoardEditor && aChangedItem->Type() == PCB_ZONE_T )
146 {
147 // A named zone can have custom DRC rules targetting it.
148 if( !static_cast<ZONE*>( aChangedItem )->GetZoneName().IsEmpty() )
149 aStaleRuleAreas.push_back( damageBBox );
150 }
151
152 if( aStaleZones )
153 {
154 if( damageLayers.test( Edge_Cuts ) || damageLayers.test( Margin ) )
155 damageLayers = LSET::PhysicalLayersMask();
156 else
157 damageLayers &= LSET::AllCuMask();
158
159 if( damageLayers.any() )
160 {
161 for( ZONE* zone : board->Zones() )
162 {
163 if( zone->GetIsRuleArea() )
164 continue;
165
166 if( ( zone->GetLayerSet() & damageLayers ).any()
167 && zone->GetBoundingBox().Intersects( damageBBox ) )
168 {
169 aStaleZones->push_back( zone );
170 }
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() );
183 PCB_GROUP* enteredGroup = selTool ? selTool->GetEnteredGroup() : nullptr;
184
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
215 && !( 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& ent : m_changes )
226 {
227 if( !ent.m_item || !ent.m_item->IsBOARD_ITEM() )
228 continue;
229
230 BOARD_ITEM* boardItem = static_cast<BOARD_ITEM*>( ent.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() )
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& ent : m_changes )
301 {
302 if( !ent.m_item || !ent.m_item->IsBOARD_ITEM() )
303 continue;
304
305 BOARD_ITEM* boardItem = static_cast<BOARD_ITEM*>( ent.m_item );
306 int changeType = ent.m_type & CHT_TYPE;
307 int changeFlags = ent.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 FOOTPRINT* parentFP = board->GetFirstFootprint();
323 wxCHECK2_MSG( parentFP, continue, "Commit thinks this is footprint editor, but "
324 "there is no first footprint!" );
325 parentFP->Add( boardItem );
326 }
327 else if( FOOTPRINT* parentFP = boardItem->GetParentFootprint() )
328 {
329 parentFP->Add( boardItem );
330 }
331 else
332 {
333 board->Add( boardItem, ADD_MODE::BULK_INSERT ); // handles connectivity
334 bulkAddedItems.push_back( boardItem );
335 }
336 }
337
338 if( boardItem->Type() != PCB_MARKER_T )
339 propagateDamage( boardItem, staleZones, staleRuleAreas );
340
341 if( view && boardItem->Type() != PCB_NETINFO_T )
342 view->Add( boardItem );
343
344 updateComponentClasses( boardItem );
345
346 break;
347
348 case CHT_REMOVE:
349 {
350 FOOTPRINT* parentFP = boardItem->GetParentFootprint();
351 EDA_GROUP* parentGroup = boardItem->GetParentGroup();
352
353 if( !( aCommitFlags & SKIP_UNDO ) )
354 {
355 ITEM_PICKER itemWrapper( nullptr, boardItem, UNDO_REDO::DELETED );
356 itemWrapper.SetLink( ent.m_copy );
357 ent.m_copy = nullptr; // We've transferred ownership to the undo list
358 undoList.PushItem( itemWrapper );
359 }
360
361 if( boardItem->IsSelected() )
362 {
363 if( selTool )
364 selTool->RemoveItemFromSel( boardItem, true /* quiet mode */ );
365
366 itemsDeselected = true;
367 }
368
369 if( parentGroup && !( parentGroup->AsEdaItem()->GetFlags() & STRUCT_DELETED ) )
370 parentGroup->RemoveItem( boardItem );
371
372 if( parentFP && !( parentFP->GetFlags() & STRUCT_DELETED ) )
373 ent.m_parent = parentFP->m_Uuid;
374
375 if( boardItem->Type() != PCB_MARKER_T )
376 propagateDamage( boardItem, staleZones, staleRuleAreas );
377
378 switch( boardItem->Type() )
379 {
380 case PCB_FIELD_T:
381 static_cast<PCB_FIELD*>( boardItem )->SetVisible( false );
382 break;
383
384 case PCB_TEXT_T:
385 case PCB_PAD_T:
386 case PCB_SHAPE_T: // a shape (normally not on copper layers)
387 case PCB_REFERENCE_IMAGE_T: // a bitmap on an associated layer
388 case PCB_GENERATOR_T: // a generator on a layer
389 case PCB_TEXTBOX_T: // a line-wrapped (and optionally bordered) text item
390 case PCB_TABLE_T: // rows and columns of tablecells
391 case PCB_TRACE_T: // a track segment (segment on a copper layer)
392 case PCB_ARC_T: // an arced track segment (segment on a copper layer)
393 case PCB_VIA_T: // a via (like track segment on a copper layer)
394 case PCB_DIM_ALIGNED_T: // a dimension (graphic item)
395 case PCB_DIM_CENTER_T:
396 case PCB_DIM_RADIAL_T:
398 case PCB_DIM_LEADER_T: // a leader dimension
399 case PCB_TARGET_T: // a target (graphic item)
400 case PCB_MARKER_T: // a marker used to show something
401 case PCB_ZONE_T:
402 case PCB_FOOTPRINT_T:
403 case PCB_GROUP_T:
404 if( view )
405 view->Remove( boardItem );
406
407 if( !( changeFlags & CHT_DONE ) )
408 {
409 if( parentFP )
410 {
411 parentFP->Remove( boardItem );
412 }
413 else
414 {
415 board->Remove( boardItem, REMOVE_MODE::BULK );
416 bulkRemovedItems.push_back( boardItem );
417 }
418 }
419
420 break;
421
422 // Metadata items
423 case PCB_NETINFO_T:
424 board->Remove( boardItem, REMOVE_MODE::BULK );
425 bulkRemovedItems.push_back( boardItem );
426 break;
427
428 default: // other types do not need to (or should not) be handled
429 wxASSERT( false );
430 break;
431 }
432
433 // The item has been removed from the board; it is now owned by undo/redo.
434 boardItem->SetFlags( UR_TRANSIENT );
435 break;
436 }
437
438 case CHT_MODIFY:
439 {
440 BOARD_ITEM* boardItemCopy = static_cast<BOARD_ITEM*>( ent.m_copy );
441
442 if( !( aCommitFlags & SKIP_UNDO ) )
443 {
444 ITEM_PICKER itemWrapper( nullptr, boardItem, UNDO_REDO::CHANGED );
445 itemWrapper.SetLink( ent.m_copy );
446 ent.m_copy = nullptr; // We've transferred ownership to the undo list
447 undoList.PushItem( itemWrapper );
448 }
449
450 if( !( aCommitFlags & SKIP_CONNECTIVITY ) )
451 {
452 connectivity->MarkItemNetAsDirty( boardItemCopy );
453 connectivity->Update( boardItem );
454 }
455
456 if( boardItem->Type() != PCB_MARKER_T )
457 {
458 propagateDamage( boardItemCopy, staleZones, staleRuleAreas ); // before
459 propagateDamage( boardItem, staleZones, staleRuleAreas ); // after
460 }
461
462 updateComponentClasses( boardItem );
463
464 if( view )
465 view->Update( boardItem );
466
467 itemsChanged.push_back( boardItem );
468 break;
469 }
470
471 default:
472 UNIMPLEMENTED_FOR( boardItem->GetClass() );
473 break;
474 }
475
476 // Delete any copies we still have ownership of
477 delete ent.m_copy;
478 ent.m_copy = nullptr;
479
480 boardItem->ClearEditFlags();
481 boardItem->RunOnChildren(
482 [&]( BOARD_ITEM* item )
483 {
484 item->ClearEditFlags();
485 },
486 RECURSE_MODE::RECURSE );
487 } // ... and regenerate them.
488
489 // Invalidate component classes
491
492 if( m_isBoardEditor )
493 {
494 size_t num_changes = m_changes.size();
495
496 if( aCommitFlags & SKIP_CONNECTIVITY )
497 {
498 connectivity->ClearRatsnest();
499 connectivity->ClearLocalRatsnest();
500 }
501 else
502 {
503 connectivity->RecalculateRatsnest( this );
505 connectivity->ClearLocalRatsnest();
506
507 if( frame )
508 frame->GetCanvas()->RedrawRatsnest();
509
510 board->OnRatsnestChanged();
511 }
512
513 if( solderMaskDirty )
514 {
515 if( frame )
516 frame->HideSolderMask();
517 }
518
519 if( updateBoardBoundingBox && view )
520 {
521 if( PCB_BOARD_OUTLINE* outline = board->BoardOutline() )
522 {
523 board->UpdateBoardOutline();
524
525 if( view->HasItem( outline ) )
526 view->Update( outline );
527 else
528 view->Add( outline );
529 }
530 }
531
532 if( PCBNEW_SETTINGS* cfg = GetAppSettings<PCBNEW_SETTINGS>( "pcbnew" ) )
533 {
534 if( !staleRuleAreas.empty() && ( cfg->m_Display.m_TrackClearance == SHOW_WITH_VIA_ALWAYS
535 || cfg->m_Display.m_PadClearance ) )
536 {
537 if( view )
538 view->UpdateCollidingItems( staleRuleAreas, { PCB_TRACE_T, PCB_ARC_T, PCB_VIA_T, PCB_PAD_T } );
539 }
540 }
541
542 if( !staleTeardropPadsAndVias.empty() || !staleTeardropTracks.empty() )
543 {
544 teardropMgr.UpdateTeardrops( *this, &staleTeardropPadsAndVias, &staleTeardropTracks );
545
546 // UpdateTeardrops() can modify the ratsnest data. So rebuild this ratsnest data
547 connectivity->RecalculateRatsnest( this );
548 }
549
550 // Log undo items for any connectivity or teardrop changes
551 for( size_t i = num_changes; i < m_changes.size(); ++i )
552 {
553 COMMIT_LINE& ent = m_changes[i];
554 BOARD_ITEM* boardItem = nullptr;
555 BOARD_ITEM* boardItemCopy = nullptr;
556
557 if( ent.m_item && ent.m_item->IsBOARD_ITEM() )
558 boardItem = static_cast<BOARD_ITEM*>( ent.m_item );
559
560 if( ent.m_copy && ent.m_copy->IsBOARD_ITEM() )
561 boardItemCopy = static_cast<BOARD_ITEM*>( ent.m_copy );
562
563 wxCHECK2( boardItem, continue );
564
565 if( !( aCommitFlags & SKIP_UNDO ) )
566 {
567 ITEM_PICKER itemWrapper( nullptr, boardItem, convert( ent.m_type & CHT_TYPE ) );
568 itemWrapper.SetLink( boardItemCopy );
569 undoList.PushItem( itemWrapper );
570 }
571 else
572 {
573 delete ent.m_copy;
574 }
575
576 if( view )
577 {
578 if( ( ent.m_type & CHT_TYPE ) == CHT_ADD )
579 view->Add( boardItem );
580 else if( ( ent.m_type & CHT_TYPE ) == CHT_REMOVE )
581 view->Remove( boardItem );
582 else
583 view->Update( boardItem );
584 }
585 }
586 }
587
588 if( bulkAddedItems.size() > 0 || bulkRemovedItems.size() > 0 || itemsChanged.size() > 0 )
589 board->OnItemsCompositeUpdate( bulkAddedItems, bulkRemovedItems, itemsChanged );
590
591 if( frame )
592 {
593 if( !( aCommitFlags & SKIP_UNDO ) )
594 {
595 if( aCommitFlags & APPEND_UNDO )
596 frame->AppendCopyToUndoList( undoList, UNDO_REDO::UNSPECIFIED );
597 else
598 frame->SaveCopyInUndoList( undoList, UNDO_REDO::UNSPECIFIED );
599 }
600 }
601
603
604 if( itemsDeselected )
606
607 if( autofillZones )
608 {
610
611 for( ZONE* zone : *staleZones )
612 zoneFillerTool->DirtyZone( zone );
613
615 }
616
618
619 if( selectedModified )
621
622 if( frame )
623 {
624 if( !( aCommitFlags & SKIP_SET_DIRTY ) )
625 frame->OnModify();
626 else
628
629 // Ensure the message panel is updated after committing changes.
630 // By default (i.e. if no event posted), display the updated board info
631 if( !itemsDeselected && !autofillZones && !selectedModified )
632 {
633 std::vector<MSG_PANEL_ITEM> msg_list;
634 board->GetMsgPanelInfo( frame, msg_list );
635 frame->SetMsgPanel( msg_list );
636 }
637 }
638
639 clear();
640}
641
642
644{
645 return aItem;
646}
647
648
650{
651 return MakeImage( aItem );
652}
653
654
656{
657 EDA_ITEM* clone = aItem->Clone();
658 clone->SetFlags( UR_TRANSIENT );
659
660 return clone;
661}
662
663
665{
666 PICKED_ITEMS_LIST undoList;
667 KIGFX::VIEW* view = m_toolMgr->GetView();
668 BOARD* board = (BOARD*) m_toolMgr->GetModel();
669 std::shared_ptr<CONNECTIVITY_DATA> connectivity = board->GetConnectivity();
670
671 board->IncrementTimeStamp(); // clear caches
672
673 auto updateComponentClasses = [this]( BOARD_ITEM* boardItem )
674 {
675 if( boardItem->Type() != PCB_FOOTPRINT_T )
676 return;
677
678 FOOTPRINT* footprint = static_cast<FOOTPRINT*>( boardItem );
680 };
681
682 std::vector<BOARD_ITEM*> bulkAddedItems;
683 std::vector<BOARD_ITEM*> bulkRemovedItems;
684 std::vector<BOARD_ITEM*> itemsChanged;
685
686 for( COMMIT_LINE& entry : m_changes )
687 {
688 if( !entry.m_item || !entry.m_item->IsBOARD_ITEM() )
689 continue;
690
691 BOARD_ITEM* boardItem = static_cast<BOARD_ITEM*>( entry.m_item );
692 int changeType = entry.m_type & CHT_TYPE;
693 int changeFlags = entry.m_type & CHT_FLAGS;
694
695 switch( changeType )
696 {
697 case CHT_ADD:
698 if( !( changeFlags & CHT_DONE ) )
699 break;
700
701 view->Remove( boardItem );
702
703 if( FOOTPRINT* parentFP = boardItem->GetParentFootprint() )
704 {
705 parentFP->Remove( boardItem );
706 }
707 else
708 {
709 board->Remove( boardItem, REMOVE_MODE::BULK );
710 bulkRemovedItems.push_back( boardItem );
711 }
712
713 break;
714
715 case CHT_REMOVE:
716 {
717 if( !( changeFlags & CHT_DONE ) )
718 break;
719
720 view->Add( boardItem );
721
722 if( BOARD_ITEM* parent = board->ResolveItem( entry.m_parent, true ) )
723 {
724 if( parent->Type() == PCB_FOOTPRINT_T )
725 {
726 static_cast<FOOTPRINT*>( parent )->Add( boardItem, ADD_MODE::INSERT );
727 }
728 else
729 {
730 board->Add( boardItem, ADD_MODE::INSERT );
731 bulkAddedItems.push_back( boardItem );
732 }
733 }
734
735 updateComponentClasses( boardItem );
736
737 break;
738 }
739
740 case CHT_MODIFY:
741 {
742 view->Remove( boardItem );
743 connectivity->Remove( boardItem );
744
745 wxASSERT( entry.m_copy && entry.m_copy->IsBOARD_ITEM() );
746 BOARD_ITEM* boardItemCopy = static_cast<BOARD_ITEM*>( entry.m_copy );
747 boardItem->SwapItemData( boardItemCopy );
748
749 view->Add( boardItem );
750 connectivity->Add( boardItem );
751 itemsChanged.push_back( boardItem );
752
753 updateComponentClasses( boardItem );
754
755 delete entry.m_copy;
756 break;
757 }
758
759 default:
760 UNIMPLEMENTED_FOR( boardItem->GetClass() );
761 break;
762 }
763
764 boardItem->ClearEditFlags();
765 }
766
767 // Invalidate component classes
769
770 if( bulkAddedItems.size() > 0 || bulkRemovedItems.size() > 0 || itemsChanged.size() > 0 )
771 board->OnItemsCompositeUpdate( bulkAddedItems, bulkRemovedItems, itemsChanged );
772
773 if( m_isBoardEditor )
774 {
775 connectivity->RecalculateRatsnest();
777 board->OnRatsnestChanged();
778 }
779
781 selTool->RebuildSelection();
782
783 // Property panel needs to know about the reselect
785
786 clear();
787}
#define SKIP_CONNECTIVITY
Definition: board_commit.h:44
#define SKIP_SET_DIRTY
Definition: board_commit.h:43
#define APPEND_UNDO
Definition: board_commit.h:42
#define SKIP_UNDO
Definition: board_commit.h:41
#define ZONE_FILL_OP
Definition: board_commit.h:45
#define SKIP_TEARDROPS
Definition: board_commit.h:46
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.
EDA_ITEM * parentObject(EDA_ITEM *aItem) const override
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)
bool m_isBoardEditor
Definition: board_commit.h:84
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
Definition: board_commit.h:83
bool m_isFootprintEditor
Definition: board_commit.h:85
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
Definition: board_item.cpp:41
void SwapItemData(BOARD_ITEM *aImage)
Swap data between aItem and aImage.
Definition: board_item.cpp:270
virtual bool IsOnLayer(PCB_LAYER_ID aLayer) const
Test to see if this object is on the given layer.
Definition: board_item.h:314
FOOTPRINT * GetParentFootprint() const
Definition: board_item.cpp:97
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:317
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT, bool aSkipConnectivity=false) override
Removes an item from the container.
Definition: board.cpp:1147
PCB_BOARD_OUTLINE * BoardOutline()
Definition: board.h:366
void UpdateBoardOutline()
Definition: board.cpp:3192
const ZONES & Zones() const
Definition: board.h:362
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:2818
FOOTPRINT * GetFirstFootprint() const
Get the first footprint on the board or nullptr.
Definition: board.h:489
void IncrementTimeStamp()
Definition: board.cpp:254
void OnRatsnestChanged()
Notify the board and its listeners that the ratsnest has been recomputed.
Definition: board.cpp:2827
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:1912
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:1345
void Remove(BOARD_ITEM *aBoardItem, REMOVE_MODE aMode=REMOVE_MODE::NORMAL) override
Removes an item from the container.
Definition: board.cpp:1310
BOARD_ITEM * ResolveItem(const KIID &aID, bool aAllowNullptrReturn=false) const
Definition: board.cpp:1583
std::shared_ptr< CONNECTIVITY_DATA > GetConnectivity() const
Return a list of missing connections between components/tracks.
Definition: board.h:522
Represent a set of changes (additions, deletions or modifications) of a data model (e....
Definition: commit.h:73
bool Empty() const
Definition: commit.h:152
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:107
COMMIT & Add(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Add a new item to the model.
Definition: commit.h:79
void clear()
Should be called in Push() & Revert() methods.
Definition: commit.h:173
std::vector< COMMIT_LINE > m_changes
Definition: commit.h:203
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
const KIID m_Uuid
Definition: eda_item.h:516
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
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:349
static const TOOL_EVENT UnselectedEvent
Definition: actions.h:343
void Remove(BOARD_ITEM *aItem, REMOVE_MODE aMode=REMOVE_MODE::NORMAL) override
Removes an item from the container.
Definition: footprint.cpp:1149
std::deque< PAD * > & Pads()
Definition: footprint.h:209
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT, bool aSkipConnectivity=false) override
Removes an item from the container.
Definition: footprint.cpp:1080
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
Definition: pcb_actions.h:376
static TOOL_ACTION zoneFillDirty
Definition: pcb_actions.h:393
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:180
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:135
Base abstract interface for all kinds of tools.
Definition: tool_base.h:66
Master controller class:
Definition: tool_manager.h:62
bool ProcessEvent(const TOOL_EVENT &aEvent)
Propagate an event to tools that requested events of matching type(s).
void PostEvent(const TOOL_EVENT &aEvent)
Put an event to the event queue to be processed at the end of event processing cycle.
TOOLS_HOLDER * GetToolHolder() const
Definition: tool_manager.h:406
bool PostAction(const std::string &aActionName, T aParam)
Run the specified action after the current action (coroutine) ends.
Definition: tool_manager.h:235
EDA_ITEM * GetModel() const
Definition: tool_manager.h:402
KIGFX::VIEW * GetView() const
Definition: tool_manager.h:395
Handle actions specific to filling copper zones.
void DirtyZone(ZONE *aZone)
Handle a list of polygons defining a copper zone.
Definition: zone.h:74
const wxString & GetZoneName() const
Definition: zone.h:163
CHANGE_TYPE
Types of changes.
Definition: commit.h:42
@ CHT_MODIFY
Definition: commit.h:45
@ CHT_REMOVE
Definition: commit.h:44
@ CHT_DONE
Flag to indicate the change is already applied.
Definition: commit.h:48
@ CHT_TYPE
Definition: commit.h:46
@ CHT_ADD
Definition: commit.h:43
@ CHT_FLAGS
Definition: commit.h:49
RECURSE_MODE
Definition: eda_item.h:50
#define STRUCT_DELETED
flag indication structures to be erased
#define UR_TRANSIENT
indicates the item is owned by the undo/redo stack
@ FRAME_PCB_EDITOR
Definition: frame_type.h:42
@ FRAME_FOOTPRINT_EDITOR
Definition: frame_type.h:43
@ Edge_Cuts
Definition: layer_ids.h:112
@ B_Mask
Definition: layer_ids.h:98
@ F_Mask
Definition: layer_ids.h:97
@ Margin
Definition: layer_ids.h:113
This file contains miscellaneous commonly used macros and functions.
#define UNIMPLEMENTED_FOR(type)
Definition: macros.h:96
Class to handle a set of BOARD_ITEMs.
@ SHOW_WITH_VIA_ALWAYS
see class PGM_BASE
EDA_ITEM * m_copy
Optional copy of the item.
Definition: commit.h:166
CHANGE_TYPE m_type
Modification type.
Definition: commit.h:167
EDA_ITEM * m_item
Main item that is added/deleted/modified.
Definition: commit.h:165
@ 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:105
@ PCB_DIM_LEADER_T
class PCB_DIM_LEADER, a leader dimension (graphic item)
Definition: typeinfo.h:102
@ PCB_GENERATOR_T
class PCB_GENERATOR, generator on a layer
Definition: typeinfo.h:91
@ PCB_VIA_T
class PCB_VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:97
@ PCB_DIM_CENTER_T
class PCB_DIM_CENTER, a center point marking (graphic item)
Definition: typeinfo.h:103
@ PCB_GROUP_T
class PCB_GROUP, a set of BOARD_ITEMs
Definition: typeinfo.h:110
@ PCB_TEXTBOX_T
class PCB_TEXTBOX, wrapped text on a layer
Definition: typeinfo.h:93
@ PCB_ZONE_T
class ZONE, a copper pour area
Definition: typeinfo.h:107
@ PCB_TEXT_T
class PCB_TEXT, text on a layer
Definition: typeinfo.h:92
@ PCB_REFERENCE_IMAGE_T
class PCB_REFERENCE_IMAGE, bitmap on a layer
Definition: typeinfo.h:89
@ PCB_FIELD_T
class PCB_FIELD, text associated with a footprint property
Definition: typeinfo.h:90
@ PCB_MARKER_T
class PCB_MARKER, a marker used to show something
Definition: typeinfo.h:99
@ PCB_TARGET_T
class PCB_TARGET, a target (graphic item)
Definition: typeinfo.h:106
@ PCB_FOOTPRINT_T
class FOOTPRINT, a footprint
Definition: typeinfo.h:86
@ PCB_DIM_ALIGNED_T
class PCB_DIM_ALIGNED, a linear dimension (graphic item)
Definition: typeinfo.h:101
@ PCB_PAD_T
class PAD, a pad in a footprint
Definition: typeinfo.h:87
@ PCB_ARC_T
class PCB_ARC, an arc track segment on a copper layer
Definition: typeinfo.h:98
@ PCB_TABLE_T
class PCB_TABLE, table of PCB_TABLECELLs
Definition: typeinfo.h:94
@ PCB_NETINFO_T
class NETINFO_ITEM, a description of a net
Definition: typeinfo.h:109
@ PCB_TRACE_T
class PCB_TRACK, a track segment (segment on a copper layer)
Definition: typeinfo.h:96
@ PCB_DIM_RADIAL_T
class PCB_DIM_RADIAL, a radius or diameter dimension
Definition: typeinfo.h:104
UNDO_REDO
Undo Redo considerations: Basically we have 3 cases New item Deleted item Modified item there is also...