Stage/add/delete group members when adding/deleting group.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/16540
This commit is contained in:
Jeff Young 2024-01-07 12:57:22 +00:00
parent f795e40584
commit cd83dfa831
5 changed files with 59 additions and 33 deletions

View File

@ -173,12 +173,19 @@ void ARRAY_CREATOR::Invoke()
this_item->ClearSelected();
this_item->RunOnDescendants(
[&]( BOARD_ITEM* aItem )
[]( BOARD_ITEM* aItem )
{
aItem->ClearSelected();
});
} );
TransformItem( *array_opts, ptN, *this_item );
this_item->RunOnDescendants(
[&]( BOARD_ITEM* aItem )
{
commit.Add( aItem );
} );
commit.Add( this_item );
}
}

View File

@ -2210,8 +2210,23 @@ BOARD_ITEM* FOOTPRINT::DuplicateItem( const BOARD_ITEM* aItem, bool aAddToFootpr
}
case PCB_GROUP_T:
new_item = static_cast<const PCB_GROUP*>( aItem )->DeepDuplicate();
{
PCB_GROUP* group = static_cast<const PCB_GROUP*>( aItem )->DeepDuplicate();
if( aAddToFootprint )
{
group->RunOnDescendants(
[&]( BOARD_ITEM* aItem )
{
Add( aItem );
} );
Add( new_item );
}
new_item = group;
break;
}
case PCB_FOOTPRINT_T:
// Ignore the footprint itself

View File

@ -2135,8 +2135,17 @@ void EDIT_TOOL::DeleteItems( const PCB_SELECTION& aItems, bool aIsCut )
break;
case PCB_GROUP_T:
for( BOARD_ITEM* member : static_cast<PCB_GROUP*>( board_item )->GetItems() )
commit.Stage( member, CHT_UNGROUP );
board_item->RunOnDescendants(
[&commit]( BOARD_ITEM* aItem )
{
commit.Stage( aItem, CHT_UNGROUP );
} );
board_item->RunOnDescendants(
[&commit]( BOARD_ITEM* aItem )
{
commit.Remove( aItem );
} );
commit.Remove( board_item );
break;
@ -2409,20 +2418,6 @@ int EDIT_TOOL::Duplicate( const TOOL_EVENT& aEvent )
sTool->FilterCollectorForFreePads( aCollector, true );
sTool->FilterCollectorForMarkers( aCollector );
sTool->FilterCollectorForHierarchy( aCollector, true );
// Iterate from the back so we don't have to worry about removals.
for( int i = aCollector.GetCount() - 1; i >= 0; --i )
{
BOARD_ITEM* item = aCollector[i];
if( item->Type() == PCB_GENERATOR_T )
{
// Could you duplicate something like a generated stitching pattern?
// Dunno. But duplicating a tuning pattern is a sure crash.
//
aCollector.Remove( item );
}
}
} );
if( selection.Empty() )
@ -2475,7 +2470,6 @@ int EDIT_TOOL::Duplicate( const TOOL_EVENT& aEvent )
case PCB_TEXT_T:
case PCB_TEXTBOX_T:
case PCB_REFERENCE_IMAGE_T:
case PCB_GENERATOR_T:
case PCB_SHAPE_T:
case PCB_TRACE_T:
case PCB_ARC_T:
@ -2488,10 +2482,30 @@ int EDIT_TOOL::Duplicate( const TOOL_EVENT& aEvent )
case PCB_DIM_ORTHOGONAL_T:
case PCB_DIM_LEADER_T:
dupe_item = orig_item->Duplicate();
// Clear the selection flag here, otherwise the PCB_SELECTION_TOOL
// will not properly select it later on
dupe_item->ClearSelected();
new_items.push_back( dupe_item );
commit.Add( dupe_item );
break;
case PCB_GENERATOR_T:
case PCB_GROUP_T:
dupe_item = static_cast<PCB_GROUP*>( orig_item )->DeepDuplicate();
dupe_item->RunOnDescendants(
[&]( BOARD_ITEM* aItem )
{
aItem->ClearSelected();
new_items.push_back( aItem );
commit.Add( aItem );
} );
dupe_item->ClearSelected();
new_items.push_back( dupe_item );
commit.Add( dupe_item );
break;
default:
@ -2500,16 +2514,6 @@ int EDIT_TOOL::Duplicate( const TOOL_EVENT& aEvent )
break;
}
}
if( dupe_item )
{
// Clear the selection flag here, otherwise the PCB_SELECTION_TOOL
// will not properly select it later on
dupe_item->ClearSelected();
new_items.push_back( dupe_item );
commit.Add( dupe_item );
}
}
// Clear the old selection first

View File

@ -142,12 +142,12 @@ public:
*/
int Remove( const TOOL_EVENT& aEvent );
void DeleteItems( const PCB_SELECTION& aItems, bool aIsCut );
void DeleteItems( const PCB_SELECTION& aItem, bool aIsCut );
/**
* Duplicate the current selection and starts a move action.
*/
int Duplicate( const TOOL_EVENT& aEvent );
int Duplicate( const TOOL_EVENT& aItem );
/**
* Invoke a dialog box to allow moving of the item by an exact amount.

View File

@ -1204,7 +1204,7 @@ bool PCB_CONTROL::placeBoardItems( BOARD_COMMIT* aCommit, std::vector<BOARD_ITEM
if( aReannotateDuplicates && m_isBoardEditor )
m_toolMgr->GetTool<BOARD_REANNOTATE_TOOL>()->ReannotateDuplicatesInSelection();
for( BOARD_ITEM* item : itemsToSel )
for( BOARD_ITEM* item : aItems )
{
if( aIsNew )
aCommit->Add( item );