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 (C) 2012-2023 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_generator.h>
35#include <pcb_target.h>
36#include <footprint.h>
37#include <pad.h>
38#include <origin_viewitem.h>
40#include <tool/tool_manager.h>
41#include <tool/actions.h>
43#include <tools/pcb_control.h>
45#include <board_commit.h>
47#include <wx/msgdlg.h>
48
49/* Functions to undo and redo edit commands.
50 * commands to undo are stored in CurrentScreen->m_UndoList
51 * commands to redo are stored in CurrentScreen->m_RedoList
52 *
53 * m_UndoList and m_RedoList handle a std::vector of PICKED_ITEMS_LIST
54 * Each PICKED_ITEMS_LIST handle a std::vector of pickers (class ITEM_PICKER),
55 * that store the list of schematic items that are concerned by the command to undo or redo
56 * and is created for each command to undo (handle also a command to redo).
57 * each picker has a pointer pointing to an item to undo or redo (in fact: deleted, added or
58 * modified),
59 * and has a pointer to a copy of this item, when this item has been modified
60 * (the old values of parameters are therefore saved)
61 *
62 * there are 3 cases:
63 * - delete item(s) command
64 * - change item(s) command
65 * - add item(s) command
66 *
67 * Undo command
68 * - delete item(s) command:
69 * => deleted items are moved in undo list
70 *
71 * - change item(s) command
72 * => A copy of item(s) is made (a DrawPickedStruct list of wrappers)
73 * the .m_Link member of each wrapper points the modified item.
74 * the .m_Item member of each wrapper points the old copy of this item.
75 *
76 * - add item(s) command
77 * =>A list of item(s) is made. The .m_Item member of each wrapper points the new item.
78 *
79 * Redo command
80 * - delete item(s) old command:
81 * => deleted items are moved in EEDrawList list, and in
82 *
83 * - change item(s) command
84 * => the copy of item(s) is moved in Undo list
85 *
86 * - add item(s) command
87 * => The list of item(s) is used to create a deleted list in undo list(same as a delete
88 * command)
89 *
90 * Some block operations that change items can be undone without memorize items, just the
91 * coordinates of the transform:
92 * move list of items (undo/redo is made by moving with the opposite move vector)
93 * mirror (Y) and flip list of items (undo/redo is made by mirror or flip items)
94 * so they are handled specifically.
95 *
96 */
97
98
100 const PICKED_ITEMS_LIST& aItemsList,
101 UNDO_REDO aCommandType )
102{
103 int preExisting = commandToUndo->GetCount();
104
105 for( unsigned ii = 0; ii < aItemsList.GetCount(); ii++ )
106 commandToUndo->PushItem( aItemsList.GetItemWrapper(ii) );
107
108 for( unsigned ii = preExisting; ii < commandToUndo->GetCount(); ii++ )
109 {
110 EDA_ITEM* item = commandToUndo->GetPickedItem( ii );
111 UNDO_REDO command = commandToUndo->GetPickedItemStatus( ii );
112
113 if( command == UNDO_REDO::UNSPECIFIED )
114 {
115 command = aCommandType;
116 commandToUndo->SetPickedItemStatus( command, ii );
117 }
118
119 wxASSERT( item );
120
121 switch( command )
122 {
123 case UNDO_REDO::CHANGED:
124 case UNDO_REDO::DRILLORIGIN:
125 case UNDO_REDO::GRIDORIGIN:
126 // If we don't yet have a copy in the link, set one up
127 if( !commandToUndo->GetPickedItemLink( ii ) )
128 commandToUndo->SetPickedItemLink( BOARD_COMMIT::MakeImage( item ), ii );
129
130 break;
131
132 case UNDO_REDO::NEWITEM:
133 case UNDO_REDO::DELETED:
134 case UNDO_REDO::PAGESETTINGS:
135 case UNDO_REDO::REGROUP:
136 case UNDO_REDO::UNGROUP:
137 break;
138
139 default:
140 wxFAIL_MSG( wxString::Format( wxT( "Unrecognized undo command: %X" ), command ) );
141 break;
142 }
143 }
144
145 if( commandToUndo->GetCount() )
146 {
147 /* Save the copy in undo list */
148 PushCommandToUndoList( commandToUndo );
149
150 /* Clear redo list, because after a new command one cannot redo a command */
152 }
153 else
154 {
155 // Should not occur
156 wxASSERT( false );
157 delete commandToUndo;
158 }
159}
160
161
163{
164 PICKED_ITEMS_LIST* commandToUndo = new PICKED_ITEMS_LIST();
165 PICKED_ITEMS_LIST itemsList;
166
167 itemsList.PushItem( ITEM_PICKER( nullptr, aItem, aCommandType ) );
168 saveCopyInUndoList( commandToUndo, itemsList, aCommandType );
169}
170
171
173 UNDO_REDO aCommandType )
174{
175 PICKED_ITEMS_LIST* commandToUndo = new PICKED_ITEMS_LIST();
176 commandToUndo->SetDescription( aItemsList.GetDescription() );
177
178 saveCopyInUndoList( commandToUndo, aItemsList, aCommandType );
179}
180
181
183 UNDO_REDO aCommandType )
184{
185 PICKED_ITEMS_LIST* commandToUndo = PopCommandFromUndoList();
186
187 if( !commandToUndo )
188 {
189 commandToUndo = new PICKED_ITEMS_LIST();
190 commandToUndo->SetDescription( aItemsList.GetDescription() );
191 }
192
193 saveCopyInUndoList( commandToUndo, aItemsList, aCommandType );
194}
195
196
198{
199 if( UndoRedoBlocked() )
200 return;
201
202 if( GetUndoCommandCount() <= 0 )
203 return;
204
205 // Inform tools that undo command was issued
207
208 // Get the old list
210
211 // Undo the command
213
214 // Put the old list in RedoList
216 PushCommandToRedoList( list );
217
218 OnModify();
219
222
223 GetCanvas()->Refresh();
224}
225
226
228{
229 if( UndoRedoBlocked() )
230 return;
231
232 if( GetRedoCommandCount() == 0 )
233 return;
234
235 // Inform tools that redo command was issued
237
238 // Get the old list
240
241 // Redo the command
243
244 // Put the old list in UndoList
246 PushCommandToUndoList( list );
247
248 OnModify();
249
252
253 GetCanvas()->Refresh();
254}
255
256
258{
259 bool not_found = false;
260 bool reBuild_ratsnest = false;
261 bool deep_reBuild_ratsnest = false; // true later if pointers must be rebuilt
262 bool solder_mask_dirty = false;
263
264 auto view = GetCanvas()->GetView();
265 auto connectivity = GetBoard()->GetConnectivity();
266
267 GetBoard()->IncrementTimeStamp(); // clear caches
268
269 // Enum to track the modification type of items. Used to enable bulk BOARD_LISTENER
270 // callbacks at the end of the undo / redo operation
271 enum ITEM_CHANGE_TYPE
272 {
273 ADDED,
274 DELETED,
275 CHANGED
276 };
277
278 std::unordered_map<EDA_ITEM*, ITEM_CHANGE_TYPE> item_changes;
279
280 auto update_item_change_state = [&]( EDA_ITEM* item, ITEM_CHANGE_TYPE change_type )
281 {
282 auto item_itr = item_changes.find( item );
283
284 if( item_itr == item_changes.end() )
285 {
286 // First time we've seen this item - tag the current change type
287 item_changes.insert( { item, change_type } );
288 return;
289 }
290
291 // Update the item state based on the current and next change type
292 switch( item_itr->second )
293 {
294 case ITEM_CHANGE_TYPE::ADDED:
295 {
296 if( change_type == ITEM_CHANGE_TYPE::DELETED )
297 {
298 // The item was previously added, now deleted - as far as bulk callbacks
299 // are concerned, the item has never existed
300 item_changes.erase( item_itr );
301 }
302 else if( change_type == ITEM_CHANGE_TYPE::ADDED )
303 {
304 // Error condition - added an already added item
305 wxASSERT_MSG( false, wxT( "UndoRedo: should not add already added item" ) );
306 }
307
308 // For all other cases, the item remains as ADDED as seen by the bulk callbacks
309 break;
310 }
311 case ITEM_CHANGE_TYPE::DELETED:
312 {
313 // This is an error condition - item has already been deleted so should not
314 // be operated on further
315 wxASSERT_MSG( false, wxT( "UndoRedo: should not alter already deleted item" ) );
316 break;
317 }
318 case ITEM_CHANGE_TYPE::CHANGED:
319 {
320 if( change_type == ITEM_CHANGE_TYPE::DELETED )
321 {
322 item_itr->second = ITEM_CHANGE_TYPE::DELETED;
323 }
324 else if( change_type == ITEM_CHANGE_TYPE::ADDED )
325 {
326 // This is an error condition - item has already been changed so should not
327 // be added
328 wxASSERT_MSG( false,
329 wxT( "UndoRedo: should not add already changed item" ) );
330 }
331
332 // Otherwise, item remains CHANGED
333 break;
334 }
335 }
336 };
337
338 // Undo in the reverse order of list creation: (this can allow stacked changes
339 // like the same item can be changes and deleted in the same complex command
340
341 // Restore changes in reverse order
342 for( int ii = (int) aList->GetCount() - 1; ii >= 0 ; ii-- )
343 {
344 EDA_ITEM* eda_item = aList->GetPickedItem( (unsigned) ii );
345
346 /* Test for existence of item on board.
347 * It could be deleted, and no more on board:
348 * - if a call to SaveCopyInUndoList was forgotten in Pcbnew
349 * - in zones outlines, when a change in one zone merges this zone with an other
350 * This test avoids a Pcbnew crash
351 * Obviously, this test is not made for deleted items
352 */
353 UNDO_REDO status = aList->GetPickedItemStatus( ii );
354
355 if( status != UNDO_REDO::DELETED
356 && status != UNDO_REDO::REGROUP
357 && status != UNDO_REDO::UNGROUP
358 && status != UNDO_REDO::DRILLORIGIN // origin markers never on board
359 && status != UNDO_REDO::GRIDORIGIN // origin markers never on board
360 && status != UNDO_REDO::PAGESETTINGS ) // nor are page settings proxy items
361 {
362 if( GetBoard()->GetItem( eda_item->m_Uuid ) == DELETED_BOARD_ITEM::GetInstance() )
363 {
364 // Checking if it ever happens
365 wxASSERT_MSG( false, wxT( "Item in the undo buffer does not exist" ) );
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
437 if( item->GetParentFootprint() )
438 {
439 // We need the current item and it's parent, which may be different from what
440 // was stored if we're multiple frames up the undo stack.
441 item = GetBoard()->GetItem( item->m_Uuid );
442 parent = item->GetParentFootprint();
443 }
444
445 BOARD_ITEM* image = (BOARD_ITEM*) aList->GetPickedItemLink( ii );
446
447 view->Remove( item );
448 parent->Remove( item );
449
450 item->SwapItemData( image );
451
452 item->ClearFlags( UR_TRANSIENT );
453 image->SetFlags( UR_TRANSIENT );
454
455 if( PCB_GROUP* group = dynamic_cast<PCB_GROUP*>( item ) )
456 {
457 group->RunOnChildren( [&]( BOARD_ITEM* child )
458 {
459 child->SetParentGroup( group );
460 } );
461 }
462
463 view->Add( item );
464 view->Hide( item, false );
465 parent->Add( item );
466 update_item_change_state( item, ITEM_CHANGE_TYPE::CHANGED );
467 break;
468 }
469
470 case UNDO_REDO::NEWITEM: /* new items are deleted */
471 aList->SetPickedItemStatus( UNDO_REDO::DELETED, ii );
472 GetModel()->Remove( (BOARD_ITEM*) eda_item, REMOVE_MODE::BULK );
473 update_item_change_state( eda_item, ITEM_CHANGE_TYPE::DELETED );
474
475 if( eda_item->Type() != PCB_NETINFO_T )
476 view->Remove( eda_item );
477
478 eda_item->SetFlags( UR_TRANSIENT );
479
480 break;
481
482 case UNDO_REDO::DELETED: /* deleted items are put in List, as new items */
483 aList->SetPickedItemStatus( UNDO_REDO::NEWITEM, ii );
484
485 eda_item->ClearFlags( UR_TRANSIENT );
486
487 GetModel()->Add( (BOARD_ITEM*) eda_item, ADD_MODE::BULK_APPEND );
488 update_item_change_state( eda_item, ITEM_CHANGE_TYPE::ADDED );
489
490 if( eda_item->Type() != PCB_NETINFO_T )
491 view->Add( eda_item );
492
493 break;
494
495 case UNDO_REDO::REGROUP: /* grouped items are ungrouped */
496 aList->SetPickedItemStatus( UNDO_REDO::UNGROUP, ii );
497
498 if( BOARD_ITEM* boardItem = dynamic_cast<BOARD_ITEM*>( eda_item ) )
499 {
500 if( PCB_GROUP* group = boardItem->GetParentGroup() )
501 {
502 aList->SetPickedItemGroupId( group->m_Uuid, ii );
503
504 group->RemoveItem( boardItem );
505 }
506 }
507
508 break;
509
510 case UNDO_REDO::UNGROUP: /* ungrouped items are re-added to their previuos groups */
511 aList->SetPickedItemStatus( UNDO_REDO::REGROUP, ii );
512
513 if( BOARD_ITEM* boardItem = dynamic_cast<BOARD_ITEM*>( eda_item ) )
514 {
515 PCB_GROUP* group = dynamic_cast<PCB_GROUP*>(
516 GetBoard()->GetItem( aList->GetPickedItemGroupId( ii ) ) );
517
518 if( group )
519 group->AddItem( boardItem );
520 }
521
522 break;
523
524 case UNDO_REDO::DRILLORIGIN:
525 case UNDO_REDO::GRIDORIGIN:
526 {
527 // Warning: DRILLORIGIN and GRIDORIGIN undo/redo command create EDA_ITEMs
528 // that cannot be casted to BOARD_ITEMs
529 EDA_ITEM* image = aList->GetPickedItemLink( ii );
530 VECTOR2D origin = image->GetPosition();
531 image->SetPosition( eda_item->GetPosition() );
532
533 if( aList->GetPickedItemStatus( ii ) == UNDO_REDO::DRILLORIGIN )
534 BOARD_EDITOR_CONTROL::DoSetDrillOrigin( view, this, eda_item, origin );
535 else
536 PCB_CONTROL::DoSetGridOrigin( view, this, eda_item, origin );
537
538 break;
539 }
540
541 case UNDO_REDO::PAGESETTINGS:
542 {
543 // swap current settings with stored settings
544 DS_PROXY_UNDO_ITEM alt_item( this );
545 DS_PROXY_UNDO_ITEM* item = static_cast<DS_PROXY_UNDO_ITEM*>( eda_item );
546 item->Restore( this );
547 *item = std::move( alt_item );
548 break;
549 }
550
551 default:
552 wxFAIL_MSG( wxString::Format( wxT( "PutDataInPreviousState() error (unknown code %X)" ),
553 aList->GetPickedItemStatus( ii ) ) );
554 break;
555 }
556 }
557
558 if( not_found )
559 wxMessageBox( _( "Incomplete undo/redo operation: some items not found" ) );
560
561 if( IsType( FRAME_PCB_EDITOR ) )
562 {
563 if( reBuild_ratsnest || deep_reBuild_ratsnest )
564 {
565 // Connectivity may have changed; rebuild internal caches to remove stale items
567 Compile_Ratsnest( false );
568 }
569
570 if( solder_mask_dirty )
572 }
573
575 selTool->RebuildSelection();
576
578
579 // Invoke bulk BOARD_LISTENER callbacks
580 std::vector<BOARD_ITEM*> added_items, deleted_items, changed_items;
581
582 for( auto& item_itr : item_changes )
583 {
584 switch( item_itr.second )
585 {
586 case ITEM_CHANGE_TYPE::ADDED:
587 {
588 added_items.push_back( static_cast<BOARD_ITEM*>( item_itr.first ) );
589 break;
590 }
591 case ITEM_CHANGE_TYPE::DELETED:
592 {
593 deleted_items.push_back( static_cast<BOARD_ITEM*>( item_itr.first ) );
594 break;
595 }
596 case ITEM_CHANGE_TYPE::CHANGED:
597 {
598 changed_items.push_back( static_cast<BOARD_ITEM*>( item_itr.first ) );
599 break;
600 }
601 }
602 }
603
604 if( added_items.size() > 0 || deleted_items.size() > 0 || changed_items.size() > 0 )
605 GetBoard()->OnItemsCompositeUpdate( added_items, deleted_items, changed_items );
606}
607
608
610{
611 if( aItemCount == 0 )
612 return;
613
614 UNDO_REDO_CONTAINER& list = ( whichList == UNDO_LIST ) ? m_undoList : m_redoList;
615
616 if( aItemCount < 0 )
617 {
618 list.ClearCommandList();
619 }
620 else
621 {
622 for( int ii = 0; ii < aItemCount; ii++ )
623 {
624 if( list.m_CommandsList.size() == 0 )
625 break;
626
627 PICKED_ITEMS_LIST* curr_cmd = list.m_CommandsList[0];
628 list.m_CommandsList.erase( list.m_CommandsList.begin() );
629 ClearListAndDeleteItems( curr_cmd );
630 delete curr_cmd; // Delete command
631 }
632 }
633}
634
635
637{
639 []( EDA_ITEM* item )
640 {
641 wxASSERT_MSG( item->HasFlag( UR_TRANSIENT ),
642 "Item on undo/redo list not owned by undo/redo!" );
643
644 if( BOARD_ITEM* boardItem = dynamic_cast<BOARD_ITEM*>( item ) )
645 boardItem->SetParentGroup( nullptr );
646
647 delete item;
648 } );
649}
650
651
653{
657 delete undo;
658
659 GetCanvas()->Refresh();
660}
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:77
void SetParentGroup(PCB_GROUP *aGroup)
Definition: board_item.h:90
void SwapItemData(BOARD_ITEM *aImage)
Swap data between aItem and aImage.
Definition: board_item.cpp:175
FOOTPRINT * GetParentFootprint() const
Definition: board_item.cpp:248
BOARD_ITEM * GetItem(const KIID &aID) const
Definition: board.cpp:1293
void SanitizeNetcodes()
Definition: board.cpp:2489
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:180
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:2536
void IncrementTimeStamp()
Definition: board.cpp:249
std::shared_ptr< CONNECTIVITY_DATA > GetConnectivity() const
Return a list of missing connections between components/tracks.
Definition: board.h:460
static DELETED_BOARD_ITEM * GetInstance()
Definition: board_item.h:427
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
Specifies 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:88
virtual VECTOR2I GetPosition() const
Definition: eda_item.h:242
void SetFlags(EDA_ITEM_FLAGS aMask)
Definition: eda_item.h:126
const KIID m_Uuid
Definition: eda_item.h:485
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:100
void ClearFlags(EDA_ITEM_FLAGS aMask=EDA_ITEM_ALL_FLAGS)
Definition: eda_item.h:128
bool HasFlag(EDA_ITEM_FLAGS aFlag) const
Definition: eda_item.h:130
static const TOOL_EVENT UndoRedoPreEvent
Definition: actions.h:283
static const TOOL_EVENT SelectedItemsModified
Selected items were moved, this can be very high frequency on the canvas, use with care.
Definition: actions.h:267
static const TOOL_EVENT UndoRedoPostEvent
Definition: actions.h:284
LSET is a set of PCB_LAYER_IDs.
Definition: layer_ids.h:575
void ClearUndoORRedoList(UNDO_REDO_LIST whichList, int aItemCount=-1) override
Free the undo or redo list from List element.
Definition: undo_redo.cpp:609
void RestoreCopyFromUndoList(wxCommandEvent &aEvent)
Undo the last edit:
Definition: undo_redo.cpp:197
void saveCopyInUndoList(PICKED_ITEMS_LIST *commandToUndo, const PICKED_ITEMS_LIST &aItemsList, UNDO_REDO aCommandType)
Definition: undo_redo.cpp:99
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:182
void SaveCopyInUndoList(EDA_ITEM *aItemToCopy, UNDO_REDO aTypeCommand) override
Create a new entry in undo list of commands.
Definition: undo_redo.cpp:162
void ClearListAndDeleteItems(PICKED_ITEMS_LIST *aList)
Definition: undo_redo.cpp:636
void RollbackFromUndo()
Perform an undo of the last edit without logging a corresponding redo.
Definition: undo_redo.cpp:652
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:257
void RestoreCopyFromRedoList(wxCommandEvent &aEvent)
Redo the last edit:
Definition: undo_redo.cpp:227
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:51
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:167
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:106
@ F_Mask
Definition: layer_ids.h:107
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:48
@ TA_UNDO_REDO_PRE
Definition: tool_event.h:105
@ TA_UNDO_REDO_POST
Definition: tool_event.h:108
@ TC_MESSAGE
Definition: tool_event.h:57
@ 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...