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
153{
154 COMMIT_LINE* entry = findEntry( aItem );
155
156 // An add already applied to the board has to be undone through it, so only pending adds are freed
157 if( !entry || entry->m_type != CHT_ADD )
158 {
159 Remove( aItem );
160 return false;
161 }
162
163 if( EDA_GROUP* parentGroup = aItem->GetParentGroup() )
164 parentGroup->RemoveItem( aItem );
165
166 if( PCB_GROUP* group = dynamic_cast<PCB_GROUP*>( aItem ) )
167 group->RemoveAll();
168
169 Unstage( aItem, nullptr );
170 return true;
171}
172
173
174void BOARD_COMMIT::propagateDamage( BOARD_ITEM* aChangedItem, std::vector<ZONE*>* aStaleZones,
175 std::vector<BOX2I>& aStaleRuleAreas )
176{
177 wxCHECK( aChangedItem, /* void */ );
178
179 if( aStaleZones && aChangedItem->Type() == PCB_ZONE_T )
180 aStaleZones->push_back( static_cast<ZONE*>( aChangedItem ) );
181
182 aChangedItem->RunOnChildren( std::bind( &BOARD_COMMIT::propagateDamage, this, _1, aStaleZones, aStaleRuleAreas ),
184
185 BOARD* board = static_cast<BOARD*>( m_toolMgr->GetModel() );
186 BOX2I damageBBox = aChangedItem->GetBoundingBox();
187 LSET damageLayers = aChangedItem->GetLayerSet();
188
189 if( m_isBoardEditor && aChangedItem->Type() == PCB_ZONE_T )
190 {
191 // A named zone can have custom DRC rules targetting it.
192 if( !static_cast<ZONE*>( aChangedItem )->GetZoneName().IsEmpty() )
193 aStaleRuleAreas.push_back( damageBBox );
194 }
195
196 if( aStaleZones )
197 {
198 if( damageLayers.test( Edge_Cuts ) || damageLayers.test( Margin ) )
199 damageLayers = LSET::PhysicalLayersMask();
200 else
201 damageLayers &= LSET::AllCuMask();
202
203 if( damageLayers.any() )
204 {
205 for( ZONE* zone : board->Zones() )
206 {
207 if( zone->GetIsRuleArea() )
208 continue;
209
210 if( ( zone->GetLayerSet() & damageLayers ).any() && zone->GetBoundingBox().Intersects( damageBBox ) )
211 aStaleZones->push_back( zone );
212 }
213 }
214 }
215}
216
217
218void BOARD_COMMIT::Push( const wxString& aMessage, int aCommitFlags )
219{
220 KIGFX::PCB_VIEW* view = static_cast<KIGFX::PCB_VIEW*>( m_toolMgr->GetView() );
221 BOARD* board = static_cast<BOARD*>( m_toolMgr->GetModel() );
222 PCB_BASE_FRAME* frame = dynamic_cast<PCB_BASE_FRAME*>( m_toolMgr->GetToolHolder() );
223 PCB_SELECTION_TOOL* selTool = m_toolMgr->GetTool<PCB_SELECTION_TOOL>();
224 PCB_GROUP* enteredGroup = selTool && !( aCommitFlags & SKIP_ENTERED_GROUP ) ? selTool->GetEnteredGroup()
225 : nullptr;
226 // Notification info
227 PICKED_ITEMS_LIST undoList;
228 bool itemsDeselected = false;
229 bool selectedModified = false;
230
231 std::unordered_set<EDA_ITEM*> removedItems;
232
233 // Dirty flags and lists
234 bool solderMaskDirty = false;
235 bool autofillZones = false;
236 bool updateBoardBoundingBox = false;
237 std::vector<BOARD_ITEM*> staleTeardropPadsAndVias;
238 std::set<PCB_TRACK*> staleTeardropTracks;
239 std::vector<BOARD_ITEM*> dirtyCopper;
240 std::set<BOARD_ITEM*> dirtyCopperSeen;
241 std::vector<ZONE*> staleZonesStorage;
242 std::vector<ZONE*>* staleZones = nullptr;
243 std::vector<BOX2I> staleRuleAreas;
244
245 if( Empty() )
246 return;
247
248 bool containsDrillMap = false;
249 bool containsDrillChart = false;
250
251 for( const COMMIT_LINE& entry : m_entries )
252 {
253 if( !entry.m_item || !entry.m_item->IsBOARD_ITEM() )
254 continue;
255
256 BOARD_ITEM* item = static_cast<BOARD_ITEM*>( entry.m_item );
257
258 if( item->Type() == PCB_DRILL_CHART_T || item->Type() == PCB_DRILL_MAP_T )
259 {
260 containsDrillMap |= item->Type() == PCB_DRILL_MAP_T;
261 containsDrillChart |= item->Type() == PCB_DRILL_CHART_T;
262 }
263 }
264
265 undoList.SetDescription( aMessage );
266
267 TEARDROP_MANAGER teardropMgr( board, m_toolMgr );
268 std::shared_ptr<CONNECTIVITY_DATA> connectivity = board->GetConnectivity();
269
270 // Note: frame == nullptr happens in QA tests
271
272 std::vector<BOARD_ITEM*> bulkAddedItems;
273 std::vector<BOARD_ITEM*> bulkRemovedItems;
274 std::vector<BOARD_ITEM*> itemsChanged;
275
276 if( m_isBoardEditor && !( aCommitFlags & ZONE_FILL_OP )
277 && ( frame && frame->GetPcbNewSettings()->m_AutoRefillZones ) )
278 {
279 autofillZones = true;
280 staleZones = &staleZonesStorage;
281
282 for( ZONE* zone : board->Zones() )
283 zone->CacheBoundingBox();
284 }
285
286 for( COMMIT_LINE& entry : m_entries )
287 {
288 if( !entry.m_item || !entry.m_item->IsBOARD_ITEM() )
289 continue;
290
291 BOARD_ITEM* boardItem = static_cast<BOARD_ITEM*>( entry.m_item );
292
293 if( m_isBoardEditor )
294 {
295 if( boardItem->Type() == PCB_VIA_T || boardItem->Type() == PCB_FOOTPRINT_T
296 || boardItem->IsOnLayer( F_Mask ) || boardItem->IsOnLayer( B_Mask ) )
297 {
298 solderMaskDirty = true;
299 }
300
301 BOARD_ITEM* preEditItem = nullptr;
302
303 if( entry.m_copy && entry.m_copy->IsBOARD_ITEM() )
304 preEditItem = static_cast<BOARD_ITEM*>( entry.m_copy );
305
306 if( boardItem->IsOnLayer( Edge_Cuts ) || ( preEditItem && preEditItem->IsOnLayer( Edge_Cuts ) ) )
307 updateBoardBoundingBox = true;
308
309 if( !( aCommitFlags & SKIP_TEARDROPS ) )
310 {
311 // Teardrops are fitted to the copper around them, so any changed copper item
312 // can invalidate one, not only what a teardrop connects to.
313 auto collectCopper =
314 [&]( BOARD_ITEM* aItem )
315 {
316 // Pours are the filler's business. Containers have no copper of
317 // their own and their boxes sweep far more than they occupy.
318 if( aItem->Type() == PCB_ZONE_T
319 || aItem->Type() == PCB_FOOTPRINT_T
320 || aItem->Type() == PCB_GROUP_T
321 || aItem->Type() == PCB_GENERATOR_T )
322 {
323 return;
324 }
325
326 // A group and its members can both be in the commit.
327 if( ( aItem->GetLayerSet() & LSET::AllCuMask() ).any()
328 && dirtyCopperSeen.insert( aItem ).second )
329 {
330 dirtyCopper.push_back( aItem );
331 }
332 };
333
334 collectCopper( boardItem );
335 boardItem->RunOnChildren( collectCopper, RECURSE_MODE::RECURSE );
336
337 // boardItem already carries the edit, so it cannot show where the item was.
338 // The pre-edit clone is still ours here and answers a bounding box.
339 if( entry.m_copy && entry.m_copy->IsBOARD_ITEM() )
340 {
341 BOARD_ITEM* copy = static_cast<BOARD_ITEM*>( entry.m_copy );
342
343 collectCopper( copy );
344 copy->RunOnChildren( collectCopper, RECURSE_MODE::RECURSE );
345 }
346
347 if( boardItem->Type() == PCB_FOOTPRINT_T )
348 {
349 for( PAD* pad : static_cast<FOOTPRINT*>( boardItem )->Pads() )
350 staleTeardropPadsAndVias.push_back( pad );
351 }
352 else if( boardItem->Type() == PCB_PAD_T || boardItem->Type() == PCB_VIA_T )
353 {
354 staleTeardropPadsAndVias.push_back( boardItem );
355 }
356 else if( boardItem->Type() == PCB_TRACE_T || boardItem->Type() == PCB_ARC_T )
357 {
358 PCB_TRACK* track = static_cast<PCB_TRACK*>( boardItem );
359
360 staleTeardropTracks.insert( track );
361
362 std::vector<PAD*> connectedPads;
363 std::vector<PCB_VIA*> connectedVias;
364
365 connectivity->GetConnectedPadsAndVias( track, &connectedPads, &connectedVias );
366
367 for( PAD* pad : connectedPads )
368 staleTeardropPadsAndVias.push_back( pad );
369
370 for( PCB_VIA* via : connectedVias )
371 staleTeardropPadsAndVias.push_back( via );
372 }
373 }
374 }
375
376 if( boardItem->IsSelected() || ( m_isFootprintEditor && boardItem == board->GetFirstFootprint() ) )
377 selectedModified = true;
378 }
379
380 // Old teardrops must be removed before connectivity is rebuilt
381 if( !staleTeardropPadsAndVias.empty() || !staleTeardropTracks.empty() || !dirtyCopper.empty() )
382 teardropMgr.RemoveTeardrops( *this, &staleTeardropPadsAndVias, &staleTeardropTracks, &dirtyCopper );
383
384 auto updateComponentClasses =
385 [this]( BOARD_ITEM* boardItem )
386 {
387 if( boardItem->Type() != PCB_FOOTPRINT_T )
388 return;
389
390 FOOTPRINT* footprint = static_cast<FOOTPRINT*>( boardItem );
392 };
393
394 // We don't know that anything will be added to the entered group, but it does no harm to
395 // add it to the commit anyway.
396 if( enteredGroup )
397 Modify( enteredGroup );
398
399
400 for( COMMIT_LINE& entry : m_entries )
401 {
402 if( !entry.m_item || !entry.m_item->IsBOARD_ITEM() )
403 continue;
404
405 BOARD_ITEM* boardItem = static_cast<BOARD_ITEM*>( entry.m_item );
406 int changeType = entry.m_type & CHT_TYPE;
407 int changeFlags = entry.m_type & CHT_FLAGS;
408
409 switch( changeType )
410 {
411 case CHT_ADD:
412 if( enteredGroup && boardItem->IsGroupableType() && !boardItem->GetParentGroup() )
413 enteredGroup->AddItem( boardItem );
414
415 if( !( aCommitFlags & SKIP_UNDO ) )
416 undoList.PushItem( ITEM_PICKER( nullptr, boardItem, UNDO_REDO::NEWITEM ) );
417
418 if( !( changeFlags & CHT_DONE ) )
419 {
420 // Markers are always stored at the board level, even in the footprint editor
421 if( m_isFootprintEditor && boardItem->Type() != PCB_MARKER_T )
422 {
423 if( FOOTPRINT* parentFP = board->GetFirstFootprint() )
424 parentFP->Add( boardItem );
425 }
426 else
427 {
428 board->Add( boardItem, ADD_MODE::BULK_INSERT ); // handles connectivity
429 bulkAddedItems.push_back( boardItem );
430 }
431 }
432
433 if( boardItem->Type() != PCB_MARKER_T )
434 propagateDamage( boardItem, staleZones, staleRuleAreas );
435
436 if( view && !isNoGeometryItem( boardItem ) )
437 view->Add( boardItem );
438
439 updateComponentClasses( boardItem );
440
441 break;
442
443 case CHT_REMOVE:
444 {
445 EDA_GROUP* parentGroup = boardItem->GetParentGroup();
446
447 if( !( aCommitFlags & SKIP_UNDO ) )
448 {
450 ITEM_PICKER itemWrapper( nullptr, boardItem, status );
451 itemWrapper.SetLink( entry.m_copy );
452 entry.m_copy = nullptr; // We've transferred ownership to the undo list
453 undoList.PushItem( itemWrapper );
454 }
455
456 if( boardItem->IsSelected() )
457 {
458 if( selTool )
459 selTool->RemoveItemFromSel( boardItem, true /* quiet mode */ );
460
461 itemsDeselected = true;
462 }
463
464 removedItems.insert( boardItem );
465
466 if( parentGroup && !( parentGroup->AsEdaItem()->GetFlags() & STRUCT_DELETED ) )
467 parentGroup->RemoveItem( boardItem );
468
469 if( boardItem->Type() != PCB_MARKER_T )
470 propagateDamage( boardItem, staleZones, staleRuleAreas );
471
472 switch( boardItem->Type() )
473 {
474 case PCB_FIELD_T:
475 static_cast<PCB_FIELD*>( boardItem )->SetVisible( false );
476
477 if( view )
478 view->Update( boardItem );
479
480 break;
481
482 case PCB_TEXT_T:
483 case PCB_PAD_T:
484 case PCB_SHAPE_T:
486 case PCB_GENERATOR_T:
487 case PCB_TEXTBOX_T:
488 case PCB_BARCODE_T:
489 case PCB_TABLE_T:
491 case PCB_DRILL_MAP_T:
492 case PCB_TRACE_T:
493 case PCB_ARC_T:
494 case PCB_VIA_T:
496 case PCB_DIM_CENTER_T:
497 case PCB_DIM_RADIAL_T:
499 case PCB_DIM_LEADER_T:
500 case PCB_TARGET_T:
501 case PCB_POINT_T:
502 case PCB_ZONE_T:
503 case PCB_GRID_ITEM_T:
504 case PCB_FOOTPRINT_T:
505 case PCB_GROUP_T:
506 if( view )
507 view->Remove( boardItem );
508
509 if( !( changeFlags & CHT_DONE ) )
510 {
511 if( m_isFootprintEditor && boardItem->Type() != PCB_MARKER_T )
512 {
513 if( FOOTPRINT* parentFP = board->GetFirstFootprint() )
514 {
515 parentFP->Remove( boardItem );
516 connectivity->Remove( boardItem );
517 }
518 }
519 else if( FOOTPRINT* parentFP = boardItem->GetParentFootprint() )
520 {
521 parentFP->Remove( boardItem );
522 connectivity->Remove( boardItem );
523 }
524 else
525 {
526 board->Remove( boardItem, REMOVE_MODE::BULK );
527 bulkRemovedItems.push_back( boardItem );
528 }
529 }
530
531 break;
532
533 case PCB_MARKER_T:
534 if( view )
535 view->Remove( boardItem );
536
537 if( !( changeFlags & CHT_DONE ) )
538 {
539 // Markers are always stored at the board level, even in the footprint editor
540 board->Remove( boardItem, REMOVE_MODE::BULK );
541 bulkRemovedItems.push_back( boardItem );
542 }
543
544 break;
545
546 // No-geometry items: never in the view, so skip view->Remove.
547 case PCB_CONSTRAINT_T:
548 if( !( changeFlags & CHT_DONE ) )
549 {
551 {
552 if( FOOTPRINT* parentFP = board->GetFirstFootprint() )
553 parentFP->Remove( boardItem );
554 }
555 else if( FOOTPRINT* parentFP = boardItem->GetParentFootprint() )
556 {
557 parentFP->Remove( boardItem );
558 }
559 else
560 {
561 board->Remove( boardItem, REMOVE_MODE::BULK );
562 bulkRemovedItems.push_back( boardItem );
563 }
564 }
565
566 break;
567
568 // Metadata items
569 case PCB_NETINFO_T:
570 board->Remove( boardItem, REMOVE_MODE::BULK );
571 bulkRemovedItems.push_back( boardItem );
572 break;
573
574 default: // other types do not need to (or should not) be handled
575 wxASSERT( false );
576 break;
577 }
578
579 // Removed items are owned by undo/redo, but a hidden field still belongs to its footprint
580 if( boardItem->Type() != PCB_FIELD_T )
581 boardItem->SetFlags( UR_TRANSIENT );
582
583 break;
584 }
585
586 case CHT_MODIFY:
587 {
588 BOARD_ITEM* boardItemCopy = static_cast<BOARD_ITEM*>( entry.m_copy );
589
590 if( !( aCommitFlags & SKIP_UNDO ) )
591 {
592 ITEM_PICKER itemWrapper( nullptr, boardItem, UNDO_REDO::CHANGED );
593 itemWrapper.SetLink( entry.m_copy );
594 entry.m_copy = nullptr; // We've transferred ownership to the undo list
595 undoList.PushItem( itemWrapper );
596 }
597
598 if( !( aCommitFlags & SKIP_CONNECTIVITY ) && !isNoGeometryItem( boardItem ) )
599 {
600 connectivity->MarkItemNetAsDirty( boardItemCopy );
601 connectivity->Update( boardItem );
602 }
603
604 if( boardItem->Type() != PCB_MARKER_T )
605 {
606 propagateDamage( boardItemCopy, staleZones, staleRuleAreas ); // before
607 propagateDamage( boardItem, staleZones, staleRuleAreas ); // after
608 }
609
610 updateComponentClasses( boardItem );
611
612 if( view && !isNoGeometryItem( boardItem ) )
613 view->Update( boardItem );
614
615 itemsChanged.push_back( boardItem );
616 break;
617 }
618
619 default:
620 UNIMPLEMENTED_FOR( boardItem->GetClass() );
621 break;
622 }
623
624 // Delete any copies we still have ownership of
625 delete entry.m_copy;
626 entry.m_copy = nullptr;
627
628 boardItem->ClearEditFlags();
629 boardItem->RunOnChildren(
630 [&]( BOARD_ITEM* item )
631 {
632 item->ClearEditFlags();
633 },
635 } // ... and regenerate them.
636
637 // Deselection above keys off the SELECTED flag on the removed item itself, but the selection
638 // may separately hold an owned descendant such as a pad, field or table cell. Descendants
639 // are freed along with the removed parent, so prune them here or the selection keeps a
640 // dangling pointer that the next repaint dereferences.
641 if( selTool && !removedItems.empty() )
642 {
643 for( EDA_ITEM* selectedItem : selTool->GetSelection().GetItems() )
644 {
645 for( EDA_ITEM* ancestor = selectedItem; ancestor; ancestor = ancestor->GetParent() )
646 {
647 if( removedItems.count( ancestor ) )
648 {
649 selTool->RemoveItemFromSel( selectedItem, true /* quiet mode */ );
650 itemsDeselected = true;
651 break;
652 }
653 }
654 }
655 }
656
657 // Invalidate component classes
659
660 if( m_isBoardEditor )
661 {
662 size_t originalCount = m_entries.size();
663
664 if( aCommitFlags & SKIP_CONNECTIVITY )
665 {
666 connectivity->ClearRatsnest();
667 connectivity->ClearLocalRatsnest();
668 }
669 else
670 {
671 connectivity->RecalculateRatsnest( this );
673 connectivity->ClearLocalRatsnest();
674
675 if( frame )
676 frame->GetCanvas()->RedrawRatsnest();
677
678 board->OnRatsnestChanged();
679 }
680
681 if( solderMaskDirty )
682 {
683 if( frame )
684 frame->HideSolderMask();
685 }
686
687 if( updateBoardBoundingBox && view )
688 {
689 if( PCB_BOARD_OUTLINE* outline = board->BoardOutline() )
690 {
691 board->UpdateBoardOutline();
692
693 if( view->HasItem( outline ) )
694 view->Update( outline );
695 else
696 view->Add( outline );
697 }
698
699 RefreshDrillMapOutlines( *board, view );
700 }
701
702 if( PCBNEW_SETTINGS* cfg = GetAppSettings<PCBNEW_SETTINGS>( "pcbnew" ) )
703 {
704 if( !staleRuleAreas.empty() && ( cfg->m_Display.m_TrackClearance == SHOW_WITH_VIA_ALWAYS
705 || cfg->m_Display.m_PadClearance ) )
706 {
707 if( view )
708 view->UpdateCollidingItems( staleRuleAreas, { PCB_TRACE_T, PCB_ARC_T, PCB_VIA_T, PCB_PAD_T } );
709 }
710 }
711
712 if( !staleTeardropPadsAndVias.empty() || !staleTeardropTracks.empty() )
713 {
714 teardropMgr.UpdateTeardrops( *this, &staleTeardropPadsAndVias, &staleTeardropTracks );
715
716 // UpdateTeardrops() can modify the ratsnest data. So rebuild this ratsnest data
717 connectivity->RecalculateRatsnest( this );
718 }
719
720 // Log undo items for any connectivity or teardrop changes
721 for( size_t i = originalCount; i < m_entries.size(); ++i )
722 {
723 COMMIT_LINE& entry = m_entries[i];
724 BOARD_ITEM* boardItem = nullptr;
725 BOARD_ITEM* boardItemCopy = nullptr;
726
727 if( entry.m_item && entry.m_item->IsBOARD_ITEM() )
728 boardItem = static_cast<BOARD_ITEM*>( entry.m_item );
729
730 if( entry.m_copy && entry.m_copy->IsBOARD_ITEM() )
731 boardItemCopy = static_cast<BOARD_ITEM*>( entry.m_copy );
732
733 wxCHECK2( boardItem, continue );
734
735 if( !( aCommitFlags & SKIP_UNDO ) )
736 {
737 ITEM_PICKER itemWrapper( nullptr, boardItem, convert( entry.m_type & CHT_TYPE ) );
738 itemWrapper.SetLink( boardItemCopy );
739 undoList.PushItem( itemWrapper );
740 }
741 else
742 {
743 delete entry.m_copy;
744 }
745
746 if( view && !isNoGeometryItem( boardItem ) )
747 {
748 if( ( entry.m_type & CHT_TYPE ) == CHT_ADD )
749 view->Add( boardItem );
750 else if( ( entry.m_type & CHT_TYPE ) == CHT_REMOVE )
751 view->Remove( boardItem );
752 else
753 view->Update( boardItem );
754 }
755 }
756 }
757
758 if( bulkAddedItems.size() > 0 || bulkRemovedItems.size() > 0 || itemsChanged.size() > 0 )
759 board->OnItemsCompositeUpdate( bulkAddedItems, bulkRemovedItems, itemsChanged );
760
761 // A shrinking table deletes the cells past its new end and the selection holds those
762 // cells directly, so it has to be resolved again from what is still on the board
763 if( containsDrillChart && selTool )
764 selTool->RebuildSelection();
765
766 if( frame )
767 {
768 if( !( aCommitFlags & SKIP_UNDO ) )
769 {
770 if( aCommitFlags & APPEND_UNDO )
772 else
773 frame->SaveCopyInUndoList( undoList, UNDO_REDO::UNSPECIFIED );
774 }
775 }
776
777 m_toolMgr->PostEvent( { TC_MESSAGE, TA_MODEL_CHANGE, AS_GLOBAL } );
778
779 if( itemsDeselected )
781
782 if( autofillZones )
783 {
784 ZONE_FILLER_TOOL* zoneFillerTool = m_toolMgr->GetTool<ZONE_FILLER_TOOL>();
785
786 for( ZONE* zone : *staleZones )
787 zoneFillerTool->DirtyZone( zone );
788
790 }
791
792 // Rehatching only refreshes cached view geometry (consumers regenerate it lazily), and
793 // dispatching it headlessly makes the tool manager query the platform cursor position
794 if( view )
796
797 if( selectedModified )
799
800 if( frame )
801 {
802 if( !( aCommitFlags & SKIP_SET_DIRTY ) )
803 frame->OnModify();
804 else
806
807 // Ensure the message panel is updated after committing changes.
808 // By default (i.e. if no event posted), display the updated board info
809 if( !itemsDeselected && !autofillZones && !selectedModified )
810 {
811 std::vector<MSG_PANEL_ITEM> msg_list;
812 board->GetMsgPanelInfo( frame, msg_list );
813 frame->SetMsgPanel( msg_list );
814 }
815 }
816
817 if( containsDrillMap && frame )
819
820 clear();
821}
822
823
825{
826 // Easiest way to disallow both a parent and one of its children appearing in the list
827 // is to only ever add the parent when either can be legal (ie: in the board editor).
828 if( m_isBoardEditor && aItem->IsBOARD_ITEM() )
829 {
830 if( FOOTPRINT* footprint = static_cast<BOARD_ITEM*>( aItem )->GetParentFootprint() )
831 return footprint;
832 }
833
834 EDA_ITEM* parent = aItem->GetParent();
835
836 if( parent && BaseType( parent->Type() ) == PCB_TABLE_T )
837 return parent;
838
839 return aItem;
840}
841
842
844{
845 return MakeImage( aItem );
846}
847
848
850{
851 EDA_ITEM* clone = aItem->Clone();
852 clone->SetFlags( UR_TRANSIENT );
853
854 return clone;
855}
856
857
859{
861}
862
863
864void BOARD_COMMIT::RevertToCheckpoint( int aCheckpoint )
865{
866 PICKED_ITEMS_LIST undoList;
867 KIGFX::VIEW* view = m_toolMgr->GetView(); // null in headless sessions
868 BOARD* board = (BOARD*) m_toolMgr->GetModel();
869 std::shared_ptr<CONNECTIVITY_DATA> connectivity = board->GetConnectivity();
870
871 board->IncrementTimeStamp(); // clear caches
872
873 auto updateComponentClasses =
874 [this]( BOARD_ITEM* boardItem )
875 {
876 if( boardItem->Type() != PCB_FOOTPRINT_T )
877 return;
878
879 FOOTPRINT* footprint = static_cast<FOOTPRINT*>( boardItem );
881 };
882
883 std::vector<BOARD_ITEM*> bulkAddedItems;
884 std::vector<BOARD_ITEM*> bulkRemovedItems;
885 std::vector<BOARD_ITEM*> itemsChanged;
886 std::vector<BOARD_ITEM*> itemsToDelete;
887 bool containsDrillMap = false;
888
889 for( int ii = aCheckpoint; ii < (int) m_entries.size(); ++ii )
890 {
891 COMMIT_LINE& entry = m_entries[ii];
892
893 if( !entry.m_item || !entry.m_item->IsBOARD_ITEM() )
894 continue;
895
896 BOARD_ITEM* boardItem = static_cast<BOARD_ITEM*>( entry.m_item );
897 int changeType = entry.m_type & CHT_TYPE;
898 int changeFlags = entry.m_type & CHT_FLAGS;
899
900 if( boardItem->Type() == PCB_DRILL_CHART_T || boardItem->Type() == PCB_DRILL_MAP_T )
901 {
902 containsDrillMap |= boardItem->Type() == PCB_DRILL_MAP_T;
903 }
904
905 switch( changeType )
906 {
907 case CHT_ADD:
908 if( changeFlags & CHT_DONE )
909 {
910 if( view && !isNoGeometryItem( boardItem ) )
911 view->Remove( boardItem );
912
913 connectivity->Remove( boardItem );
914
916 {
917 if( FOOTPRINT* parentFP = board->GetFirstFootprint() )
918 parentFP->Remove( boardItem );
919 }
920 else if( FOOTPRINT* parentFP = boardItem->GetParentFootprint() )
921 {
922 parentFP->Remove( boardItem );
923 }
924 else
925 {
926 board->Remove( boardItem, REMOVE_MODE::BULK );
927 bulkRemovedItems.push_back( boardItem );
928 }
929 }
930
931 if( PCB_GROUP* group = dynamic_cast<PCB_GROUP*>( boardItem ) )
932 group->RemoveAll();
933
934 // Defer deletion until after OnItemsCompositeUpdate so that
935 // board listeners do not receive dangling pointers.
936 itemsToDelete.push_back( boardItem );
937 entry.m_item = nullptr;
938 continue;
939
940 case CHT_REMOVE:
941 {
942 if( !( changeFlags & CHT_DONE ) )
943 break;
944
945 if( view && !isNoGeometryItem( boardItem ) )
946 view->Add( boardItem );
947
949 {
950 if( FOOTPRINT* parentFP = board->GetFirstFootprint() )
951 {
952 parentFP->Add( boardItem, ADD_MODE::INSERT );
953 connectivity->Add( boardItem );
954 }
955 }
956 else if( FOOTPRINT* parentFP = boardItem->GetParentFootprint() )
957 {
958 parentFP->Add( boardItem, ADD_MODE::INSERT );
959 connectivity->Add( boardItem );
960 }
961 else
962 {
963 board->Add( boardItem, ADD_MODE::INSERT );
964 bulkAddedItems.push_back( boardItem );
965 }
966
967 updateComponentClasses( boardItem );
968 break;
969 }
970
971 case CHT_MODIFY:
972 {
973 if( view && !isNoGeometryItem( boardItem ) )
974 view->Remove( boardItem );
975
976 connectivity->Remove( boardItem );
977
978 wxASSERT( entry.m_copy && entry.m_copy->IsBOARD_ITEM() );
979 BOARD_ITEM* boardItemCopy = static_cast<BOARD_ITEM*>( entry.m_copy );
980 boardItem->SwapItemData( boardItemCopy );
981
982 if( view && !isNoGeometryItem( boardItem ) )
983 view->Add( boardItem );
984
985 connectivity->Add( boardItem );
986 itemsChanged.push_back( boardItem );
987
988 updateComponentClasses( boardItem );
989 break;
990 }
991
992 default:
993 UNIMPLEMENTED_FOR( boardItem->GetClass() );
994 break;
995 }
996
997 // Delete any copies we still have ownership of
998 delete entry.m_copy;
999 entry.m_copy = nullptr;
1000
1001 boardItem->ClearEditFlags();
1002 }
1003
1004 // Invalidate component classes
1006
1007 if( bulkAddedItems.size() > 0 || bulkRemovedItems.size() > 0 || itemsChanged.size() > 0 )
1008 board->OnItemsCompositeUpdate( bulkAddedItems, bulkRemovedItems, itemsChanged );
1009
1010 if( m_isBoardEditor )
1011 {
1012 for( BOARD_ITEM* item : itemsToDelete )
1013 connectivity->Remove( item );
1014 }
1015
1016 for( BOARD_ITEM* item : itemsToDelete )
1017 delete item;
1018
1019 if( m_isBoardEditor )
1020 {
1021 connectivity->RecalculateRatsnest();
1022 board->UpdateRatsnestExclusions();
1023 board->OnRatsnestChanged();
1024 }
1025
1026 if( PCB_SELECTION_TOOL* selTool = m_toolMgr->GetTool<PCB_SELECTION_TOOL>() )
1027 selTool->RebuildSelection();
1028
1029 // Property panel needs to know about the reselect
1031
1032 if( containsDrillMap )
1033 {
1034 if( PCB_BASE_FRAME* frame = dynamic_cast<PCB_BASE_FRAME*>( m_toolMgr->GetToolHolder() ) )
1035 {
1036 frame->RefreshDrillSymbols( KIGFX::LAYERS | KIGFX::GEOMETRY | KIGFX::REPAINT );
1037 }
1038 }
1039
1040 m_entries.erase( m_entries.begin() + aCheckpoint, m_entries.end() );
1041}
1042
1043
1045{
1046 if( aID == niluuid )
1047 return nullptr;
1048
1049 for( COMMIT_LINE& entry : m_entries )
1050 {
1051 if( entry.m_item && entry.m_item->IsBOARD_ITEM() && entry.m_item->m_Uuid == aID )
1052 return entry.m_item;
1053 }
1054
1055 return nullptr;
1056}
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:914
Handles how to draw a screen (a board, a schematic ...)
Definition base_screen.h:37
void Push(const wxString &aMessage=wxEmptyString, int aCommitFlags=0) override
Execute the changes.
bool RemoveOrDiscard(BOARD_ITEM *aItem)
Remove aItem, or free it if it was added earlier in this commit and never reached the board.
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
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
void RevertToCheckpoint(int aCheckpoint) override
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:409
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:410
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT, bool aSkipConnectivity=false) override
Removes an item from the container.
Definition board.cpp:1524
PCB_BOARD_OUTLINE * BoardOutline()
Definition board.h:486
void UpdateBoardOutline()
Definition board.cpp:4483
const ZONES & Zones() const
Definition board.h:468
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:4043
FOOTPRINT * GetFirstFootprint() const
Get the first footprint on the board or nullptr.
Definition board.h:712
void IncrementTimeStamp()
Definition board.cpp:449
void OnRatsnestChanged()
Notify the board and its listeners that the ratsnest has been recomputed.
Definition board.cpp:4054
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:2811
void UpdateRatsnestExclusions()
Update the visibility flags on the current unconnected ratsnest lines.
Definition board.cpp:539
COMPONENT_CLASS_MANAGER & GetComponentClassManager()
Gets the component class manager.
Definition board.h:1677
void Remove(BOARD_ITEM *aBoardItem, REMOVE_MODE aMode=REMOVE_MODE::NORMAL) override
Removes an item from the container.
Definition board.cpp:1695
std::shared_ptr< CONNECTIVITY_DATA > GetConnectivity() const
Return a list of missing connections between components/tracks.
Definition board.h:759
COMMIT & Remove(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Remove a new item from the model.
Definition commit.h:86
std::set< std::pair< EDA_ITEM *, BASE_SCREEN * > > m_deletedItems
Definition commit.h:193
void Unstage(EDA_ITEM *aItem, BASE_SCREEN *aScreen)
Definition commit.cpp:177
bool Empty() const
Definition commit.h:145
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
COMMIT_LINE * findEntry(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Search for an entry describing change for a particular item.
Definition commit.cpp:267
virtual void makeEntry(EDA_ITEM *aItem, CHANGE_TYPE aType, EDA_ITEM *aCopy=nullptr, BASE_SCREEN *aScreen=nullptr)
Definition commit.cpp:243
std::vector< COMMIT_LINE > m_entries
Definition commit.h:194
void clear()
Should be called in Push() & Revert() methods.
Definition commit.h:165
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 item had a property changed (except movement)
Definition actions.h:352
static const TOOL_EVENT UnselectedEvent
Definition actions.h:346
void SetLink(EDA_ITEM *aItem)
virtual void Update(const VIEW_ITEM *aItem, int aUpdateFlags) const override
For dynamic VIEWs, inform the associated VIEW that the graphical representation of this item has chan...
Definition pcb_view.cpp: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:297
virtual void Remove(VIEW_ITEM *aItem)
Remove a VIEW_ITEM from the view.
Definition view.cpp:412
bool HasItem(const VIEW_ITEM *aItem) const
Indicates whether or not the given item has been added to the view.
Definition view.cpp:1878
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()
Force refresh of the ratsnest visual representation.
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:434
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:240
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:159
CHANGE_TYPE m_type
Modification type.
Definition commit.h:160
EDA_ITEM * m_item
Main item that is added/deleted/modified.
Definition commit.h:158
@ 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...