Improve encapsulation of group internals.

(It's still leaking into BOARD_COMMIT and some other places, but at
least it no longer leaks into all the edit tools.)

Also fixes some bugs when moving/copying/pasting multiple selections
containing length-tuning patterns.
This commit is contained in:
Jeff Young 2023-11-09 13:55:00 +00:00
parent 78e00ade7a
commit cc721c4907
23 changed files with 153 additions and 298 deletions

View File

@ -64,11 +64,11 @@ void FOOTPRINT_DIFF_WIDGET::DisplayDiff( FOOTPRINT* aBoardFootprint,
m_boardItemCopy->ClearSelected();
m_boardItemCopy->ClearBrightened();
m_boardItemCopy->RunOnChildren(
[&]( BOARD_ITEM* child )
m_boardItemCopy->RunOnDescendants(
[&]( BOARD_ITEM* item )
{
child->ClearSelected();
child->ClearBrightened();
item->ClearSelected();
item->ClearBrightened();
} );
m_boardItemCopy->Move( -m_boardItemCopy->GetPosition() );
@ -103,10 +103,10 @@ void FOOTPRINT_DIFF_WIDGET::onSlider( wxScrollEvent& aEvent )
m_boardItemCopy->SetForcedTransparency( val );
m_boardItemCopy->RunOnChildren(
[&]( BOARD_ITEM* child )
m_boardItemCopy->RunOnDescendants(
[&]( BOARD_ITEM* item )
{
child->SetForcedTransparency( val );
item->SetForcedTransparency( val );
} );
}
@ -121,10 +121,10 @@ void FOOTPRINT_DIFF_WIDGET::onSlider( wxScrollEvent& aEvent )
m_libraryItem->SetForcedTransparency( val );
m_libraryItem->RunOnChildren(
[&]( BOARD_ITEM* child )
m_libraryItem->RunOnDescendants(
[&]( BOARD_ITEM* item )
{
child->SetForcedTransparency( val );
item->SetForcedTransparency( val );
} );
}

View File

@ -190,13 +190,16 @@ public:
/**
* Invoke a function on all children.
*
* @note This function should not add or remove items to the parent.
*
* @param aFunction is the function to be invoked.
*/
virtual void RunOnChildren( const std::function<void ( BOARD_ITEM* )>& aFunction ) const { }
/**
* Invoke a function on all descendants.
* @note This function should not add or remove items.
*/
virtual void RunOnDescendants( const std::function<void ( BOARD_ITEM* )>& aFunction ) const { }
BOARD_ITEM_CONTAINER* GetParent() const { return (BOARD_ITEM_CONTAINER*) m_parent; }
FOOTPRINT* GetParentFootprint() const;

View File

@ -196,35 +196,14 @@ public:
/// @copydoc EDA_ITEM::GetMenuImage
BITMAPS GetMenuImage() const override;
/**
* Add all the immediate children of this group to the board commit. This function does not
* enter any subgroups of this group, or add the group itself.
*
* @param aCommit is the commit to add the children to.
*/
void AddChildrenToCommit( BOARD_COMMIT& aCommit )
{
RunOnChildren( [&]( BOARD_ITEM* bItem )
{
aCommit.Add( bItem );
} );
}
/// @copydoc EDA_ITEM::GetMsgPanelInfo
void GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList ) override;
///< @copydoc BOARD_ITEM::RunOnChildren
void RunOnChildren( const std::function<void ( BOARD_ITEM* )>& aFunction ) const override;
/**
* Invoke a function on all descendants of the group.
*
* @note This function should not add or remove items to the group or descendant groups.
* @param aFunction is the function to be invoked.
*/
void RunOnDescendants( const std::function<void( BOARD_ITEM* )>& aFunction ) const;
///< @copydoc BOARD_ITEM::RunOnDescendants
void RunOnDescendants( const std::function<void( BOARD_ITEM* )>& aFunction ) const override;
/**
* Check if the proposed type can be added to a group

View File

@ -157,23 +157,11 @@ void ARRAY_CREATOR::Invoke()
// it this state, reset the selected stated of aItem:
this_item->ClearSelected();
if( this_item->Type() == PCB_GROUP_T )
{
static_cast<PCB_GROUP*>( this_item )->RunOnDescendants(
[&]( BOARD_ITEM* aItem )
{
aItem->ClearSelected();
commit.Add( aItem );
});
}
else if( this_item->Type() == PCB_FOOTPRINT_T )
{
static_cast<FOOTPRINT*>( this_item )->RunOnChildren(
[&]( BOARD_ITEM* aItem )
{
aItem->ClearSelected();
});
}
this_item->RunOnDescendants(
[&]( BOARD_ITEM* aItem )
{
aItem->ClearSelected();
});
TransformItem( *array_opts, ptN, *this_item );
commit.Add( this_item );

View File

@ -76,11 +76,11 @@ COMMIT& BOARD_COMMIT::Stage( EDA_ITEM* aItem, CHANGE_TYPE aChangeType, BASE_SCRE
{
wxCHECK( aItem, *this );
if( aChangeType == CHT_MODIFY && aItem->Type() == PCB_GROUP_T )
// Many operations (move, rotate, etc.) are applied directly to a group's children, so they
// must be staged as well.
if( PCB_GROUP* group = dynamic_cast<PCB_GROUP*>( aItem ) )
{
// Many operations on group (move, rotate, etc.) are applied directly to their
// children, so it's the children that must be staged.
static_cast<PCB_GROUP*>( aItem )->RunOnChildren(
group->RunOnChildren(
[&]( BOARD_ITEM* child )
{
COMMIT::Stage( child, aChangeType );
@ -305,6 +305,9 @@ void BOARD_COMMIT::Push( const wxString& aMessage, int aCommitFlags )
switch( boardItem->Type() )
{
case PCB_FIELD_T:
static_cast<PCB_FIELD*>( boardItem )->SetVisible( false );
break;
case PCB_TEXT_T:
case PCB_PAD_T:
case PCB_SHAPE_T: // a shape (normally not on copper layers)

View File

@ -83,12 +83,6 @@ bool DIALOG_GROUP_PROPERTIES::TransferDataFromWindow()
BOARD_COMMIT commit( m_brdEditor );
commit.Modify( m_group );
m_group->RunOnDescendants(
[&]( BOARD_ITEM* descendant )
{
commit.Modify( descendant );
} );
for( size_t ii = 0; ii < m_membersList->GetCount(); ++ii )
{
BOARD_ITEM* item = static_cast<BOARD_ITEM*>( m_membersList->GetClientData( ii ) );

View File

@ -1695,24 +1695,24 @@ EDA_ITEM* FOOTPRINT::Clone() const
}
void FOOTPRINT::RunOnChildren( const std::function<void ( BOARD_ITEM*)>& aFunction ) const
void FOOTPRINT::RunOnChildren( const std::function<void ( BOARD_ITEM* )>& aFunction ) const
{
try
{
for( PCB_FIELD* field : m_fields )
aFunction( static_cast<PCB_FIELD*>( field ) );
aFunction( field );
for( PAD* pad : m_pads )
aFunction( static_cast<BOARD_ITEM*>( pad ) );
aFunction( pad );
for( ZONE* zone : m_zones )
aFunction( static_cast<ZONE*>( zone ) );
aFunction( zone );
for( PCB_GROUP* group : m_groups )
aFunction( static_cast<PCB_GROUP*>( group ) );
aFunction( group );
for( BOARD_ITEM* drawing : m_drawings )
aFunction( static_cast<BOARD_ITEM*>( drawing ) );
aFunction( drawing );
}
catch( std::bad_function_call& )
{
@ -1721,6 +1721,38 @@ void FOOTPRINT::RunOnChildren( const std::function<void ( BOARD_ITEM*)>& aFuncti
}
void FOOTPRINT::RunOnDescendants( const std::function<void( BOARD_ITEM* )>& aFunction ) const
{
try
{
for( PCB_FIELD* field : m_fields )
aFunction( field );
for( PAD* pad : m_pads )
aFunction( pad );
for( ZONE* zone : m_zones )
aFunction( zone );
for( PCB_GROUP* group : m_groups )
{
aFunction( group );
group->RunOnDescendants( aFunction );
}
for( BOARD_ITEM* drawing : m_drawings )
{
aFunction( drawing );
drawing->RunOnDescendants( aFunction );
}
}
catch( std::bad_function_call& )
{
wxFAIL_MSG( wxT( "Error running FOOTPRINT::RunOnDescendants" ) );
}
}
void FOOTPRINT::ViewGetLayers( int aLayers[], int& aCount ) const
{
aCount = 2;
@ -2063,10 +2095,10 @@ BOARD_ITEM* FOOTPRINT::Duplicate() const
{
FOOTPRINT* dupe = static_cast<FOOTPRINT*>( BOARD_ITEM::Duplicate() );
dupe->RunOnChildren( [&]( BOARD_ITEM* child )
{
const_cast<KIID&>( child->m_Uuid ) = KIID();
});
dupe->RunOnDescendants( [&]( BOARD_ITEM* child )
{
const_cast<KIID&>( child->m_Uuid ) = KIID();
});
return dupe;
}
@ -2755,17 +2787,14 @@ void FOOTPRINT::CheckNetTies( const std::function<void( const BOARD_ITEM* aItem,
for( BOARD_ITEM* item : m_drawings )
{
if( item->IsOnCopperLayer() )
{
copperItems.push_back( item );
}
else if( PCB_GROUP* group = dynamic_cast<PCB_GROUP*>( item ) )
{
group->RunOnDescendants( [&]( BOARD_ITEM* descendent )
{
if( descendent->IsOnCopperLayer() )
copperItems.push_back( descendent );
} );
}
item->RunOnDescendants(
[&]( BOARD_ITEM* descendent )
{
if( descendent->IsOnCopperLayer() )
copperItems.push_back( descendent );
} );
}
for( ZONE* zone : m_zones )

View File

@ -827,15 +827,12 @@ public:
EDA_ITEM* Clone() const override;
/**
* Invoke a function on all BOARD_ITEMs that belong to the footprint (pads, drawings, texts).
*
* @note This function should not add or remove items to the footprint.
*
* @param aFunction is the function to be invoked.
*/
///< @copydoc BOARD_ITEM::RunOnChildren
void RunOnChildren( const std::function<void (BOARD_ITEM*)>& aFunction ) const override;
///< @copydoc BOARD_ITEM::RunOnDescendants
void RunOnDescendants( const std::function<void( BOARD_ITEM* )>& aFunction ) const override;
virtual void ViewGetLayers( int aLayers[], int& aCount ) const override;
double ViewGetLOD( int aLayer, KIGFX::VIEW* aView ) const override;

View File

@ -894,7 +894,8 @@ bool FOOTPRINT_EDIT_FRAME::SaveFootprintToBoard( bool aAddNew )
};
fixUuid( const_cast<KIID&>( newFootprint->m_Uuid ) );
newFootprint->RunOnChildren(
newFootprint->RunOnDescendants(
[&]( BOARD_ITEM* aChild )
{
fixUuid( const_cast<KIID&>( aChild->m_Uuid ) );
@ -1311,7 +1312,7 @@ FOOTPRINT* PCB_BASE_FRAME::CreateNewFootprint( const wxString& aFootprintName,
if( footprint->GetValue().IsEmpty() )
footprint->SetValue( footprintName );
footprint->RunOnChildren(
footprint->RunOnDescendants(
[&]( BOARD_ITEM* aChild )
{
if( aChild->Type() == PCB_FIELD_T || aChild->Type() == PCB_TEXT_T )

View File

@ -127,6 +127,14 @@ public:
{
m_origin += aMoveVector;
m_end += aMoveVector;
PCB_GROUP::Move( aMoveVector );
if( m_baseLine )
m_baseLine->Move( aMoveVector );
if( m_baseLineCoupled )
m_baseLineCoupled->Move( aMoveVector );
}
void Rotate( const VECTOR2I& aRotCentre, const EDA_ANGLE& aAngle ) override

View File

@ -144,7 +144,7 @@ void CLIPBOARD_IO::SaveSelection( const PCB_SELECTION& aSelected, bool isFootpri
if( group )
{
static_cast<PCB_GROUP*>( clone )->RunOnDescendants(
clone->RunOnDescendants(
[&]( BOARD_ITEM* descendant )
{
// One cannot add an additional mandatory field to a given footprint:
@ -239,14 +239,9 @@ void CLIPBOARD_IO::SaveSelection( const PCB_SELECTION& aSelected, bool isFootpri
copy = static_cast<BOARD_ITEM*>( boardItem->Clone() );
}
auto prepItem = [&]( BOARD_ITEM* aItem )
{
aItem->SetLocked( false );
};
if( copy )
{
prepItem( copy );
copy->SetLocked( false );
// locate the reference point at (0, 0) in the copied items
copy->Move( -refPoint );
@ -255,11 +250,12 @@ void CLIPBOARD_IO::SaveSelection( const PCB_SELECTION& aSelected, bool isFootpri
if( copy->Type() == PCB_GROUP_T )
{
static_cast<PCB_GROUP*>( copy )->RunOnDescendants( prepItem );
static_cast<PCB_GROUP*>( copy )->RunOnDescendants( [&]( BOARD_ITEM* titem )
{
Format( titem, 1 );
} );
copy->RunOnDescendants(
[&]( BOARD_ITEM* titem )
{
titem->SetLocked( false );
Format( titem, 1 );
} );
}
copy->SetParentGroup( nullptr );

View File

@ -121,7 +121,7 @@ bool FOOTPRINT_EDIT_FRAME::LoadFootprintFromBoard( FOOTPRINT* aFootprint )
newFootprint->ClearFlags();
recordAndUpdateUuid( newFootprint );
newFootprint->RunOnChildren(
newFootprint->RunOnDescendants(
[&]( BOARD_ITEM* aItem )
{
if( aItem->Type() == PCB_PAD_T )

View File

@ -290,7 +290,7 @@ void PCB_BASE_FRAME::FocusOnItems( std::vector<BOARD_ITEM*> aItems, PCB_LAYER_ID
{
lastItem->ClearBrightened();
lastItem->RunOnChildren(
lastItem->RunOnDescendants(
[&]( BOARD_ITEM* child )
{
child->ClearBrightened();
@ -337,7 +337,7 @@ void PCB_BASE_FRAME::FocusOnItems( std::vector<BOARD_ITEM*> aItems, PCB_LAYER_ID
{
item->SetBrightened();
item->RunOnChildren(
item->RunOnDescendants(
[&]( BOARD_ITEM* child )
{
child->SetBrightened();

View File

@ -40,12 +40,6 @@ void PCB_GENERATOR::EditStart( GENERATOR_TOOL* aTool, BOARD* aBoard, PCB_BASE_ED
BOARD_COMMIT* aCommit )
{
aCommit->Modify( this );
RunOnDescendants(
[&]( BOARD_ITEM* aItem )
{
aCommit->Modify( aItem );
} );
}
@ -66,14 +60,6 @@ void PCB_GENERATOR::EditRevert( GENERATOR_TOOL* aTool, BOARD* aBoard, PCB_BASE_E
void PCB_GENERATOR::Remove( GENERATOR_TOOL* aTool, BOARD* aBoard, PCB_BASE_EDIT_FRAME* aFrame,
BOARD_COMMIT* aCommit )
{
RunOnDescendants(
[&]( BOARD_ITEM* aItem )
{
aCommit->Stage( aItem, CHT_MODIFY );
} );
RemoveAll();
aCommit->Remove( this );
}

View File

@ -426,7 +426,7 @@ void PCB_GROUP::RunOnDescendants( const std::function<void( BOARD_ITEM* )>& aFun
aFunction( item );
if( item->Type() == PCB_GROUP_T )
static_cast<PCB_GROUP*>( item )->RunOnDescendants( aFunction );
item->RunOnDescendants( aFunction );
}
}
catch( std::bad_function_call& )
@ -435,6 +435,7 @@ void PCB_GROUP::RunOnDescendants( const std::function<void( BOARD_ITEM* )>& aFun
}
}
bool PCB_GROUP::operator==( const BOARD_ITEM& aOther ) const
{
if( aOther.Type() != Type() )

View File

@ -1942,13 +1942,12 @@ void BOARD_INSPECTION_TOOL::calculateSelectionRatsnest( const VECTOR2I& aDelta )
items.push_back( pad );
}
}
else if( item->Type() == PCB_GROUP_T )
else if( item->Type() == PCB_GROUP_T || item->Type() == PCB_GENERATOR_T )
{
PCB_GROUP *group = static_cast<PCB_GROUP*>( item );
group->RunOnDescendants( [ &queued_items ]( BOARD_ITEM *aItem )
{
queued_items.push_back( aItem );
} );
item->RunOnDescendants( [ &queued_items ]( BOARD_ITEM *aItem )
{
queued_items.push_back( aItem );
} );
}
else if( BOARD_CONNECTED_ITEM* boardItem = dyn_cast<BOARD_CONNECTED_ITEM*>( item ) )
{

View File

@ -648,10 +648,6 @@ int DRAWING_TOOL::InteractivePlaceWithPreview( const TOOL_EVENT& aEvent,
for( BOARD_ITEM* item : aItems )
{
item->Move( cursorPosition );
if( item->Type() == PCB_GROUP_T )
static_cast<PCB_GROUP*>( item )->AddChildrenToCommit( commit );
commit.Add( item );
}

View File

@ -1760,20 +1760,8 @@ int EDIT_TOOL::Rotate( const TOOL_EVENT& aEvent )
for( EDA_ITEM* item : selection )
{
if( !item->IsNew() && !item->IsMoving() )
{
commit->Modify( item );
// If rotating a group, record position of all the descendants for undo
if( item->Type() == PCB_GROUP_T || item->Type() == PCB_GENERATOR_T )
{
static_cast<PCB_GROUP*>( item )->RunOnDescendants(
[&]( BOARD_ITEM* bItem )
{
commit->Modify( bItem );
});
}
}
if( BOARD_ITEM* board_item = dynamic_cast<BOARD_ITEM*>( item ) )
{
board_item->Rotate( refPt, rotateAngle );
@ -2046,19 +2034,8 @@ int EDIT_TOOL::Flip( const TOOL_EVENT& aEvent )
if( BOARD_ITEM* boardItem = dynamic_cast<BOARD_ITEM*>( item ) )
{
if( !boardItem->IsNew() && !boardItem->IsMoving() )
{
commit->Modify( boardItem );
if( boardItem->Type() == PCB_GROUP_T || boardItem->Type() == PCB_GENERATOR_T )
{
static_cast<PCB_GROUP*>( boardItem )->RunOnDescendants(
[&]( BOARD_ITEM* descendant )
{
commit->Modify( descendant );
});
}
}
boardItem->Flip( refPt, leftRight );
boardItem->Normalize();
}
@ -2125,6 +2102,7 @@ void EDIT_TOOL::DeleteItems( const PCB_SELECTION& aItems, bool aIsCut )
case PCB_DIM_CENTER_T:
case PCB_DIM_RADIAL_T:
case PCB_DIM_ORTHOGONAL_T:
case PCB_GROUP_T:
if( parentFP )
{
commit.Modify( parentFP );
@ -2193,61 +2171,20 @@ void EDIT_TOOL::DeleteItems( const PCB_SELECTION& aItems, bool aIsCut )
break;
case PCB_GROUP_T:
{
PCB_GROUP* group = static_cast<PCB_GROUP*>( board_item );
auto removeItem =
[&]( BOARD_ITEM* bItem )
{
if( bItem->GetParent() && bItem->GetParent()->Type() == PCB_FOOTPRINT_T )
{
// Just make fields invisible if they happen to be in group.
if( bItem->Type() == PCB_FIELD_T )
{
commit.Modify( bItem->GetParent() );
static_cast<PCB_FIELD*>( board_item )->SetVisible( false );
getView()->Update( board_item );
return;
}
else if( bItem->Type() == PCB_PAD_T )
{
if( !IsFootprintEditor()
&& !frame()->GetPcbNewSettings()->m_AllowFreePads )
{
return;
}
}
commit.Modify( bItem->GetParent() );
getView()->Remove( bItem );
bItem->GetParent()->Remove( bItem );
}
else
{
commit.Remove( bItem );
}
};
removeItem( group );
group->RunOnDescendants( [&]( BOARD_ITEM* aDescendant )
{
removeItem( aDescendant );
});
break;
}
case PCB_GENERATOR_T:
{
PCB_GENERATOR* generator = static_cast<PCB_GENERATOR*>( board_item );
if( aItems.Size() == 1 )
{
PCB_GENERATOR* generator = static_cast<PCB_GENERATOR*>( board_item );
m_toolMgr->RunSynchronousAction<PCB_GENERATOR*>( PCB_ACTIONS::genRemove, &commit,
generator );
m_toolMgr->RunSynchronousAction<PCB_GENERATOR*>( PCB_ACTIONS::genRemove, &commit,
generator );
}
else
{
commit.Remove( board_item );
}
break;
}
default:
wxASSERT_MSG( parentFP == nullptr, wxT( "Try to delete an item living in a footrprint" ) );
@ -2392,20 +2329,8 @@ int EDIT_TOOL::MoveExact( const TOOL_EVENT& aEvent )
wxCHECK2( boardItem, continue );
if( !boardItem->IsNew() )
{
commit.Modify( boardItem );
if( boardItem->Type() == PCB_GROUP_T || boardItem->Type() == PCB_GENERATOR_T )
{
PCB_GROUP* group = static_cast<PCB_GROUP*>( boardItem );
group->RunOnDescendants( [&]( BOARD_ITEM* descendant )
{
commit.Modify( descendant );
});
}
}
if( !boardItem->GetParent() || !boardItem->GetParent()->IsSelected() )
boardItem->Move( translation );
@ -2554,15 +2479,6 @@ int EDIT_TOOL::Duplicate( const TOOL_EVENT& aEvent )
if( dupe_item )
{
if( dupe_item->Type() == PCB_GROUP_T )
{
static_cast<PCB_GROUP*>( dupe_item )->RunOnDescendants(
[&]( BOARD_ITEM* bItem )
{
commit.Add( bItem );
});
}
// Clear the selection flag here, otherwise the PCB_SELECTION_TOOL
// will not properly select it later on
dupe_item->ClearSelected();

View File

@ -91,19 +91,7 @@ int EDIT_TOOL::Swap( const TOOL_EVENT& aEvent )
for( EDA_ITEM* item : selection )
{
if( !item->IsNew() && !item->IsMoving() )
{
commit->Modify( item );
// If swapping a group, record position of all the descendants for undo
if( item->Type() == PCB_GROUP_T || item->Type() == PCB_GENERATOR_T )
{
PCB_GROUP* group = static_cast<PCB_GROUP*>( item );
group->RunOnDescendants( [&]( BOARD_ITEM* descendant )
{
commit->Modify( descendant );
});
}
}
}
for( size_t i = 0; i < sorted.size() - 1; i++ )
@ -559,15 +547,14 @@ bool EDIT_TOOL::doMoveSelection( const TOOL_EVENT& aEvent, BOARD_COMMIT* aCommit
if( !item->GetParent() || !item->GetParent()->IsSelected() )
static_cast<BOARD_ITEM*>( item )->Move( movement );
if( item->Type() == PCB_GENERATOR_T )
if( item->Type() == PCB_GENERATOR_T && sel_items.size() == 1 )
{
m_toolMgr->RunSynchronousAction( PCB_ACTIONS::genUpdateEdit, aCommit,
static_cast<PCB_GENERATOR*>( item ) );
}
else if( item->Type() == PCB_FOOTPRINT_T )
{
if( item->Type() == PCB_FOOTPRINT_T )
redraw3D = true;
}
}
if( redraw3D && allowRedraw3D )
@ -595,7 +582,7 @@ bool EDIT_TOOL::doMoveSelection( const TOOL_EVENT& aEvent, BOARD_COMMIT* aCommit
if( !item->IsNew() && !item->IsMoving() )
{
if( item->Type() == PCB_GENERATOR_T )
if( item->Type() == PCB_GENERATOR_T && sel_items.size() == 1 )
{
m_toolMgr->RunSynchronousAction( PCB_ACTIONS::genStartEdit, aCommit,
static_cast<PCB_GENERATOR*>( item ) );
@ -603,19 +590,14 @@ bool EDIT_TOOL::doMoveSelection( const TOOL_EVENT& aEvent, BOARD_COMMIT* aCommit
else
{
aCommit->Modify( item );
item->SetFlags( IS_MOVING );
// If moving a group, record position of all the descendants for undo
if( item->Type() == PCB_GROUP_T )
{
PCB_GROUP* group = static_cast<PCB_GROUP*>( item );
group->RunOnDescendants(
[&]( BOARD_ITEM* bItem )
{
aCommit->Modify( bItem );
item->SetFlags( IS_MOVING );
} );
}
static_cast<BOARD_ITEM*>( item )->RunOnDescendants(
[&]( BOARD_ITEM* bItem )
{
item->SetFlags( IS_MOVING );
} );
}
}
}

View File

@ -1203,7 +1203,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 : aItems )
for( BOARD_ITEM* item : itemsToSel )
{
if( aIsNew )
aCommit->Add( item );

View File

@ -526,7 +526,7 @@ std::set<BOARD_ITEM*> PCB_GRID_HELPER::queryVisible( const BOX2I& aArea,
{
items.erase( aItem );
aItem->RunOnChildren(
aItem->RunOnDescendants(
[&]( BOARD_ITEM* aChild )
{
skipItem( aChild );

View File

@ -641,26 +641,17 @@ PCB_SELECTION& PCB_SELECTION_TOOL::RequestSelection( CLIENT_SELECTION_FILTER aCl
for( EDA_ITEM* item : m_selection )
{
BOARD_ITEM* boardItem = static_cast<BOARD_ITEM*>( item );
bool lockedDescendant = false;
if( boardItem->Type() == PCB_GROUP_T )
{
PCB_GROUP* group = static_cast<PCB_GROUP*>( boardItem );
bool lockedDescendant = false;
boardItem->RunOnDescendants(
[&]( BOARD_ITEM* item )
{
if( item->IsLocked() )
lockedDescendant = true;
} );
group->RunOnDescendants(
[&lockedDescendant]( BOARD_ITEM* child )
{
if( child->IsLocked() )
lockedDescendant = true;
} );
if( lockedDescendant )
lockedItems.push_back( group );
}
else if( boardItem->IsLocked() )
{
if( boardItem->IsLocked() || lockedDescendant )
lockedItems.push_back( boardItem );
}
}
if( !lockedItems.empty() )
@ -2882,8 +2873,8 @@ void PCB_SELECTION_TOOL::highlightInternal( EDA_ITEM* aItem, int aMode, bool aUs
if( BOARD_ITEM* boardItem = dynamic_cast<BOARD_ITEM*>( aItem ) )
{
boardItem->RunOnChildren( std::bind( &PCB_SELECTION_TOOL::highlightInternal, this, _1,
aMode, aUsingOverlay ) );
boardItem->RunOnDescendants( std::bind( &PCB_SELECTION_TOOL::highlightInternal, this, _1,
aMode, aUsingOverlay ) );
}
}
@ -2914,8 +2905,8 @@ void PCB_SELECTION_TOOL::unhighlightInternal( EDA_ITEM* aItem, int aMode, bool a
if( BOARD_ITEM* boardItem = dynamic_cast<BOARD_ITEM*>( aItem ) )
{
boardItem->RunOnChildren( std::bind( &PCB_SELECTION_TOOL::unhighlightInternal, this, _1,
aMode, aUsingOverlay ) );
boardItem->RunOnDescendants( std::bind( &PCB_SELECTION_TOOL::unhighlightInternal, this, _1,
aMode, aUsingOverlay ) );
}
}
@ -2938,15 +2929,12 @@ bool PCB_SELECTION_TOOL::selectionContains( const VECTOR2I& aPoint ) const
bool found = false;
if( PCB_GROUP* group = dynamic_cast<PCB_GROUP*>( item ) )
{
group->RunOnDescendants(
[&]( BOARD_ITEM* aItem )
{
if( aItem->HitTest( aPoint, margin ) )
found = true;
} );
}
static_cast<BOARD_ITEM*>( item )->RunOnDescendants(
[&]( BOARD_ITEM* aItem )
{
if( aItem->HitTest( aPoint, margin ) )
found = true;
} );
if( found )
return true;

View File

@ -139,17 +139,6 @@ int POSITION_RELATIVE_TOOL::RelativeItemSelectionMove( const VECTOR2I& aPosAncho
}
m_commit->Modify( boardItem );
// If moving a group, record position of all the descendants for undo
if( boardItem->Type() == PCB_GROUP_T )
{
PCB_GROUP* group = static_cast<PCB_GROUP*>( boardItem );
group->RunOnDescendants( [&]( BOARD_ITEM* descendant )
{
m_commit->Modify( descendant );
});
}
boardItem->Move( aggregateTranslation );
}
}