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 = [&]( EDA_ITEM* item, ITEM_CHANGE_TYPE change_type )
282 {
283 auto item_itr = item_changes.find( item );
284
285 if( item_itr == item_changes.end() )
286 {
287 // First time we've seen this item - tag the current change type
288 item_changes.insert( { item, change_type } );
289 return;
290 }
291
292 // Update the item state based on the current and next change type
293 switch( item_itr->second )
294 {
295 case ITEM_CHANGE_TYPE::ADDED:
296 {
297 if( change_type == ITEM_CHANGE_TYPE::DELETED )
298 {
299 // The item was previously added, now deleted - as far as bulk callbacks
300 // are concerned, the item has never existed
301 item_changes.erase( item_itr );
302 }
303 else if( change_type == ITEM_CHANGE_TYPE::ADDED )
304 {
305 // Error condition - added an already added item
306 wxASSERT_MSG( false, wxT( "UndoRedo: should not add already added item" ) );
307 }
308
309 // For all other cases, the item remains as ADDED as seen by the bulk callbacks
310 break;
311 }
312 case ITEM_CHANGE_TYPE::DELETED:
313 {
314 // This is an error condition - item has already been deleted so should not
315 // be operated on further
316 wxASSERT_MSG( false, wxT( "UndoRedo: should not alter already deleted item" ) );
317 break;
318 }
319 case ITEM_CHANGE_TYPE::CHANGED:
320 {
321 if( change_type == ITEM_CHANGE_TYPE::DELETED )
322 {
323 item_itr->second = ITEM_CHANGE_TYPE::DELETED;
324 }
325 else if( change_type == ITEM_CHANGE_TYPE::ADDED )
326 {
327 // This is an error condition - item has already been changed so should not
328 // be added
329 wxASSERT_MSG( false,
330 wxT( "UndoRedo: should not add already changed item" ) );
331 }
332
333 // Otherwise, item remains CHANGED
334 break;
335 }
336 }
337 };
338
339 // Undo in the reverse order of list creation: (this can allow stacked changes
340 // like the same item can be changes and deleted in the same complex command
341
342 // Restore changes in reverse order
343 for( int ii = (int) aList->GetCount() - 1; ii >= 0 ; ii-- )
344 {
345 EDA_ITEM* eda_item = aList->GetPickedItem( (unsigned) ii );
346
347 /* Test for existence of item on board.
348 * It could be deleted, and no more on board:
349 * - if a call to SaveCopyInUndoList was forgotten in Pcbnew
350 * - in zones outlines, when a change in one zone merges this zone with an other
351 * This test avoids a Pcbnew crash
352 * Obviously, this test is not made for deleted items
353 */
354 UNDO_REDO status = aList->GetPickedItemStatus( ii );
355
356 if( status != UNDO_REDO::DELETED
357 && status != UNDO_REDO::REGROUP
358 && status != UNDO_REDO::UNGROUP
359 && status != UNDO_REDO::DRILLORIGIN // origin markers never on board
360 && status != UNDO_REDO::GRIDORIGIN // origin markers never on board
361 && status != UNDO_REDO::PAGESETTINGS ) // nor are page settings proxy items
362 {
363 if( GetBoard()->GetItem( eda_item->m_Uuid ) == DELETED_BOARD_ITEM::GetInstance() )
364 {
365 // Checking if it ever happens
366 wxASSERT_MSG( false, wxT( "Item in the undo buffer does not exist" ) );
367
368 // Remove this non existent item
369 aList->RemovePicker( ii );
370 not_found = true;
371
372 if( aList->GetCount() == 0 )
373 break;
374
375 continue;
376 }
377 }
378
379 // see if we must rebuild ratsnets and pointers lists
380 switch( eda_item->Type() )
381 {
382 case PCB_FOOTPRINT_T:
383 deep_reBuild_ratsnest = true; // Pointers on pads can be invalid
385
386 case PCB_ZONE_T:
387 case PCB_TRACE_T:
388 case PCB_ARC_T:
389 case PCB_VIA_T:
390 case PCB_PAD_T:
391 reBuild_ratsnest = true;
392 break;
393
394 case PCB_NETINFO_T:
395 reBuild_ratsnest = true;
396 deep_reBuild_ratsnest = true;
397 break;
398
399 default:
400 break;
401 }
402
403 switch( eda_item->Type() )
404 {
405 case PCB_FOOTPRINT_T:
406 solder_mask_dirty = true;
407 break;
408
409 case PCB_VIA_T:
410 solder_mask_dirty = true;
411 break;
412
413 case PCB_ZONE_T:
414 case PCB_TRACE_T:
415 case PCB_ARC_T:
416 case PCB_PAD_T:
417 case PCB_SHAPE_T:
418 {
419 LSET layers = static_cast<BOARD_ITEM*>( eda_item )->GetLayerSet();
420
421 if( layers.test( F_Mask ) || layers.test( B_Mask ) )
422 solder_mask_dirty = true;
423
424 break;
425 }
426
427 default:
428 break;
429 }
430
431 switch( aList->GetPickedItemStatus( ii ) )
432 {
433 case UNDO_REDO::CHANGED: /* Exchange old and new data for each item */
434 {
435 BOARD_ITEM* item = (BOARD_ITEM*) eda_item;
436 BOARD_ITEM_CONTAINER* parent = GetBoard();
437 PCB_GROUP* parentGroup = item->GetParentGroup();
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()->GetItem( 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 if( parentGroup )
452 parentGroup->RemoveItem( item );
453
454 parent->Remove( item );
455
456 item->SwapItemData( image );
457
458 item->ClearFlags( UR_TRANSIENT );
459 image->SetFlags( UR_TRANSIENT );
460
461 if( PCB_GROUP* group = dynamic_cast<PCB_GROUP*>( item ) )
462 {
463 group->RunOnChildren( [&]( BOARD_ITEM* child )
464 {
465 child->SetParentGroup( group );
466 } );
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( BOARD_ITEM* boardItem = dynamic_cast<BOARD_ITEM*>( eda_item ) )
509 {
510 if( PCB_GROUP* group = boardItem->GetParentGroup() )
511 {
512 aList->SetPickedItemGroupId( group->m_Uuid, ii );
513
514 group->RemoveItem( boardItem );
515 }
516 }
517
518 break;
519
520 case UNDO_REDO::UNGROUP: /* ungrouped items are re-added to their previuos groups */
521 aList->SetPickedItemStatus( UNDO_REDO::REGROUP, ii );
522
523 if( BOARD_ITEM* boardItem = dynamic_cast<BOARD_ITEM*>( eda_item ) )
524 {
525 PCB_GROUP* group = dynamic_cast<PCB_GROUP*>(
526 GetBoard()->GetItem( aList->GetPickedItemGroupId( ii ) ) );
527
528 if( group )
529 group->AddItem( boardItem );
530 }
531
532 break;
533
534 case UNDO_REDO::DRILLORIGIN:
535 case UNDO_REDO::GRIDORIGIN:
536 {
537 // Warning: DRILLORIGIN and GRIDORIGIN undo/redo command create EDA_ITEMs
538 // that cannot be casted to BOARD_ITEMs
539 EDA_ITEM* image = aList->GetPickedItemLink( ii );
540 VECTOR2D origin = image->GetPosition();
541 image->SetPosition( eda_item->GetPosition() );
542
543 if( aList->GetPickedItemStatus( ii ) == UNDO_REDO::DRILLORIGIN )
544 BOARD_EDITOR_CONTROL::DoSetDrillOrigin( view, this, eda_item, origin );
545 else
546 PCB_CONTROL::DoSetGridOrigin( view, this, eda_item, origin );
547
548 break;
549 }
550
551 case UNDO_REDO::PAGESETTINGS:
552 {
553 // swap current settings with stored settings
554 DS_PROXY_UNDO_ITEM alt_item( this );
555 DS_PROXY_UNDO_ITEM* item = static_cast<DS_PROXY_UNDO_ITEM*>( eda_item );
556 item->Restore( this );
557 *item = std::move( alt_item );
558 break;
559 }
560
561 default:
562 wxFAIL_MSG( wxString::Format( wxT( "PutDataInPreviousState() error (unknown code %X)" ),
563 aList->GetPickedItemStatus( ii ) ) );
564 break;
565 }
566 }
567
568 if( not_found )
569 wxMessageBox( _( "Incomplete undo/redo operation: some items not found" ) );
570
571 if( IsType( FRAME_PCB_EDITOR ) )
572 {
573 if( reBuild_ratsnest || deep_reBuild_ratsnest )
574 {
575 // Connectivity may have changed; rebuild internal caches to remove stale items
577 Compile_Ratsnest( false );
578 }
579
580 if( solder_mask_dirty )
582 }
583
585 selTool->RebuildSelection();
586
588
589 // Invoke bulk BOARD_LISTENER callbacks
590 std::vector<BOARD_ITEM*> added_items, deleted_items, changed_items;
591
592 for( auto& item_itr : item_changes )
593 {
594 switch( item_itr.second )
595 {
596 case ITEM_CHANGE_TYPE::ADDED:
597 {
598 added_items.push_back( static_cast<BOARD_ITEM*>( item_itr.first ) );
599 break;
600 }
601 case ITEM_CHANGE_TYPE::DELETED:
602 {
603 deleted_items.push_back( static_cast<BOARD_ITEM*>( item_itr.first ) );
604 break;
605 }
606 case ITEM_CHANGE_TYPE::CHANGED:
607 {
608 changed_items.push_back( static_cast<BOARD_ITEM*>( item_itr.first ) );
609 break;
610 }
611 }
612 }
613
614 if( added_items.size() > 0 || deleted_items.size() > 0 || changed_items.size() > 0 )
615 GetBoard()->OnItemsCompositeUpdate( added_items, deleted_items, changed_items );
616}
617
618
620{
621 if( aItemCount == 0 )
622 return;
623
624 UNDO_REDO_CONTAINER& list = ( whichList == UNDO_LIST ) ? m_undoList : m_redoList;
625
626 if( aItemCount < 0 )
627 {
628 list.ClearCommandList();
629 }
630 else
631 {
632 for( int ii = 0; ii < aItemCount; ii++ )
633 {
634 if( list.m_CommandsList.size() == 0 )
635 break;
636
637 PICKED_ITEMS_LIST* curr_cmd = list.m_CommandsList[0];
638 list.m_CommandsList.erase( list.m_CommandsList.begin() );
639 ClearListAndDeleteItems( curr_cmd );
640 delete curr_cmd; // Delete command
641 }
642 }
643}
644
645
647{
649 []( EDA_ITEM* item )
650 {
651 wxASSERT_MSG( item->HasFlag( UR_TRANSIENT ),
652 "Item on undo/redo list not owned by undo/redo!" );
653
654 if( BOARD_ITEM* boardItem = dynamic_cast<BOARD_ITEM*>( item ) )
655 boardItem->SetParentGroup( nullptr );
656
657 delete item;
658 } );
659}
660
661
663{
667 delete undo;
668
669 GetCanvas()->Refresh();
670}
bool test(size_t pos) const
Definition: base_set.h:47
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:191
PCB_GROUP * GetParentGroup() const
Definition: board_item.h:93
FOOTPRINT * GetParentFootprint() const
Definition: board_item.cpp:264
BOARD_ITEM * GetItem(const KIID &aID) const
Definition: board.cpp:1390
void SanitizeNetcodes()
Definition: board.cpp:2632
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:2679
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:619
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:646
void RollbackFromUndo()
Perform an undo of the last edit without logging a corresponding redo.
Definition: undo_redo.cpp:662
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...