KiCad PCB EDA Suite
Loading...
Searching...
No Matches
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, [email protected]
5 * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <[email protected]>
6 * Copyright (C) 2016 CERN
7 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
8 * @author Maciej Suminski <[email protected]>
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>
44#include <tools/pcb_actions.h>
46#include <tools/pcb_control.h>
48#include <board_commit.h>
50#include <wx/msgdlg.h>
51#include <pcb_board_outline.h>
52
53/* Functions to undo and redo edit commands.
54 * commands to undo are stored in CurrentScreen->m_UndoList
55 * commands to redo are stored in CurrentScreen->m_RedoList
56 *
57 * m_UndoList and m_RedoList handle a std::vector of PICKED_ITEMS_LIST
58 * Each PICKED_ITEMS_LIST handle a std::vector of pickers (class ITEM_PICKER),
59 * that store the list of schematic items that are concerned by the command to undo or redo
60 * and is created for each command to undo (handle also a command to redo).
61 * each picker has a pointer pointing to an item to undo or redo (in fact: deleted, added or
62 * modified),
63 * and has a pointer to a copy of this item, when this item has been modified
64 * (the old values of parameters are therefore saved)
65 *
66 * there are 3 cases:
67 * - delete item(s) command
68 * - change item(s) command
69 * - add item(s) command
70 *
71 * Undo command
72 * - delete item(s) command:
73 * => deleted items are moved in undo list
74 *
75 * - change item(s) command
76 * => A copy of item(s) is made (a DrawPickedStruct list of wrappers)
77 * the .m_Link member of each wrapper points the modified item.
78 * the .m_Item member of each wrapper points the old copy of this item.
79 *
80 * - add item(s) command
81 * =>A list of item(s) is made. The .m_Item member of each wrapper points the new item.
82 *
83 * Redo command
84 * - delete item(s) old command:
85 * => deleted items are moved in EEDrawList list, and in
86 *
87 * - change item(s) command
88 * => the copy of item(s) is moved in Undo list
89 *
90 * - add item(s) command
91 * => The list of item(s) is used to create a deleted list in undo list(same as a delete
92 * command)
93 *
94 * Some block operations that change items can be undone without memorize items, just the
95 * coordinates of the transform:
96 * move list of items (undo/redo is made by moving with the opposite move vector)
97 * mirror (Y) and flip list of items (undo/redo is made by mirror or flip items)
98 * so they are handled specifically.
99 *
100 */
101
102
104 const PICKED_ITEMS_LIST& aItemsList,
105 UNDO_REDO aCommandType )
106{
107 int preExisting = (int) commandToUndo->GetCount();
108
109 for( unsigned ii = 0; ii < aItemsList.GetCount(); ii++ )
110 commandToUndo->PushItem( aItemsList.GetItemWrapper(ii) );
111
112 for( unsigned ii = preExisting; ii < commandToUndo->GetCount(); ii++ )
113 {
114 EDA_ITEM* item = commandToUndo->GetPickedItem( ii );
115 UNDO_REDO command = commandToUndo->GetPickedItemStatus( ii );
116
117 if( command == UNDO_REDO::UNSPECIFIED )
118 {
119 command = aCommandType;
120 commandToUndo->SetPickedItemStatus( command, ii );
121 }
122
123 wxASSERT( item );
124
125 switch( command )
126 {
127 case UNDO_REDO::CHANGED:
128 case UNDO_REDO::DRILLORIGIN:
129 case UNDO_REDO::GRIDORIGIN:
130 // If we don't yet have a copy in the link, set one up
131 if( !commandToUndo->GetPickedItemLink( ii ) )
132 commandToUndo->SetPickedItemLink( BOARD_COMMIT::MakeImage( item ), ii );
133
134 break;
135
136 case UNDO_REDO::NEWITEM:
137 case UNDO_REDO::DELETED:
138 case UNDO_REDO::PAGESETTINGS:
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
227 GetCanvas()->Refresh();
228}
229
230
232{
233 if( UndoRedoBlocked() )
234 return;
235
236 if( GetRedoCommandCount() == 0 )
237 return;
238
239 // Inform tools that redo command was issued
241
242 // Get the old list
244
245 // Redo the command
247
248 // Put the old list in UndoList
250 PushCommandToUndoList( list );
251
252 OnModify();
253
256
259 GetCanvas()->Refresh();
260}
261
262
264{
265 bool not_found = false;
266 bool reBuild_ratsnest = false;
267 bool deep_reBuild_ratsnest = false; // true later if pointers must be rebuilt
268 bool solder_mask_dirty = false;
269 std::vector<BOX2I> dirty_rule_areas;
270
271 KIGFX::PCB_VIEW* view = GetCanvas()->GetView();
272 std::shared_ptr<CONNECTIVITY_DATA> connectivity = GetBoard()->GetConnectivity();
273
274 GetBoard()->IncrementTimeStamp(); // clear caches
275
276 // Enum to track the modification type of items. Used to enable bulk BOARD_LISTENER
277 // callbacks at the end of the undo / redo operation
278 enum ITEM_CHANGE_TYPE
279 {
280 ADDED,
281 DELETED,
282 CHANGED
283 };
284
285 std::unordered_map<EDA_ITEM*, ITEM_CHANGE_TYPE> item_changes;
286
287 auto update_item_change_state =
288 [&]( EDA_ITEM* item, ITEM_CHANGE_TYPE change_type )
289 {
290 auto item_itr = item_changes.find( item );
291
292 if( item_itr == item_changes.end() )
293 {
294 // First time we've seen this item - tag the current change type
295 item_changes.insert( { item, change_type } );
296 return;
297 }
298
299 // Update the item state based on the current and next change type
300 switch( item_itr->second )
301 {
302 case ITEM_CHANGE_TYPE::ADDED:
303 {
304 if( change_type == ITEM_CHANGE_TYPE::DELETED )
305 {
306 // The item was previously added, now deleted - as far as bulk callbacks
307 // are concerned, the item has never existed
308 item_changes.erase( item_itr );
309 }
310 else if( change_type == ITEM_CHANGE_TYPE::ADDED )
311 {
312 // Error condition - added an already added item
313 wxASSERT_MSG( false, wxT( "UndoRedo: should not add already added item" ) );
314 }
315
316 // For all other cases, the item remains as ADDED as seen by the bulk callbacks
317 break;
318 }
319 case ITEM_CHANGE_TYPE::DELETED:
320 {
321 // This is an error condition - item has already been deleted so should not
322 // be operated on further
323 wxASSERT_MSG( false, wxT( "UndoRedo: should not alter already deleted item" ) );
324 break;
325 }
326 case ITEM_CHANGE_TYPE::CHANGED:
327 {
328 if( change_type == ITEM_CHANGE_TYPE::DELETED )
329 {
330 item_itr->second = ITEM_CHANGE_TYPE::DELETED;
331 }
332 else if( change_type == ITEM_CHANGE_TYPE::ADDED )
333 {
334 // This is an error condition - item has already been changed so should not
335 // be added
336 wxASSERT_MSG( false, wxT( "UndoRedo: should not add already changed item" ) );
337 }
338
339 // Otherwise, item remains CHANGED
340 break;
341 }
342 }
343 };
344
345 // Undo in the reverse order of list creation: (this can allow stacked changes
346 // like the same item can be changes and deleted in the same complex command
347
348 // Restore changes in reverse order
349 for( int ii = (int) aList->GetCount() - 1; ii >= 0 ; ii-- )
350 {
351 EDA_ITEM* eda_item = aList->GetPickedItem( (unsigned) ii );
352
353 /* Test for existence of item on board.
354 * It could be deleted, and no more on board:
355 * - if a call to SaveCopyInUndoList was forgotten in Pcbnew
356 * - in zones outlines, when a change in one zone merges this zone with an other
357 * This test avoids a Pcbnew crash
358 * Obviously, this test is not made for deleted items
359 */
360 UNDO_REDO status = aList->GetPickedItemStatus( ii );
361
362 if( status != UNDO_REDO::DELETED
363 && status != UNDO_REDO::DRILLORIGIN // origin markers never on board
364 && status != UNDO_REDO::GRIDORIGIN // origin markers never on board
365 && status != UNDO_REDO::PAGESETTINGS ) // nor are page settings proxy items
366 {
367 if( !GetBoard()->ResolveItem( eda_item->m_Uuid, true ) )
368 {
369 // Remove this non existent item
370 aList->RemovePicker( ii );
371 not_found = true;
372
373 if( aList->GetCount() == 0 )
374 break;
375
376 continue;
377 }
378 }
379
380 // see if we must rebuild ratsnets and pointers lists
381 switch( eda_item->Type() )
382 {
383 case PCB_FOOTPRINT_T:
384 deep_reBuild_ratsnest = true; // Pointers on pads can be invalid
386
387 case PCB_ZONE_T:
388 case PCB_TRACE_T:
389 case PCB_ARC_T:
390 case PCB_VIA_T:
391 case PCB_PAD_T:
392 reBuild_ratsnest = true;
393 break;
394
395 case PCB_NETINFO_T:
396 reBuild_ratsnest = true;
397 deep_reBuild_ratsnest = true;
398 break;
399
400 default:
401 break;
402 }
403
404 switch( eda_item->Type() )
405 {
406 case PCB_FOOTPRINT_T:
407 solder_mask_dirty = true;
408 break;
409
410 case PCB_VIA_T:
411 solder_mask_dirty = true;
412 break;
413
414 case PCB_ZONE_T:
415 case PCB_TRACE_T:
416 case PCB_ARC_T:
417 case PCB_PAD_T:
418 case PCB_SHAPE_T:
419 {
420 LSET layers = static_cast<BOARD_ITEM*>( eda_item )->GetLayerSet();
421
422 if( layers.test( F_Mask ) || layers.test( B_Mask ) )
423 solder_mask_dirty = true;
424
425 break;
426 }
427
428 default:
429 break;
430 }
431
432 switch( aList->GetPickedItemStatus( ii ) )
433 {
434 case UNDO_REDO::CHANGED: /* Exchange old and new data for each item */
435 {
436 BOARD_ITEM* item = (BOARD_ITEM*) eda_item;
437 BOARD_ITEM_CONTAINER* parent = GetBoard();
438
439 if( item->GetParentFootprint() )
440 {
441 // We need the current item and it's parent, which may be different from what
442 // was stored if we're multiple frames up the undo stack.
443 item = GetBoard()->ResolveItem( item->m_Uuid );
444 parent = item->GetParentFootprint();
445 }
446
447 BOARD_ITEM* image = (BOARD_ITEM*) aList->GetPickedItemLink( ii );
448
449 view->Remove( item );
450
451 parent->Remove( item );
452
453 item->SwapItemData( image );
454
455 item->ClearFlags( UR_TRANSIENT );
456 image->SetFlags( UR_TRANSIENT );
457
458 view->Add( item );
459 view->Hide( item, false );
460 parent->Add( item );
461
462 if( item->Type() == PCB_ZONE_T && static_cast<ZONE*>( item )->GetIsRuleArea() )
463 {
464 dirty_rule_areas.push_back( item->GetBoundingBox() );
465 dirty_rule_areas.push_back( image->GetBoundingBox() );
466 }
467
468 update_item_change_state( item, ITEM_CHANGE_TYPE::CHANGED );
469 break;
470 }
471
472 case UNDO_REDO::NEWITEM: /* new items are deleted */
473 aList->SetPickedItemStatus( UNDO_REDO::DELETED, ii );
474 GetModel()->Remove( (BOARD_ITEM*) eda_item, REMOVE_MODE::BULK );
475 update_item_change_state( eda_item, ITEM_CHANGE_TYPE::DELETED );
476
477 if( eda_item->Type() != PCB_NETINFO_T )
478 view->Remove( eda_item );
479
480 eda_item->SetFlags( UR_TRANSIENT );
481
482 if( eda_item->Type() == PCB_ZONE_T && static_cast<ZONE*>( eda_item )->GetIsRuleArea() )
483 dirty_rule_areas.push_back( eda_item->GetBoundingBox() );
484
485 break;
486
487 case UNDO_REDO::DELETED: /* deleted items are put in List, as new items */
488 aList->SetPickedItemStatus( UNDO_REDO::NEWITEM, ii );
489
490 eda_item->ClearFlags( UR_TRANSIENT );
491
492 GetModel()->Add( (BOARD_ITEM*) eda_item, ADD_MODE::BULK_APPEND );
493 update_item_change_state( eda_item, ITEM_CHANGE_TYPE::ADDED );
494
495 if( eda_item->Type() != PCB_NETINFO_T )
496 view->Add( eda_item );
497
498 if( eda_item->Type() == PCB_ZONE_T && static_cast<ZONE*>( eda_item )->GetIsRuleArea() )
499 dirty_rule_areas.push_back( eda_item->GetBoundingBox() );
500
501 break;
502
503 case UNDO_REDO::DRILLORIGIN:
504 case UNDO_REDO::GRIDORIGIN:
505 {
506 // Warning: DRILLORIGIN and GRIDORIGIN undo/redo command create EDA_ITEMs
507 // that cannot be casted to BOARD_ITEMs
508 EDA_ITEM* image = aList->GetPickedItemLink( ii );
509 VECTOR2D origin = image->GetPosition();
510 image->SetPosition( eda_item->GetPosition() );
511
512 if( aList->GetPickedItemStatus( ii ) == UNDO_REDO::DRILLORIGIN )
513 BOARD_EDITOR_CONTROL::DoSetDrillOrigin( view, this, eda_item, origin );
514 else
515 PCB_CONTROL::DoSetGridOrigin( view, this, eda_item, origin );
516
517 break;
518 }
519
520 case UNDO_REDO::PAGESETTINGS:
521 {
522 // swap current settings with stored settings
523 DS_PROXY_UNDO_ITEM alt_item( this );
524 DS_PROXY_UNDO_ITEM* item = static_cast<DS_PROXY_UNDO_ITEM*>( eda_item );
525 item->Restore( this );
526 *item = std::move( alt_item );
527 break;
528 }
529
530 default:
531 wxFAIL_MSG( wxString::Format( wxT( "PutDataInPreviousState() error (unknown code %X)" ),
532 aList->GetPickedItemStatus( ii ) ) );
533 break;
534 }
535
536 if( eda_item->Type() == PCB_FOOTPRINT_T )
537 {
538 FOOTPRINT* fp = static_cast<FOOTPRINT*>( eda_item );
541 }
542 }
543
544 if( not_found )
545 wxMessageBox( _( "Incomplete undo/redo operation: some items not found" ) );
546
547 // We have now swapped all the group parent and group member pointers. But it is a
548 // risky proposition to bet on the pointers being invariant, so validate them all.
549 for( int ii = 0; ii < (int) aList->GetCount(); ++ii )
550 {
551 ITEM_PICKER& wrapper = aList->GetItemWrapper( ii );
552
553 if( wrapper.GetStatus() == UNDO_REDO::DELETED )
554 continue;
555
556 BOARD_ITEM* parentGroup = GetBoard()->ResolveItem( wrapper.GetGroupId(), true );
557 wrapper.GetItem()->SetParentGroup( dynamic_cast<PCB_GROUP*>( parentGroup ) );
558
559 if( EDA_GROUP* group = dynamic_cast<PCB_GROUP*>( wrapper.GetItem() ) )
560 {
561 // Items list may contain dodgy pointers, so don't use RemoveAll()
562 group->GetItems().clear();
563
564 for( const KIID& member : wrapper.GetGroupMembers() )
565 {
566 if( BOARD_ITEM* memberItem = GetBoard()->ResolveItem( member, true ) )
567 group->AddItem( memberItem );
568 }
569 }
570
571 // And prepare for a redo by updating group info based on current image
572 if( EDA_ITEM* item = wrapper.GetLink() )
573 wrapper.SetLink( item );
574 }
575
576 if( IsType( FRAME_PCB_EDITOR ) )
577 {
578 if( !dirty_rule_areas.empty() && ( GetPcbNewSettings()->m_Display.m_TrackClearance == SHOW_WITH_VIA_ALWAYS
579 || GetPcbNewSettings()->m_Display.m_PadClearance ) )
580 {
581 view->UpdateCollidingItems( dirty_rule_areas, { PCB_TRACE_T, PCB_ARC_T, PCB_VIA_T, PCB_PAD_T } );
582 }
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
624
625 if( added_items.size() > 0 || deleted_items.size() > 0 || changed_items.size() > 0 )
626 GetBoard()->OnItemsCompositeUpdate( added_items, deleted_items, changed_items );
627}
628
629
631{
632 if( aItemCount == 0 )
633 return;
634
635 UNDO_REDO_CONTAINER& list = ( whichList == UNDO_LIST ) ? m_undoList : m_redoList;
636
637 if( aItemCount < 0 )
638 {
639 list.ClearCommandList();
640 }
641 else
642 {
643 for( int ii = 0; ii < aItemCount; ii++ )
644 {
645 if( list.m_CommandsList.size() == 0 )
646 break;
647
648 PICKED_ITEMS_LIST* curr_cmd = list.m_CommandsList[0];
649 list.m_CommandsList.erase( list.m_CommandsList.begin() );
650 ClearListAndDeleteItems( curr_cmd );
651 delete curr_cmd; // Delete command
652 }
653 }
654}
655
656
658{
660 []( EDA_ITEM* item )
661 {
662 wxASSERT_MSG( item->HasFlag( UR_TRANSIENT ),
663 "Item on undo/redo list not owned by undo/redo!" );
664
665 delete item;
666 } );
667}
668
669
671{
675 delete undo;
676
679 GetCanvas()->Refresh();
680}
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:79
void SwapItemData(BOARD_ITEM *aImage)
Swap data between aItem and aImage.
Definition: board_item.cpp:270
FOOTPRINT * GetParentFootprint() const
Definition: board_item.cpp:97
PCB_BOARD_OUTLINE * BoardOutline()
Definition: board.h:366
void UpdateBoardOutline()
Definition: board.cpp:3192
void SanitizeNetcodes()
Definition: board.cpp:2771
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:186
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:2818
void IncrementTimeStamp()
Definition: board.cpp:254
COMPONENT_CLASS_MANAGER & GetComponentClassManager()
Gets the component class manager.
Definition: board.h:1345
BOARD_ITEM * ResolveItem(const KIID &aID, bool aAllowNullptrReturn=false) const
Definition: board.cpp:1583
std::shared_ptr< CONNECTIVITY_DATA > GetConnectivity() const
Return a list of missing connections between components/tracks.
Definition: board.h:522
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.
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 set of EDA_ITEMs (i.e., without duplicates).
Definition: eda_group.h:46
A base class for most all the KiCad significant classes used in schematics and boards.
Definition: eda_item.h:98
virtual VECTOR2I GetPosition() const
Definition: eda_item.h:272
virtual const BOX2I GetBoundingBox() const
Return the orthogonal bounding box of this object for display purposes.
Definition: eda_item.cpp:110
void SetFlags(EDA_ITEM_FLAGS aMask)
Definition: eda_item.h:142
const KIID m_Uuid
Definition: eda_item.h:516
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:110
void ClearFlags(EDA_ITEM_FLAGS aMask=EDA_ITEM_ALL_FLAGS)
Definition: eda_item.h:144
bool HasFlag(EDA_ITEM_FLAGS aFlag) const
Definition: eda_item.h:146
static const TOOL_EVENT UndoRedoPreEvent
Definition: actions.h:365
static const TOOL_EVENT SelectedItemsModified
Selected items were moved, this can be very high frequency on the canvas, use with care.
Definition: actions.h:349
static const TOOL_EVENT UndoRedoPostEvent
Definition: actions.h:366
void InvalidateComponentClassCache() const
Forces deferred (on next access) recalculation of the component class for this footprint.
Definition: footprint.cpp:4146
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:91
virtual void Add(VIEW_ITEM *aItem, int aDrawPriority=-1) override
Add a VIEW_ITEM to the view.
Definition: pcb_view.cpp:57
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:122
virtual void Remove(VIEW_ITEM *aItem) override
Remove a VIEW_ITEM from the view.
Definition: pcb_view.cpp:74
void Hide(VIEW_ITEM *aItem, bool aHide=true, bool aHideOverlay=false)
Temporarily hide the item in the view (e.g.
Definition: view.cpp:1633
Definition: kiid.h:49
LSET is a set of PCB_LAYER_IDs.
Definition: lset.h:37
static TOOL_ACTION rehatchShapes
Definition: pcb_actions.h:376
void ClearUndoORRedoList(UNDO_REDO_LIST whichList, int aItemCount=-1) override
Free the undo or redo list from List element.
Definition: undo_redo.cpp:630
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:103
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:657
void RollbackFromUndo()
Perform an undo of the last edit without logging a corresponding redo.
Definition: undo_redo.cpp:670
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:263
void RestoreCopyFromRedoList(wxCommandEvent &aEvent)
Redo the last edit:
Definition: undo_redo.cpp:231
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 ...
EDA_ITEM * ResolveItem(const KIID &aId, bool aAllowNullptrReturn=false) const override
Fetch an item by KIID.
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:53
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
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.
const ITEM_PICKER & GetItemWrapper(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...
EDA_ITEM * GetPickedItem(unsigned int aIdx) const
TOOL_MANAGER * m_toolManager
Definition: tools_holder.h:171
TOOL_MANAGER * GetToolManager() const
Return the MVC controller.
Definition: tools_holder.h:55
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.
bool PostAction(const std::string &aActionName, T aParam)
Run the specified action after the current action (coroutine) ends.
Definition: tool_manager.h:235
A holder to handle a list of undo (or redo) commands.
std::vector< PICKED_ITEMS_LIST * > m_CommandsList
Handle a list of polygons defining a copper zone.
Definition: zone.h:74
bool GetIsRuleArea() const
Accessors to parameters used in Rule Area zones:
Definition: zone.h:704
#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.
@ SHOW_WITH_VIA_ALWAYS
@ 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...