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, see <https://www.gnu.org/licenses/>.
20 */
21
22#include <macros.h>
23#include <pgm_base.h>
25#include <board.h>
27#include <footprint.h>
28#include <lset.h>
29#include <pad.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#include <pcb_board_outline.h>
44#include <pcb_drill_map.h>
45#include <pcb_base_frame.h>
46
47#include <functional>
48#include <unordered_set>
50using namespace std::placeholders;
51
52
53// A no-geometry board item (net metadata or a geometric constraint) is never pushed into the
54// VIEW or the connectivity graph. VIEW::Add early-returns on an empty layer set but still
55// stamps the item's view private data, which a later VIEW::Remove would mis-index.
56static bool isNoGeometryItem( const BOARD_ITEM* aItem )
57{
58 return aItem->Type() == PCB_NETINFO_T || aItem->Type() == PCB_CONSTRAINT_T;
59}
60
61
63 COMMIT(),
64 m_toolMgr( aTool->GetManager() ),
65 m_isBoardEditor( false ),
66 m_isFootprintEditor( false )
67{
68 if( PCB_TOOL_BASE* pcb_tool = dynamic_cast<PCB_TOOL_BASE*>( aTool ) )
69 {
70 m_isBoardEditor = pcb_tool->IsBoardEditor();
71 m_isFootprintEditor = pcb_tool->IsFootprintEditor();
72 }
73}
74
75
77 COMMIT(),
78 m_toolMgr( aFrame->GetToolManager() ),
79 m_isBoardEditor( aFrame->IsType( FRAME_PCB_EDITOR ) ),
81{
82}
83
84
86 COMMIT(),
87 m_toolMgr( aMgr ),
88 m_isBoardEditor( false ),
89 m_isFootprintEditor( false )
90{
91 EDA_DRAW_FRAME* frame = dynamic_cast<EDA_DRAW_FRAME*>( aMgr->GetToolHolder() );
92
93 if( frame && frame->IsType( FRAME_PCB_EDITOR ) )
94 m_isBoardEditor = true;
95 else if( frame && frame->IsType( FRAME_FOOTPRINT_EDITOR ) )
97}
98
99
100BOARD_COMMIT::BOARD_COMMIT( TOOL_MANAGER* aMgr, bool aIsBoardEditor, bool aIsFootprintEditor ) :
101 COMMIT(),
102 m_toolMgr( aMgr ),
103 m_isBoardEditor( aIsBoardEditor ),
104 m_isFootprintEditor( aIsFootprintEditor )
105{
106}
107
108
110{
111 return static_cast<BOARD*>( m_toolMgr->GetModel() );
112}
113
114
115COMMIT& BOARD_COMMIT::Stage( EDA_ITEM* aItem, CHANGE_TYPE aChangeType, BASE_SCREEN* aScreen, RECURSE_MODE aRecurse )
116{
117 if( aRecurse == RECURSE_MODE::RECURSE )
118 {
119 if( PCB_GROUP* group = dynamic_cast<PCB_GROUP*>( aItem ) )
120 {
121 for( EDA_ITEM* member : group->GetItems() )
122 Stage( member, aChangeType, aScreen, aRecurse );
123 }
124 }
125
126 if( m_isBoardEditor && ( aChangeType & CHT_TYPE ) == CHT_REMOVE
127 && aItem->IsBOARD_ITEM()
128 && static_cast<BOARD_ITEM*>( aItem )->GetParentFootprint() )
129 {
130 if( m_deletedItems.find( { aItem, aScreen } ) == m_deletedItems.end() )
131 makeEntry( aItem, aChangeType, makeImage( aItem ), aScreen );
132
133 return *this;
134 }
135
136 return COMMIT::Stage( aItem, aChangeType );
137}
138
139
140COMMIT& BOARD_COMMIT::Stage( std::vector<EDA_ITEM*>& container, CHANGE_TYPE aChangeType, BASE_SCREEN* aScreen )
141{
142 return COMMIT::Stage( container, aChangeType, aScreen );
143}
144
145
147{
148 return COMMIT::Stage( aItems, aModFlag, aScreen );
149}
150
151
152void BOARD_COMMIT::propagateDamage( BOARD_ITEM* aChangedItem, std::vector<ZONE*>* aStaleZones,
153 std::vector<BOX2I>& aStaleRuleAreas )
154{
155 wxCHECK( aChangedItem, /* void */ );
156
157 if( aStaleZones && aChangedItem->Type() == PCB_ZONE_T )
158 aStaleZones->push_back( static_cast<ZONE*>( aChangedItem ) );
159
160 aChangedItem->RunOnChildren( std::bind( &BOARD_COMMIT::propagateDamage, this, _1, aStaleZones, aStaleRuleAreas ),
162
163 BOARD* board = static_cast<BOARD*>( m_toolMgr->GetModel() );
164 BOX2I damageBBox = aChangedItem->GetBoundingBox();
165 LSET damageLayers = aChangedItem->GetLayerSet();
166
167 if( m_isBoardEditor && aChangedItem->Type() == PCB_ZONE_T )
168 {
169 // A named zone can have custom DRC rules targetting it.
170 if( !static_cast<ZONE*>( aChangedItem )->GetZoneName().IsEmpty() )
171 aStaleRuleAreas.push_back( damageBBox );
172 }
173
174 if( aStaleZones )
175 {
176 if( damageLayers.test( Edge_Cuts ) || damageLayers.test( Margin ) )
177 damageLayers = LSET::PhysicalLayersMask();
178 else
179 damageLayers &= LSET::AllCuMask();
180
181 if( damageLayers.any() )
182 {
183 for( ZONE* zone : board->Zones() )
184 {
185 if( zone->GetIsRuleArea() )
186 continue;
187
188 if( ( zone->GetLayerSet() & damageLayers ).any() && zone->GetBoundingBox().Intersects( damageBBox ) )
189 aStaleZones->push_back( zone );
190 }
191 }
192 }
193}
194
195
196void BOARD_COMMIT::Push( const wxString& aMessage, int aCommitFlags )
197{
198 KIGFX::PCB_VIEW* view = static_cast<KIGFX::PCB_VIEW*>( m_toolMgr->GetView() );
199 BOARD* board = static_cast<BOARD*>( m_toolMgr->GetModel() );
200 PCB_BASE_FRAME* frame = dynamic_cast<PCB_BASE_FRAME*>( m_toolMgr->GetToolHolder() );
201 PCB_SELECTION_TOOL* selTool = m_toolMgr->GetTool<PCB_SELECTION_TOOL>();
202 PCB_GROUP* enteredGroup = selTool && !( aCommitFlags & SKIP_ENTERED_GROUP ) ? selTool->GetEnteredGroup()
203 : nullptr;
204 // Notification info
205 PICKED_ITEMS_LIST undoList;
206 bool itemsDeselected = false;
207 bool selectedModified = false;
208
209 std::unordered_set<EDA_ITEM*> removedItems;
210
211 // Dirty flags and lists
212 bool solderMaskDirty = false;
213 bool autofillZones = false;
214 bool updateBoardBoundingBox = false;
215 std::vector<BOARD_ITEM*> staleTeardropPadsAndVias;
216 std::set<PCB_TRACK*> staleTeardropTracks;
217 std::vector<BOARD_ITEM*> dirtyCopper;
218 std::set<BOARD_ITEM*> dirtyCopperSeen;
219 std::vector<ZONE*> staleZonesStorage;
220 std::vector<ZONE*>* staleZones = nullptr;
221 std::vector<BOX2I> staleRuleAreas;
222
223 if( Empty() )
224 return;
225
226 bool containsDrillMap = false;
227 bool containsDrillChart = false;
228
229 for( const COMMIT_LINE& entry : m_entries )
230 {
231 if( !entry.m_item || !entry.m_item->IsBOARD_ITEM() )
232 continue;
233
234 BOARD_ITEM* item = static_cast<BOARD_ITEM*>( entry.m_item );
235
236 if( item->Type() == PCB_DRILL_CHART_T || item->Type() == PCB_DRILL_MAP_T )
237 {
238 containsDrillMap |= item->Type() == PCB_DRILL_MAP_T;
239 containsDrillChart |= item->Type() == PCB_DRILL_CHART_T;
240 }
241 }
242
243 undoList.SetDescription( aMessage );
244
245 TEARDROP_MANAGER teardropMgr( board, m_toolMgr );
246 std::shared_ptr<CONNECTIVITY_DATA> connectivity = board->GetConnectivity();
247
248 // Note: frame == nullptr happens in QA tests
249
250 std::vector<BOARD_ITEM*> bulkAddedItems;
251 std::vector<BOARD_ITEM*> bulkRemovedItems;
252 std::vector<BOARD_ITEM*> itemsChanged;
253
254 if( m_isBoardEditor && !( aCommitFlags & ZONE_FILL_OP )
255 && ( frame && frame->GetPcbNewSettings()->m_AutoRefillZones ) )
256 {
257 autofillZones = true;
258 staleZones = &staleZonesStorage;
259
260 for( ZONE* zone : board->Zones() )
261 zone->CacheBoundingBox();
262 }
263
264 for( COMMIT_LINE& entry : m_entries )
265 {
266 if( !entry.m_item || !entry.m_item->IsBOARD_ITEM() )
267 continue;
268
269 BOARD_ITEM* boardItem = static_cast<BOARD_ITEM*>( entry.m_item );
270
271 if( m_isBoardEditor )
272 {
273 if( boardItem->Type() == PCB_VIA_T || boardItem->Type() == PCB_FOOTPRINT_T
274 || boardItem->IsOnLayer( F_Mask ) || boardItem->IsOnLayer( B_Mask ) )
275 {
276 solderMaskDirty = true;
277 }
278
279 if( boardItem->IsOnLayer( Edge_Cuts ) )
280 {
281 updateBoardBoundingBox = true;
282 }
283
284 if( !( aCommitFlags & SKIP_TEARDROPS ) )
285 {
286 // Teardrops are fitted to the copper around them, so any changed copper item
287 // can invalidate one, not only what a teardrop connects to.
288 auto collectCopper =
289 [&]( BOARD_ITEM* aItem )
290 {
291 // Pours are the filler's business. Containers have no copper of
292 // their own and their boxes sweep far more than they occupy.
293 if( aItem->Type() == PCB_ZONE_T || aItem->Type() == PCB_FOOTPRINT_T
294 || aItem->Type() == PCB_GROUP_T
295 || aItem->Type() == PCB_GENERATOR_T )
296 {
297 return;
298 }
299
300 // A group and its members can both be in the commit.
301 if( ( aItem->GetLayerSet() & LSET::AllCuMask() ).any()
302 && dirtyCopperSeen.insert( aItem ).second )
303 {
304 dirtyCopper.push_back( aItem );
305 }
306 };
307
308 collectCopper( boardItem );
309 boardItem->RunOnChildren( collectCopper, RECURSE_MODE::RECURSE );
310
311 // boardItem already carries the edit, so it cannot show where the item was.
312 // The pre-edit clone is still ours here and answers a bounding box.
313 if( entry.m_copy && entry.m_copy->IsBOARD_ITEM() )
314 {
315 BOARD_ITEM* copy = static_cast<BOARD_ITEM*>( entry.m_copy );
316
317 collectCopper( copy );
318 copy->RunOnChildren( collectCopper, RECURSE_MODE::RECURSE );
319 }
320
321 if( boardItem->Type() == PCB_FOOTPRINT_T )
322 {
323 for( PAD* pad : static_cast<FOOTPRINT*>( boardItem )->Pads() )
324 staleTeardropPadsAndVias.push_back( pad );
325 }
326 else if( boardItem->Type() == PCB_PAD_T || boardItem->Type() == PCB_VIA_T )
327 {
328 staleTeardropPadsAndVias.push_back( boardItem );
329 }
330 else if( boardItem->Type() == PCB_TRACE_T || boardItem->Type() == PCB_ARC_T )
331 {
332 PCB_TRACK* track = static_cast<PCB_TRACK*>( boardItem );
333
334 staleTeardropTracks.insert( track );
335
336 std::vector<PAD*> connectedPads;
337 std::vector<PCB_VIA*> connectedVias;
338
339 connectivity->GetConnectedPadsAndVias( track, &connectedPads, &connectedVias );
340
341 for( PAD* pad : connectedPads )
342 staleTeardropPadsAndVias.push_back( pad );
343
344 for( PCB_VIA* via : connectedVias )
345 staleTeardropPadsAndVias.push_back( via );
346 }
347 }
348 }
349
350 if( boardItem->IsSelected() || ( m_isFootprintEditor && boardItem == board->GetFirstFootprint() ) )
351 selectedModified = true;
352 }
353
354 // Old teardrops must be removed before connectivity is rebuilt
355 if( !staleTeardropPadsAndVias.empty() || !staleTeardropTracks.empty()
356 || !dirtyCopper.empty() )
357 {
358 teardropMgr.RemoveTeardrops( *this, &staleTeardropPadsAndVias, &staleTeardropTracks,
359 &dirtyCopper );
360 }
361
362 auto updateComponentClasses =
363 [this]( BOARD_ITEM* boardItem )
364 {
365 if( boardItem->Type() != PCB_FOOTPRINT_T )
366 return;
367
368 FOOTPRINT* footprint = static_cast<FOOTPRINT*>( boardItem );
370 };
371
372 // We don't know that anything will be added to the entered group, but it does no harm to
373 // add it to the commit anyway.
374 if( enteredGroup )
375 Modify( enteredGroup );
376
377
378 for( COMMIT_LINE& entry : m_entries )
379 {
380 if( !entry.m_item || !entry.m_item->IsBOARD_ITEM() )
381 continue;
382
383 BOARD_ITEM* boardItem = static_cast<BOARD_ITEM*>( entry.m_item );
384 int changeType = entry.m_type & CHT_TYPE;
385 int changeFlags = entry.m_type & CHT_FLAGS;
386
387 switch( changeType )
388 {
389 case CHT_ADD:
390 if( enteredGroup && boardItem->IsGroupableType() && !boardItem->GetParentGroup() )
391 enteredGroup->AddItem( boardItem );
392
393 if( !( aCommitFlags & SKIP_UNDO ) )
394 undoList.PushItem( ITEM_PICKER( nullptr, boardItem, UNDO_REDO::NEWITEM ) );
395
396 if( !( changeFlags & CHT_DONE ) )
397 {
398 // Markers are always stored at the board level, even in the footprint editor
399 if( m_isFootprintEditor && boardItem->Type() != PCB_MARKER_T )
400 {
401 if( FOOTPRINT* parentFP = board->GetFirstFootprint() )
402 parentFP->Add( boardItem );
403 }
404 else
405 {
406 board->Add( boardItem, ADD_MODE::BULK_INSERT ); // handles connectivity
407 bulkAddedItems.push_back( boardItem );
408 }
409 }
410
411 if( boardItem->Type() != PCB_MARKER_T )
412 propagateDamage( boardItem, staleZones, staleRuleAreas );
413
414 if( view && !isNoGeometryItem( boardItem ) )
415 view->Add( boardItem );
416
417 updateComponentClasses( boardItem );
418
419 break;
420
421 case CHT_REMOVE:
422 {
423 EDA_GROUP* parentGroup = boardItem->GetParentGroup();
424
425 if( !( aCommitFlags & SKIP_UNDO ) )
426 {
428 ITEM_PICKER itemWrapper( nullptr, boardItem, status );
429 itemWrapper.SetLink( entry.m_copy );
430 entry.m_copy = nullptr; // We've transferred ownership to the undo list
431 undoList.PushItem( itemWrapper );
432 }
433
434 if( boardItem->IsSelected() )
435 {
436 if( selTool )
437 selTool->RemoveItemFromSel( boardItem, true /* quiet mode */ );
438
439 itemsDeselected = true;
440 }
441
442 removedItems.insert( boardItem );
443
444 if( parentGroup && !( parentGroup->AsEdaItem()->GetFlags() & STRUCT_DELETED ) )
445 parentGroup->RemoveItem( boardItem );
446
447 if( boardItem->Type() != PCB_MARKER_T )
448 propagateDamage( boardItem, staleZones, staleRuleAreas );
449
450 switch( boardItem->Type() )
451 {
452 case PCB_FIELD_T:
453 static_cast<PCB_FIELD*>( boardItem )->SetVisible( false );
454
455 if( view )
456 view->Update( boardItem );
457
458 break;
459
460 case PCB_TEXT_T:
461 case PCB_PAD_T:
462 case PCB_SHAPE_T:
464 case PCB_GENERATOR_T:
465 case PCB_TEXTBOX_T:
466 case PCB_BARCODE_T:
467 case PCB_TABLE_T:
469 case PCB_DRILL_MAP_T:
470 case PCB_TRACE_T:
471 case PCB_ARC_T:
472 case PCB_VIA_T:
474 case PCB_DIM_CENTER_T:
475 case PCB_DIM_RADIAL_T:
477 case PCB_DIM_LEADER_T:
478 case PCB_TARGET_T:
479 case PCB_POINT_T:
480 case PCB_ZONE_T:
481 case PCB_GRID_ITEM_T:
482 case PCB_FOOTPRINT_T:
483 case PCB_GROUP_T:
484 if( view )
485 view->Remove( boardItem );
486
487 if( !( changeFlags & CHT_DONE ) )
488 {
489 if( m_isFootprintEditor && boardItem->Type() != PCB_MARKER_T )
490 {
491 if( FOOTPRINT* parentFP = board->GetFirstFootprint() )
492 parentFP->Remove( boardItem );
493 }
494 else if( FOOTPRINT* parentFP = boardItem->GetParentFootprint() )
495 {
496 parentFP->Remove( boardItem );
497 }
498 else
499 {
500 board->Remove( boardItem, REMOVE_MODE::BULK );
501 bulkRemovedItems.push_back( boardItem );
502 }
503 }
504
505 break;
506
507 case PCB_MARKER_T:
508 if( view )
509 view->Remove( boardItem );
510
511 if( !( changeFlags & CHT_DONE ) )
512 {
513 // Markers are always stored at the board level, even in the footprint editor
514 board->Remove( boardItem, REMOVE_MODE::BULK );
515 bulkRemovedItems.push_back( boardItem );
516 }
517
518 break;
519
520 // No-geometry items: never in the view, so skip view->Remove.
521 case PCB_CONSTRAINT_T:
522 if( !( changeFlags & CHT_DONE ) )
523 {
525 {
526 if( FOOTPRINT* parentFP = board->GetFirstFootprint() )
527 parentFP->Remove( boardItem );
528 }
529 else if( FOOTPRINT* parentFP = boardItem->GetParentFootprint() )
530 {
531 parentFP->Remove( boardItem );
532 }
533 else
534 {
535 board->Remove( boardItem, REMOVE_MODE::BULK );
536 bulkRemovedItems.push_back( boardItem );
537 }
538 }
539
540 break;
541
542 // Metadata items
543 case PCB_NETINFO_T:
544 board->Remove( boardItem, REMOVE_MODE::BULK );
545 bulkRemovedItems.push_back( boardItem );
546 break;
547
548 default: // other types do not need to (or should not) be handled
549 wxASSERT( false );
550 break;
551 }
552
553 // Removed items are owned by undo/redo, but a hidden field still belongs to its footprint
554 if( boardItem->Type() != PCB_FIELD_T )
555 boardItem->SetFlags( UR_TRANSIENT );
556
557 break;
558 }
559
560 case CHT_MODIFY:
561 {
562 BOARD_ITEM* boardItemCopy = static_cast<BOARD_ITEM*>( entry.m_copy );
563
564 if( !( aCommitFlags & SKIP_UNDO ) )
565 {
566 ITEM_PICKER itemWrapper( nullptr, boardItem, UNDO_REDO::CHANGED );
567 itemWrapper.SetLink( entry.m_copy );
568 entry.m_copy = nullptr; // We've transferred ownership to the undo list
569 undoList.PushItem( itemWrapper );
570 }
571
572 if( !( aCommitFlags & SKIP_CONNECTIVITY ) && !isNoGeometryItem( boardItem ) )
573 {
574 connectivity->MarkItemNetAsDirty( boardItemCopy );
575 connectivity->Update( boardItem );
576 }
577
578 if( boardItem->Type() != PCB_MARKER_T )
579 {
580 propagateDamage( boardItemCopy, staleZones, staleRuleAreas ); // before
581 propagateDamage( boardItem, staleZones, staleRuleAreas ); // after
582 }
583
584 updateComponentClasses( boardItem );
585
586 if( view && !isNoGeometryItem( boardItem ) )
587 view->Update( boardItem );
588
589 itemsChanged.push_back( boardItem );
590 break;
591 }
592
593 default:
594 UNIMPLEMENTED_FOR( boardItem->GetClass() );
595 break;
596 }
597
598 // Delete any copies we still have ownership of
599 delete entry.m_copy;
600 entry.m_copy = nullptr;
601
602 boardItem->ClearEditFlags();
603 boardItem->RunOnChildren(
604 [&]( BOARD_ITEM* item )
605 {
606 item->ClearEditFlags();
607 },
609 } // ... and regenerate them.
610
611 // Deselection above keys off the SELECTED flag on the removed item itself, but the selection
612 // may separately hold an owned descendant such as a pad, field or table cell. Descendants
613 // are freed along with the removed parent, so prune them here or the selection keeps a
614 // dangling pointer that the next repaint dereferences.
615 if( selTool && !removedItems.empty() )
616 {
617 for( EDA_ITEM* selectedItem : selTool->GetSelection().GetItems() )
618 {
619 for( EDA_ITEM* ancestor = selectedItem; ancestor; ancestor = ancestor->GetParent() )
620 {
621 if( removedItems.count( ancestor ) )
622 {
623 selTool->RemoveItemFromSel( selectedItem, true /* quiet mode */ );
624 itemsDeselected = true;
625 break;
626 }
627 }
628 }
629 }
630
631 // Invalidate component classes
633
634 if( m_isBoardEditor )
635 {
636 size_t originalCount = m_entries.size();
637
638 if( aCommitFlags & SKIP_CONNECTIVITY )
639 {
640 connectivity->ClearRatsnest();
641 connectivity->ClearLocalRatsnest();
642 }
643 else
644 {
645 connectivity->RecalculateRatsnest( this );
647 connectivity->ClearLocalRatsnest();
648
649 if( frame )
650 frame->GetCanvas()->RedrawRatsnest();
651
652 board->OnRatsnestChanged();
653 }
654
655 if( solderMaskDirty )
656 {
657 if( frame )
658 frame->HideSolderMask();
659 }
660
661 if( updateBoardBoundingBox && view )
662 {
663 if( PCB_BOARD_OUTLINE* outline = board->BoardOutline() )
664 {
665 board->UpdateBoardOutline();
666
667 if( view->HasItem( outline ) )
668 view->Update( outline );
669 else
670 view->Add( outline );
671 }
672
673 RefreshDrillMapOutlines( *board, view );
674 }
675
676 if( PCBNEW_SETTINGS* cfg = GetAppSettings<PCBNEW_SETTINGS>( "pcbnew" ) )
677 {
678 if( !staleRuleAreas.empty() && ( cfg->m_Display.m_TrackClearance == SHOW_WITH_VIA_ALWAYS
679 || cfg->m_Display.m_PadClearance ) )
680 {
681 if( view )
682 view->UpdateCollidingItems( staleRuleAreas, { PCB_TRACE_T, PCB_ARC_T, PCB_VIA_T, PCB_PAD_T } );
683 }
684 }
685
686 if( !staleTeardropPadsAndVias.empty() || !staleTeardropTracks.empty() )
687 {
688 teardropMgr.UpdateTeardrops( *this, &staleTeardropPadsAndVias, &staleTeardropTracks );
689
690 // UpdateTeardrops() can modify the ratsnest data. So rebuild this ratsnest data
691 connectivity->RecalculateRatsnest( this );
692 }
693
694 // Log undo items for any connectivity or teardrop changes
695 for( size_t i = originalCount; i < m_entries.size(); ++i )
696 {
697 COMMIT_LINE& entry = m_entries[i];
698 BOARD_ITEM* boardItem = nullptr;
699 BOARD_ITEM* boardItemCopy = nullptr;
700
701 if( entry.m_item && entry.m_item->IsBOARD_ITEM() )
702 boardItem = static_cast<BOARD_ITEM*>( entry.m_item );
703
704 if( entry.m_copy && entry.m_copy->IsBOARD_ITEM() )
705 boardItemCopy = static_cast<BOARD_ITEM*>( entry.m_copy );
706
707 wxCHECK2( boardItem, continue );
708
709 if( !( aCommitFlags & SKIP_UNDO ) )
710 {
711 ITEM_PICKER itemWrapper( nullptr, boardItem, convert( entry.m_type & CHT_TYPE ) );
712 itemWrapper.SetLink( boardItemCopy );
713 undoList.PushItem( itemWrapper );
714 }
715 else
716 {
717 delete entry.m_copy;
718 }
719
720 if( view && !isNoGeometryItem( boardItem ) )
721 {
722 if( ( entry.m_type & CHT_TYPE ) == CHT_ADD )
723 view->Add( boardItem );
724 else if( ( entry.m_type & CHT_TYPE ) == CHT_REMOVE )
725 view->Remove( boardItem );
726 else
727 view->Update( boardItem );
728 }
729 }
730 }
731
732 if( bulkAddedItems.size() > 0 || bulkRemovedItems.size() > 0 || itemsChanged.size() > 0 )
733 board->OnItemsCompositeUpdate( bulkAddedItems, bulkRemovedItems, itemsChanged );
734
735 // A shrinking table deletes the cells past its new end and the selection holds those
736 // cells directly, so it has to be resolved again from what is still on the board
737 if( containsDrillChart && selTool )
738 selTool->RebuildSelection();
739
740 if( frame )
741 {
742 if( !( aCommitFlags & SKIP_UNDO ) )
743 {
744 if( aCommitFlags & APPEND_UNDO )
746 else
747 frame->SaveCopyInUndoList( undoList, UNDO_REDO::UNSPECIFIED );
748 }
749 }
750
751 m_toolMgr->PostEvent( { TC_MESSAGE, TA_MODEL_CHANGE, AS_GLOBAL } );
752
753 if( itemsDeselected )
755
756 if( autofillZones )
757 {
758 ZONE_FILLER_TOOL* zoneFillerTool = m_toolMgr->GetTool<ZONE_FILLER_TOOL>();
759
760 for( ZONE* zone : *staleZones )
761 zoneFillerTool->DirtyZone( zone );
762
764 }
765
766 // Rehatching only refreshes cached view geometry (consumers regenerate it lazily), and
767 // dispatching it headlessly makes the tool manager query the platform cursor position
768 if( view )
770
771 if( selectedModified )
773
774 if( frame )
775 {
776 if( !( aCommitFlags & SKIP_SET_DIRTY ) )
777 frame->OnModify();
778 else
780
781 // Ensure the message panel is updated after committing changes.
782 // By default (i.e. if no event posted), display the updated board info
783 if( !itemsDeselected && !autofillZones && !selectedModified )
784 {
785 std::vector<MSG_PANEL_ITEM> msg_list;
786 board->GetMsgPanelInfo( frame, msg_list );
787 frame->SetMsgPanel( msg_list );
788 }
789 }
790
791 if( containsDrillMap && frame )
793
794 clear();
795}
796
797
799{
800 // Easiest way to disallow both a parent and one of its children appearing in the list
801 // is to only ever add the parent when either can be legal (ie: in the board editor).
802 if( m_isBoardEditor && aItem->IsBOARD_ITEM() )
803 {
804 if( FOOTPRINT* footprint = static_cast<BOARD_ITEM*>( aItem )->GetParentFootprint() )
805 return footprint;
806 }
807
808 EDA_ITEM* parent = aItem->GetParent();
809
810 if( parent && BaseType( parent->Type() ) == PCB_TABLE_T )
811 return parent;
812
813 return aItem;
814}
815
816
818{
819 return MakeImage( aItem );
820}
821
822
824{
825 EDA_ITEM* clone = aItem->Clone();
826 clone->SetFlags( UR_TRANSIENT );
827
828 return clone;
829}
830
831
833{
834 PICKED_ITEMS_LIST undoList;
835 KIGFX::VIEW* view = m_toolMgr->GetView(); // null in headless sessions
836 BOARD* board = (BOARD*) m_toolMgr->GetModel();
837 std::shared_ptr<CONNECTIVITY_DATA> connectivity = board->GetConnectivity();
838
839 board->IncrementTimeStamp(); // clear caches
840
841 auto updateComponentClasses =
842 [this]( BOARD_ITEM* boardItem )
843 {
844 if( boardItem->Type() != PCB_FOOTPRINT_T )
845 return;
846
847 FOOTPRINT* footprint = static_cast<FOOTPRINT*>( boardItem );
849 };
850
851 std::vector<BOARD_ITEM*> bulkAddedItems;
852 std::vector<BOARD_ITEM*> bulkRemovedItems;
853 std::vector<BOARD_ITEM*> itemsChanged;
854 std::vector<BOARD_ITEM*> itemsToDelete;
855 bool containsDrillMap = false;
856
857 for( COMMIT_LINE& entry : m_entries )
858 {
859 if( !entry.m_item || !entry.m_item->IsBOARD_ITEM() )
860 continue;
861
862 BOARD_ITEM* boardItem = static_cast<BOARD_ITEM*>( entry.m_item );
863 int changeType = entry.m_type & CHT_TYPE;
864 int changeFlags = entry.m_type & CHT_FLAGS;
865
866 if( boardItem->Type() == PCB_DRILL_CHART_T || boardItem->Type() == PCB_DRILL_MAP_T )
867 {
868 containsDrillMap |= boardItem->Type() == PCB_DRILL_MAP_T;
869 }
870
871 switch( changeType )
872 {
873 case CHT_ADD:
874 if( changeFlags & CHT_DONE )
875 {
876 if( view && !isNoGeometryItem( boardItem ) )
877 view->Remove( boardItem );
878
879 connectivity->Remove( boardItem );
880
882 {
883 if( FOOTPRINT* parentFP = board->GetFirstFootprint() )
884 parentFP->Remove( boardItem );
885 }
886 else if( FOOTPRINT* parentFP = boardItem->GetParentFootprint() )
887 {
888 parentFP->Remove( boardItem );
889 }
890 else
891 {
892 board->Remove( boardItem, REMOVE_MODE::BULK );
893 bulkRemovedItems.push_back( boardItem );
894 }
895 }
896
897 if( PCB_GROUP* group = dynamic_cast<PCB_GROUP*>( boardItem ) )
898 group->RemoveAll();
899
900 // Defer deletion until after OnItemsCompositeUpdate so that
901 // board listeners do not receive dangling pointers.
902 itemsToDelete.push_back( boardItem );
903 entry.m_item = nullptr;
904 continue;
905
906 case CHT_REMOVE:
907 {
908 if( !( changeFlags & CHT_DONE ) )
909 break;
910
911 if( view && !isNoGeometryItem( boardItem ) )
912 view->Add( boardItem );
913
915 {
916 if( FOOTPRINT* parentFP = board->GetFirstFootprint() )
917 parentFP->Add( boardItem, ADD_MODE::INSERT );
918 }
919 else if( FOOTPRINT* parentFP = boardItem->GetParentFootprint() )
920 {
921 parentFP->Add( boardItem, ADD_MODE::INSERT );
922 }
923 else
924 {
925 board->Add( boardItem, ADD_MODE::INSERT );
926 bulkAddedItems.push_back( boardItem );
927 }
928
929 updateComponentClasses( boardItem );
930 break;
931 }
932
933 case CHT_MODIFY:
934 {
935 if( view && !isNoGeometryItem( boardItem ) )
936 view->Remove( boardItem );
937
938 connectivity->Remove( boardItem );
939
940 wxASSERT( entry.m_copy && entry.m_copy->IsBOARD_ITEM() );
941 BOARD_ITEM* boardItemCopy = static_cast<BOARD_ITEM*>( entry.m_copy );
942 boardItem->SwapItemData( boardItemCopy );
943
944 if( view && !isNoGeometryItem( boardItem ) )
945 view->Add( boardItem );
946
947 connectivity->Add( boardItem );
948 itemsChanged.push_back( boardItem );
949
950 updateComponentClasses( boardItem );
951 break;
952 }
953
954 default:
955 UNIMPLEMENTED_FOR( boardItem->GetClass() );
956 break;
957 }
958
959 // Delete any copies we still have ownership of
960 delete entry.m_copy;
961 entry.m_copy = nullptr;
962
963 boardItem->ClearEditFlags();
964 }
965
966 // Invalidate component classes
968
969 if( bulkAddedItems.size() > 0 || bulkRemovedItems.size() > 0 || itemsChanged.size() > 0 )
970 board->OnItemsCompositeUpdate( bulkAddedItems, bulkRemovedItems, itemsChanged );
971
972 if( m_isBoardEditor )
973 {
974 for( BOARD_ITEM* item : itemsToDelete )
975 connectivity->Remove( item );
976 }
977
978 for( BOARD_ITEM* item : itemsToDelete )
979 delete item;
980
981 if( m_isBoardEditor )
982 {
983 connectivity->RecalculateRatsnest();
985 board->OnRatsnestChanged();
986 }
987
988 if( PCB_SELECTION_TOOL* selTool = m_toolMgr->GetTool<PCB_SELECTION_TOOL>() )
989 selTool->RebuildSelection();
990
991 // Property panel needs to know about the reselect
993
994 if( containsDrillMap )
995 {
996 if( PCB_BASE_FRAME* frame = dynamic_cast<PCB_BASE_FRAME*>( m_toolMgr->GetToolHolder() ) )
997 {
998 frame->RefreshDrillSymbols( KIGFX::LAYERS | KIGFX::GEOMETRY | KIGFX::REPAINT );
999 }
1000 }
1001
1002 clear();
1003}
1004
1006{
1007 if( aID == niluuid )
1008 return nullptr;
1009
1010 for( COMMIT_LINE& entry : m_entries )
1011 {
1012 if( entry.m_item && entry.m_item->IsBOARD_ITEM() && entry.m_item->m_Uuid == aID )
1013 return entry.m_item;
1014 }
1015
1016 return nullptr;
1017}
static bool isNoGeometryItem(const BOARD_ITEM *aItem)
#define SKIP_CONNECTIVITY
#define SKIP_SET_DIRTY
#define APPEND_UNDO
#define SKIP_UNDO
#define ZONE_FILL_OP
#define SKIP_ENTERED_GROUP
#define SKIP_TEARDROPS
BOX2< VECTOR2I > BOX2I
Definition box2.h:927
Handles how to draw a screen (a board, a schematic ...)
Definition base_screen.h:37
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.
virtual EDA_ITEM * ResolveItem(KIID &aID) override
Search for an item in this commit that matches the provided KIID.
BOARD * GetBoard() const
virtual void Revert() override
Revert the commit by restoring the modified items state.
static EDA_ITEM * MakeImage(EDA_ITEM *aItem)
EDA_ITEM * undoLevelItem(EDA_ITEM *aItem) const override
bool m_isBoardEditor
EDA_ITEM * makeImage(EDA_ITEM *aItem) const override
void propagateDamage(BOARD_ITEM *aItem, std::vector< ZONE * > *aStaleZones, std::vector< BOX2I > &aStaleRuleAreas)
TOOL_MANAGER * m_toolMgr
bool m_isFootprintEditor
BOARD_COMMIT(EDA_DRAW_FRAME *aFrame)
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition board_item.h:84
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:408
FOOTPRINT * GetParentFootprint() const
virtual LSET GetLayerSet() const
Return a std::bitset of all layers on which the item physically resides.
Definition board_item.h:346
virtual void RunOnChildren(const std::function< void(BOARD_ITEM *)> &aFunction, RECURSE_MODE aMode) const
Invoke a function on all children.
Definition board_item.h:264
Information pertinent to a Pcbnew printed circuit board.
Definition board.h:409
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT, bool aSkipConnectivity=false) override
Removes an item from the container.
Definition board.cpp:1497
PCB_BOARD_OUTLINE * BoardOutline()
Definition board.h:478
void UpdateBoardOutline()
Definition board.cpp:4462
const ZONES & Zones() const
Definition board.h:467
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:4022
FOOTPRINT * GetFirstFootprint() const
Get the first footprint on the board or nullptr.
Definition board.h:704
void IncrementTimeStamp()
Definition board.cpp:446
void OnRatsnestChanged()
Notify the board and its listeners that the ratsnest has been recomputed.
Definition board.cpp:4033
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:2790
void UpdateRatsnestExclusions()
Update the visibility flags on the current unconnected ratsnest lines.
Definition board.cpp:538
COMPONENT_CLASS_MANAGER & GetComponentClassManager()
Gets the component class manager.
Definition board.h:1668
void Remove(BOARD_ITEM *aBoardItem, REMOVE_MODE aMode=REMOVE_MODE::NORMAL) override
Removes an item from the container.
Definition board.cpp:1668
std::shared_ptr< CONNECTIVITY_DATA > GetConnectivity() const
Return a list of missing connections between components/tracks.
Definition board.h:751
std::set< std::pair< EDA_ITEM *, BASE_SCREEN * > > m_deletedItems
Definition commit.h:190
bool Empty() const
Definition commit.h:142
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:102
COMMIT()
Definition commit.cpp:30
virtual void makeEntry(EDA_ITEM *aItem, CHANGE_TYPE aType, EDA_ITEM *aCopy=nullptr, BASE_SCREEN *aScreen=nullptr)
Definition commit.cpp:240
std::vector< COMMIT_LINE > m_entries
Definition commit.h:191
void clear()
Should be called in Push() & Revert() methods.
Definition commit.h:162
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:42
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:43
void RemoveItem(EDA_ITEM *aItem)
Remove item from group.
Definition eda_group.cpp:77
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:178
virtual const BOX2I GetBoundingBox() const
Return the orthogonal bounding box of this object for display purposes.
Definition eda_item.cpp:270
void SetFlags(EDA_ITEM_FLAGS aMask)
Definition eda_item.h:158
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:134
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:278
EDA_ITEM_FLAGS GetFlags() const
Definition eda_item.h:167
static const TOOL_EVENT SelectedItemsModified
Selected items were moved, this can be very high frequency on the canvas, use with care.
Definition actions.h:350
static const TOOL_EVENT UnselectedEvent
Definition actions.h:344
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:87
virtual void Add(VIEW_ITEM *aItem, int aDrawPriority=-1) override
Add a VIEW_ITEM to the view.
Definition pcb_view.cpp:53
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:118
virtual void Remove(VIEW_ITEM *aItem) override
Remove a VIEW_ITEM from the view.
Definition pcb_view.cpp:70
bool IsBOARD_ITEM() const
Definition view_item.h:98
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:63
virtual void Add(VIEW_ITEM *aItem, int aDrawPriority=-1)
Add a VIEW_ITEM to the view.
Definition view.cpp:301
virtual void Remove(VIEW_ITEM *aItem)
Remove a VIEW_ITEM from the view.
Definition view.cpp:416
bool HasItem(const VIEW_ITEM *aItem) const
Indicates whether or not the given item has been added to the view.
Definition view.cpp:1838
Definition kiid.h:46
LSET is a set of PCB_LAYER_IDs.
Definition lset.h:37
static const LSET & AllCuMask()
return AllCuMask( MAX_CU_LAYERS );
Definition lset.cpp:604
static LSET AllCuMask(int aCuLayerCount)
Return a mask holding the requested number of Cu PCB_LAYER_IDs.
Definition lset.cpp:595
static const LSET & PhysicalLayersMask()
Return a mask holding all layers which are physically realized.
Definition lset.cpp:693
Definition pad.h:61
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 RefreshDrillSymbols(int aUpdateFlags)
Refresh cached drill symbols in frames that render drill maps.
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:51
The selection tool: currently supports:
PCB_GROUP * GetEnteredGroup()
PCB_SELECTION & GetSelection()
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)
const std::deque< EDA_ITEM * > GetItems() const
Definition selection.h:125
TEARDROP_MANAGER manage and build teardrop areas A teardrop area is a polygonal area (a copper ZONE) ...
Definition teardrop.h:86
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:422
void RemoveTeardrops(BOARD_COMMIT &aCommit, std::vector< BOARD_ITEM * > *dirtyPadsAndVias, std::set< PCB_TRACK * > *dirtyTracks, const std::vector< BOARD_ITEM * > *dirtyCopper=nullptr)
Remove teardrops on dirty pads, vias or tracks, and any whose neighbouring copper moved,...
Definition teardrop.cpp:228
Base abstract interface for all kinds of tools.
Definition tool_base.h:62
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:70
CHANGE_TYPE
Types of changes.
Definition commit.h:37
@ CHT_MODIFY
Definition commit.h:40
@ CHT_REMOVE
Definition commit.h:39
@ CHT_DONE
Flag to indicate the change is already applied.
Definition commit.h:43
@ CHT_TYPE
Definition commit.h:41
@ CHT_ADD
Definition commit.h:38
@ CHT_FLAGS
Definition commit.h:44
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:38
@ FRAME_FOOTPRINT_EDITOR
Definition frame_type.h:39
KIID niluuid(0)
@ Edge_Cuts
Definition layer_ids.h:108
@ B_Mask
Definition layer_ids.h:94
@ F_Mask
Definition layer_ids.h:93
@ Margin
Definition layer_ids.h:109
This file contains miscellaneous commonly used macros and functions.
#define UNIMPLEMENTED_FOR(type)
Definition macros.h:92
@ REPAINT
Item needs to be redrawn.
Definition view_item.h:54
@ GEOMETRY
Position or shape has changed.
Definition view_item.h:51
@ LAYERS
Layers have changed.
Definition view_item.h:52
void RefreshDrillMapOutlines(const BOARD &aBoard, KIGFX::VIEW *aView)
Repaint every drill map after an Edge.Cuts edit.
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:156
CHANGE_TYPE m_type
Modification type.
Definition commit.h:157
EDA_ITEM * m_item
Main item that is added/deleted/modified.
Definition commit.h:155
@ AS_GLOBAL
Global action (toolbar/main menu event, global shortcut)
Definition tool_action.h:45
@ TA_MODEL_CHANGE
Model has changed (partial update).
Definition tool_event.h:117
@ TC_MESSAGE
Definition tool_event.h:54
constexpr KICAD_T BaseType(const KICAD_T aType)
Return the underlying type of the given type.
Definition typeinfo.h:259
@ PCB_CONSTRAINT_T
a geometric constraint between board items
Definition typeinfo.h:237
@ PCB_SHAPE_T
class PCB_SHAPE, a segment not on copper layers
Definition typeinfo.h:80
@ PCB_DIM_ORTHOGONAL_T
class PCB_DIM_ORTHOGONAL, a linear dimension constrained to x/y
Definition typeinfo.h:98
@ PCB_DIM_LEADER_T
class PCB_DIM_LEADER, a leader dimension (graphic item)
Definition typeinfo.h:95
@ PCB_GENERATOR_T
class PCB_GENERATOR, generator on a layer
Definition typeinfo.h:83
@ PCB_VIA_T
class PCB_VIA, a via (like a track segment on a copper layer)
Definition typeinfo.h:89
@ PCB_DRILL_MAP_T
class PCB_DRILL_MAP, drill symbols drawn at the holes
Definition typeinfo.h:240
@ PCB_DIM_CENTER_T
class PCB_DIM_CENTER, a center point marking (graphic item)
Definition typeinfo.h:96
@ PCB_GROUP_T
class PCB_GROUP, a set of BOARD_ITEMs
Definition typeinfo.h:103
@ PCB_TEXTBOX_T
class PCB_TEXTBOX, wrapped text on a layer
Definition typeinfo.h:85
@ PCB_ZONE_T
class ZONE, a copper pour area
Definition typeinfo.h:100
@ PCB_TEXT_T
class PCB_TEXT, text on a layer
Definition typeinfo.h:84
@ PCB_REFERENCE_IMAGE_T
class PCB_REFERENCE_IMAGE, bitmap on a layer
Definition typeinfo.h:81
@ PCB_FIELD_T
class PCB_FIELD, text associated with a footprint property
Definition typeinfo.h:82
@ PCB_MARKER_T
class PCB_MARKER, a marker used to show something
Definition typeinfo.h:91
@ PCB_BARCODE_T
class PCB_BARCODE, a barcode (graphic item)
Definition typeinfo.h:93
@ PCB_TARGET_T
class PCB_TARGET, a target (graphic item)
Definition typeinfo.h:99
@ PCB_FOOTPRINT_T
class FOOTPRINT, a footprint
Definition typeinfo.h:78
@ PCB_GRID_ITEM_T
a subgrid placed on a board
Definition typeinfo.h:238
@ PCB_DIM_ALIGNED_T
class PCB_DIM_ALIGNED, a linear dimension (graphic item)
Definition typeinfo.h:94
@ PCB_PAD_T
class PAD, a pad in a footprint
Definition typeinfo.h:79
@ PCB_ARC_T
class PCB_ARC, an arc track segment on a copper layer
Definition typeinfo.h:90
@ PCB_TABLE_T
class PCB_TABLE, table of PCB_TABLECELLs
Definition typeinfo.h:86
@ PCB_NETINFO_T
class NETINFO_ITEM, a description of a net
Definition typeinfo.h:102
@ PCB_POINT_T
class PCB_POINT, a 0-dimensional point
Definition typeinfo.h:105
@ PCB_TRACE_T
class PCB_TRACK, a track segment (segment on a copper layer)
Definition typeinfo.h:88
@ PCB_DIM_RADIAL_T
class PCB_DIM_RADIAL, a radius or diameter dimension
Definition typeinfo.h:97
@ PCB_DRILL_CHART_T
class PCB_DRILL_CHART, a live drill chart derived from PCB_TABLE
Definition typeinfo.h:239
UNDO_REDO
Undo Redo considerations: Basically we have 3 cases New item Deleted item Modified item there is also...