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 <board.h>
28#include <footprint.h>
29#include <lset.h>
30#include <pcb_group.h>
31#include <pcb_track.h>
32#include <pcb_shape.h>
33#include <tool/tool_manager.h>
36#include <view/view.h>
37#include <board_commit.h>
38#include <tools/pcb_tool_base.h>
39#include <tools/pcb_actions.h>
42#include <teardrop/teardrop.h>
43
44#include <functional>
46using namespace std::placeholders;
47
48
50 m_toolMgr( aTool->GetManager() ),
51 m_isBoardEditor( false ),
52 m_isFootprintEditor( false )
53{
54 if( PCB_TOOL_BASE* pcb_tool = dynamic_cast<PCB_TOOL_BASE*>( aTool ) )
55 {
56 m_isBoardEditor = pcb_tool->IsBoardEditor();
57 m_isFootprintEditor = pcb_tool->IsFootprintEditor();
58 }
59}
60
61
63 m_toolMgr( aFrame->GetToolManager() ),
64 m_isBoardEditor( aFrame->IsType( FRAME_PCB_EDITOR ) ),
65 m_isFootprintEditor( aFrame->IsType( FRAME_FOOTPRINT_EDITOR ) )
66{
67}
68
69
71 m_toolMgr( aMgr ),
72 m_isBoardEditor( false ),
73 m_isFootprintEditor( false )
74{
75 EDA_DRAW_FRAME* frame = dynamic_cast<EDA_DRAW_FRAME*>( aMgr->GetToolHolder() );
76
77 if( frame && frame->IsType( FRAME_PCB_EDITOR ) )
78 m_isBoardEditor = true;
79 else if( frame && frame->IsType( FRAME_FOOTPRINT_EDITOR ) )
81}
82
83BOARD_COMMIT::BOARD_COMMIT( TOOL_MANAGER* aMgr, bool aIsBoardEditor ) :
84 m_toolMgr( aMgr ),
85 m_isBoardEditor( aIsBoardEditor ),
86 m_isFootprintEditor( false )
87{
88}
89
90
92{
93 return static_cast<BOARD*>( m_toolMgr->GetModel() );
94}
95
96
98{
99 // Many operations (move, rotate, etc.) are applied directly to a group's children, so they
100 // must be staged as well.
101 if( aChangeType == CHT_MODIFY )
102 {
103 if( PCB_GROUP* group = dynamic_cast<PCB_GROUP*>( aItem ) )
104 {
105 group->RunOnChildren(
106 [&]( BOARD_ITEM* child )
107 {
108 Stage( child, aChangeType );
109 },
110 RECURSE_MODE::NO_RECURSE );
111 }
112 }
113
114 return COMMIT::Stage( aItem, aChangeType );
115}
116
117
118COMMIT& BOARD_COMMIT::Stage( std::vector<EDA_ITEM*>& container, CHANGE_TYPE aChangeType,
119 BASE_SCREEN* aScreen )
120{
121 return COMMIT::Stage( container, aChangeType, aScreen );
122}
123
124
126 BASE_SCREEN* aScreen )
127{
128 return COMMIT::Stage( aItems, aModFlag, aScreen );
129}
130
131
132void BOARD_COMMIT::propagateDamage( BOARD_ITEM* aChangedItem, std::vector<ZONE*>* aStaleZones )
133{
134 wxCHECK( aChangedItem, /* void */ );
135
136 if( aStaleZones && aChangedItem->Type() == PCB_ZONE_T )
137 aStaleZones->push_back( static_cast<ZONE*>( aChangedItem ) );
138
139 aChangedItem->RunOnChildren(
140 std::bind( &BOARD_COMMIT::propagateDamage, this, _1, aStaleZones ),
141 RECURSE_MODE::NO_RECURSE );
142
143 BOARD* board = static_cast<BOARD*>( m_toolMgr->GetModel() );
144 BOX2I damageBBox = aChangedItem->GetBoundingBox();
145 LSET damageLayers = aChangedItem->GetLayerSet();
146
147 if( aStaleZones )
148 {
149 if( damageLayers.test( Edge_Cuts ) || damageLayers.test( Margin ) )
150 damageLayers = LSET::PhysicalLayersMask();
151 else
152 damageLayers &= LSET::AllCuMask();
153
154 if( damageLayers.any() )
155 {
156 for( ZONE* zone : board->Zones() )
157 {
158 if( zone->GetIsRuleArea() )
159 continue;
160
161 if( ( zone->GetLayerSet() & damageLayers ).any()
162 && zone->GetBoundingBox().Intersects( damageBBox ) )
163 {
164 aStaleZones->push_back( zone );
165 }
166 }
167 }
168 }
169}
170
171
172void BOARD_COMMIT::Push( const wxString& aMessage, int aCommitFlags )
173{
174 KIGFX::VIEW* view = m_toolMgr->GetView();
175 BOARD* board = static_cast<BOARD*>( m_toolMgr->GetModel() );
176 PCB_BASE_FRAME* frame = dynamic_cast<PCB_BASE_FRAME*>( m_toolMgr->GetToolHolder() );
178
179 // Notification info
180 PICKED_ITEMS_LIST undoList;
181 bool itemsDeselected = false;
182 bool selectedModified = false;
183
184 // Dirty flags and lists
185 bool solderMaskDirty = false;
186 bool autofillZones = false;
187 std::vector<BOARD_ITEM*> staleTeardropPadsAndVias;
188 std::set<PCB_TRACK*> staleTeardropTracks;
189 PCB_GROUP* addedGroup = nullptr;
190 std::vector<ZONE*> staleZonesStorage;
191 std::vector<ZONE*>* staleZones = nullptr;
192
193 if( Empty() )
194 return;
195
196 undoList.SetDescription( aMessage );
197
198 TEARDROP_MANAGER teardropMgr( board, m_toolMgr );
199 std::shared_ptr<CONNECTIVITY_DATA> connectivity = board->GetConnectivity();
200
201 // Note: frame == nullptr happens in QA tests
202
203 std::vector<BOARD_ITEM*> bulkAddedItems;
204 std::vector<BOARD_ITEM*> bulkRemovedItems;
205 std::vector<BOARD_ITEM*> itemsChanged;
206
208 && !( aCommitFlags & ZONE_FILL_OP )
209 && ( frame && frame->GetPcbNewSettings()->m_AutoRefillZones ) )
210 {
211 autofillZones = true;
212 staleZones = &staleZonesStorage;
213
214 for( ZONE* zone : board->Zones() )
215 zone->CacheBoundingBox();
216 }
217
218 for( COMMIT_LINE& ent : m_changes )
219 {
220 if( !ent.m_item || !ent.m_item->IsBOARD_ITEM() )
221 continue;
222
223 BOARD_ITEM* boardItem = static_cast<BOARD_ITEM*>( ent.m_item );
224
225 if( m_isBoardEditor )
226 {
227 if( boardItem->Type() == PCB_VIA_T || boardItem->Type() == PCB_FOOTPRINT_T
228 || boardItem->IsOnLayer( F_Mask ) || boardItem->IsOnLayer( B_Mask ) )
229 {
230 solderMaskDirty = true;
231 }
232
233 if( !( aCommitFlags & SKIP_TEARDROPS ) )
234 {
235 if( boardItem->Type() == PCB_FOOTPRINT_T )
236 {
237 for( PAD* pad : static_cast<FOOTPRINT*>( boardItem )->Pads() )
238 staleTeardropPadsAndVias.push_back( pad );
239 }
240 else if( boardItem->Type() == PCB_PAD_T || boardItem->Type() == PCB_VIA_T )
241 {
242 staleTeardropPadsAndVias.push_back( boardItem );
243 }
244 else if( boardItem->Type() == PCB_TRACE_T || boardItem->Type() == PCB_ARC_T )
245 {
246 PCB_TRACK* track = static_cast<PCB_TRACK*>( boardItem );
247
248 staleTeardropTracks.insert( track );
249
250 std::vector<PAD*> connectedPads;
251 std::vector<PCB_VIA*> connectedVias;
252
253 connectivity->GetConnectedPadsAndVias( track, &connectedPads, &connectedVias );
254
255 for( PAD* pad : connectedPads )
256 staleTeardropPadsAndVias.push_back( pad );
257
258 for( PCB_VIA* via : connectedVias )
259 staleTeardropPadsAndVias.push_back( via );
260 }
261 }
262 }
263
264 if( boardItem->IsSelected() )
265 selectedModified = true;
266 }
267
268 // Old teardrops must be removed before connectivity is rebuilt
269 if( !staleTeardropPadsAndVias.empty() || !staleTeardropTracks.empty() )
270 teardropMgr.RemoveTeardrops( *this, &staleTeardropPadsAndVias, &staleTeardropTracks );
271
272 auto updateComponentClasses = [this]( BOARD_ITEM* boardItem )
273 {
274 if( boardItem->Type() != PCB_FOOTPRINT_T )
275 return;
276
277 FOOTPRINT* footprint = static_cast<FOOTPRINT*>( boardItem );
279 };
280
281 for( COMMIT_LINE& ent : m_changes )
282 {
283 if( !ent.m_item || !ent.m_item->IsBOARD_ITEM() )
284 continue;
285
286 BOARD_ITEM* boardItem = static_cast<BOARD_ITEM*>( ent.m_item );
287 int changeType = ent.m_type & CHT_TYPE;
288 int changeFlags = ent.m_type & CHT_FLAGS;
289
290 switch( changeType )
291 {
292 case CHT_ADD:
293 if( selTool && selTool->GetEnteredGroup() && !boardItem->GetParentGroup()
294 && PCB_GROUP::IsGroupableType( boardItem->Type() ) )
295 {
296 selTool->GetEnteredGroup()->AddItem( boardItem );
297 }
298
299 if( !( aCommitFlags & SKIP_UNDO ) )
300 undoList.PushItem( ITEM_PICKER( nullptr, boardItem, UNDO_REDO::NEWITEM ) );
301
302 if( !( changeFlags & CHT_DONE ) )
303 {
305 {
306 FOOTPRINT* parentFP = board->GetFirstFootprint();
307 wxCHECK2_MSG( parentFP, continue, "Commit thinks this is footprint editor, but "
308 "there is no first footprint!" );
309 parentFP->Add( boardItem );
310 }
311 else if( FOOTPRINT* parentFP = boardItem->GetParentFootprint() )
312 {
313 parentFP->Add( boardItem );
314 }
315 else
316 {
317 board->Add( boardItem, ADD_MODE::BULK_INSERT ); // handles connectivity
318 bulkAddedItems.push_back( boardItem );
319 }
320 }
321
322 if( boardItem->Type() == PCB_GROUP_T || boardItem->Type() == PCB_GENERATOR_T )
323 addedGroup = static_cast<PCB_GROUP*>( boardItem );
324
325 if( boardItem->Type() != PCB_MARKER_T )
326 propagateDamage( boardItem, staleZones );
327
328 if( view && boardItem->Type() != PCB_NETINFO_T )
329 view->Add( boardItem );
330
331 updateComponentClasses( boardItem );
332
333 break;
334
335 case CHT_REMOVE:
336 {
337 FOOTPRINT* parentFP = boardItem->GetParentFootprint();
338 EDA_GROUP* parentGroup = boardItem->GetParentGroup();
339
340 if( !( aCommitFlags & SKIP_UNDO ) )
341 undoList.PushItem( ITEM_PICKER( nullptr, boardItem, UNDO_REDO::DELETED ) );
342
343 if( boardItem->IsSelected() )
344 {
345 if( selTool )
346 selTool->RemoveItemFromSel( boardItem, true /* quiet mode */ );
347
348 itemsDeselected = true;
349 }
350
351 if( parentGroup && !( parentGroup->AsEdaItem()->GetFlags() & STRUCT_DELETED ) )
352 parentGroup->RemoveItem( boardItem );
353
354 if( parentFP && !( parentFP->GetFlags() & STRUCT_DELETED ) )
355 ent.m_parent = parentFP->m_Uuid;
356
357 if( boardItem->Type() != PCB_MARKER_T )
358 propagateDamage( boardItem, staleZones );
359
360 switch( boardItem->Type() )
361 {
362 case PCB_FIELD_T:
363 static_cast<PCB_FIELD*>( boardItem )->SetVisible( false );
364 break;
365
366 case PCB_TEXT_T:
367 case PCB_PAD_T:
368 case PCB_SHAPE_T: // a shape (normally not on copper layers)
369 case PCB_REFERENCE_IMAGE_T: // a bitmap on an associated layer
370 case PCB_GENERATOR_T: // a generator on a layer
371 case PCB_TEXTBOX_T: // a line-wrapped (and optionally bordered) text item
372 case PCB_TABLE_T: // rows and columns of tablecells
373 case PCB_TRACE_T: // a track segment (segment on a copper layer)
374 case PCB_ARC_T: // an arced track segment (segment on a copper layer)
375 case PCB_VIA_T: // a via (like track segment on a copper layer)
376 case PCB_DIM_ALIGNED_T: // a dimension (graphic item)
377 case PCB_DIM_CENTER_T:
378 case PCB_DIM_RADIAL_T:
380 case PCB_DIM_LEADER_T: // a leader dimension
381 case PCB_TARGET_T: // a target (graphic item)
382 case PCB_MARKER_T: // a marker used to show something
383 case PCB_ZONE_T:
384 case PCB_FOOTPRINT_T:
385 case PCB_GROUP_T:
386 if( view )
387 view->Remove( boardItem );
388
389 if( !( changeFlags & CHT_DONE ) )
390 {
391 if( parentFP )
392 {
393 parentFP->Remove( boardItem );
394 }
395 else
396 {
397 board->Remove( boardItem, REMOVE_MODE::BULK );
398 bulkRemovedItems.push_back( boardItem );
399 }
400 }
401
402 break;
403
404 // Metadata items
405 case PCB_NETINFO_T:
406 board->Remove( boardItem, REMOVE_MODE::BULK );
407 bulkRemovedItems.push_back( boardItem );
408 break;
409
410 default: // other types do not need to (or should not) be handled
411 wxASSERT( false );
412 break;
413 }
414
415 // The item has been removed from the board; it is now owned by undo/redo.
416 boardItem->SetFlags( UR_TRANSIENT );
417
418 break;
419 }
420
421 case CHT_UNGROUP:
422 if( EDA_GROUP* group = boardItem->GetParentGroup() )
423 {
424 if( !( aCommitFlags & SKIP_UNDO ) )
425 {
426 ITEM_PICKER itemWrapper( nullptr, boardItem, UNDO_REDO::UNGROUP );
427 itemWrapper.SetGroupId( group->AsEdaItem()->m_Uuid );
428 undoList.PushItem( itemWrapper );
429 }
430
431 group->RemoveItem( boardItem );
432 }
433
434 break;
435
436 case CHT_GROUP:
437 if( addedGroup )
438 {
439 addedGroup->AddItem( boardItem );
440
441 if( !( aCommitFlags & SKIP_UNDO ) )
442 undoList.PushItem( ITEM_PICKER( nullptr, boardItem, UNDO_REDO::REGROUP ) );
443 }
444
445 break;
446
447 case CHT_MODIFY:
448 {
449 BOARD_ITEM* boardItemCopy = nullptr;
450
451 if( ent.m_copy && ent.m_copy->IsBOARD_ITEM() )
452 boardItemCopy = static_cast<BOARD_ITEM*>( ent.m_copy );
453
454 if( !( aCommitFlags & SKIP_UNDO ) )
455 {
456 ITEM_PICKER itemWrapper( nullptr, boardItem, UNDO_REDO::CHANGED );
457 wxASSERT( boardItemCopy );
458 itemWrapper.SetLink( boardItemCopy );
459 undoList.PushItem( itemWrapper );
460 }
461
462 if( !( aCommitFlags & SKIP_CONNECTIVITY ) )
463 {
464 if( boardItemCopy )
465 connectivity->MarkItemNetAsDirty( boardItemCopy );
466
467 connectivity->Update( boardItem );
468 }
469
470 if( boardItem->Type() != PCB_MARKER_T )
471 {
472 propagateDamage( boardItemCopy, staleZones ); // before
473 propagateDamage( boardItem, staleZones ); // after
474 }
475
476 updateComponentClasses( boardItem );
477
478 if( view )
479 view->Update( boardItem );
480
481 itemsChanged.push_back( boardItem );
482
483 // if no undo entry is needed, the copy would create a memory leak
484 if( aCommitFlags & SKIP_UNDO )
485 delete ent.m_copy;
486
487 break;
488 }
489
490 default:
491 UNIMPLEMENTED_FOR( boardItem->GetClass() );
492 break;
493 }
494
495 boardItem->ClearEditFlags();
496 boardItem->RunOnChildren(
497 [&]( BOARD_ITEM* item )
498 {
499 item->ClearEditFlags();
500 },
501 RECURSE_MODE::RECURSE );
502 } // ... and regenerate them.
503
504 // Invalidate component classes
506
507 if( m_isBoardEditor )
508 {
509 size_t num_changes = m_changes.size();
510
511 if( aCommitFlags & SKIP_CONNECTIVITY )
512 {
513 connectivity->ClearRatsnest();
514 connectivity->ClearLocalRatsnest();
515 }
516 else
517 {
518 connectivity->RecalculateRatsnest( this );
520 connectivity->ClearLocalRatsnest();
521
522 if( frame )
523 frame->GetCanvas()->RedrawRatsnest();
524
525 board->OnRatsnestChanged();
526 }
527
528 if( solderMaskDirty )
529 {
530 if( frame )
531 frame->HideSolderMask();
532 }
533
534 if( !staleTeardropPadsAndVias.empty() || !staleTeardropTracks.empty() )
535 {
536 teardropMgr.UpdateTeardrops( *this, &staleTeardropPadsAndVias, &staleTeardropTracks );
537
538 // UpdateTeardrops() can modify the ratsnest data. So rebuild this ratsnest data
539 connectivity->RecalculateRatsnest( this );
540 }
541
542 // Log undo items for any connectivity or teardrop changes
543 for( size_t i = num_changes; i < m_changes.size(); ++i )
544 {
545 COMMIT_LINE& ent = m_changes[i];
546 BOARD_ITEM* boardItem = nullptr;
547 BOARD_ITEM* boardItemCopy = nullptr;
548
549 if( ent.m_item && ent.m_item->IsBOARD_ITEM() )
550 boardItem = static_cast<BOARD_ITEM*>( ent.m_item );
551
552 if( ent.m_copy && ent.m_copy->IsBOARD_ITEM() )
553 boardItemCopy = static_cast<BOARD_ITEM*>( ent.m_copy );
554
555 wxCHECK2( boardItem, continue );
556
557 if( !( aCommitFlags & SKIP_UNDO ) )
558 {
559 ITEM_PICKER itemWrapper( nullptr, boardItem, convert( ent.m_type & CHT_TYPE ) );
560 itemWrapper.SetLink( boardItemCopy );
561 undoList.PushItem( itemWrapper );
562 }
563 else
564 {
565 delete ent.m_copy;
566 }
567
568 if( view )
569 {
570 if( ( ent.m_type & CHT_TYPE ) == CHT_ADD )
571 view->Add( boardItem );
572 else if( ( ent.m_type & CHT_TYPE ) == CHT_REMOVE )
573 view->Remove( boardItem );
574 else
575 view->Update( boardItem );
576 }
577 }
578 }
579
580 if( bulkAddedItems.size() > 0 || bulkRemovedItems.size() > 0 || itemsChanged.size() > 0 )
581 board->OnItemsCompositeUpdate( bulkAddedItems, bulkRemovedItems, itemsChanged );
582
583 if( frame )
584 {
585 if( !( aCommitFlags & SKIP_UNDO ) )
586 {
587 if( aCommitFlags & APPEND_UNDO )
588 frame->AppendCopyToUndoList( undoList, UNDO_REDO::UNSPECIFIED );
589 else
590 frame->SaveCopyInUndoList( undoList, UNDO_REDO::UNSPECIFIED );
591 }
592 }
593
595
596 if( itemsDeselected )
598
599 if( autofillZones )
600 {
602
603 for( ZONE* zone : *staleZones )
604 zoneFillerTool->DirtyZone( zone );
605
607 }
608
610
611 if( selectedModified )
613
614 if( frame )
615 {
616 if( !( aCommitFlags & SKIP_SET_DIRTY ) )
617 frame->OnModify();
618 else
620
621 // Ensure the message panel is updated after committing changes.
622 // By default (i.e. if no event posted), display the updated board info
623 if( !itemsDeselected && !autofillZones && !selectedModified )
624 {
625 std::vector<MSG_PANEL_ITEM> msg_list;
626 board->GetMsgPanelInfo( frame, msg_list );
627 frame->SetMsgPanel( msg_list );
628 }
629 }
630
631 clear();
632}
633
634
636{
637 return aItem;
638}
639
640
642{
643 return MakeImage( aItem );
644}
645
646
648{
649 EDA_ITEM* clone = aItem->Clone();
650
651 if( clone->IsBOARD_ITEM() )
652 static_cast<BOARD_ITEM*>( clone )->SetParentGroup( nullptr );
653
654 clone->SetFlags( UR_TRANSIENT );
655
656 return clone;
657}
658
659
661{
662 PICKED_ITEMS_LIST undoList;
663 KIGFX::VIEW* view = m_toolMgr->GetView();
664 BOARD* board = (BOARD*) m_toolMgr->GetModel();
665 std::shared_ptr<CONNECTIVITY_DATA> connectivity = board->GetConnectivity();
666
667 board->IncrementTimeStamp(); // clear caches
668
669 auto updateComponentClasses = [this]( BOARD_ITEM* boardItem )
670 {
671 if( boardItem->Type() != PCB_FOOTPRINT_T )
672 return;
673
674 FOOTPRINT* footprint = static_cast<FOOTPRINT*>( boardItem );
676 };
677
678 std::vector<BOARD_ITEM*> bulkAddedItems;
679 std::vector<BOARD_ITEM*> bulkRemovedItems;
680 std::vector<BOARD_ITEM*> itemsChanged;
681
682 for( COMMIT_LINE& entry : m_changes )
683 {
684 if( !entry.m_item || !entry.m_item->IsBOARD_ITEM() )
685 continue;
686
687 BOARD_ITEM* boardItem = static_cast<BOARD_ITEM*>( entry.m_item );
688 int changeType = entry.m_type & CHT_TYPE;
689 int changeFlags = entry.m_type & CHT_FLAGS;
690
691 switch( changeType )
692 {
693 case CHT_ADD:
694 // Items are auto-added to the parent group by BOARD_ITEM::Duplicate(), not when
695 // the commit is pushed.
696 if( EDA_GROUP* parentGroup = boardItem->GetParentGroup() )
697 {
698 if( GetStatus( parentGroup->AsEdaItem() ) == 0 )
699 parentGroup->RemoveItem( boardItem );
700 }
701
702 if( !( changeFlags & CHT_DONE ) )
703 break;
704
705 view->Remove( boardItem );
706
707 if( FOOTPRINT* parentFP = boardItem->GetParentFootprint() )
708 {
709 parentFP->Remove( boardItem );
710 }
711 else
712 {
713 board->Remove( boardItem, REMOVE_MODE::BULK );
714 bulkRemovedItems.push_back( boardItem );
715 }
716
717 break;
718
719 case CHT_REMOVE:
720 {
721 if( !( changeFlags & CHT_DONE ) )
722 break;
723
724 view->Add( boardItem );
725
726 // Note: parent can be nullptr, because entry.m_parent is only set for children
727 // of footprints.
728 BOARD_ITEM* parent = board->GetItem( entry.m_parent );
729
730 if( parent && parent->Type() == PCB_FOOTPRINT_T )
731 {
732 static_cast<FOOTPRINT*>( parent )->Add( boardItem, ADD_MODE::INSERT );
733 }
734 else
735 {
736 board->Add( boardItem, ADD_MODE::INSERT );
737 bulkAddedItems.push_back( boardItem );
738 }
739
740 updateComponentClasses( boardItem );
741
742 break;
743 }
744
745 case CHT_MODIFY:
746 {
747 view->Remove( boardItem );
748 connectivity->Remove( boardItem );
749
750 wxASSERT( entry.m_copy && entry.m_copy->IsBOARD_ITEM() );
751 BOARD_ITEM* boardItemCopy = static_cast<BOARD_ITEM*>( entry.m_copy );
752 boardItem->SwapItemData( boardItemCopy );
753
754 view->Add( boardItem );
755 connectivity->Add( boardItem );
756 itemsChanged.push_back( boardItem );
757
758 updateComponentClasses( boardItem );
759
760 delete entry.m_copy;
761 break;
762 }
763
764 default:
765 UNIMPLEMENTED_FOR( boardItem->GetClass() );
766 break;
767 }
768
769 boardItem->ClearEditFlags();
770 }
771
772 // Invalidate component classes
774
775 if( bulkAddedItems.size() > 0 || bulkRemovedItems.size() > 0 || itemsChanged.size() > 0 )
776 board->OnItemsCompositeUpdate( bulkAddedItems, bulkRemovedItems, itemsChanged );
777
778 if( m_isBoardEditor )
779 {
780 connectivity->RecalculateRatsnest();
782 board->OnRatsnestChanged();
783 }
784
786 selTool->RebuildSelection();
787
788 // Property panel needs to know about the reselect
790
791 clear();
792}
#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.
COMMIT & Stage(EDA_ITEM *aItem, CHANGE_TYPE aChangeType, BASE_SCREEN *aScreen=nullptr) override
Add a change of the item aItem of type aChangeType to the change list.
EDA_ITEM * parentObject(EDA_ITEM *aItem) const override
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:82
void propagateDamage(BOARD_ITEM *aItem, std::vector< ZONE * > *aStaleZones)
EDA_ITEM * makeImage(EDA_ITEM *aItem) const override
TOOL_MANAGER * m_toolMgr
Definition: board_commit.h:81
bool m_isFootprintEditor
Definition: board_commit.h:83
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:78
void SwapItemData(BOARD_ITEM *aImage)
Swap data between aItem and aImage.
Definition: board_item.cpp:226
virtual bool IsOnLayer(PCB_LAYER_ID aLayer) const
Test to see if this object is on the given layer.
Definition: board_item.h:311
FOOTPRINT * GetParentFootprint() const
Definition: board_item.cpp:299
virtual LSET GetLayerSet() const
Return a std::bitset of all layers on which the item physically resides.
Definition: board_item.h:249
virtual void RunOnChildren(const std::function< void(BOARD_ITEM *)> &aFunction, RECURSE_MODE aMode) const
Invoke a function on all children.
Definition: board_item.h:205
Information pertinent to a Pcbnew printed circuit board.
Definition: board.h:297
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT, bool aSkipConnectivity=false) override
Removes an item from the container.
Definition: board.cpp:1069
BOARD_ITEM * GetItem(const KIID &aID) const
Definition: board.cpp:1510
const ZONES & Zones() const
Definition: board.h:342
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:2747
FOOTPRINT * GetFirstFootprint() const
Get the first footprint on the board or nullptr.
Definition: board.h:463
void IncrementTimeStamp()
Definition: board.cpp:262
void OnRatsnestChanged()
Notify the board and its listeners that the ratsnest has been recomputed.
Definition: board.cpp:2756
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:1833
void UpdateRatsnestExclusions()
Update the visibility flags on the current unconnected ratsnest lines.
Definition: board.cpp:306
COMPONENT_CLASS_MANAGER & GetComponentClassManager()
Gets the component class manager.
Definition: board.h:1298
void Remove(BOARD_ITEM *aBoardItem, REMOVE_MODE aMode=REMOVE_MODE::NORMAL) override
Removes an item from the container.
Definition: board.cpp:1222
std::shared_ptr< CONNECTIVITY_DATA > GetConnectivity() const
Return a list of missing connections between components/tracks.
Definition: board.h:495
Represent a set of changes (additions, deletions or modifications) of a data model (e....
Definition: commit.h:74
virtual COMMIT & Stage(EDA_ITEM *aItem, CHANGE_TYPE aChangeType, BASE_SCREEN *aScreen=nullptr)
Add a change of the item aItem of type aChangeType to the change list.
Definition: commit.cpp:63
bool Empty() const
Definition: commit.h:150
COMMIT & Add(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Add a new item to the model.
Definition: commit.h:80
int GetStatus(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Returns status of an item.
Definition: commit.cpp:145
void clear()
Should be called in Push() & Revert() methods.
Definition: commit.h:171
std::vector< COMMIT_LINE > m_changes
Definition: commit.h:201
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
virtual bool RemoveItem(EDA_ITEM *aItem)=0
Remove item from group.
virtual EDA_ITEM * AsEdaItem()=0
A base class for most all the KiCad significant classes used in schematics and boards.
Definition: eda_item.h:96
virtual void ClearEditFlags()
Definition: eda_item.h:152
virtual const BOX2I GetBoundingBox() const
Return the orthogonal bounding box of this object for display purposes.
Definition: eda_item.cpp:84
void SetFlags(EDA_ITEM_FLAGS aMask)
Definition: eda_item.h:138
const KIID m_Uuid
Definition: eda_item.h:502
virtual EDA_GROUP * GetParentGroup() const
Definition: eda_item.h:114
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:108
bool IsSelected() const
Definition: eda_item.h:123
virtual EDA_ITEM * Clone() const
Create a duplicate of this item with linked list members set to NULL.
Definition: eda_item.cpp:92
virtual wxString GetClass() const =0
Return the class name.
EDA_ITEM_FLAGS GetFlags() const
Definition: eda_item.h:141
static const TOOL_EVENT SelectedItemsModified
Selected items were moved, this can be very high frequency on the canvas, use with care.
Definition: actions.h:347
static const TOOL_EVENT UnselectedEvent
Definition: actions.h:341
void Remove(BOARD_ITEM *aItem, REMOVE_MODE aMode=REMOVE_MODE::NORMAL) override
Removes an item from the container.
Definition: footprint.cpp:1133
std::deque< PAD * > & Pads()
Definition: footprint.h:211
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT, bool aSkipConnectivity=false) override
Removes an item from the container.
Definition: footprint.cpp:1072
void SetGroupId(KIID aId)
void SetLink(EDA_ITEM *aItem)
bool IsBOARD_ITEM() const
Definition: view_item.h:102
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:297
virtual void Remove(VIEW_ITEM *aItem)
Remove a VIEW_ITEM from the view.
Definition: view.cpp:332
virtual void Update(const VIEW_ITEM *aItem, int aUpdateFlags) const
For dynamic VIEWs, inform the associated VIEW that the graphical representation of this item has chan...
Definition: view.cpp:1673
LSET is a set of PCB_LAYER_IDs.
Definition: lset.h:37
static LSET AllCuMask(int aCuLayerCount=MAX_CU_LAYERS)
Return a mask holding the requested number of Cu PCB_LAYER_IDs.
Definition: lset.cpp:583
static const LSET & PhysicalLayersMask()
Return a mask holding all layers which are physically realized.
Definition: lset.cpp:683
Definition: pad.h:54
DISPLAY_OPTIONS m_Display
static TOOL_ACTION rehatchShapes
Definition: pcb_actions.h:371
static TOOL_ACTION zoneFillDirty
Definition: pcb_actions.h:388
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
static bool IsGroupableType(KICAD_T aType)
Check if the proposed type can be added to a group.
Definition: pcb_group.cpp:50
bool AddItem(EDA_ITEM *aItem) override
Add item to group.
Definition: pcb_group.cpp:81
The selection tool: currently supports:
PCB_GROUP * GetEnteredGroup()
void RebuildSelection()
Rebuild the selection from the EDA_ITEMs' selection flags.
A holder to handle information on schematic or board items.
int RemoveItemFromSel(const TOOL_EVENT &aEvent)
TEARDROP_MANAGER manage and build teardrop areas A teardrop area is a polygonal area (a copper ZONE) ...
Definition: teardrop.h: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
CHANGE_TYPE
Types of changes.
Definition: commit.h:41
@ CHT_MODIFY
Definition: commit.h:44
@ CHT_GROUP
Definition: commit.h:45
@ CHT_REMOVE
Definition: commit.h:43
@ CHT_DONE
Flag to indicate the change is already applied.
Definition: commit.h:49
@ CHT_TYPE
Definition: commit.h:47
@ CHT_ADD
Definition: commit.h:42
@ CHT_UNGROUP
Definition: commit.h:46
@ CHT_FLAGS
Definition: commit.h:50
#define STRUCT_DELETED
flag indication structures to be erased
#define UR_TRANSIENT
indicates the item is owned by the undo/redo stack
@ FRAME_PCB_EDITOR
Definition: frame_type.h:42
@ FRAME_FOOTPRINT_EDITOR
Definition: frame_type.h:43
@ Edge_Cuts
Definition: layer_ids.h:112
@ B_Mask
Definition: layer_ids.h:98
@ F_Mask
Definition: layer_ids.h:97
@ Margin
Definition: layer_ids.h:113
This file contains miscellaneous commonly used macros and functions.
#define UNIMPLEMENTED_FOR(type)
Definition: macros.h:96
Class to handle a set of BOARD_ITEMs.
EDA_ITEM * m_copy
Optional copy of the item.
Definition: commit.h:164
CHANGE_TYPE m_type
Modification type.
Definition: commit.h:165
EDA_ITEM * m_item
Main item that is added/deleted/modified.
Definition: commit.h:163
@ 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...