diff --git a/include/undo_redo_container.h b/include/undo_redo_container.h index 941eabe797..5cb038a77d 100644 --- a/include/undo_redo_container.h +++ b/include/undo_redo_container.h @@ -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 }; diff --git a/pcbnew/board_commit.cpp b/pcbnew/board_commit.cpp index 6402908820..17f5fd05fd 100644 --- a/pcbnew/board_commit.cpp +++ b/pcbnew/board_commit.cpp @@ -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; diff --git a/pcbnew/tools/pcb_editor_control.cpp b/pcbnew/tools/pcb_editor_control.cpp index b4c4d8c6ba..3d73483b02 100644 --- a/pcbnew/tools/pcb_editor_control.cpp +++ b/pcbnew/tools/pcb_editor_control.cpp @@ -1007,18 +1007,23 @@ int PCB_EDITOR_CONTROL::Group( const TOOL_EVENT& aEvent ) SELECTION_TOOL* selTool = m_toolMgr->GetTool(); const PCBNEW_SELECTION& selection = selTool->GetSelection(); BOARD* board = getModel(); - 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( 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(); - const PCBNEW_SELECTION& selection = selTool->GetSelection(); - BOARD_COMMIT commit( m_frame ); + const PCBNEW_SELECTION& selection = m_toolMgr->GetTool()->GetSelection(); + PICKED_ITEMS_LIST undoList; + std::vector 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(); diff --git a/pcbnew/undo_redo.cpp b/pcbnew/undo_redo.cpp index 10d6f6e50e..15ab8d4ed8 100644 --- a/pcbnew/undo_redo.cpp +++ b/pcbnew/undo_redo.cpp @@ -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( eda_item ); + + break; + + case UNDO_REDO::GROUP: + static_cast( eda_item )->SetParentGroup( nullptr ); + break; + + case UNDO_REDO::UNGROUP: + group->AddItem( static_cast( eda_item ) ); break; case UNDO_REDO::MOVED: