Re-implement undo/redo of group ops in a pointer-safe way.
This commit is contained in:
parent
92c8ed2943
commit
44af3978af
|
@ -69,7 +69,9 @@ enum class UNDO_REDO {
|
|||
// data structure is insufficient to restore the change.
|
||||
DRILLORIGIN, // origin changed (like CHANGED, contains the origin and a copy)
|
||||
GRIDORIGIN, // origin changed (like CHANGED, contains the origin and a copy)
|
||||
PAGESETTINGS // page settings or title block changes
|
||||
PAGESETTINGS, // page settings or title block changes
|
||||
GROUP,
|
||||
UNGROUP
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -223,7 +223,6 @@ void BOARD_COMMIT::Push( const wxString& aMessage, bool aCreateUndoEntry, bool a
|
|||
case PCB_DIM_LEADER_T: // a leader dimension
|
||||
case PCB_TARGET_T: // a target (graphic item)
|
||||
case PCB_MARKER_T: // a marker used to show something
|
||||
case PCB_GROUP_T: // a group of items
|
||||
case PCB_ZONE_AREA_T:
|
||||
view->Remove( boardItem );
|
||||
|
||||
|
@ -248,6 +247,7 @@ void BOARD_COMMIT::Push( const wxString& aMessage, bool aCreateUndoEntry, bool a
|
|||
|
||||
// Metadata items
|
||||
case PCB_NETINFO_T:
|
||||
case PCB_GROUP_T:
|
||||
if( !( changeFlags & CHT_DONE ) )
|
||||
board->Remove( boardItem );
|
||||
break;
|
||||
|
|
|
@ -1007,18 +1007,23 @@ int PCB_EDITOR_CONTROL::Group( const TOOL_EVENT& aEvent )
|
|||
SELECTION_TOOL* selTool = m_toolMgr->GetTool<SELECTION_TOOL>();
|
||||
const PCBNEW_SELECTION& selection = selTool->GetSelection();
|
||||
BOARD* board = getModel<BOARD>();
|
||||
BOARD_COMMIT commit( m_frame );
|
||||
PICKED_ITEMS_LIST undoList;
|
||||
|
||||
if( selection.Empty() )
|
||||
m_toolMgr->RunAction( PCB_ACTIONS::selectionCursor, true );
|
||||
|
||||
PCB_GROUP* group = new PCB_GROUP( board );
|
||||
board->Add( group );
|
||||
|
||||
undoList.PushItem( ITEM_PICKER( nullptr, group, UNDO_REDO::NEWITEM ) );
|
||||
|
||||
for( EDA_ITEM* item : selection )
|
||||
{
|
||||
group->AddItem( static_cast<BOARD_ITEM*>( item ) );
|
||||
undoList.PushItem( ITEM_PICKER( nullptr, item, UNDO_REDO::GROUP ) );
|
||||
}
|
||||
|
||||
commit.Add( group );
|
||||
commit.Push( _( "Group Items" ) );
|
||||
m_frame->SaveCopyInUndoList( undoList, UNDO_REDO::GROUP );
|
||||
|
||||
selTool->ClearSelection();
|
||||
selTool->select( group );
|
||||
|
@ -1032,16 +1037,15 @@ int PCB_EDITOR_CONTROL::Group( const TOOL_EVENT& aEvent )
|
|||
|
||||
int PCB_EDITOR_CONTROL::Ungroup( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
SELECTION_TOOL* selTool = m_toolMgr->GetTool<SELECTION_TOOL>();
|
||||
const PCBNEW_SELECTION& selection = selTool->GetSelection();
|
||||
BOARD_COMMIT commit( m_frame );
|
||||
const PCBNEW_SELECTION& selection = m_toolMgr->GetTool<SELECTION_TOOL>()->GetSelection();
|
||||
PICKED_ITEMS_LIST undoList;
|
||||
std::vector<BOARD_ITEM*> members;
|
||||
|
||||
if( selection.Empty() )
|
||||
m_toolMgr->RunAction( PCB_ACTIONS::selectionCursor, true );
|
||||
|
||||
PCBNEW_SELECTION selCopy = selection;
|
||||
|
||||
selTool->ClearSelection();
|
||||
m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true );
|
||||
|
||||
for( EDA_ITEM* item : selCopy )
|
||||
{
|
||||
|
@ -1050,14 +1054,22 @@ int PCB_EDITOR_CONTROL::Ungroup( const TOOL_EVENT& aEvent )
|
|||
if( group )
|
||||
{
|
||||
for( BOARD_ITEM* member : group->GetItems() )
|
||||
selTool->select( member );
|
||||
{
|
||||
undoList.PushItem( ITEM_PICKER( nullptr, member, UNDO_REDO::UNGROUP ) );
|
||||
members.push_back( member );
|
||||
}
|
||||
|
||||
group->RemoveAll();
|
||||
commit.Remove( group );
|
||||
m_frame->GetBoard()->Remove( group );
|
||||
|
||||
group->SetSelected();
|
||||
undoList.PushItem( ITEM_PICKER( nullptr, group, UNDO_REDO::DELETED ) );
|
||||
}
|
||||
}
|
||||
|
||||
commit.Push( "Ungroup Items" );
|
||||
m_frame->SaveCopyInUndoList( undoList, UNDO_REDO::UNGROUP );
|
||||
|
||||
m_toolMgr->RunAction( PCB_ACTIONS::selectItems, true, &members );
|
||||
|
||||
m_toolMgr->PostEvent( EVENTS::SelectedItemsModified );
|
||||
m_frame->OnModify();
|
||||
|
|
|
@ -160,6 +160,7 @@ static bool TestForExistingItem( BOARD* aPcb, BOARD_ITEM* aItem )
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
static void SwapItemData( BOARD_ITEM* aItem, BOARD_ITEM* aImage )
|
||||
{
|
||||
if( aImage == NULL )
|
||||
|
@ -181,6 +182,7 @@ static void SwapItemData( BOARD_ITEM* aItem, BOARD_ITEM* aImage )
|
|||
aItem->SetParent( parent );
|
||||
}
|
||||
|
||||
|
||||
void PCB_BASE_EDIT_FRAME::SaveCopyInUndoList( EDA_ITEM* aItem, UNDO_REDO aCommandType,
|
||||
const wxPoint& aTransformPoint )
|
||||
{
|
||||
|
@ -303,6 +305,8 @@ void PCB_BASE_EDIT_FRAME::SaveCopyInUndoList( const PICKED_ITEMS_LIST& aItemsLis
|
|||
case UNDO_REDO::NEWITEM:
|
||||
case UNDO_REDO::DELETED:
|
||||
case UNDO_REDO::PAGESETTINGS:
|
||||
case UNDO_REDO::GROUP:
|
||||
case UNDO_REDO::UNGROUP:
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -400,6 +404,8 @@ void PCB_BASE_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool
|
|||
auto view = GetCanvas()->GetView();
|
||||
auto connectivity = GetBoard()->GetConnectivity();
|
||||
|
||||
PCB_GROUP* group = nullptr;
|
||||
|
||||
// Undo in the reverse order of list creation: (this can allow stacked changes
|
||||
// like the same item can be changes and deleted in the same complex command
|
||||
|
||||
|
@ -488,7 +494,7 @@ void PCB_BASE_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool
|
|||
aList->SetPickedItemStatus( UNDO_REDO::DELETED, ii );
|
||||
GetModel()->Remove( (BOARD_ITEM*) eda_item );
|
||||
|
||||
if( eda_item->Type() != PCB_NETINFO_T )
|
||||
if( eda_item->Type() != PCB_NETINFO_T && eda_item->Type() != PCB_GROUP_T )
|
||||
view->Remove( eda_item );
|
||||
|
||||
break;
|
||||
|
@ -497,9 +503,20 @@ void PCB_BASE_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool
|
|||
aList->SetPickedItemStatus( UNDO_REDO::NEWITEM, ii );
|
||||
GetModel()->Add( (BOARD_ITEM*) eda_item );
|
||||
|
||||
if( eda_item->Type() != PCB_NETINFO_T )
|
||||
if( eda_item->Type() != PCB_NETINFO_T && eda_item->Type() != PCB_GROUP_T )
|
||||
view->Add( eda_item );
|
||||
|
||||
if( eda_item->Type() == PCB_GROUP_T )
|
||||
group = static_cast<PCB_GROUP*>( eda_item );
|
||||
|
||||
break;
|
||||
|
||||
case UNDO_REDO::GROUP:
|
||||
static_cast<BOARD_ITEM*>( eda_item )->SetParentGroup( nullptr );
|
||||
break;
|
||||
|
||||
case UNDO_REDO::UNGROUP:
|
||||
group->AddItem( static_cast<BOARD_ITEM*>( eda_item ) );
|
||||
break;
|
||||
|
||||
case UNDO_REDO::MOVED:
|
||||
|
|
Loading…
Reference in New Issue