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