Remove a bunch of blind (and a few redundant) static_casts.

This commit is contained in:
Jeff Young 2023-07-13 11:24:33 +01:00
parent 181ae7f450
commit cf8294b5c2
16 changed files with 315 additions and 238 deletions

View File

@ -62,7 +62,7 @@ public:
virtual ~COLLECTOR() {} virtual ~COLLECTOR() {}
virtual INSPECT_RESULT Inspect( EDA_ITEM* aItem, void* aTestData ) virtual INSPECT_RESULT Inspect( EDA_ITEM* aTestItem, void* aTestData )
{ {
return INSPECT_RESULT::QUIT; return INSPECT_RESULT::QUIT;
}; };

View File

@ -82,7 +82,10 @@ void ARRAY_CREATOR::Invoke()
for ( int i = 0; i < m_selection.Size(); ++i ) for ( int i = 0; i < m_selection.Size(); ++i )
{ {
BOARD_ITEM* item = static_cast<BOARD_ITEM*>( m_selection[ i ] ); BOARD_ITEM* item = dynamic_cast<BOARD_ITEM*>( m_selection[ i ] );
if( !item )
continue;
if( item->Type() == PCB_PAD_T && !m_isFootprintEditor ) if( item->Type() == PCB_PAD_T && !m_isFootprintEditor )
{ {

View File

@ -426,13 +426,13 @@ void BOARD::Move( const VECTOR2I& aMoveVector ) // overload
INSPECTOR_FUNC inspector = INSPECTOR_FUNC inspector =
[&] ( EDA_ITEM* item, void* testData ) [&] ( EDA_ITEM* item, void* testData )
{ {
BOARD_ITEM* brdItem = static_cast<BOARD_ITEM*>( item ); if( BOARD_ITEM* board_item = dynamic_cast<BOARD_ITEM*>( item ) )
{
// aMoveVector was snapshotted, don't need "data". // aMoveVector was snapshotted, don't need "data".
// Only move the top level group // Only move the top level group
if( brdItem->GetParentGroup() == nullptr if( !board_item->GetParentGroup() && !board_item->GetParentFootprint() )
&& brdItem->GetParentFootprint() == nullptr ) board_item->Move( aMoveVector );
brdItem->Move( aMoveVector ); }
return INSPECT_RESULT::CONTINUE; return INSPECT_RESULT::CONTINUE;
}; };
@ -2257,11 +2257,14 @@ BOARD::GroupLegalOpsField BOARD::GroupLegalOps( const PCB_SELECTION& selection )
for( EDA_ITEM* item : selection ) for( EDA_ITEM* item : selection )
{ {
if( item->Type() == PCB_GROUP_T ) if( BOARD_ITEM* board_item = dynamic_cast<BOARD_ITEM*>( item ) )
hasGroup = true; {
if( board_item->Type() == PCB_GROUP_T )
hasGroup = true;
if( static_cast<BOARD_ITEM*>( item )->GetParentGroup() ) if( board_item->GetParentGroup() )
hasMember = true; hasMember = true;
}
} }
GroupLegalOpsField legalOps; GroupLegalOpsField legalOps;

View File

@ -269,7 +269,6 @@ void BOARD_COMMIT::Push( const wxString& aMessage, int aCommitFlags )
{ {
int changeType = ent.m_type & CHT_TYPE; int changeType = ent.m_type & CHT_TYPE;
int changeFlags = ent.m_type & CHT_FLAGS; int changeFlags = ent.m_type & CHT_FLAGS;
BOARD_ITEM* boardItem = static_cast<BOARD_ITEM*>( ent.m_item );
wxASSERT( ent.m_item ); wxASSERT( ent.m_item );
@ -307,7 +306,10 @@ void BOARD_COMMIT::Push( const wxString& aMessage, int aCommitFlags )
} }
} }
if( m_isBoardEditor ) BOARD_ITEM* boardItem = dynamic_cast<BOARD_ITEM*>( ent.m_item );
wxCHECK2( boardItem, continue );
if( m_isBoardEditor && boardItem )
{ {
if( boardItem->Type() == PCB_VIA_T || boardItem->Type() == PCB_FOOTPRINT_T if( boardItem->Type() == PCB_VIA_T || boardItem->Type() == PCB_FOOTPRINT_T
|| boardItem->IsOnLayer( F_Mask ) || boardItem->IsOnLayer( B_Mask ) ) || boardItem->IsOnLayer( F_Mask ) || boardItem->IsOnLayer( B_Mask ) )
@ -519,26 +521,28 @@ void BOARD_COMMIT::Push( const wxString& aMessage, int aCommitFlags )
case CHT_MODIFY: case CHT_MODIFY:
{ {
BOARD_ITEM* boardItemCopy = dynamic_cast<BOARD_ITEM*>( ent.m_copy );
if( !m_isFootprintEditor && !( aCommitFlags & SKIP_UNDO ) ) if( !m_isFootprintEditor && !( aCommitFlags & SKIP_UNDO ) )
{ {
ITEM_PICKER itemWrapper( nullptr, boardItem, UNDO_REDO::CHANGED ); ITEM_PICKER itemWrapper( nullptr, boardItem, UNDO_REDO::CHANGED );
wxASSERT( ent.m_copy ); wxASSERT( boardItemCopy );
itemWrapper.SetLink( ent.m_copy ); itemWrapper.SetLink( boardItemCopy );
undoList.PushItem( itemWrapper ); undoList.PushItem( itemWrapper );
} }
if( !( aCommitFlags & SKIP_CONNECTIVITY ) ) if( !( aCommitFlags & SKIP_CONNECTIVITY ) )
{ {
if( ent.m_copy ) if( boardItemCopy )
connectivity->MarkItemNetAsDirty( static_cast<BOARD_ITEM*>( ent.m_copy ) ); connectivity->MarkItemNetAsDirty( boardItemCopy );
connectivity->Update( boardItem ); connectivity->Update( boardItem );
} }
if( autofillZones ) if( autofillZones )
{ {
dirtyIntersectingZones( static_cast<BOARD_ITEM*>( ent.m_copy ), changeType ); // before dirtyIntersectingZones( boardItemCopy, changeType ); // before
dirtyIntersectingZones( boardItem, changeType ); // after dirtyIntersectingZones( boardItem, changeType ); // after
} }
if( view ) if( view )
@ -565,7 +569,7 @@ void BOARD_COMMIT::Push( const wxString& aMessage, int aCommitFlags )
} }
default: default:
wxASSERT( false ); UNIMPLEMENTED_FOR( boardItem->GetClass() );
break; break;
} }
@ -616,12 +620,16 @@ void BOARD_COMMIT::Push( const wxString& aMessage, int aCommitFlags )
for( size_t i = num_changes; i < m_changes.size(); ++i ) for( size_t i = num_changes; i < m_changes.size(); ++i )
{ {
COMMIT_LINE& ent = m_changes[i]; COMMIT_LINE& ent = m_changes[i];
BOARD_ITEM* boardItem = static_cast<BOARD_ITEM*>( ent.m_item ); BOARD_ITEM* boardItem = dynamic_cast<BOARD_ITEM*>( ent.m_item );
BOARD_ITEM* boardItemCopy = dynamic_cast<BOARD_ITEM*>( ent.m_copy );
wxCHECK2( boardItem, continue );
if( !( aCommitFlags & SKIP_UNDO ) ) if( !( aCommitFlags & SKIP_UNDO ) )
{ {
ITEM_PICKER itemWrapper( nullptr, boardItem, convert( ent.m_type & CHT_TYPE ) ); ITEM_PICKER itemWrapper( nullptr, boardItem, convert( ent.m_type & CHT_TYPE ) );
itemWrapper.SetLink( ent.m_copy ); wxASSERT( boardItemCopy );
itemWrapper.SetLink( boardItemCopy );
undoList.PushItem( itemWrapper ); undoList.PushItem( itemWrapper );
} }
else else
@ -686,9 +694,11 @@ EDA_ITEM* BOARD_COMMIT::parentObject( EDA_ITEM* aItem ) const
EDA_ITEM* BOARD_COMMIT::makeImage( EDA_ITEM* aItem ) const EDA_ITEM* BOARD_COMMIT::makeImage( EDA_ITEM* aItem ) const
{ {
BOARD_ITEM* clone = static_cast<BOARD_ITEM*>( aItem->Clone() ); EDA_ITEM* clone = aItem->Clone();
if( BOARD_ITEM* board_item = dynamic_cast<BOARD_ITEM*>( clone ) )
board_item->SetParentGroup( nullptr );
clone->SetParentGroup( nullptr );
return clone; return clone;
} }
@ -709,10 +719,11 @@ void BOARD_COMMIT::Revert()
for( auto it = m_changes.rbegin(); it != m_changes.rend(); ++it ) for( auto it = m_changes.rbegin(); it != m_changes.rend(); ++it )
{ {
COMMIT_LINE& ent = *it; COMMIT_LINE& ent = *it;
BOARD_ITEM* item = static_cast<BOARD_ITEM*>( ent.m_item ); BOARD_ITEM* boardItem = dynamic_cast<BOARD_ITEM*>( ent.m_item );
BOARD_ITEM* copy = static_cast<BOARD_ITEM*>( ent.m_copy ); int changeType = ent.m_type & CHT_TYPE;
int changeType = ent.m_type & CHT_TYPE; int changeFlags = ent.m_type & CHT_FLAGS;
int changeFlags = ent.m_type & CHT_FLAGS;
wxCHECK2( boardItem, continue );
switch( changeType ) switch( changeType )
{ {
@ -720,32 +731,34 @@ void BOARD_COMMIT::Revert()
if( !( changeFlags & CHT_DONE ) ) if( !( changeFlags & CHT_DONE ) )
break; break;
view->Remove( item ); view->Remove( boardItem );
connectivity->Remove( item ); connectivity->Remove( boardItem );
board->Remove( item, REMOVE_MODE::BULK ); board->Remove( boardItem, REMOVE_MODE::BULK );
bulkRemovedItems.push_back( item ); bulkRemovedItems.push_back( boardItem );
break; break;
case CHT_REMOVE: case CHT_REMOVE:
if( !( changeFlags & CHT_DONE ) ) if( !( changeFlags & CHT_DONE ) )
break; break;
view->Add( item ); view->Add( boardItem );
connectivity->Add( item ); connectivity->Add( boardItem );
board->Add( item, ADD_MODE::INSERT ); board->Add( boardItem, ADD_MODE::INSERT );
bulkAddedItems.push_back( item ); bulkAddedItems.push_back( boardItem );
break; break;
case CHT_MODIFY: case CHT_MODIFY:
{ {
view->Remove( item ); view->Remove( boardItem );
connectivity->Remove( item ); connectivity->Remove( boardItem );
item->SwapItemData( copy ); BOARD_ITEM* boardItemCopy = dynamic_cast<BOARD_ITEM*>( ent.m_copy );
wxASSERT( boardItemCopy );
boardItem->SwapItemData( boardItemCopy );
if( item->Type() == PCB_GROUP_T ) if( boardItem->Type() == PCB_GROUP_T )
{ {
PCB_GROUP* group = static_cast<PCB_GROUP*>( item ); PCB_GROUP* group = static_cast<PCB_GROUP*>( boardItem );
group->RunOnChildren( [&]( BOARD_ITEM* child ) group->RunOnChildren( [&]( BOARD_ITEM* child )
{ {
@ -753,21 +766,21 @@ void BOARD_COMMIT::Revert()
} ); } );
} }
view->Add( item ); view->Add( boardItem );
connectivity->Add( item ); connectivity->Add( boardItem );
board->OnItemChanged( item ); board->OnItemChanged( boardItem );
itemsChanged.push_back( item ); itemsChanged.push_back( boardItem );
delete copy; delete ent.m_copy;
break; break;
} }
default: default:
wxASSERT( false ); UNIMPLEMENTED_FOR( boardItem->GetClass() );
break; break;
} }
item->ClearEditFlags(); boardItem->ClearEditFlags();
} }
if( bulkAddedItems.size() > 0 ) if( bulkAddedItems.size() > 0 )

View File

@ -190,7 +190,7 @@ BOARD_ITEM* BOARD_ITEM::Duplicate() const
if( dupe->GetParentGroup() ) if( dupe->GetParentGroup() )
dupe->GetParentGroup()->AddItem( dupe ); dupe->GetParentGroup()->AddItem( dupe );
return static_cast<BOARD_ITEM*>( dupe ); return dupe;
} }

View File

@ -136,26 +136,16 @@ const std::vector<KICAD_T> GENERAL_COLLECTOR::DraggableItems = {
}; };
INSPECT_RESULT GENERAL_COLLECTOR::Inspect( EDA_ITEM* testItem, void* testData ) INSPECT_RESULT GENERAL_COLLECTOR::Inspect( EDA_ITEM* aTestItem, void* aTestData )
{ {
BOARD_ITEM* item = static_cast<BOARD_ITEM*>( testItem ); #if 1 // debugging
FOOTPRINT* footprint = item->GetParentFootprint();
PCB_GROUP* group = nullptr;
PAD* pad = nullptr;
bool pad_through = false;
PCB_VIA* via = nullptr;
PCB_MARKER* marker = nullptr;
ZONE* zone = nullptr;
PCB_DIMENSION_BASE* dimension = nullptr;
#if 0 // debugging
static int breakhere = 0; static int breakhere = 0;
switch( item->Type() ) switch( aTestItem->Type() )
{ {
case PCB_PAD_T: case PCB_PAD_T:
{ {
FOOTPRINT* footprint = (FOOTPRINT*) item->GetParent(); FOOTPRINT* footprint = (FOOTPRINT*) aTestItem->GetParent();
if( footprint->GetReference() == wxT( "Y2" ) ) if( footprint->GetReference() == wxT( "Y2" ) )
breakhere++; breakhere++;
@ -190,7 +180,7 @@ INSPECT_RESULT GENERAL_COLLECTOR::Inspect( EDA_ITEM* testItem, void* testData )
case PCB_FOOTPRINT_T: case PCB_FOOTPRINT_T:
{ {
FOOTPRINT* footprint = (FOOTPRINT*) item; FOOTPRINT* footprint = (FOOTPRINT*) aTestItem;
if( footprint->GetReference() == wxT( "C98" ) ) if( footprint->GetReference() == wxT( "C98" ) )
breakhere++; breakhere++;
@ -208,7 +198,19 @@ INSPECT_RESULT GENERAL_COLLECTOR::Inspect( EDA_ITEM* testItem, void* testData )
#endif #endif
switch( item->Type() ) BOARD_ITEM* boardItem = nullptr;
FOOTPRINT* footprint = nullptr;
PCB_GROUP* group = nullptr;
PAD* pad = nullptr;
bool pad_through = false;
PCB_VIA* via = nullptr;
PCB_MARKER* marker = nullptr;
ZONE* zone = nullptr;
PCB_FIELD* field = nullptr;
PCB_TEXT* text = nullptr;
PCB_DIMENSION_BASE* dimension = nullptr;
switch( aTestItem->Type() )
{ {
case PCB_PAD_T: case PCB_PAD_T:
// there are pad specific visibility controls. // there are pad specific visibility controls.
@ -217,7 +219,8 @@ INSPECT_RESULT GENERAL_COLLECTOR::Inspect( EDA_ITEM* testItem, void* testData )
// board side must be visible // board side must be visible
// if pad is a thru hole, then it can be visible when its parent footprint is not. // if pad is a thru hole, then it can be visible when its parent footprint is not.
// for through pads: pads on Front or Back board sides must be visible // for through pads: pads on Front or Back board sides must be visible
pad = static_cast<PAD*>( item ); pad = static_cast<PAD*>( aTestItem );
boardItem = pad;
if( ( pad->GetAttribute() != PAD_ATTRIB::SMD ) && if( ( pad->GetAttribute() != PAD_ATTRIB::SMD ) &&
( pad->GetAttribute() != PAD_ATTRIB::CONN ) ) // a hole is present, so multiple layers ( pad->GetAttribute() != PAD_ATTRIB::CONN ) ) // a hole is present, so multiple layers
@ -230,7 +233,8 @@ INSPECT_RESULT GENERAL_COLLECTOR::Inspect( EDA_ITEM* testItem, void* testData )
break; break;
case PCB_VIA_T: // vias are on many layers, so layer test is specific case PCB_VIA_T: // vias are on many layers, so layer test is specific
via = static_cast<PCB_VIA*>( item ); via = static_cast<PCB_VIA*>( aTestItem );
boardItem = via;
break; break;
case PCB_TRACE_T: case PCB_TRACE_T:
@ -238,14 +242,17 @@ INSPECT_RESULT GENERAL_COLLECTOR::Inspect( EDA_ITEM* testItem, void* testData )
if( m_Guide->IgnoreTracks() ) if( m_Guide->IgnoreTracks() )
return INSPECT_RESULT::CONTINUE; return INSPECT_RESULT::CONTINUE;
boardItem = static_cast<PCB_TRACK*>( aTestItem );
break; break;
case PCB_ZONE_T: case PCB_ZONE_T:
zone = static_cast<ZONE*>( item ); zone = static_cast<ZONE*>( aTestItem );
boardItem = zone;
break; break;
case PCB_TEXTBOX_T: case PCB_TEXTBOX_T:
case PCB_SHAPE_T: case PCB_SHAPE_T:
boardItem = static_cast<BOARD_ITEM*>( aTestItem );
break; break;
case PCB_DIM_ALIGNED_T: case PCB_DIM_ALIGNED_T:
@ -253,29 +260,32 @@ INSPECT_RESULT GENERAL_COLLECTOR::Inspect( EDA_ITEM* testItem, void* testData )
case PCB_DIM_RADIAL_T: case PCB_DIM_RADIAL_T:
case PCB_DIM_ORTHOGONAL_T: case PCB_DIM_ORTHOGONAL_T:
case PCB_DIM_LEADER_T: case PCB_DIM_LEADER_T:
dimension = static_cast<PCB_DIMENSION_BASE*>( item ); dimension = static_cast<PCB_DIMENSION_BASE*>( aTestItem );
boardItem = dimension;
break; break;
case PCB_TARGET_T: case PCB_TARGET_T:
boardItem = static_cast<BOARD_ITEM*>( aTestItem );
break; break;
case PCB_FIELD_T: case PCB_FIELD_T:
{ field = static_cast<PCB_FIELD*>( aTestItem );
PCB_FIELD* field = static_cast<PCB_FIELD*>( item );
if( field->IsReference() && m_Guide->IgnoreFPReferences() ) if( field->IsReference() && m_Guide->IgnoreFPReferences() )
return INSPECT_RESULT::CONTINUE; return INSPECT_RESULT::CONTINUE;
if( field->IsValue() && m_Guide->IgnoreFPValues() ) if( field->IsValue() && m_Guide->IgnoreFPValues() )
return INSPECT_RESULT::CONTINUE; return INSPECT_RESULT::CONTINUE;
}
KI_FALLTHROUGH; KI_FALLTHROUGH;
case PCB_TEXT_T: case PCB_TEXT_T:
if( item->GetParentFootprint() ) text = static_cast<PCB_TEXT*>( aTestItem );
boardItem = text;
if( text->GetParentFootprint() )
{ {
PCB_TEXT* text = static_cast<PCB_TEXT*>( item ); PCB_LAYER_ID layer = text->GetLayer();
PCB_LAYER_ID layer = item->GetLayer();
if( m_Guide->IgnoreHiddenFPText() ) if( m_Guide->IgnoreHiddenFPText() )
{ {
@ -293,21 +303,28 @@ INSPECT_RESULT GENERAL_COLLECTOR::Inspect( EDA_ITEM* testItem, void* testData )
break; break;
case PCB_FOOTPRINT_T: case PCB_FOOTPRINT_T:
footprint = static_cast<FOOTPRINT*>( item ); footprint = static_cast<FOOTPRINT*>( aTestItem );
boardItem = footprint;
break; break;
case PCB_GROUP_T: case PCB_GROUP_T:
group = static_cast<PCB_GROUP*>( item ); group = static_cast<PCB_GROUP*>( aTestItem );
boardItem = group;
break; break;
case PCB_MARKER_T: case PCB_MARKER_T:
marker = static_cast<PCB_MARKER*>( item ); marker = static_cast<PCB_MARKER*>( aTestItem );
boardItem = marker;
break; break;
default: default:
boardItem = dynamic_cast<BOARD_ITEM*>( aTestItem );
break; break;
} }
if( boardItem && !footprint )
footprint = boardItem->GetParentFootprint();
// common tests: // common tests:
if( footprint ) if( footprint )
@ -341,7 +358,7 @@ INSPECT_RESULT GENERAL_COLLECTOR::Inspect( EDA_ITEM* testItem, void* testData )
{ {
// Markers are not sensitive to the layer // Markers are not sensitive to the layer
if( marker->HitTest( m_refPos ) ) if( marker->HitTest( m_refPos ) )
Append( item ); Append( aTestItem );
return INSPECT_RESULT::CONTINUE; return INSPECT_RESULT::CONTINUE;
} }
@ -350,7 +367,7 @@ INSPECT_RESULT GENERAL_COLLECTOR::Inspect( EDA_ITEM* testItem, void* testData )
{ {
// Groups are not sensitive to the layer ... ? // Groups are not sensitive to the layer ... ?
if( group->HitTest( m_refPos ) ) if( group->HitTest( m_refPos ) )
Append( item ); Append( aTestItem );
return INSPECT_RESULT::CONTINUE; return INSPECT_RESULT::CONTINUE;
} }
@ -367,8 +384,9 @@ INSPECT_RESULT GENERAL_COLLECTOR::Inspect( EDA_ITEM* testItem, void* testData )
} }
} }
if( ( item->IsOnLayer( m_Guide->GetPreferredLayer() ) ) if( boardItem
&& ( !item->IsLocked() || !m_Guide->IgnoreLockedItems() ) ) && ( boardItem->IsOnLayer( m_Guide->GetPreferredLayer() ) )
&& ( !boardItem->IsLocked() || !m_Guide->IgnoreLockedItems() ) )
{ {
// footprints and their subcomponents: reference, value and pads are not sensitive // footprints and their subcomponents: reference, value and pads are not sensitive
// to the layer visibility controls. They all have their own separate visibility // to the layer visibility controls. They all have their own separate visibility
@ -382,7 +400,7 @@ INSPECT_RESULT GENERAL_COLLECTOR::Inspect( EDA_ITEM* testItem, void* testData )
if( zone->HitTestForCorner( m_refPos, accuracy * 2 ) if( zone->HitTestForCorner( m_refPos, accuracy * 2 )
|| zone->HitTestForEdge( m_refPos, accuracy ) ) || zone->HitTestForEdge( m_refPos, accuracy ) )
{ {
Append( item ); Append( aTestItem );
return INSPECT_RESULT::CONTINUE; return INSPECT_RESULT::CONTINUE;
} }
else if( !m_Guide->IgnoreZoneFills() ) else if( !m_Guide->IgnoreZoneFills() )
@ -392,32 +410,32 @@ INSPECT_RESULT GENERAL_COLLECTOR::Inspect( EDA_ITEM* testItem, void* testData )
if( m_Guide->IsLayerVisible( layer ) if( m_Guide->IsLayerVisible( layer )
&& zone->HitTestFilledArea( layer, m_refPos ) ) && zone->HitTestFilledArea( layer, m_refPos ) )
{ {
Append( item ); Append( aTestItem );
return INSPECT_RESULT::CONTINUE; return INSPECT_RESULT::CONTINUE;
} }
} }
} }
} }
else if( item == footprint ) else if( aTestItem == footprint )
{ {
if( footprint->HitTest( m_refPos, accuracy ) if( footprint->HitTest( m_refPos, accuracy )
&& footprint->HitTestAccurate( m_refPos, accuracy ) ) && footprint->HitTestAccurate( m_refPos, accuracy ) )
{ {
Append( item ); Append( aTestItem );
return INSPECT_RESULT::CONTINUE; return INSPECT_RESULT::CONTINUE;
} }
} }
else if( pad || via ) else if( pad || via )
{ {
if( item->HitTest( m_refPos, accuracy ) ) if( aTestItem->HitTest( m_refPos, accuracy ) )
{ {
Append( item ); Append( aTestItem );
return INSPECT_RESULT::CONTINUE; return INSPECT_RESULT::CONTINUE;
} }
} }
else else
{ {
PCB_LAYER_ID layer = item->GetLayer(); PCB_LAYER_ID layer = boardItem->GetLayer();
if( m_Guide->IsLayerVisible( layer ) ) if( m_Guide->IsLayerVisible( layer ) )
{ {
@ -428,16 +446,17 @@ INSPECT_RESULT GENERAL_COLLECTOR::Inspect( EDA_ITEM* testItem, void* testData )
accuracy = KiROUND( accuracy * 1.5 ); accuracy = KiROUND( accuracy * 1.5 );
} }
if( item->HitTest( m_refPos, accuracy ) ) if( aTestItem->HitTest( m_refPos, accuracy ) )
{ {
Append( item ); Append( aTestItem );
return INSPECT_RESULT::CONTINUE; return INSPECT_RESULT::CONTINUE;
} }
} }
} }
} }
if( m_Guide->IncludeSecondary() && ( !item->IsLocked() || !m_Guide->IgnoreLockedItems() ) ) if( m_Guide->IncludeSecondary()
&& ( !boardItem || !boardItem->IsLocked() || !m_Guide->IgnoreLockedItems() ) )
{ {
// for now, "secondary" means "tolerate any visible layer". It has no effect on other // for now, "secondary" means "tolerate any visible layer". It has no effect on other
// criteria, since there is a separate "ignore" control for those in the COLLECTORS_GUIDE // criteria, since there is a separate "ignore" control for those in the COLLECTORS_GUIDE
@ -454,7 +473,7 @@ INSPECT_RESULT GENERAL_COLLECTOR::Inspect( EDA_ITEM* testItem, void* testData )
if( zone->HitTestForCorner( m_refPos, accuracy * 2 ) if( zone->HitTestForCorner( m_refPos, accuracy * 2 )
|| zone->HitTestForEdge( m_refPos, accuracy ) ) || zone->HitTestForEdge( m_refPos, accuracy ) )
{ {
Append2nd( item ); Append2nd( aTestItem );
return INSPECT_RESULT::CONTINUE; return INSPECT_RESULT::CONTINUE;
} }
else if( !m_Guide->IgnoreZoneFills() ) else if( !m_Guide->IgnoreZoneFills() )
@ -464,47 +483,42 @@ INSPECT_RESULT GENERAL_COLLECTOR::Inspect( EDA_ITEM* testItem, void* testData )
if( m_Guide->IsLayerVisible( layer ) if( m_Guide->IsLayerVisible( layer )
&& zone->HitTestFilledArea( layer, m_refPos ) ) && zone->HitTestFilledArea( layer, m_refPos ) )
{ {
Append2nd( item ); Append2nd( aTestItem );
return INSPECT_RESULT::CONTINUE; return INSPECT_RESULT::CONTINUE;
} }
} }
} }
} }
else if( item->Type() == PCB_FOOTPRINT_T ) else if( aTestItem->Type() == PCB_FOOTPRINT_T )
{ {
if( footprint->HitTest( m_refPos, accuracy ) if( footprint->HitTest( m_refPos, accuracy )
&& footprint->HitTestAccurate( m_refPos, accuracy ) ) && footprint->HitTestAccurate( m_refPos, accuracy ) )
{ {
Append2nd( item ); Append2nd( aTestItem );
return INSPECT_RESULT::CONTINUE; return INSPECT_RESULT::CONTINUE;
} }
} }
else if( pad || via ) else if( pad || via )
{ {
if( item->HitTest( m_refPos, accuracy ) ) if( aTestItem->HitTest( m_refPos, accuracy ) )
{ {
Append2nd( item ); Append2nd( aTestItem );
return INSPECT_RESULT::CONTINUE; return INSPECT_RESULT::CONTINUE;
} }
} }
else else if( boardItem && m_Guide->IsLayerVisible( boardItem->GetLayer() ) )
{ {
PCB_LAYER_ID layer = item->GetLayer(); if( dimension )
if( m_Guide->IsLayerVisible( layer ) )
{ {
if( dimension ) // Dimensions feel particularly hard to select, probably due to their
{ // noisy shape making it feel like they should have a larger boundary.
// Dimensions feel particularly hard to select, probably due to their accuracy = KiROUND( accuracy * 1.5 );
// noisy shape making it feel like they should have a larger boundary. }
accuracy = KiROUND( accuracy * 1.5 );
}
if( item->HitTest( m_refPos, accuracy ) ) if( aTestItem->HitTest( m_refPos, accuracy ) )
{ {
Append2nd( item ); Append2nd( aTestItem );
return INSPECT_RESULT::CONTINUE; return INSPECT_RESULT::CONTINUE;
}
} }
} }
} }

