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
52/* Functions to undo and redo edit commands.
53 * commands to undo are stored in CurrentScreen->m_UndoList
54 * commands to redo are stored in CurrentScreen->m_RedoList
55 *
56 * m_UndoList and m_RedoList handle a std::vector of PICKED_ITEMS_LIST
57 * Each PICKED_ITEMS_LIST handle a std::vector of pickers (class ITEM_PICKER),
58 * that store the list of schematic items that are concerned by the command to undo or redo
59 * and is created for each command to undo (handle also a command to redo).
60 * each picker has a pointer pointing to an item to undo or redo (in fact: deleted, added or
61 * modified),
62 * and has a pointer to a copy of this item, when this item has been modified
63 * (the old values of parameters are therefore saved)
64 *
65 * there are 3 cases:
66 * - delete item(s) command
67 * - change item(s) command
68 * - add item(s) command
69 *
70 * Undo command
71 * - delete item(s) command:
72 * => deleted items are moved in undo list
73 *
74 * - change item(s) command
75 * => A copy of item(s) is made (a DrawPickedStruct list of wrappers)
76 * the .m_Link member of each wrapper points the modified item.
77 * the .m_Item member of each wrapper points the old copy of this item.
78 *
79 * - add item(s) command
80 * =>A list of item(s) is made. The .m_Item member of each wrapper points the new item.
81 *
82 * Redo command
83 * - delete item(s) old command:
84 * => deleted items are moved in EEDrawList list, and in
85 *
86 * - change item(s) command
87 * => the copy of item(s) is moved in Undo list
88 *
89 * - add item(s) command
90 * => The list of item(s) is used to create a deleted list in undo list(same as a delete
91 * command)
92 *
93 * Some block operations that change items can be undone without memorize items, just the
94 * coordinates of the transform:
95 * move list of items (undo/redo is made by moving with the opposite move vector)
96 * mirror (Y) and flip list of items (undo/redo is made by mirror or flip items)
97 * so they are handled specifically.
98 *
99 */
100
101
103 const PICKED_ITEMS_LIST& aItemsList,
104 UNDO_REDO aCommandType )
105{
106 int preExisting = commandToUndo->GetCount();
107
108 for( unsigned ii = 0; ii < aItemsList.GetCount(); ii++ )
109 commandToUndo->PushItem( aItemsList.GetItemWrapper(ii) );
110
111 for( unsigned ii = preExisting; ii < commandToUndo->GetCount(); ii++ )
112 {
113 EDA_ITEM* item = commandToUndo->GetPickedItem( ii );
114 UNDO_REDO command = commandToUndo->GetPickedItemStatus( ii );
115
116 if( command == UNDO_REDO::UNSPECIFIED )
117 {
118 command = aCommandType;
119 commandToUndo->SetPickedItemStatus( command, ii );
120 }
121
122 wxASSERT( item );
123
124 switch( command )
125 {
126 case UNDO_REDO::CHANGED:
127 case UNDO_REDO::DRILLORIGIN:
128 case UNDO_REDO::GRIDORIGIN:
129 // If we don't yet have a copy in the link, set one up
130 if( !commandToUndo->GetPickedItemLink( ii ) )
131 commandToUndo->SetPickedItemLink( BOARD_COMMIT::MakeImage( item ), ii );
132
133 break;
134
135 case UNDO_REDO::NEWITEM:
136 case UNDO_REDO::DELETED:
137 case UNDO_REDO::PAGESETTINGS:
138 case UNDO_REDO::REGROUP:
139 case UNDO_REDO::UNGROUP:
140 break;
141
142 default:
143 wxFAIL_MSG( wxString::Format( wxT( "Unrecognized undo command: %X" ), command ) );
144 break;
145 }
146 }
147
148 if( commandToUndo->GetCount() )
149 {
150 /* Save the copy in undo list */
151 PushCommandToUndoList( commandToUndo );
152
153 /* Clear redo list, because after a new command one cannot redo a command */
155 }
156 else
157 {
158 // Should not occur
159 wxASSERT( false );
160 delete commandToUndo;
161 }
162}
163
164
166{
167 PICKED_ITEMS_LIST* commandToUndo = new PICKED_ITEMS_LIST();
168 PICKED_ITEMS_LIST itemsList;
169
170 itemsList.PushItem( ITEM_PICKER( nullptr, aItem, aCommandType ) );
171 saveCopyInUndoList( commandToUndo, itemsList, aCommandType );
172}
173
174
176 UNDO_REDO aCommandType )
177{
178 PICKED_ITEMS_LIST* commandToUndo = new PICKED_ITEMS_LIST();
179 commandToUndo->SetDescription( aItemsList.GetDescription() );
180
181 saveCopyInUndoList( commandToUndo, aItemsList, aCommandType );
182}
183
184
186 UNDO_REDO aCommandType )
187{
188 PICKED_ITEMS_LIST* commandToUndo = PopCommandFromUndoList();
189
190 if( !commandToUndo )
191 {
192 commandToUndo = new PICKED_ITEMS_LIST();
193 commandToUndo->SetDescription( aItemsList.GetDescription() );
194 }
195
196 saveCopyInUndoList( commandToUndo, aItemsList, aCommandType );
197}
198
199
201{
202 if( UndoRedoBlocked() )
203 return;
204
205 if( GetUndoCommandCount() <= 0 )
206 return;
207
208 // Inform tools that undo command was issued
210
211 // Get the old list
213
214 // Undo the command
216
217 // Put the old list in RedoList
219 PushCommandToRedoList( list );
220
221 OnModify();
222
225
226 GetCanvas()->Refresh();
227}
228
229
231{
232 if( UndoRedoBlocked() )
233 return;
234
235 if( GetRedoCommandCount() == 0 )
236 return;
237
238 // Inform tools that redo command was issued
240
241 // Get the old list
243
244 // Redo the command
246
247 // Put the old list in UndoList
249 PushCommandToUndoList( list );
250
251 OnModify();
252
255
256 GetCanvas()->Refresh();
257}
258
259
261{
262 bool not_found = false;
263 bool reBuild_ratsnest = false;
264 bool deep_reBuild_ratsnest = false; // true later if pointers must be rebuilt
265 bool solder_mask_dirty = false;
266
267 auto view = GetCanvas()->GetView();
268 auto connectivity = GetBoard()->GetConnectivity();
269
270 GetBoard()->IncrementTimeStamp(); // clear caches
271
272 // Enum to track the modification type of items. Used to enable bulk BOARD_LISTENER
273 // callbacks at the end of the undo / redo operation
274 enum ITEM_CHANGE_TYPE
275 {
276 ADDED,
277 DELETED,
278 CHANGED
279 };
280
281 std::unordered_map<EDA_ITEM*, ITEM_CHANGE_TYPE> item_changes;
282
283 auto update_item_change_state =
284 [&]( EDA_ITEM* item, ITEM_CHANGE_TYPE change_type )
285 {
286 auto item_itr = item_changes.find( item );
287
288 if( item_itr == item_changes.end() )
289 {
290 // First time we've seen this item - tag the current change type
291 item_changes.insert( { item, change_type } );
292 return;
293 }
294
295 // Update the item state based on the current and next change type
296 switch( item_itr->second )
297 {
298 case ITEM_CHANGE_TYPE::ADDED:
299 {
300 if( change_type == ITEM_CHANGE_TYPE::DELETED )
301 {
302 // The item was previously added, now deleted - as far as bulk callbacks
303 // are concerned, the item has never existed
304 item_changes.erase( item_itr );
305 }
306 else if( change_type == ITEM_CHANGE_TYPE::ADDED )
307 {
308 // Error condition - added an already added item
309 wxASSERT_MSG( false, wxT( "UndoRedo: should not add already added item" ) );
310 }
311
312 // For all other cases, the item remains as ADDED as seen by the bulk callbacks
313 break;
314 }
315 case ITEM_CHANGE_TYPE::DELETED:
316 {
317 // This is an error condition - item has already been deleted so should not
318 // be operated on further
319 wxASSERT_MSG( false, wxT( "UndoRedo: should not alter already deleted item" ) );
320 break;
321 }
322 case ITEM_CHANGE_TYPE::CHANGED:
323 {
324 if( change_type == ITEM_CHANGE_TYPE::DELETED )
325 {
326 item_itr->second = ITEM_CHANGE_TYPE::DELETED;
327 }
328 else if( change_type == ITEM_CHANGE_TYPE::ADDED )
329 {
330 // This is an error condition - item has already been changed so should not
331 // be added
332 wxASSERT_MSG( false,
333 wxT( "UndoRedo: should not add already changed item" ) );
334 }
335
336 // Otherwise, item remains CHANGED
337 break;
338 }
339 }
340 };
341
342 // Undo in the reverse order of list creation: (this can allow stacked changes
343 // like the same item can be changes and deleted in the same complex command
344
345 // Restore changes in reverse order
346 for( int ii = (int) aList->GetCount() - 1; ii >= 0 ; ii-- )
347 {
348 EDA_ITEM* eda_item = aList->GetPickedItem( (unsigned) ii );
349
350 /* Test for existence of item on board.
351 * It could be deleted, and no more on board:
352 * - if a call to SaveCopyInUndoList was forgotten in Pcbnew
353 * - in zones outlines, when a change in one zone merges this zone with an other
354 * This test avoids a Pcbnew crash
355 * Obviously, this test is not made for deleted items
356 */
357 UNDO_REDO status = aList->GetPickedItemStatus( ii );
358
359 if( status != UNDO_REDO::DELETED
360 && status != UNDO_REDO::REGROUP
361 && status != UNDO_REDO::UNGROUP
362 && status != UNDO_REDO::DRILLORIGIN // origin markers never on board
363 && status != UNDO_REDO::GRIDORIGIN // origin markers never on board
364 && status != UNDO_REDO::PAGESETTINGS ) // nor are page settings proxy items
365 {
366 if( GetBoard()->GetItem( eda_item->m_Uuid ) == DELETED_BOARD_ITEM::GetInstance() )
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 EDA_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 RECURSE_MODE::NO_RECURSE );
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( eda_item->IsBOARD_ITEM() )
510 {
511 BOARD_ITEM* boardItem = static_cast<BOARD_ITEM*>( eda_item );
512
513 if( EDA_GROUP* group = boardItem->GetParentGroup() )
514 {
515 aList->SetPickedItemGroupId( group->AsEdaItem()->m_Uuid, ii );
516
517 group->RemoveItem( boardItem );
518 }
519 }
520
521 break;
522
523 case UNDO_REDO::UNGROUP: /* ungrouped items are re-added to their previuos groups */
524 aList->SetPickedItemStatus( UNDO_REDO::REGROUP, ii );
525
526 if( eda_item->IsBOARD_ITEM() )
527 {
528 BOARD_ITEM* boardItem = static_cast<BOARD_ITEM*>( eda_item );
529
530 PCB_GROUP* group = dynamic_cast<PCB_GROUP*>(
531 GetBoard()->GetItem( aList->GetPickedItemGroupId( ii ) ) );
532
533 if( group )
534 group->AddItem( boardItem );
535 }
536
537 break;
538
539 case UNDO_REDO::DRILLORIGIN:
540 case UNDO_REDO::GRIDORIGIN:
541 {
542 // Warning: DRILLORIGIN and GRIDORIGIN undo/redo command create EDA_ITEMs
543 // that cannot be casted to BOARD_ITEMs
544 EDA_ITEM* image = aList->GetPickedItemLink( ii );
545 VECTOR2D origin = image->GetPosition();
546 image->SetPosition( eda_item->GetPosition() );
547
548 if( aList->GetPickedItemStatus( ii ) == UNDO_REDO::DRILLORIGIN )
549 BOARD_EDITOR_CONTROL::DoSetDrillOrigin( view, this, eda_item, origin );
550 else
551 PCB_CONTROL::DoSetGridOrigin( view, this, eda_item, origin );
552
553 break;
554 }
555
556 case UNDO_REDO::PAGESETTINGS:
557 {
558 // swap current settings with stored settings
559 DS_PROXY_UNDO_ITEM alt_item( this );
560 DS_PROXY_UNDO_ITEM* item = static_cast<DS_PROXY_UNDO_ITEM*>( eda_item );
561 item->Restore( this );
562 *item = std::move( alt_item );
563 break;
564 }
565
566 default:
567 wxFAIL_MSG( wxString::Format( wxT( "PutDataInPreviousState() error (unknown code %X)" ),
568 aList->GetPickedItemStatus( ii ) ) );
569 break;
570 }
571
572 if( eda_item->Type() == PCB_FOOTPRINT_T )
573 {
574 FOOTPRINT* fp = static_cast<FOOTPRINT*>( eda_item );
577 }
578 }
579
580 if( not_found )
581 wxMessageBox( _( "Incomplete undo/redo operation: some items not found" ) );
582
583 if( IsType( FRAME_PCB_EDITOR ) )
584 {
585 if( reBuild_ratsnest || deep_reBuild_ratsnest )
586 {
587 // Connectivity may have changed; rebuild internal caches to remove stale items
589 Compile_Ratsnest( false );
590 }
591
592 if( solder_mask_dirty )
594 }
595
597
599 selTool->RebuildSelection();
600
602
603 // Invoke bulk BOARD_LISTENER callbacks
604 std::vector<BOARD_ITEM*> added_items, deleted_items, changed_items;
605
606 for( auto& [item, changeType] : item_changes )
607 {
608 switch( changeType )
609 {
610 case ITEM_CHANGE_TYPE::ADDED:
611 added_items.push_back( static_cast<BOARD_ITEM*>( item ) );
612 break;
613
614 case ITEM_CHANGE_TYPE::DELETED:
615 deleted_items.push_back( static_cast<BOARD_ITEM*>( item ) );
616 break;
617
618 case ITEM_CHANGE_TYPE::CHANGED:
619 changed_items.push_back( static_cast<BOARD_ITEM*>( item ) );
620 break;
621 }
622 }
623
625
626 if( added_items.size() > 0 || deleted_items.size() > 0 || changed_items.size() > 0 )
627 GetBoard()->OnItemsCompositeUpdate( added_items, deleted_items, changed_items );
628}
629
630
632{
633 if( aItemCount == 0 )
634 return;
635
636 UNDO_REDO_CONTAINER& list = ( whichList == UNDO_LIST ) ? m_undoList : m_redoList;
637
638 if( aItemCount < 0 )
639 {
640 list.ClearCommandList();
641 }
642 else
643 {
644 for( int ii = 0; ii < aItemCount; ii++ )
645 {
646 if( list.m_CommandsList.size() == 0 )
647 break;
648
649 PICKED_ITEMS_LIST* curr_cmd = list.m_CommandsList[0];
650 list.m_CommandsList.erase( list.m_CommandsList.begin() );
651 ClearListAndDeleteItems( curr_cmd );
652 delete curr_cmd; // Delete command
653 }
654 }
655}
656
657
659{
661 []( EDA_ITEM* item )
662 {
663 wxASSERT_MSG( item->HasFlag( UR_TRANSIENT ),
664 "Item on undo/redo list not owned by undo/redo!" );
665
666 if( item->IsBOARD_ITEM() )
667 static_cast<BOARD_ITEM*>( item )->SetParentGroup( nullptr );
668
669 delete item;
670 } );
671}
672
673
675{
679 delete undo;
680
681 GetCanvas()->Refresh();
682}
static EDA_ITEM * MakeImage(EDA_ITEM *aItem)
static void DoSetDrillOrigin(KIGFX::VIEW *aView, PCB_BASE_FRAME *aFrame, EDA_ITEM *aItem, const VECTOR2D &aPoint)
Abstract interface for BOARD_ITEMs capable of storing other items inside.
virtual void Remove(BOARD_ITEM *aItem, REMOVE_MODE aMode=REMOVE_MODE::NORMAL)=0
Removes an item from the container.
virtual void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT, bool aSkipConnectivity=false)=0
Adds an item to the container.
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition: board_item.h:78
void SwapItemData(BOARD_ITEM *aImage)
Swap data between aItem and aImage.
Definition: board_item.cpp:226
FOOTPRINT * GetParentFootprint() const
Definition: board_item.cpp:299
BOARD_ITEM * GetItem(const KIID &aID) const
Definition: board.cpp:1510
void SanitizeNetcodes()
Definition: board.cpp:2700
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:194
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:2747
void IncrementTimeStamp()
Definition: board.cpp:262
COMPONENT_CLASS_MANAGER & GetComponentClassManager()
Gets the component class manager.
Definition: board.h:1298
std::shared_ptr< CONNECTIVITY_DATA > GetConnectivity() const
Return a list of missing connections between components/tracks.
Definition: board.h:495
void InvalidateComponentClasses()
Invalidates any caches component classes and recomputes caches if required.
void RebuildRequiredCaches(FOOTPRINT *aFootprint=nullptr) const
Rebuilds any caches that may be required by custom assignment rules.
static DELETED_BOARD_ITEM * GetInstance()
Definition: board_item.h:482
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:45
virtual bool RemoveItem(EDA_ITEM *aItem)=0
Remove item from group.
virtual bool AddItem(EDA_ITEM *aItem)=0
Add item to group.
A base class for most all the KiCad significant classes used in schematics and boards.
Definition: eda_item.h:96
virtual VECTOR2I GetPosition() const
Definition: eda_item.h:255
void SetFlags(EDA_ITEM_FLAGS aMask)
Definition: eda_item.h:138
const KIID m_Uuid
Definition: eda_item.h:501
virtual EDA_GROUP * GetParentGroup() const
Definition: eda_item.h:114
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:108
void ClearFlags(EDA_ITEM_FLAGS aMask=EDA_ITEM_ALL_FLAGS)
Definition: eda_item.h:140
virtual void SetParentGroup(EDA_GROUP *aGroup)
Definition: eda_item.h:113
bool HasFlag(EDA_ITEM_FLAGS aFlag) const
Definition: eda_item.h:142
static const TOOL_EVENT UndoRedoPreEvent
Definition: actions.h:360
static const TOOL_EVENT SelectedItemsModified
Selected items were moved, this can be very high frequency on the canvas, use with care.
Definition: actions.h:344
static const TOOL_EVENT UndoRedoPostEvent
Definition: actions.h:361
void InvalidateComponentClassCache() const
Forces deferred (on next access) recalculation of the component class for this footprint.
Definition: footprint.cpp:4089
bool IsBOARD_ITEM() const
Definition: view_item.h:102
LSET is a set of PCB_LAYER_IDs.
Definition: lset.h:37
static TOOL_ACTION rehatchShapes
Definition: pcb_actions.h:374
void ClearUndoORRedoList(UNDO_REDO_LIST whichList, int aItemCount=-1) override
Free the undo or redo list from List element.
Definition: undo_redo.cpp:631
void RestoreCopyFromUndoList(wxCommandEvent &aEvent)
Undo the last edit:
Definition: undo_redo.cpp:200
void saveCopyInUndoList(PICKED_ITEMS_LIST *commandToUndo, const PICKED_ITEMS_LIST &aItemsList, UNDO_REDO aCommandType)
Definition: undo_redo.cpp:102
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:185
void SaveCopyInUndoList(EDA_ITEM *aItemToCopy, UNDO_REDO aTypeCommand) override
Create a new entry in undo list of commands.
Definition: undo_redo.cpp:165
void ClearListAndDeleteItems(PICKED_ITEMS_LIST *aList)
Definition: undo_redo.cpp:658
void RollbackFromUndo()
Perform an undo of the last edit without logging a corresponding redo.
Definition: undo_redo.cpp:674
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:260
void RestoreCopyFromRedoList(wxCommandEvent &aEvent)
Redo the last edit:
Definition: undo_redo.cpp:230
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: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
ITEM_PICKER GetItemWrapper(unsigned int aIdx) const
EDA_ITEM * GetPickedItemLink(unsigned int aIdx) const
wxString GetDescription() const
bool RemovePicker(unsigned aIdx)
Remove one entry (one picker) from the list of picked items.
KIID GetPickedItemGroupId(unsigned int aIdx) const
unsigned GetCount() const
void ReversePickersListOrder()
Reverse the order of pickers stored in this list.
bool SetPickedItemLink(EDA_ITEM *aLink, unsigned aIdx)
Set the link associated to a given picked item.
void ClearListAndDeleteItems(std::function< void(EDA_ITEM *)> aItemDeleter)
Delete the list of pickers AND the data pointed by #m_PickedItem or #m_PickedItemLink according to th...
bool SetPickedItemGroupId(KIID aId, unsigned aIdx)
Set the group id associated to a given picked item.
EDA_ITEM * GetPickedItem(unsigned int aIdx) const
TOOL_MANAGER * m_toolManager
Definition: tools_holder.h:171
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
#define _(s)
#define UR_TRANSIENT
indicates the item is owned by the undo/redo stack
@ FRAME_PCB_EDITOR
Definition: frame_type.h:42
@ B_Mask
Definition: layer_ids.h:98
@ F_Mask
Definition: layer_ids.h:97
This file contains miscellaneous commonly used macros and functions.
#define KI_FALLTHROUGH
The KI_FALLTHROUGH macro is to be used when switch statement cases should purposely fallthrough from ...
Definition: macros.h:83
Class to handle a set of BOARD_ITEMs.
@ AS_GLOBAL
Global action (toolbar/main menu event, global shortcut)
Definition: tool_action.h:49
@ TA_UNDO_REDO_PRE
This event is sent before undo/redo command is performed.
Definition: tool_event.h:106
@ TA_UNDO_REDO_POST
This event is sent after undo/redo command is performed.
Definition: tool_event.h:109
@ TC_MESSAGE
Definition: tool_event.h:58
@ PCB_SHAPE_T
class PCB_SHAPE, a segment not on copper layers
Definition: typeinfo.h:88
@ PCB_VIA_T
class PCB_VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:97
@ PCB_ZONE_T
class ZONE, a copper pour area
Definition: typeinfo.h:107
@ PCB_FOOTPRINT_T
class FOOTPRINT, a footprint
Definition: typeinfo.h:86
@ PCB_PAD_T
class PAD, a pad in a footprint
Definition: typeinfo.h:87
@ PCB_ARC_T
class PCB_ARC, an arc track segment on a copper layer
Definition: typeinfo.h:98
@ PCB_NETINFO_T
class NETINFO_ITEM, a description of a net
Definition: typeinfo.h:109
@ PCB_TRACE_T
class PCB_TRACK, a track segment (segment on a copper layer)
Definition: typeinfo.h:96
UNDO_REDO
Undo Redo considerations: Basically we have 3 cases New item Deleted item Modified item there is also...