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