KiCad PCB EDA Suite
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages Concepts
undo_redo.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) 2012 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
5 * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
6 * Copyright (C) 2016 CERN
7 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
8 * @author Maciej Suminski <maciej.suminski@cern.ch>
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 2
13 * of the License, or (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, you may find one here:
22 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
23 * or you may search the http://www.gnu.org website for the version 2 license,
24 * or you may write to the Free Software Foundation, Inc.,
25 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
26 */
27
28#include <functional>
29using namespace std::placeholders;
30#include <macros.h>
31#include <pcb_edit_frame.h>
32#include <pcb_track.h>
33#include <pcb_group.h>
34#include <pcb_shape.h>
35#include <pcb_generator.h>
36#include <pcb_target.h>
37#include <footprint.h>
38#include <lset.h>
39#include <pad.h>
40#include <origin_viewitem.h>
42#include <tool/tool_manager.h>
43#include <tool/actions.h>
45#include <tools/pcb_control.h>
47#include <board_commit.h>
49#include <wx/msgdlg.h>
50
51/* Functions to undo and redo edit commands.
52 * commands to undo are stored in CurrentScreen->m_UndoList
53 * commands to redo are stored in CurrentScreen->m_RedoList
54 *
55 * m_UndoList and m_RedoList handle a std::vector of PICKED_ITEMS_LIST
56 * Each PICKED_ITEMS_LIST handle a std::vector of pickers (class ITEM_PICKER),
57 * that store the list of schematic items that are concerned by the command to undo or redo
58 * and is created for each command to undo (handle also a command to redo).
59 * each picker has a pointer pointing to an item to undo or redo (in fact: deleted, added or
60 * modified),
61 * and has a pointer to a copy of this item, when this item has been modified
62 * (the old values of parameters are therefore saved)
63 *
64 * there are 3 cases:
65 * - delete item(s) command
66 * - change item(s) command
67 * - add item(s) command
68 *
69 * Undo command
70 * - delete item(s) command:
71 * => deleted items are moved in undo list
72 *
73 * - change item(s) command
74 * => A copy of item(s) is made (a DrawPickedStruct list of wrappers)
75 * the .m_Link member of each wrapper points the modified item.
76 * the .m_Item member of each wrapper points the old copy of this item.
77 *
78 * - add item(s) command
79 * =>A list of item(s) is made. The .m_Item member of each wrapper points the new item.
80 *
81 * Redo command
82 * - delete item(s) old command:
83 * => deleted items are moved in EEDrawList list, and in
84 *
85 * - change item(s) command
86 * => the copy of item(s) is moved in Undo list
87 *
88 * - add item(s) command
89 * => The list of item(s) is used to create a deleted list in undo list(same as a delete
90 * command)
91 *
92 * Some block operations that change items can be undone without memorize items, just the
93 * coordinates of the transform:
94 * move list of items (undo/redo is made by moving with the opposite move vector)
95 * mirror (Y) and flip list of items (undo/redo is made by mirror or flip items)
96 * so they are handled specifically.
97 *
98 */
99
100
102 const PICKED_ITEMS_LIST& aItemsList,
103 UNDO_REDO aCommandType )
104{
105 int preExisting = commandToUndo->GetCount();
106
107 for( unsigned ii = 0; ii < aItemsList.GetCount(); ii++ )
108 commandToUndo->PushItem( aItemsList.GetItemWrapper(ii) );
109
110 for( unsigned ii = preExisting; ii < commandToUndo->GetCount(); ii++ )
111 {
112 EDA_ITEM* item = commandToUndo->GetPickedItem( ii );
113 UNDO_REDO command = commandToUndo->GetPickedItemStatus( ii );
114
115 if( command == UNDO_REDO::UNSPECIFIED )
116 {
117 command = aCommandType;
118 commandToUndo->SetPickedItemStatus( command, ii );
119 }
120
121 wxASSERT( item );
122
123 switch( command )
124 {
125 case UNDO_REDO::CHANGED:
126 case UNDO_REDO::DRILLORIGIN:
127 case UNDO_REDO::GRIDORIGIN:
128 // If we don't yet have a copy in the link, set one up
129 if( !commandToUndo->GetPickedItemLink( ii ) )
130 commandToUndo->SetPickedItemLink( BOARD_COMMIT::MakeImage( item ), ii );
131
132 break;
133
134 case UNDO_REDO::NEWITEM:
135 case UNDO_REDO::DELETED:
136 case UNDO_REDO::PAGESETTINGS:
137 case UNDO_REDO::REGROUP:
138 case UNDO_REDO::UNGROUP:
139 break;
140
141 default:
142 wxFAIL_MSG( wxString::Format( wxT( "Unrecognized undo command: %X" ), command ) );
143 break;
144 }
145 }
146
147 if( commandToUndo->GetCount() )
148 {
149 /* Save the copy in undo list */
150 PushCommandToUndoList( commandToUndo );
151
152 /* Clear redo list, because after a new command one cannot redo a command */
154 }
155 else
156 {
157 // Should not occur
158 wxASSERT( false );
159 delete commandToUndo;
160 }
161}
162
163
165{
166 PICKED_ITEMS_LIST* commandToUndo = new PICKED_ITEMS_LIST();
167 PICKED_ITEMS_LIST itemsList;
168
169 itemsList.PushItem( ITEM_PICKER( nullptr, aItem, aCommandType ) );
170 saveCopyInUndoList( commandToUndo, itemsList, aCommandType );
171}
172
173
175 UNDO_REDO aCommandType )
176{
177 PICKED_ITEMS_LIST* commandToUndo = new PICKED_ITEMS_LIST();
178 commandToUndo->SetDescription( aItemsList.GetDescription() );
179
180 saveCopyInUndoList( commandToUndo, aItemsList, aCommandType );
181}
182
183
185 UNDO_REDO aCommandType )
186{
187 PICKED_ITEMS_LIST* commandToUndo = PopCommandFromUndoList();
188
189 if( !commandToUndo )
190 {
191 commandToUndo = new PICKED_ITEMS_LIST();
192 commandToUndo->SetDescription( aItemsList.GetDescription() );
193 }
194
195 saveCopyInUndoList( commandToUndo, aItemsList, aCommandType );
196}
197
198
200{
201 if( UndoRedoBlocked() )
202 return;
203
204 if( GetUndoCommandCount() <= 0 )
205 return;
206
207 // Inform tools that undo command was issued
209
210 // Get the old list
212
213 // Undo the command
215
216 // Put the old list in RedoList
218 PushCommandToRedoList( list );
219
220 OnModify();
221
224
225 GetCanvas()->Refresh();
226}
227
228
230{
231 if( UndoRedoBlocked() )
232 return;
233
234 if( GetRedoCommandCount() == 0 )
235 return;
236
237 // Inform tools that redo command was issued
239
240 // Get the old list
242
243 // Redo the command
245
246 // Put the old list in UndoList
248 PushCommandToUndoList( list );
249
250 OnModify();
251
254
255 GetCanvas()->Refresh();
256}
257
258
260{
261 bool not_found = false;
262 bool reBuild_ratsnest = false;
263 bool deep_reBuild_ratsnest = false; // true later if pointers must be rebuilt
264 bool solder_mask_dirty = false;
265
266 auto view = GetCanvas()->GetView();
267 auto connectivity = GetBoard()->GetConnectivity();
268
269 GetBoard()->IncrementTimeStamp(); // clear caches
270
271 // Enum to track the modification type of items. Used to enable bulk BOARD_LISTENER
272 // callbacks at the end of the undo / redo operation
273 enum ITEM_CHANGE_TYPE
274 {
275 ADDED,
276 DELETED,
277 CHANGED
278 };
279
280 std::unordered_map<EDA_ITEM*, ITEM_CHANGE_TYPE> item_changes;
281
282 auto update_item_change_state =
283 [&]( EDA_ITEM* item, ITEM_CHANGE_TYPE change_type )
284 {
285 auto item_itr = item_changes.find( item );
286
287 if( item_itr == item_changes.end() )
288 {
289 // First time we've seen this item - tag the current change type
290 item_changes.insert( { item, change_type } );
291 return;
292 }
293
294 // Update the item state based on the current and next change type
295 switch( item_itr->second )
296 {
297 case ITEM_CHANGE_TYPE::ADDED:
298 {
299 if( change_type == ITEM_CHANGE_TYPE::DELETED )
300 {
301 // The item was previously added, now deleted - as far as bulk callbacks
302 // are concerned, the item has never existed
303 item_changes.erase( item_itr );
304 }
305 else if( change_type == ITEM_CHANGE_TYPE::ADDED )
306 {
307 // Error condition - added an already added item
308 wxASSERT_MSG( false, wxT( "UndoRedo: should not add already added item" ) );
309 }
310
311 // For all other cases, the item remains as ADDED as seen by the bulk callbacks
312 break;
313 }
314 case ITEM_CHANGE_TYPE::DELETED:
315 {
316 // This is an error condition - item has already been deleted so should not
317 // be operated on further
318 wxASSERT_MSG( false, wxT( "UndoRedo: should not alter already deleted item" ) );
319 break;
320 }
321 case ITEM_CHANGE_TYPE::CHANGED:
322 {
323 if( change_type == ITEM_CHANGE_TYPE::DELETED )
324 {
325 item_itr->second = ITEM_CHANGE_TYPE::DELETED;
326 }
327 else if( change_type == ITEM_CHANGE_TYPE::ADDED )
328 {
329 // This is an error condition - item has already been changed so should not
330 // be added
331 wxASSERT_MSG( false,
332 wxT( "UndoRedo: should not add already changed item" ) );
333 }
334
335 // Otherwise, item remains CHANGED
336 break;
337 }
338 }
339 };
340
341 // Undo in the reverse order of list creation: (this can allow stacked changes
342 // like the same item can be changes and deleted in the same complex command
343
344 // Restore changes in reverse order
345 for( int ii = (int) aList->GetCount() - 1; ii >= 0 ; ii-- )
346 {
347 EDA_ITEM* eda_item = aList->GetPickedItem( (unsigned) ii );
348
349 /* Test for existence of item on board.
350 * It could be deleted, and no more on board:
351 * - if a call to SaveCopyInUndoList was forgotten in Pcbnew
352 * - in zones outlines, when a change in one zone merges this zone with an other
353 * This test avoids a Pcbnew crash
354 * Obviously, this test is not made for deleted items
355 */
356 UNDO_REDO status = aList->GetPickedItemStatus( ii );
357
358 if( status != UNDO_REDO::DELETED
359 && status != UNDO_REDO::REGROUP
360 && status != UNDO_REDO::UNGROUP
361 && status != UNDO_REDO::DRILLORIGIN // origin markers never on board
362 && status != UNDO_REDO::GRIDORIGIN // origin markers never on board
363 && status != UNDO_REDO::PAGESETTINGS ) // nor are page settings proxy items
364 {
365 if( GetBoard()->GetItem( eda_item->m_Uuid ) == DELETED_BOARD_ITEM::GetInstance() )
366 {
367 // Remove this non existent item
368 aList->RemovePicker( ii );
369 not_found = true;
370
371 if( aList->GetCount() == 0 )
372 break;
373
374 continue;
375 }
376 }
377
378 // see if we must rebuild ratsnets and pointers lists
379 switch( eda_item->Type() )
380 {
381 case PCB_FOOTPRINT_T:
382 deep_reBuild_ratsnest = true; // Pointers on pads can be invalid
384
385 case PCB_ZONE_T:
386 case PCB_TRACE_T:
387 case PCB_ARC_T:
388 case PCB_VIA_T:
389 case PCB_PAD_T:
390 reBuild_ratsnest = true;
391 break;
392
393 case PCB_NETINFO_T:
394 reBuild_ratsnest = true;
395 deep_reBuild_ratsnest = true;
396 break;
397
398 default:
399 break;
400 }
401
402 switch( eda_item->Type() )
403 {
404 case PCB_FOOTPRINT_T:
405 solder_mask_dirty = true;
406 break;
407
408 case PCB_VIA_T:
409 solder_mask_dirty = true;
410 break;
411
412 case PCB_ZONE_T:
413 case PCB_TRACE_T:
414 case PCB_ARC_T:
415 case PCB_PAD_T:
416 case PCB_SHAPE_T:
417 {
418 LSET layers = static_cast<BOARD_ITEM*>( eda_item )->GetLayerSet();
419
420 if( layers.test( F_Mask ) || layers.test( B_Mask ) )
421 solder_mask_dirty = true;
422
423 break;
424 }
425
426 default:
427 break;
428 }
429
430 switch( aList->GetPickedItemStatus( ii ) )
431 {
432 case UNDO_REDO::CHANGED: /* Exchange old and new data for each item */
433 {
434 BOARD_ITEM* item = (BOARD_ITEM*) eda_item;
435 BOARD_ITEM_CONTAINER* parent = GetBoard();
436 PCB_GROUP* parentGroup = item->GetParentGroup();
437
438 if( item->GetParentFootprint() )
439 {
440 // We need the current item and it's parent, which may be different from what
441 // was stored if we're multiple frames up the undo stack.
442 item = GetBoard()->GetItem( item->m_Uuid );
443 parent = item->GetParentFootprint();
444 }
445
446 BOARD_ITEM* image = (BOARD_ITEM*) aList->GetPickedItemLink( ii );
447
448 view->Remove( item );
449
450 if( parentGroup )
451 parentGroup->RemoveItem( item );
452
453 parent->Remove( item );
454
455 item->SwapItemData( image );
456
457 item->ClearFlags( UR_TRANSIENT );
458 image->SetFlags( UR_TRANSIENT );
459
460 if( PCB_GROUP* group = dynamic_cast<PCB_GROUP*>( item ) )
461 {
462 group->RunOnChildren( [&]( BOARD_ITEM* child )
463 {
464 child->SetParentGroup( group );
465 },
466 RECURSE_MODE::NO_RECURSE );
467 }
468
469 view->Add( item );
470 view->Hide( item, false );
471 parent->Add( item );
472
473 if( parentGroup )
474 parentGroup->AddItem( item );
475
476 update_item_change_state( item, ITEM_CHANGE_TYPE::CHANGED );
477 break;
478 }
479
480 case UNDO_REDO::NEWITEM: /* new items are deleted */
481 aList->SetPickedItemStatus( UNDO_REDO::DELETED, ii );
482 GetModel()->Remove( (BOARD_ITEM*) eda_item, REMOVE_MODE::BULK );
483 update_item_change_state( eda_item, ITEM_CHANGE_TYPE::DELETED );
484
485 if( eda_item->Type() != PCB_NETINFO_T )
486 view->Remove( eda_item );
487
488 eda_item->SetFlags( UR_TRANSIENT );
489
490 break;
491
492 case UNDO_REDO::DELETED: /* deleted items are put in List, as new items */
493 aList->SetPickedItemStatus( UNDO_REDO::NEWITEM, ii );
494
495 eda_item->ClearFlags( UR_TRANSIENT );
496
497 GetModel()->Add( (BOARD_ITEM*) eda_item, ADD_MODE::BULK_APPEND );
498 update_item_change_state( eda_item, ITEM_CHANGE_TYPE::ADDED );
499
500 if( eda_item->Type() != PCB_NETINFO_T )
501 view->Add( eda_item );
502
503 break;
504
505 case UNDO_REDO::REGROUP: /* grouped items are ungrouped */
506 aList->SetPickedItemStatus( UNDO_REDO::UNGROUP, ii );
507
508 if( eda_item->IsBOARD_ITEM() )
509 {
510 BOARD_ITEM* boardItem = static_cast<BOARD_ITEM*>( eda_item );
511
512 if( PCB_GROUP* group = boardItem->GetParentGroup() )
513 {
514 aList->SetPickedItemGroupId( group->m_Uuid, ii );
515
516 group->RemoveItem( boardItem );
517 }
518 }
519
520 break;
521
522 case UNDO_REDO::UNGROUP: /* ungrouped items are re-added to their previuos groups */
523 aList->SetPickedItemStatus( UNDO_REDO::REGROUP, ii );
524
525 if( eda_item->IsBOARD_ITEM() )
526 {
527 BOARD_ITEM* boardItem = static_cast<BOARD_ITEM*>( eda_item );
528
529 PCB_GROUP* group = dynamic_cast<PCB_GROUP*>(
530 GetBoard()->GetItem( aList->GetPickedItemGroupId( ii ) ) );
531
532 if( group )
533 group->AddItem( boardItem );
534 }
535
536 break;
537
538 case UNDO_REDO::DRILLORIGIN:
539 case UNDO_REDO::GRIDORIGIN:
540 {
541 // Warning: DRILLORIGIN and GRIDORIGIN undo/redo command create EDA_ITEMs
542 // that cannot be casted to BOARD_ITEMs
543 EDA_ITEM* image = aList->GetPickedItemLink( ii );
544 VECTOR2D origin = image->GetPosition();
545 image->SetPosition( eda_item->GetPosition() );
546
547 if( aList->GetPickedItemStatus( ii ) == UNDO_REDO::DRILLORIGIN )
548 BOARD_EDITOR_CONTROL::DoSetDrillOrigin( view, this, eda_item, origin );
549 else
550 PCB_CONTROL::DoSetGridOrigin( view, this, eda_item, origin );
551
552 break;
553 }
554
555 case UNDO_REDO::PAGESETTINGS:
556 {
557 // swap current settings with stored settings
558 DS_PROXY_UNDO_ITEM alt_item( this );
559 DS_PROXY_UNDO_ITEM* item = static_cast<DS_PROXY_UNDO_ITEM*>( eda_item );
560 item->Restore( this );
561 *item = std::move( alt_item );
562 break;
563 }
564
565 default:
566 wxFAIL_MSG( wxString::Format( wxT( "PutDataInPreviousState() error (unknown code %X)" ),
567 aList->GetPickedItemStatus( ii ) ) );
568 break;
569 }
570
571 if( eda_item->Type() == PCB_FOOTPRINT_T )
572 {
573 FOOTPRINT* fp = static_cast<FOOTPRINT*>( eda_item );
576 }
577 }
578
579 if( not_found )
580 wxMessageBox( _( "Incomplete undo/redo operation: some items not found" ) );
581
582 if( IsType( FRAME_PCB_EDITOR ) )
583 {
584 if( reBuild_ratsnest || deep_reBuild_ratsnest )
585 {
586 // Connectivity may have changed; rebuild internal caches to remove stale items
588 Compile_Ratsnest( false );
589 }
590
591 if( solder_mask_dirty )
593 }
594
596
598 selTool->RebuildSelection();
599
601
602 // Invoke bulk BOARD_LISTENER callbacks
603 std::vector<BOARD_ITEM*> added_items, deleted_items, changed_items;
604
605 for( auto& [item, changeType] : item_changes )
606 {
607 switch( changeType )
608 {
609 case ITEM_CHANGE_TYPE::ADDED:
610 added_items.push_back( static_cast<BOARD_ITEM*>( item ) );
611 break;
612
613 case ITEM_CHANGE_TYPE::DELETED:
614 deleted_items.push_back( static_cast<BOARD_ITEM*>( item ) );
615 break;
616
617 case ITEM_CHANGE_TYPE::CHANGED:
618 changed_items.push_back( static_cast<BOARD_ITEM*>( item ) );
619 break;
620 }
621 }
622
623 auto checkHatching =
624 [&]( BOARD_ITEM* item )
625 {
626 if( item->Type() == PCB_SHAPE_T )
627 {
628 PCB_SHAPE* shape = static_cast<PCB_SHAPE*>( item );
629
630 if( shape->IsHatchedFill() )
631 {
632 shape->SetHatchingDirty();
633 view->Update( shape );
634 }
635 }
636 };
637
638 for( BOARD_ITEM* item : GetBoard()->Drawings() )
639 checkHatching( item );
640
641 for( FOOTPRINT* footprint : GetBoard()->Footprints() )
642 {
643 footprint->RunOnChildren(
644 [&]( BOARD_ITEM* item )
645 {
646 checkHatching( item );
647 },
648 RECURSE_MODE::RECURSE );
649 }
650
651 if( added_items.size() > 0 || deleted_items.size() > 0 || changed_items.size() > 0 )
652 GetBoard()->OnItemsCompositeUpdate( added_items, deleted_items, changed_items );
653}
654
655
657{
658 if( aItemCount == 0 )
659 return;
660
661 UNDO_REDO_CONTAINER& list = ( whichList == UNDO_LIST ) ? m_undoList : m_redoList;
662
663 if( aItemCount < 0 )
664 {
665 list.ClearCommandList();
666 }
667 else
668 {
669 for( int ii = 0; ii < aItemCount; ii++ )
670 {
671 if( list.m_CommandsList.size() == 0 )
672 break;
673
674 PICKED_ITEMS_LIST* curr_cmd = list.m_CommandsList[0];
675 list.m_CommandsList.erase( list.m_CommandsList.begin() );
676 ClearListAndDeleteItems( curr_cmd );
677 delete curr_cmd; // Delete command
678 }
679 }
680}
681
682
684{
686 []( EDA_ITEM* item )
687 {
688 wxASSERT_MSG( item->HasFlag( UR_TRANSIENT ),
689 "Item on undo/redo list not owned by undo/redo!" );
690
691 if( item->IsBOARD_ITEM() )
692 static_cast<BOARD_ITEM*>( item )->SetParentGroup( nullptr );
693
694 delete item;
695 } );
696}
697
698
700{
704 delete undo;
705
706 GetCanvas()->Refresh();
707}
static EDA_ITEM * MakeImage(EDA_ITEM *aItem)
static void DoSetDrillOrigin(KIGFX::VIEW *aView, PCB_BASE_FRAME *aFrame, EDA_ITEM *aItem, const VECTOR2D &aPoint)
Abstract interface for BOARD_ITEMs capable of storing other items inside.
virtual void Remove(BOARD_ITEM *aItem, REMOVE_MODE aMode=REMOVE_MODE::NORMAL)=0
Removes an item from the container.
virtual void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT, bool aSkipConnectivity=false)=0
Adds an item to the container.
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition: board_item.h:78
void SetParentGroup(PCB_GROUP *aGroup)
Definition: board_item.h:93
void SwapItemData(BOARD_ITEM *aImage)
Swap data between aItem and aImage.
Definition: board_item.cpp:232
PCB_GROUP * GetParentGroup() const
Definition: board_item.h:94
FOOTPRINT * GetParentFootprint() const
Definition: board_item.cpp:305
BOARD_ITEM * GetItem(const KIID &aID) const
Definition: board.cpp:1501
void SanitizeNetcodes()
Definition: board.cpp:2701
bool BuildConnectivity(PROGRESS_REPORTER *aReporter=nullptr)
Build or rebuild the board connectivity database for the board, especially the list of connected item...
Definition: board.cpp:185
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:2748
void IncrementTimeStamp()
Definition: board.cpp:253
const FOOTPRINTS & Footprints() const
Definition: board.h:338
COMPONENT_CLASS_MANAGER & GetComponentClassManager()
Gets the component class manager.
Definition: board.h:1316
std::shared_ptr< CONNECTIVITY_DATA > GetConnectivity() const
Return a list of missing connections between components/tracks.
Definition: board.h:495
const DRAWINGS & Drawings() const
Definition: board.h:340
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.
static DELETED_BOARD_ITEM * GetInstance()
Definition: board_item.h:490
void Restore(EDA_DRAW_FRAME *aFrame, KIGFX::VIEW *aView=nullptr)
virtual void PushCommandToUndoList(PICKED_ITEMS_LIST *aItem)
Add a command to undo in the undo list.
virtual int GetRedoCommandCount() const
UNDO_REDO_CONTAINER m_undoList
UNDO_REDO_LIST
Specify whether we are interacting with the undo or redo stacks.
virtual PICKED_ITEMS_LIST * PopCommandFromRedoList()
Return the last command to undo and remove it from list, nothing is deleted.
UNDO_REDO_CONTAINER m_redoList
virtual PICKED_ITEMS_LIST * PopCommandFromUndoList()
Return the last command to undo and remove it from list, nothing is deleted.
virtual int GetUndoCommandCount() const
virtual void PushCommandToRedoList(PICKED_ITEMS_LIST *aItem)
Add a command to redo in the redo list.
bool IsType(FRAME_T aType) const
virtual void Refresh(bool aEraseBackground=true, const wxRect *aRect=nullptr) override
A base class for most all the KiCad significant classes used in schematics and boards.
Definition: eda_item.h:95
virtual VECTOR2I GetPosition() const
Definition: eda_item.h:248
void SetFlags(EDA_ITEM_FLAGS aMask)
Definition: eda_item.h:131
const KIID m_Uuid
Definition: eda_item.h:494
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:107
void ClearFlags(EDA_ITEM_FLAGS aMask=EDA_ITEM_ALL_FLAGS)
Definition: eda_item.h:133
bool HasFlag(EDA_ITEM_FLAGS aFlag) const
Definition: eda_item.h:135
bool IsHatchedFill() const
Definition: eda_shape.h:124
void SetHatchingDirty()
Definition: eda_shape.h:147
static const TOOL_EVENT UndoRedoPreEvent
Definition: actions.h:319
static const TOOL_EVENT SelectedItemsModified
Selected items were moved, this can be very high frequency on the canvas, use with care.
Definition: actions.h:303
static const TOOL_EVENT UndoRedoPostEvent
Definition: actions.h:320
void InvalidateComponentClassCache() const
Forces deferred (on next access) recalculation of the component class for this footprint.
Definition: footprint.cpp:4083
bool IsBOARD_ITEM() const
Definition: view_item.h:102
LSET is a set of PCB_LAYER_IDs.
Definition: lset.h:37
void ClearUndoORRedoList(UNDO_REDO_LIST whichList, int aItemCount=-1) override
Free the undo or redo list from List element.
Definition: undo_redo.cpp:656
void RestoreCopyFromUndoList(wxCommandEvent &aEvent)
Undo the last edit:
Definition: undo_redo.cpp:199
void saveCopyInUndoList(PICKED_ITEMS_LIST *commandToUndo, const PICKED_ITEMS_LIST &aItemsList, UNDO_REDO aCommandType)
Definition: undo_redo.cpp:101
void AppendCopyToUndoList(const PICKED_ITEMS_LIST &aItemsList, UNDO_REDO aCommandType) override
As SaveCopyInUndoList, but appends the changes to the last undo item on the stack.
Definition: undo_redo.cpp:184
void SaveCopyInUndoList(EDA_ITEM *aItemToCopy, UNDO_REDO aTypeCommand) override
Create a new entry in undo list of commands.
Definition: undo_redo.cpp:164
void ClearListAndDeleteItems(PICKED_ITEMS_LIST *aList)
Definition: undo_redo.cpp:683
void RollbackFromUndo()
Perform an undo of the last edit without logging a corresponding redo.
Definition: undo_redo.cpp:699
bool UndoRedoBlocked() const
Check if the undo and redo operations are currently blocked.
void PutDataInPreviousState(PICKED_ITEMS_LIST *aList)
Used in undo or redo command.
Definition: undo_redo.cpp:259
void RestoreCopyFromRedoList(wxCommandEvent &aEvent)
Redo the last edit:
Definition: undo_redo.cpp:229
EDA_ITEM * GetItem(const KIID &aId) const override
Fetch an item by KIID.
void OnModify() override
Must be called after a change in order to set the "modify" flag and update other data structures and ...
PCB_DRAW_PANEL_GAL * GetCanvas() const override
Return a pointer to GAL-based canvas of given EDA draw frame.
BOARD * GetBoard() const
virtual BOARD_ITEM_CONTAINER * GetModel() const =0
void Compile_Ratsnest(bool aDisplayStatus)
Create the entire board ratsnest.
Definition: ratsnest.cpp:35
static void DoSetGridOrigin(KIGFX::VIEW *aView, PCB_BASE_FRAME *aFrame, EDA_ITEM *originViewItem, const VECTOR2D &aPoint)
virtual KIGFX::PCB_VIEW * GetView() const override
Return a pointer to the #VIEW instance used in the panel.
A set of BOARD_ITEMs (i.e., without duplicates).
Definition: pcb_group.h:52
virtual bool RemoveItem(BOARD_ITEM *aItem)
Remove item from group.
Definition: pcb_group.cpp:96
virtual bool AddItem(BOARD_ITEM *aItem)
Add item to group.
Definition: pcb_group.cpp:81
The selection tool: currently supports:
void RebuildSelection()
Rebuild the selection from the EDA_ITEMs' selection flags.
A holder to handle information on schematic or board items.
bool SetPickedItemStatus(UNDO_REDO aStatus, unsigned aIdx)
Set the type of undo/redo operation for a given picked item.
void PushItem(const ITEM_PICKER &aItem)
Push aItem to the top of the list.
void SetDescription(const wxString &aDescription)
UNDO_REDO GetPickedItemStatus(unsigned int aIdx) const
ITEM_PICKER GetItemWrapper(unsigned int aIdx) const
EDA_ITEM * GetPickedItemLink(unsigned int aIdx) const
wxString GetDescription() const
bool RemovePicker(unsigned aIdx)
Remove one entry (one picker) from the list of picked items.
KIID GetPickedItemGroupId(unsigned int aIdx) const
unsigned GetCount() const
void ReversePickersListOrder()
Reverse the order of pickers stored in this list.
bool SetPickedItemLink(EDA_ITEM *aLink, unsigned aIdx)
Set the link associated to a given picked item.
void ClearListAndDeleteItems(std::function< void(EDA_ITEM *)> aItemDeleter)
Delete the list of pickers AND the data pointed by #m_PickedItem or #m_PickedItemLink according to th...
bool SetPickedItemGroupId(KIID aId, unsigned aIdx)
Set the group id associated to a given picked item.
EDA_ITEM * GetPickedItem(unsigned int aIdx) const
TOOL_MANAGER * m_toolManager
Definition: tools_holder.h:171
bool ProcessEvent(const TOOL_EVENT &aEvent)
Propagate an event to tools that requested events of matching type(s).
void PostEvent(const TOOL_EVENT &aEvent)
Put an event to the event queue to be processed at the end of event processing cycle.
A holder to handle a list of undo (or redo) commands.
std::vector< PICKED_ITEMS_LIST * > m_CommandsList
#define _(s)
#define UR_TRANSIENT
indicates the item is owned by the undo/redo stack
@ FRAME_PCB_EDITOR
Definition: frame_type.h:42
@ B_Mask
Definition: layer_ids.h:98
@ F_Mask
Definition: layer_ids.h:97
This file contains miscellaneous commonly used macros and functions.
#define KI_FALLTHROUGH
The KI_FALLTHROUGH macro is to be used when switch statement cases should purposely fallthrough from ...
Definition: macros.h:83
Class to handle a set of BOARD_ITEMs.
@ AS_GLOBAL
Global action (toolbar/main menu event, global shortcut)
Definition: tool_action.h:49
@ TA_UNDO_REDO_PRE
This event is sent before undo/redo command is performed.
Definition: tool_event.h:106
@ TA_UNDO_REDO_POST
This event is sent after undo/redo command is performed.
Definition: tool_event.h:109
@ TC_MESSAGE
Definition: tool_event.h:58
@ PCB_SHAPE_T
class PCB_SHAPE, a segment not on copper layers
Definition: typeinfo.h:88
@ PCB_VIA_T
class PCB_VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:97
@ PCB_ZONE_T
class ZONE, a copper pour area
Definition: typeinfo.h:107
@ PCB_FOOTPRINT_T
class FOOTPRINT, a footprint
Definition: typeinfo.h:86
@ PCB_PAD_T
class PAD, a pad in a footprint
Definition: typeinfo.h:87
@ PCB_ARC_T
class PCB_ARC, an arc track segment on a copper layer
Definition: typeinfo.h:98
@ PCB_NETINFO_T
class NETINFO_ITEM, a description of a net
Definition: typeinfo.h:109
@ PCB_TRACE_T
class PCB_TRACK, a track segment (segment on a copper layer)
Definition: typeinfo.h:96
UNDO_REDO
Undo Redo considerations: Basically we have 3 cases New item Deleted item Modified item there is also...