More active tracking of undo/redo items.

This commit is contained in:
Jeff Young 2024-01-27 20:02:40 +00:00
parent 54b46c6968
commit 07cefa7883
3 changed files with 25 additions and 13 deletions

View File

@ -408,7 +408,7 @@ void BOARD_COMMIT::Push( const wxString& aMessage, int aCommitFlags )
if( !( aCommitFlags & SKIP_UNDO ) ) if( !( aCommitFlags & SKIP_UNDO ) )
{ {
ITEM_PICKER itemWrapper( nullptr, boardItem, UNDO_REDO::UNGROUP ); ITEM_PICKER itemWrapper( nullptr, boardItem, UNDO_REDO::UNGROUP );
itemWrapper.SetLink( group->Clone() ); itemWrapper.SetLink( MakeImage( group ) );
undoList.PushItem( itemWrapper ); undoList.PushItem( itemWrapper );
} }
@ -597,12 +597,20 @@ EDA_ITEM* BOARD_COMMIT::parentObject( EDA_ITEM* aItem ) const
EDA_ITEM* BOARD_COMMIT::makeImage( EDA_ITEM* aItem ) const EDA_ITEM* BOARD_COMMIT::makeImage( EDA_ITEM* aItem ) const
{
return MakeImage( aItem );
}
EDA_ITEM* BOARD_COMMIT::MakeImage( EDA_ITEM* aItem )
{ {
EDA_ITEM* clone = aItem->Clone(); EDA_ITEM* clone = aItem->Clone();
if( BOARD_ITEM* board_item = dynamic_cast<BOARD_ITEM*>( clone ) ) if( BOARD_ITEM* board_item = dynamic_cast<BOARD_ITEM*>( clone ) )
board_item->SetParentGroup( nullptr ); board_item->SetParentGroup( nullptr );
clone->SetFlags( UR_TRANSIENT );
return clone; return clone;
} }

View File

@ -65,6 +65,8 @@ public:
UNDO_REDO aModFlag = UNDO_REDO::UNSPECIFIED, UNDO_REDO aModFlag = UNDO_REDO::UNSPECIFIED,
BASE_SCREEN* aScreen = nullptr ) override; BASE_SCREEN* aScreen = nullptr ) override;
static EDA_ITEM* MakeImage( EDA_ITEM* aItem );
private: private:
EDA_ITEM* parentObject( EDA_ITEM* aItem ) const override; EDA_ITEM* parentObject( EDA_ITEM* aItem ) const override;

View File

@ -42,6 +42,7 @@ using namespace std::placeholders;
#include <tools/pcb_selection_tool.h> #include <tools/pcb_selection_tool.h>
#include <tools/pcb_control.h> #include <tools/pcb_control.h>
#include <tools/board_editor_control.h> #include <tools/board_editor_control.h>
#include <board_commit.h>
#include <drawing_sheet/ds_proxy_undo_item.h> #include <drawing_sheet/ds_proxy_undo_item.h>
#include <wx/msgdlg.h> #include <wx/msgdlg.h>
@ -124,17 +125,7 @@ void PCB_BASE_EDIT_FRAME::saveCopyInUndoList( PICKED_ITEMS_LIST* commandToUndo,
case UNDO_REDO::GRIDORIGIN: case UNDO_REDO::GRIDORIGIN:
// If we don't yet have a copy in the link, set one up // If we don't yet have a copy in the link, set one up
if( !commandToUndo->GetPickedItemLink( ii ) ) if( !commandToUndo->GetPickedItemLink( ii ) )
{ commandToUndo->SetPickedItemLink( BOARD_COMMIT::MakeImage( item ), ii );
// Warning: DRILLORIGIN and GRIDORIGIN undo/redo command create EDA_ITEMs
// that cannot be casted blindly to BOARD_ITEMs (a BOARD_ITEM is derived from a EDA_ITEM)
// Especially SetParentGroup() does not exist in EDA_ITEM
EDA_ITEM* clone = static_cast<EDA_ITEM*>( item->Clone() );
if( BOARD_ITEM* brdclone = dynamic_cast<BOARD_ITEM*>( clone ) )
brdclone->SetParentGroup( nullptr );
commandToUndo->SetPickedItemLink( clone, ii );
}
break; break;
@ -379,6 +370,9 @@ void PCB_BASE_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList )
item->SwapItemData( image ); item->SwapItemData( image );
eda_item->ClearFlags( UR_TRANSIENT );
image->SetFlags( UR_TRANSIENT );
if( PCB_GROUP* group = dynamic_cast<PCB_GROUP*>( item ) ) if( PCB_GROUP* group = dynamic_cast<PCB_GROUP*>( item ) )
{ {
group->RunOnChildren( [&]( BOARD_ITEM* child ) group->RunOnChildren( [&]( BOARD_ITEM* child )
@ -401,10 +395,15 @@ void PCB_BASE_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList )
if( eda_item->Type() != PCB_NETINFO_T ) if( eda_item->Type() != PCB_NETINFO_T )
view->Remove( eda_item ); view->Remove( eda_item );
eda_item->SetFlags( UR_TRANSIENT );
break; break;
case UNDO_REDO::DELETED: /* deleted items are put in List, as new items */ case UNDO_REDO::DELETED: /* deleted items are put in List, as new items */
aList->SetPickedItemStatus( UNDO_REDO::NEWITEM, ii ); aList->SetPickedItemStatus( UNDO_REDO::NEWITEM, ii );
eda_item->ClearFlags( UR_TRANSIENT );
GetModel()->Add( (BOARD_ITEM*) eda_item ); GetModel()->Add( (BOARD_ITEM*) eda_item );
if( eda_item->Type() != PCB_NETINFO_T ) if( eda_item->Type() != PCB_NETINFO_T )
@ -420,7 +419,7 @@ void PCB_BASE_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList )
if( PCB_GROUP* group = boardItem->GetParentGroup() ) if( PCB_GROUP* group = boardItem->GetParentGroup() )
{ {
if( !aList->GetPickedItemLink( ii ) ) if( !aList->GetPickedItemLink( ii ) )
aList->SetPickedItemLink( group->Clone(), ii ); aList->SetPickedItemLink( BOARD_COMMIT::MakeImage( group ), ii );
group->RemoveItem( boardItem ); group->RemoveItem( boardItem );
} }
@ -528,6 +527,9 @@ void PCB_BASE_EDIT_FRAME::ClearListAndDeleteItems( PICKED_ITEMS_LIST* aList )
aList->ClearListAndDeleteItems( aList->ClearListAndDeleteItems(
[]( EDA_ITEM* item ) []( EDA_ITEM* item )
{ {
wxASSERT_MSG( item->HasFlag( UR_TRANSIENT ),
"Item on undo/redo list not owned by undo/redo!" );
if( BOARD_ITEM* boardItem = dynamic_cast<BOARD_ITEM*>( item ) ) if( BOARD_ITEM* boardItem = dynamic_cast<BOARD_ITEM*>( item ) )
boardItem->SetParentGroup( nullptr ); boardItem->SetParentGroup( nullptr );