schematic: add groups support to undo/redo/commit

This commit is contained in:
Mike Williams 2025-04-03 14:15:25 -04:00
parent fa02c70604
commit f483fcd2d9
2 changed files with 88 additions and 0 deletions

View File

@ -27,6 +27,7 @@
#include <lib_symbol.h>
#include <sch_group.h>
#include <sch_screen.h>
#include <schematic.h>
@ -81,6 +82,21 @@ COMMIT& SCH_COMMIT::Stage( EDA_ITEM *aItem, CHANGE_TYPE aChangeType, BASE_SCREEN
aChangeType = CHT_MODIFY;
}
// Many operations (move, rotate, etc.) are applied directly to a group's children, so they
// must be staged as well.
if( aChangeType == CHT_MODIFY )
{
if( SCH_GROUP* group = dynamic_cast<SCH_GROUP*>( aItem ) )
{
group->RunOnChildren(
[&]( EDA_ITEM* child )
{
Stage( child, aChangeType, aScreen );
},
RECURSE_MODE::NO_RECURSE );
}
}
// IS_SELECTED flag should not be set on undo items which were added for
// a drag operation.
if( aItem->IsSelected() && aItem->HasFlag( SELECTED_BY_DRAG ) )
@ -187,6 +203,7 @@ void SCH_COMMIT::pushSchEdit( const wxString& aMessage, int aCommitFlags )
bool dirtyConnectivity = false;
bool refreshHierarchy = false;
SCH_CLEANUP_FLAGS connectivityCleanUp = NO_CLEANUP;
SCH_GROUP* addedGroup = nullptr;
if( Empty() )
return;
@ -259,6 +276,9 @@ void SCH_COMMIT::pushSchEdit( const wxString& aMessage, int aCommitFlags )
view->Add( schItem );
}
if( schItem->Type() == SCH_GROUP_T )
addedGroup = static_cast<SCH_GROUP*>( schItem );
if( frame )
frame->UpdateItem( schItem, true, true );
@ -363,6 +383,32 @@ void SCH_COMMIT::pushSchEdit( const wxString& aMessage, int aCommitFlags )
break;
}
case CHT_UNGROUP:
if( EDA_GROUP* group = schItem->GetParentGroup() )
{
if( !( aCommitFlags & SKIP_UNDO ) )
{
ITEM_PICKER itemWrapper( nullptr, schItem, UNDO_REDO::UNGROUP );
itemWrapper.SetGroupId( group->AsEdaItem()->m_Uuid );
undoList.PushItem( itemWrapper );
}
group->RemoveItem( schItem );
}
break;
case CHT_GROUP:
if( addedGroup )
{
addedGroup->AddItem( schItem );
if( !( aCommitFlags & SKIP_UNDO ) )
undoList.PushItem( ITEM_PICKER( nullptr, schItem, UNDO_REDO::REGROUP ) );
}
break;
default:
wxASSERT( false );
break;

View File

@ -28,6 +28,7 @@
#include <schematic.h>
#include <sch_bus_entry.h>
#include <sch_commit.h>
#include <sch_group.h>
#include <sch_junction.h>
#include <sch_line.h>
#include <sch_bitmap.h>
@ -254,6 +255,8 @@ void SCH_EDIT_FRAME::SaveCopyInUndoList( const PICKED_ITEMS_LIST& aItemsList,
case UNDO_REDO::DELETED:
case UNDO_REDO::PAGESETTINGS:
case UNDO_REDO::REPEAT_ITEM:
case UNDO_REDO::REGROUP:
case UNDO_REDO::UNGROUP:
break;
default:
@ -387,6 +390,26 @@ void SCH_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList )
bulkAddedItems.emplace_back( schItem );
}
else if( status == UNDO_REDO::REGROUP ) /* grouped items are ungrouped */
{
aList->SetPickedItemStatus( UNDO_REDO::UNGROUP, ii );
if( EDA_GROUP* group = eda_item->GetParentGroup() )
{
aList->SetPickedItemGroupId( group->AsEdaItem()->m_Uuid, ii );
group->RemoveItem( eda_item );
}
}
else if( status == UNDO_REDO::UNGROUP ) /* ungrouped items are re-added to their previuos groups */
{
aList->SetPickedItemStatus( UNDO_REDO::REGROUP, ii );
EDA_GROUP* group = dynamic_cast<EDA_GROUP*>( Schematic().GetItem( aList->GetPickedItemGroupId( ii ) ) );
if( group )
group->AddItem( eda_item );
}
else if( status == UNDO_REDO::PAGESETTINGS )
{
if( GetCurrentSheet() != undoSheet )
@ -427,6 +450,8 @@ void SCH_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList )
wxCHECK2( itemCopy, continue );
EDA_GROUP* parentGroup = schItem->GetParentGroup();
if( schItem->HasConnectivityChanges( itemCopy, &GetCurrentSheet() ) )
propagateConnectivityDamage( schItem );
@ -460,7 +485,24 @@ void SCH_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList )
}
}
if( parentGroup )
parentGroup->RemoveItem( schItem );
schItem->SwapItemData( itemCopy );
if( SCH_GROUP* group = dynamic_cast<SCH_GROUP*>( schItem ) )
{
group->RunOnChildren( [&]( SCH_ITEM* child )
{
child->SetParentGroup( group );
},
RECURSE_MODE::NO_RECURSE );
}
if( parentGroup )
parentGroup->AddItem( schItem );
bulkChangedItems.emplace_back( schItem );
// Special cases for items which have instance data