Make sure group items get added to commit.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/16705
This commit is contained in:
Jeff Young 2024-01-22 23:32:13 +00:00
parent 92ed389ad2
commit d47a000564
6 changed files with 35 additions and 35 deletions

View File

@ -198,7 +198,8 @@ public:
* Invoke a function on all descendants. * Invoke a function on all descendants.
* @note This function should not add or remove items. * @note This function should not add or remove items.
*/ */
virtual void RunOnDescendants( const std::function<void ( BOARD_ITEM* )>& aFunction ) const { } virtual void RunOnDescendants( const std::function<void ( BOARD_ITEM* )>& aFunction,
int aDepth = 0 ) const { }
BOARD_ITEM_CONTAINER* GetParent() const { return (BOARD_ITEM_CONTAINER*) m_parent; } BOARD_ITEM_CONTAINER* GetParent() const { return (BOARD_ITEM_CONTAINER*) m_parent; }

View File

@ -1724,8 +1724,13 @@ void FOOTPRINT::RunOnChildren( const std::function<void ( BOARD_ITEM* )>& aFunct
} }
void FOOTPRINT::RunOnDescendants( const std::function<void( BOARD_ITEM* )>& aFunction ) const void FOOTPRINT::RunOnDescendants( const std::function<void( BOARD_ITEM* )>& aFunction,
int aDepth ) const
{ {
// Avoid freezes with infinite recursion
if( aDepth > 20 )
return;
try try
{ {
for( PCB_FIELD* field : m_fields ) for( PCB_FIELD* field : m_fields )
@ -1740,13 +1745,13 @@ void FOOTPRINT::RunOnDescendants( const std::function<void( BOARD_ITEM* )>& aFun
for( PCB_GROUP* group : m_groups ) for( PCB_GROUP* group : m_groups )
{ {
aFunction( group ); aFunction( group );
group->RunOnDescendants( aFunction ); group->RunOnDescendants( aFunction, aDepth + 1 );
} }
for( BOARD_ITEM* drawing : m_drawings ) for( BOARD_ITEM* drawing : m_drawings )
{ {
aFunction( drawing ); aFunction( drawing );
drawing->RunOnDescendants( aFunction ); drawing->RunOnDescendants( aFunction, aDepth + 1 );
} }
} }
catch( std::bad_function_call& ) catch( std::bad_function_call& )

View File

@ -831,7 +831,8 @@ public:
void RunOnChildren( const std::function<void (BOARD_ITEM*)>& aFunction ) const override; void RunOnChildren( const std::function<void (BOARD_ITEM*)>& aFunction ) const override;
///< @copydoc BOARD_ITEM::RunOnDescendants ///< @copydoc BOARD_ITEM::RunOnDescendants
void RunOnDescendants( const std::function<void( BOARD_ITEM* )>& aFunction ) const override; void RunOnDescendants( const std::function<void( BOARD_ITEM* )>& aFunction,
int aDepth = 0 ) const override;
virtual void ViewGetLayers( int aLayers[], int& aCount ) const override; virtual void ViewGetLayers( int aLayers[], int& aCount ) const override;

View File

@ -179,22 +179,6 @@ void PCB_GROUP::SetPosition( const VECTOR2I& aNewpos )
} }
void PCB_GROUP::SetLayerRecursive( PCB_LAYER_ID aLayer, int aDepth )
{
for( BOARD_ITEM* item : m_items )
{
if( ( item->Type() == PCB_GROUP_T ) && ( aDepth > 0 ) )
{
static_cast<PCB_GROUP*>( item )->SetLayerRecursive( aLayer, aDepth - 1 );
}
else
{
item->SetLayer( aLayer );
}
}
}
void PCB_GROUP::SetLocked( bool aLockState ) void PCB_GROUP::SetLocked( bool aLockState )
{ {
BOARD_ITEM::SetLocked( aLockState ); BOARD_ITEM::SetLocked( aLockState );
@ -417,8 +401,13 @@ void PCB_GROUP::RunOnChildren( const std::function<void( BOARD_ITEM* )>& aFuncti
} }
void PCB_GROUP::RunOnDescendants( const std::function<void( BOARD_ITEM* )>& aFunction ) const void PCB_GROUP::RunOnDescendants( const std::function<void( BOARD_ITEM* )>& aFunction,
int aDepth ) const
{ {
// Avoid freezes with infinite recursion
if( aDepth > 20 )
return;
try try
{ {
for( BOARD_ITEM* item : m_items ) for( BOARD_ITEM* item : m_items )
@ -426,7 +415,7 @@ void PCB_GROUP::RunOnDescendants( const std::function<void( BOARD_ITEM* )>& aFun
aFunction( item ); aFunction( item );
if( item->Type() == PCB_GROUP_T ) if( item->Type() == PCB_GROUP_T )
item->RunOnDescendants( aFunction ); item->RunOnDescendants( aFunction, aDepth + 1 );
} }
} }
catch( std::bad_function_call& ) catch( std::bad_function_call& )

View File

@ -125,7 +125,7 @@ public:
/// @copydoc BOARD_ITEM::SetLayer /// @copydoc BOARD_ITEM::SetLayer
void SetLayer( PCB_LAYER_ID aLayer ) override void SetLayer( PCB_LAYER_ID aLayer ) override
{ {
wxFAIL_MSG( wxT( "groups don't support layer SetLayer" ) ); // NOP
} }
bool IsOnCopperLayer() const override bool IsOnCopperLayer() const override
@ -134,12 +134,6 @@ public:
return false; return false;
} }
/** Set layer for all items within the group.
*
* To avoid freezes with circular references, the maximum depth is 20 by default.
*/
void SetLayerRecursive( PCB_LAYER_ID aLayer, int aDepth );
void SetLocked( bool aLocked ) override; void SetLocked( bool aLocked ) override;
/// @copydoc EDA_ITEM::Clone /// @copydoc EDA_ITEM::Clone
@ -203,7 +197,8 @@ public:
void RunOnChildren( const std::function<void ( BOARD_ITEM* )>& aFunction ) const override; void RunOnChildren( const std::function<void ( BOARD_ITEM* )>& aFunction ) const override;
///< @copydoc BOARD_ITEM::RunOnDescendants ///< @copydoc BOARD_ITEM::RunOnDescendants
void RunOnDescendants( const std::function<void( BOARD_ITEM* )>& aFunction ) const override; void RunOnDescendants( const std::function<void( BOARD_ITEM* )>& aFunction,
int aDepth = 0 ) const override;
/** /**
* Check if the proposed type can be added to a group * Check if the proposed type can be added to a group

View File

@ -638,10 +638,13 @@ int DRAWING_TOOL::InteractivePlaceWithPreview( const TOOL_EVENT& aEvent,
for( BOARD_ITEM* item : aItems ) for( BOARD_ITEM* item : aItems )
{ {
if( item->Type() == PCB_GROUP_T ) item->SetLayer( destLayer );
static_cast<PCB_GROUP*>( item )->SetLayerRecursive( destLayer, 200 );
else item->RunOnDescendants(
item->SetLayer( destLayer ); [&]( BOARD_ITEM* descendant )
{
descendant->SetLayer( destLayer );
} );
} }
} }
@ -649,6 +652,12 @@ int DRAWING_TOOL::InteractivePlaceWithPreview( const TOOL_EVENT& aEvent,
{ {
item->Move( cursorPosition ); item->Move( cursorPosition );
commit.Add( item ); commit.Add( item );
item->RunOnDescendants(
[&]( BOARD_ITEM* descendant )
{
commit.Add( descendant );
} );
} }
commit.Push( wxT( "Placing items" ) ); commit.Push( wxT( "Placing items" ) );