View File

@ -209,7 +209,7 @@ protected:
* "2nd" choice, which will be appended to the end of COLLECTOR's prime * "2nd" choice, which will be appended to the end of COLLECTOR's prime
* "list" at the end of the search. * "list" at the end of the search.
*/ */
std::vector<BOARD_ITEM*> m_List2nd; std::vector<EDA_ITEM*> m_List2nd;
/** /**
* Determine which items are to be collected by Inspect(). * Determine which items are to be collected by Inspect().
@ -275,7 +275,7 @@ public:
m_List2nd.clear(); m_List2nd.clear();
} }
void Append2nd( BOARD_ITEM* item ) void Append2nd( EDA_ITEM* item )
{ {
m_List2nd.push_back( item ); m_List2nd.push_back( item );
} }
@ -294,10 +294,10 @@ public:
* Search and collect all the objects which match the test data. * Search and collect all the objects which match the test data.
* *
* @param testItem An EDA_ITEM to examine. * @param testItem An EDA_ITEM to examine.
* @param testData is not used in this class. * @param aTestData is not used in this class.
* @return SEARCH_QUIT if the Iterator is to stop the scan, else SCAN_CONTINUE * @return SEARCH_QUIT if the Iterator is to stop the scan, else SCAN_CONTINUE
*/ */
INSPECT_RESULT Inspect( EDA_ITEM* testItem, void* testData ) override; INSPECT_RESULT Inspect( EDA_ITEM* aTestItem, void* aTestData ) override;
/** /**
* Scan a BOARD_ITEM using this class's Inspector method, which does the collection. * Scan a BOARD_ITEM using this class's Inspector method, which does the collection.

View File

@ -109,8 +109,11 @@ void CLIPBOARD_IO::SaveSelection( const PCB_SELECTION& aSelected, bool isFootpri
for( const EDA_ITEM* item : aSelected ) for( const EDA_ITEM* item : aSelected )
{ {
const PCB_GROUP* group = dynamic_cast<const PCB_GROUP*>( item ); const BOARD_ITEM* boardItem = dynamic_cast<const BOARD_ITEM*>( item );
BOARD_ITEM* clone; const PCB_GROUP* group = dynamic_cast<const PCB_GROUP*>( item );
BOARD_ITEM* clone = nullptr;
wxCHECK2( boardItem, continue );
if( const PCB_FIELD* field = dynamic_cast<const PCB_FIELD*>( item ) ) if( const PCB_FIELD* field = dynamic_cast<const PCB_FIELD*>( item ) )
{ {
@ -121,7 +124,7 @@ void CLIPBOARD_IO::SaveSelection( const PCB_SELECTION& aSelected, bool isFootpri
if( group ) if( group )
clone = static_cast<BOARD_ITEM*>( group->DeepClone() ); clone = static_cast<BOARD_ITEM*>( group->DeepClone() );
else else
clone = static_cast<BOARD_ITEM*>( item->Clone() ); clone = static_cast<BOARD_ITEM*>( boardItem->Clone() );
// If it is only a footprint, clear the nets from the pads // If it is only a footprint, clear the nets from the pads
if( PAD* pad = dynamic_cast<PAD*>( clone ) ) if( PAD* pad = dynamic_cast<PAD*>( clone ) )
@ -198,39 +201,41 @@ void CLIPBOARD_IO::SaveSelection( const PCB_SELECTION& aSelected, bool isFootpri
m_formatter.Print( 0, "\n" ); m_formatter.Print( 0, "\n" );
for( EDA_ITEM* i : aSelected ) for( EDA_ITEM* item : aSelected )
{ {
BOARD_ITEM* item = static_cast<BOARD_ITEM*>( i ); BOARD_ITEM* boardItem = dynamic_cast<BOARD_ITEM*>( item );
BOARD_ITEM* copy = nullptr; BOARD_ITEM* copy = nullptr;
if( item->Type() == PCB_FIELD_T || item->Type() == PCB_TEXT_T ) wxCHECK2( boardItem, continue );
if( boardItem->Type() == PCB_FIELD_T || boardItem->Type() == PCB_TEXT_T )
{ {
copy = static_cast<BOARD_ITEM*>( item->Clone() ); copy = static_cast<BOARD_ITEM*>( boardItem->Clone() );
PCB_TEXT* textItem = static_cast<PCB_TEXT*>( copy ); PCB_TEXT* textItem = static_cast<PCB_TEXT*>( copy );
if( textItem->GetText() == wxT( "${VALUE}" ) ) if( textItem->GetText() == wxT( "${VALUE}" ) )
textItem->SetText( item->GetParentFootprint()->GetValue() ); textItem->SetText( boardItem->GetParentFootprint()->GetValue() );
else if( textItem->GetText() == wxT( "${REFERENCE}" ) ) else if( textItem->GetText() == wxT( "${REFERENCE}" ) )
textItem->SetText( item->GetParentFootprint()->GetReference() ); textItem->SetText( boardItem->GetParentFootprint()->GetReference() );
} }
else if( item->Type() == PCB_PAD_T ) else if( boardItem->Type() == PCB_PAD_T )
{ {
// Create a parent to own the copied pad // Create a parent to own the copied pad
FOOTPRINT* footprint = new FOOTPRINT( m_board ); FOOTPRINT* footprint = new FOOTPRINT( m_board );
PAD* pad = (PAD*) item->Clone(); PAD* pad = (PAD*) boardItem->Clone();
footprint->SetPosition( pad->GetPosition() ); footprint->SetPosition( pad->GetPosition() );
footprint->Add( pad ); footprint->Add( pad );
copy = footprint; copy = footprint;
} }
else if( item->Type() == PCB_GROUP_T ) else if( boardItem->Type() == PCB_GROUP_T )
{ {
copy = static_cast<PCB_GROUP*>( item )->DeepClone(); copy = static_cast<PCB_GROUP*>( boardItem )->DeepClone();
} }
else else
{ {
copy = static_cast<BOARD_ITEM*>( item->Clone() ); copy = static_cast<BOARD_ITEM*>( boardItem->Clone() );
} }
auto prepItem = [&]( BOARD_ITEM* aItem ) auto prepItem = [&]( BOARD_ITEM* aItem )

View File

@ -1212,9 +1212,9 @@ int BOARD_EDITOR_CONTROL::modifyLockSelected( MODIFY_MODE aMode )
for( EDA_ITEM* item : selection ) for( EDA_ITEM* item : selection )
{ {
BOARD_ITEM* board_item = static_cast<BOARD_ITEM*>( item ); BOARD_ITEM* board_item = dynamic_cast<BOARD_ITEM*>( item );
if( board_item->IsLocked() ) if( board_item && board_item->IsLocked() )
{ {
aMode = OFF; aMode = OFF;
break; break;
@ -1226,7 +1226,9 @@ int BOARD_EDITOR_CONTROL::modifyLockSelected( MODIFY_MODE aMode )
for( EDA_ITEM* item : selection ) for( EDA_ITEM* item : selection )
{ {
BOARD_ITEM* board_item = static_cast<BOARD_ITEM*>( item ); BOARD_ITEM* board_item = dynamic_cast<BOARD_ITEM*>( item );
wxCHECK2( board_item, continue );
commit.Modify( board_item ); commit.Modify( board_item );

View File

@ -581,8 +581,8 @@ int BOARD_INSPECTION_TOOL::InspectClearance( const TOOL_EVENT& aEvent )
return 0; return 0;
} }
BOARD_ITEM* a = static_cast<BOARD_ITEM*>( selection.GetItem( 0 ) ); BOARD_ITEM* a = dynamic_cast<BOARD_ITEM*>( selection.GetItem( 0 ) );
BOARD_ITEM* b = static_cast<BOARD_ITEM*>( selection.GetItem( 1 ) ); BOARD_ITEM* b = dynamic_cast<BOARD_ITEM*>( selection.GetItem( 1 ) );
wxCHECK( a && b, 0 ); wxCHECK( a && b, 0 );
@ -1210,12 +1210,14 @@ int BOARD_INSPECTION_TOOL::InspectConstraints( const TOOL_EVENT& aEvent )
dialog->DeleteAllPages(); dialog->DeleteAllPages();
BOARD_ITEM* item = static_cast<BOARD_ITEM*>( selection.GetItem( 0 ) ); BOARD_ITEM* item = dynamic_cast<BOARD_ITEM*>( selection.GetItem( 0 ) );
bool compileError = false; bool compileError = false;
bool courtyardError = false; bool courtyardError = false;
DRC_ENGINE drcEngine = makeDRCEngine( &compileError, &courtyardError ); DRC_ENGINE drcEngine = makeDRCEngine( &compileError, &courtyardError );
DRC_CONSTRAINT constraint; DRC_CONSTRAINT constraint;
wxCHECK( item, 0 );
WX_HTML_REPORT_BOX* r = nullptr; WX_HTML_REPORT_BOX* r = nullptr;
if( item->Type() == PCB_TRACE_T ) if( item->Type() == PCB_TRACE_T )
@ -1898,7 +1900,9 @@ void BOARD_INSPECTION_TOOL::calculateSelectionRatsnest( const VECTOR2I& aDelta )
for( std::size_t i = 0; i < queued_items.size(); ++i ) for( std::size_t i = 0; i < queued_items.size(); ++i )
{ {
BOARD_ITEM* item = static_cast<BOARD_ITEM*>( queued_items[i] ); BOARD_ITEM* item = dynamic_cast<BOARD_ITEM*>( queued_items[i] );
wxCHECK2( item, continue );
if( item->Type() == PCB_FOOTPRINT_T ) if( item->Type() == PCB_FOOTPRINT_T )
{ {

View File

@ -1524,7 +1524,9 @@ int DRAWING_TOOL::PlaceImportedGraphics( const TOOL_EVENT& aEvent )
for( std::unique_ptr<EDA_ITEM>& ptr : list ) for( std::unique_ptr<EDA_ITEM>& ptr : list )
{ {
BOARD_ITEM* item = static_cast<BOARD_ITEM*>( ptr.get() ); BOARD_ITEM* item = dynamic_cast<BOARD_ITEM*>( ptr.get() );
wxCHECK2( item, continue );
newItems.push_back( item ); newItems.push_back( item );

View File

@ -1348,13 +1348,14 @@ int EDIT_TOOL::Properties( const TOOL_EVENT& aEvent )
else if( selection.Size() == 1 ) else if( selection.Size() == 1 )
{ {
// Display properties dialog // Display properties dialog
BOARD_ITEM* item = static_cast<BOARD_ITEM*>( selection.Front() ); if( BOARD_ITEM* item = dynamic_cast<BOARD_ITEM*>( selection.Front() ) )
{
// Do not handle undo buffer, it is done by the properties dialogs
editFrame->OnEditItemRequest( item );
// Do not handle undo buffer, it is done by the properties dialogs // Notify other tools of the changes
editFrame->OnEditItemRequest( item ); m_toolMgr->ProcessEvent( EVENTS::SelectedItemsModified );
}
// Notify other tools of the changes
m_toolMgr->ProcessEvent( EVENTS::SelectedItemsModified );
} }
else if( selection.Size() == 0 && getView()->IsLayerVisible( LAYER_DRAWINGSHEET ) ) else if( selection.Size() == 0 && getView()->IsLayerVisible( LAYER_DRAWINGSHEET ) )
{ {
@ -1380,10 +1381,11 @@ int EDIT_TOOL::Properties( const TOOL_EVENT& aEvent )
for( EDA_ITEM* eda_item : selCopy ) for( EDA_ITEM* eda_item : selCopy )
{ {
BOARD_ITEM* item = static_cast<BOARD_ITEM*>( eda_item ); if( BOARD_ITEM* item = dynamic_cast<BOARD_ITEM*>( eda_item ) )
{
if( !( item->GetLayerSet() & visible ).any() ) if( !( item->GetLayerSet() & visible ).any() )
m_selectionTool->RemoveItemFromSel( item ); m_selectionTool->RemoveItemFromSel( item );
}
} }
} }
@ -1490,7 +1492,8 @@ int EDIT_TOOL::Rotate( const TOOL_EVENT& aEvent )
} }
} }
static_cast<BOARD_ITEM*>( item )->Rotate( refPt, rotateAngle ); if( BOARD_ITEM* board_item = dynamic_cast<BOARD_ITEM*>( item ) )
board_item->Rotate( refPt, rotateAngle );
} }
if( !localCommit.Empty() ) if( !localCommit.Empty() )
@ -1752,28 +1755,33 @@ int EDIT_TOOL::Flip( const TOOL_EVENT& aEvent )
{ {
if( m_dragging && selection.HasReferencePoint() ) if( m_dragging && selection.HasReferencePoint() )
refPt = selection.GetReferencePoint(); refPt = selection.GetReferencePoint();
else else if( BOARD_ITEM* boardItem = dynamic_cast<BOARD_ITEM*>( selection.Front() ) )
refPt = static_cast<BOARD_ITEM*>( selection.GetItem( 0 ) )->GetPosition(); refPt = boardItem->GetPosition();
} }
bool leftRight = frame()->GetPcbNewSettings()->m_FlipLeftRight; bool leftRight = frame()->GetPcbNewSettings()->m_FlipLeftRight;
for( EDA_ITEM* item : selection ) for( EDA_ITEM* item : selection )
{ {
if( !item->IsNew() && !item->IsMoving() && ( !IsFootprintEditor() || commit->Empty() ) ) if( BOARD_ITEM* boardItem = dynamic_cast<BOARD_ITEM*>( item ) )
{ {
commit->Modify( item ); if( !boardItem->IsNew() && !boardItem->IsMoving()
&& ( !IsFootprintEditor() || commit->Empty() ) )
if( item->Type() == PCB_GROUP_T )
{ {
static_cast<PCB_GROUP*>( item )->RunOnDescendants( [&]( BOARD_ITEM* bItem ) commit->Modify( boardItem );
{
commit->Modify( bItem );
});
}
}
static_cast<BOARD_ITEM*>( item )->Flip( refPt, leftRight ); if( boardItem->Type() == PCB_GROUP_T )
{
static_cast<PCB_GROUP*>( boardItem )->RunOnDescendants(
[&]( BOARD_ITEM* descendant )
{
commit->Modify( descendant );
});
}
}
boardItem->Flip( refPt, leftRight );
}
} }
if( !localCommit.Empty() ) if( !localCommit.Empty() )
@ -1807,9 +1815,12 @@ void EDIT_TOOL::DeleteItems( const PCB_SELECTION& aItems, bool aIsCut )
for( EDA_ITEM* item : aItems ) for( EDA_ITEM* item : aItems )
{ {
BOARD_ITEM* board_item = static_cast<BOARD_ITEM*>( item ); BOARD_ITEM* board_item = dynamic_cast<BOARD_ITEM*>( item );
FOOTPRINT* parentFP = board_item->GetParentFootprint();
PCB_GROUP* parentGroup = board_item->GetParentGroup(); wxCHECK2( board_item, continue );
FOOTPRINT* parentFP = board_item->GetParentFootprint();
PCB_GROUP* parentGroup = board_item->GetParentGroup();
if( parentGroup ) if( parentGroup )
{ {
@ -2090,46 +2101,47 @@ int EDIT_TOOL::MoveExact( const TOOL_EVENT& aEvent )
if( IsFootprintEditor() ) if( IsFootprintEditor() )
commit.Modify( selection.Front() ); commit.Modify( selection.Front() );
for( EDA_ITEM* selItem : selection ) for( EDA_ITEM* item : selection )
{ {
BOARD_ITEM* item = static_cast<BOARD_ITEM*>( selItem ); BOARD_ITEM* boardItem = dynamic_cast<BOARD_ITEM*>( item );
if( !item->IsNew() && !IsFootprintEditor() ) wxCHECK2( boardItem, continue );
if( !boardItem->IsNew() && !IsFootprintEditor() )
{ {
commit.Modify( item ); commit.Modify( boardItem );
if( item->Type() == PCB_GROUP_T ) if( boardItem->Type() == PCB_GROUP_T )
{ {
PCB_GROUP* group = static_cast<PCB_GROUP*>( item ); PCB_GROUP* group = static_cast<PCB_GROUP*>( boardItem );
group->RunOnDescendants( [&]( BOARD_ITEM* bItem ) group->RunOnDescendants( [&]( BOARD_ITEM* descendant )
{ {
commit.Modify( bItem ); commit.Modify( descendant );
}); });
} }
} }
if( !item->GetParent() || !item->GetParent()->IsSelected() ) if( !boardItem->GetParent() || !boardItem->GetParent()->IsSelected() )
item->Move( translation ); boardItem->Move( translation );
switch( rotationAnchor ) switch( rotationAnchor )
{ {
case ROTATE_AROUND_ITEM_ANCHOR: case ROTATE_AROUND_ITEM_ANCHOR:
item->Rotate( item->GetPosition(), angle ); boardItem->Rotate( boardItem->GetPosition(), angle );
break; break;
case ROTATE_AROUND_SEL_CENTER: case ROTATE_AROUND_SEL_CENTER: boardItem->Rotate( selCenter, angle );
item->Rotate( selCenter, angle );
break; break;
case ROTATE_AROUND_USER_ORIGIN: case ROTATE_AROUND_USER_ORIGIN:
item->Rotate( frame()->GetScreen()->m_LocalOrigin, angle ); boardItem->Rotate( frame()->GetScreen()->m_LocalOrigin, angle );
break; break;
case ROTATE_AROUND_AUX_ORIGIN: case ROTATE_AROUND_AUX_ORIGIN:
item->Rotate( board()->GetDesignSettings().GetAuxOrigin(), angle ); boardItem->Rotate( board()->GetDesignSettings().GetAuxOrigin(), angle );
break; break;
} }
if( !m_dragging ) if( !m_dragging )
getView()->Update( item ); getView()->Update( boardItem );
} }
commit.Push( _( "Move exact" ) ); commit.Push( _( "Move exact" ) );
@ -2183,7 +2195,9 @@ int EDIT_TOOL::Duplicate( const TOOL_EVENT& aEvent )
for( EDA_ITEM* item : selection ) for( EDA_ITEM* item : selection )
{ {
BOARD_ITEM* dupe_item = nullptr; BOARD_ITEM* dupe_item = nullptr;
BOARD_ITEM* orig_item = static_cast<BOARD_ITEM*>( item ); BOARD_ITEM* orig_item = dynamic_cast<BOARD_ITEM*>( item );
wxCHECK2( orig_item, continue );
if( m_isFootprintEditor ) if( m_isFootprintEditor )
{ {
@ -2324,9 +2338,7 @@ void EDIT_TOOL::PadFilter( const VECTOR2I&, GENERAL_COLLECTOR& aCollector,
{ {
for( int i = aCollector.GetCount() - 1; i >= 0; i-- ) for( int i = aCollector.GetCount() - 1; i >= 0; i-- )
{ {
BOARD_ITEM* item = static_cast<BOARD_ITEM*>( aCollector[i] ); if( aCollector[i]->Type() != PCB_PAD_T )
if( item->Type() != PCB_PAD_T )
aCollector.Remove( i ); aCollector.Remove( i );
} }
} }
@ -2337,9 +2349,7 @@ void EDIT_TOOL::FootprintFilter( const VECTOR2I&, GENERAL_COLLECTOR& aCollector,
{ {
for( int i = aCollector.GetCount() - 1; i >= 0; i-- ) for( int i = aCollector.GetCount() - 1; i >= 0; i-- )
{ {
BOARD_ITEM* item = static_cast<BOARD_ITEM*>( aCollector[i] ); if( aCollector[i]->Type() != PCB_FOOTPRINT_T )
if( item->Type() != PCB_FOOTPRINT_T )
aCollector.Remove( i ); aCollector.Remove( i );
} }
} }
@ -2357,9 +2367,8 @@ bool EDIT_TOOL::updateModificationPoint( PCB_SELECTION& aSelection )
// When there is only one item selected, the reference point is its position... // When there is only one item selected, the reference point is its position...
if( aSelection.Size() == 1 ) if( aSelection.Size() == 1 )
{ {
auto item = static_cast<BOARD_ITEM*>( aSelection.Front() ); if( BOARD_ITEM* item = dynamic_cast<BOARD_ITEM*>( aSelection.Front() ) )
auto pos = item->GetPosition(); aSelection.SetReferencePoint( item->GetPosition() );
aSelection.SetReferencePoint( VECTOR2I( pos.x, pos.y ) );
} }
// ...otherwise modify items with regard to the grid-snapped center position // ...otherwise modify items with regard to the grid-snapped center position
else else
@ -2491,7 +2500,10 @@ int EDIT_TOOL::copyToClipboard( const TOOL_EVENT& aEvent )
std::vector<BOARD_ITEM*> items; std::vector<BOARD_ITEM*> items;
for( EDA_ITEM* item : selection ) for( EDA_ITEM* item : selection )
items.push_back( static_cast<BOARD_ITEM*>( item ) ); {
if( BOARD_ITEM* boardItem = dynamic_cast<BOARD_ITEM*>( item ) )
items.push_back( boardItem );
}
VECTOR2I refPoint; VECTOR2I refPoint;

View File

@ -95,9 +95,9 @@ int EDIT_TOOL::Swap( const TOOL_EVENT& aEvent )
if( item->Type() == PCB_GROUP_T ) if( item->Type() == PCB_GROUP_T )
{ {
PCB_GROUP* group = static_cast<PCB_GROUP*>( item ); PCB_GROUP* group = static_cast<PCB_GROUP*>( item );
group->RunOnDescendants( [&]( BOARD_ITEM* bItem ) group->RunOnDescendants( [&]( BOARD_ITEM* descendant )
{ {
commit->Modify( bItem ); commit->Modify( descendant );
}); });
} }
} }
@ -105,8 +105,10 @@ int EDIT_TOOL::Swap( const TOOL_EVENT& aEvent )
for( size_t i = 0; i < sorted.size() - 1; i++ ) for( size_t i = 0; i < sorted.size() - 1; i++ )
{ {
BOARD_ITEM* a = static_cast<BOARD_ITEM*>( sorted[i] ); BOARD_ITEM* a = dynamic_cast<BOARD_ITEM*>( sorted[i] );
BOARD_ITEM* b = static_cast<BOARD_ITEM*>( sorted[( i + 1 ) % sorted.size()] ); BOARD_ITEM* b = dynamic_cast<BOARD_ITEM*>( sorted[( i + 1 ) % sorted.size()] );
wxCHECK2( a && b, continue );
// Swap X,Y position // Swap X,Y position
VECTOR2I aPos = a->GetPosition(), bPos = b->GetPosition(); VECTOR2I aPos = a->GetPosition(), bPos = b->GetPosition();
@ -404,7 +406,10 @@ bool EDIT_TOOL::doMoveSelection( const TOOL_EVENT& aEvent, BOARD_COMMIT* aCommit
orig_items.clear(); orig_items.clear();
for( EDA_ITEM* item : selection.GetItemsSortedBySelectionOrder() ) for( EDA_ITEM* item : selection.GetItemsSortedBySelectionOrder() )
orig_items.push_back( static_cast<BOARD_ITEM*>( item ) ); {
if( BOARD_ITEM* boardItem = dynamic_cast<BOARD_ITEM*>( item ) )
orig_items.push_back( boardItem );
}
updateStatusPopup( orig_items[ itemIdx ], itemIdx + 1, orig_items.size() ); updateStatusPopup( orig_items[ itemIdx ], itemIdx + 1, orig_items.size() );
statusPopup.Popup(); statusPopup.Popup();

View File

@ -91,7 +91,9 @@ std::vector<std::pair<BOARD_ITEM*, BOX2I>> GetBoundingBoxes( const T& aItems )
for( EDA_ITEM* item : aItems ) for( EDA_ITEM* item : aItems )
{ {
BOARD_ITEM* boardItem = static_cast<BOARD_ITEM*>( item ); BOARD_ITEM* boardItem = dynamic_cast<BOARD_ITEM*>( item );
wxCHECK2( boardItem, continue );
if( item->Type() == PCB_FOOTPRINT_T ) if( item->Type() == PCB_FOOTPRINT_T )
{ {
@ -163,7 +165,9 @@ size_t ALIGN_DISTRIBUTE_TOOL::GetSelections( std::vector<std::pair<BOARD_ITEM*,
for( EDA_ITEM* item : selection ) for( EDA_ITEM* item : selection )
{ {
BOARD_ITEM* boardItem = static_cast<BOARD_ITEM*>( item ); BOARD_ITEM* boardItem = dynamic_cast<BOARD_ITEM*>( item );
wxCHECK2( boardItem, continue );
// We do not lock items in the footprint editor // We do not lock items in the footprint editor
if( boardItem->IsLocked() && m_frame->IsType( FRAME_PCB_EDITOR ) ) if( boardItem->IsLocked() && m_frame->IsType( FRAME_PCB_EDITOR ) )

View File

@ -127,27 +127,30 @@ int POSITION_RELATIVE_TOOL::RelativeItemSelectionMove( const VECTOR2I& aPosAncho
for( EDA_ITEM* item : m_selection ) for( EDA_ITEM* item : m_selection )
{ {
// Don't move a pad by itself unless editing the footprint if( BOARD_ITEM* boardItem = dynamic_cast<BOARD_ITEM*>( item ) )
if( item->Type() == PCB_PAD_T
&& !frame()->GetPcbNewSettings()->m_AllowFreePads
&& frame()->IsType( FRAME_PCB_EDITOR ) )
{ {
item = item->GetParent(); // Don't move a pad by itself unless editing the footprint
if( boardItem->Type() == PCB_PAD_T
&& !frame()->GetPcbNewSettings()->m_AllowFreePads
&& frame()->IsType( FRAME_PCB_EDITOR ) )
{
boardItem = boardItem->GetParent();
}
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 );
} }
m_commit->Modify( item );
// 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 )
{
m_commit->Modify( bItem );
});
}
static_cast<BOARD_ITEM*>( item )->Move( aggregateTranslation );
} }
m_commit->Push( _( "Position Relative" ) ); m_commit->Push( _( "Position Relative" ) );

View File

@ -112,39 +112,37 @@ static bool TestForExistingItem( BOARD* aPcb, BOARD_ITEM* aItem )
{ {
for( PCB_TRACK* item : aPcb->Tracks() ) for( PCB_TRACK* item : aPcb->Tracks() )
{ {
if( aItem == static_cast<BOARD_ITEM*>( item ) ) if( aItem == item)
return true; return true;
} }
for( FOOTPRINT* item : aPcb->Footprints() ) for( FOOTPRINT* item : aPcb->Footprints() )
{ {
if( aItem == static_cast<BOARD_ITEM*>( item ) ) if( aItem == item )
return true; return true;
} }
for( BOARD_ITEM* item : aPcb->Drawings() ) for( BOARD_ITEM* item : aPcb->Drawings() )
{ {
if( aItem == static_cast<BOARD_ITEM*>( item ) ) if( aItem == item )
return true; return true;
} }
for( ZONE* item : aPcb->Zones() ) for( ZONE* item : aPcb->Zones() )
{ {
if( aItem == static_cast<BOARD_ITEM*>( item ) ) if( aItem == item )
return true; return true;
} }
NETINFO_LIST& netInfo = aPcb->GetNetInfo(); for( const NETINFO_ITEM* item : aPcb->GetNetInfo() )
for( NETINFO_LIST::iterator i = netInfo.begin(); i != netInfo.end(); ++i )
{ {
if( aItem == static_cast<BOARD_ITEM*>( *i ) ) if( aItem == item )
return true; return true;
} }
for( PCB_GROUP* item : aPcb->Groups() ) for( PCB_GROUP* item : aPcb->Groups() )
{ {
if( aItem == static_cast<BOARD_ITEM*>( item ) ) if( aItem == item )
return true; return true;
} }
@ -536,14 +534,20 @@ void PCB_BASE_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList )
case UNDO_REDO::REGROUP: case UNDO_REDO::REGROUP:
aList->SetPickedItemStatus( UNDO_REDO::UNGROUP, ii ); aList->SetPickedItemStatus( UNDO_REDO::UNGROUP, ii );
static_cast<BOARD_ITEM*>( eda_item )->SetParentGroup( nullptr );
if( BOARD_ITEM* boardItem = dynamic_cast<BOARD_ITEM*>( eda_item ) )
boardItem->SetParentGroup( nullptr );
break; break;
case UNDO_REDO::UNGROUP: case UNDO_REDO::UNGROUP:
aList->SetPickedItemStatus( UNDO_REDO::REGROUP, ii ); aList->SetPickedItemStatus( UNDO_REDO::REGROUP, ii );
if( group ) if( BOARD_ITEM* boardItem = dynamic_cast<BOARD_ITEM*>( eda_item ) )
group->AddItem( static_cast<BOARD_ITEM*>( eda_item ) ); {
if( group )
group->AddItem( boardItem );
}
break; break;
@ -626,11 +630,14 @@ void PCB_BASE_EDIT_FRAME::ClearUndoORRedoList( UNDO_REDO_LIST whichList, int aIt
void PCB_BASE_EDIT_FRAME::ClearListAndDeleteItems( PICKED_ITEMS_LIST* aList ) void PCB_BASE_EDIT_FRAME::ClearListAndDeleteItems( PICKED_ITEMS_LIST* aList )
{ {
aList->ClearListAndDeleteItems( []( EDA_ITEM* item ) aList->ClearListAndDeleteItems(
{ []( EDA_ITEM* item )
static_cast<BOARD_ITEM*>( item )->SetParentGroup( nullptr ); {
delete item; if( BOARD_ITEM* boardItem = dynamic_cast<BOARD_ITEM*>( item ) )
} ); boardItem->SetParentGroup( nullptr );
delete item;
} );
} }