Browse Source

Static cast safety.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/20958

(cherry picked from commit 116bd924c2)
9.0
Jeff Young 4 months ago
parent
commit
0a946a3d23
  1. 20
      eeschema/tools/ee_grid_helper.cpp
  2. 2
      pcbnew/python/scripting/pcbnew_action_plugins.cpp
  3. 3
      pcbnew/python/scripting/pcbnew_scripting_helpers.cpp
  4. 5
      pcbnew/router/router_tool.cpp
  5. 6
      pcbnew/tools/convert_tool.cpp
  6. 6
      pcbnew/tools/drawing_tool.cpp
  7. 5
      pcbnew/tools/edit_tool_move_fct.cpp
  8. 26
      pcbnew/tools/pcb_control.cpp
  9. 17
      pcbnew/tools/pcb_grid_helper.cpp
  10. 2
      pcbnew/tools/pcb_point_editor.cpp
  11. 43
      pcbnew/tools/pcb_selection_tool.cpp
  12. 9
      pcbnew/widgets/pcb_properties_panel.cpp

20
eeschema/tools/ee_grid_helper.cpp

@ -32,6 +32,7 @@
#include <sch_tablecell.h>
#include <sch_painter.h>
#include <tool/tool_manager.h>
#include <sch_tool_base.h>
#include <settings/app_settings.h>
#include <trigo.h>
#include <view/view.h>
@ -327,14 +328,31 @@ std::set<SCH_ITEM*> EE_GRID_HELPER::queryVisible( const BOX2I& aArea,
std::set<SCH_ITEM*> items;
std::vector<KIGFX::VIEW::LAYER_ITEM_PAIR> selectedItems;
KIGFX::VIEW* view = m_toolMgr->GetView();
EDA_DRAW_FRAME* frame = dynamic_cast<EDA_DRAW_FRAME*>( m_toolMgr->GetToolHolder() );
KIGFX::VIEW* view = m_toolMgr->GetView();
view->Query( aArea, selectedItems );
for( const KIGFX::VIEW::LAYER_ITEM_PAIR& it : selectedItems )
{
if( !it.first->IsSCH_ITEM() )
continue;
SCH_ITEM* item = static_cast<SCH_ITEM*>( it.first );
if( frame && frame->IsType( FRAME_SCH_SYMBOL_EDITOR ) )
{
// If we are in the symbol editor, don't use the symbol itself
if( item->Type() == LIB_SYMBOL_T )
continue;
}
else
{
// If we are not in the symbol editor, don't use symbol-editor-private items
if( item->IsPrivate() )
continue;
}
// The item must be visible and on an active layer
if( view->IsVisible( item ) && item->ViewGetLOD( it.second, view ) < view->GetScale() )
items.insert ( item );

2
pcbnew/python/scripting/pcbnew_action_plugins.cpp

@ -446,7 +446,7 @@ void PCB_EDIT_FRAME::RebuildAndRefresh()
for( EDA_ITEM* item : selection.GetItems() )
{
if( !item->IsSelected() )
if( !item->IsSelected() && item->IsBOARD_ITEM() )
to_remove.push_back( static_cast<BOARD_ITEM*>( item ) );
}

3
pcbnew/python/scripting/pcbnew_scripting_helpers.cpp

@ -522,7 +522,8 @@ std::deque<BOARD_ITEM*> GetCurrentSelection()
std::for_each( selection.begin(), selection.end(),
[&items]( EDA_ITEM* item )
{
items.push_back( static_cast<BOARD_ITEM*>( item ) );
if( item->IsBOARD_ITEM() )
items.push_back( static_cast<BOARD_ITEM*>( item ) );
} );
}

5
pcbnew/router/router_tool.cpp

@ -2125,7 +2125,7 @@ int ROUTER_TOOL::InlineDrag( const TOOL_EVENT& aEvent )
NeighboringSegmentFilter );
}
if( selection.Empty() )
if( selection.Empty() || !selection.Front()->IsBOARD_ITEM() )
return 0;
// selection gets cleared in the next action, we need a copy of the selected items.
@ -2151,6 +2151,9 @@ int ROUTER_TOOL::InlineDrag( const TOOL_EVENT& aEvent )
{
for( int idx = 1; idx < selection.Size(); ++idx )
{
if( !selection.GetItem( idx )->IsBOARD_ITEM() )
return 0;
if( static_cast<BOARD_ITEM*>( selection.GetItem( idx ) )->Type() != PCB_FOOTPRINT_T )
return 0;

6
pcbnew/tools/convert_tool.cpp

@ -1096,6 +1096,9 @@ int CONVERT_TOOL::CreateLines( const TOOL_EVENT& aEvent )
for( EDA_ITEM* item : selection )
{
if( !item->IsBOARD_ITEM() )
continue;
if( handleGraphicSeg( item ) )
continue;
@ -1426,6 +1429,9 @@ int CONVERT_TOOL::OutsetItems( const TOOL_EVENT& aEvent )
for( EDA_ITEM* item : selection )
{
if( !item->IsBOARD_ITEM() )
continue;
BOARD_ITEM* board_item = static_cast<BOARD_ITEM*>( item );
outset_routine.ProcessItem( *board_item );
}

6
pcbnew/tools/drawing_tool.cpp

@ -3484,6 +3484,9 @@ int DRAWING_TOOL::DrawVia( const TOOL_EVENT& aEvent )
for( const KIGFX::VIEW::LAYER_ITEM_PAIR& it : items )
{
if( !it.first->IsBOARD_ITEM() )
continue;
BOARD_ITEM* item = static_cast<BOARD_ITEM*>( it.first );
if( !( item->GetLayerSet() & lset ).any() )
@ -3690,6 +3693,9 @@ int DRAWING_TOOL::DrawVia( const TOOL_EVENT& aEvent )
for( const KIGFX::VIEW::LAYER_ITEM_PAIR& it : items )
{
if( !it.first->IsBOARD_ITEM() )
continue;
BOARD_ITEM* item = static_cast<BOARD_ITEM*>( it.first );
if( !( item->GetLayerSet() & lset ).any() )

5
pcbnew/tools/edit_tool_move_fct.cpp

@ -540,7 +540,7 @@ bool EDIT_TOOL::doMoveSelection( const TOOL_EVENT& aEvent, BOARD_COMMIT* aCommit
{
// Don't double move child items.
if( !item->GetParent() || !item->GetParent()->IsSelected() )
static_cast<BOARD_ITEM*>( item )->Move( movement );
item->Move( movement );
if( item->Type() == PCB_GENERATOR_T && sel_items.size() == 1 )
{
@ -617,6 +617,9 @@ bool EDIT_TOOL::doMoveSelection( const TOOL_EVENT& aEvent, BOARD_COMMIT* aCommit
// Drag items to the current cursor position
for( EDA_ITEM* item : selection )
{
if( !item->IsBOARD_ITEM() )
continue;
// Don't double move footprint pads, fields, etc.
if( item->GetParent() && item->GetParent()->IsSelected() )
continue;

26
pcbnew/tools/pcb_control.cpp

@ -1167,13 +1167,16 @@ int PCB_CONTROL::Paste( const TOOL_EVENT& aEvent )
clipBoard->Visit(
[&]( EDA_ITEM* item, void* testData )
{
// Anything still on the clipboard didn't get copied and needs to be
// removed from the pasted groups.
BOARD_ITEM* boardItem = static_cast<BOARD_ITEM*>( item );
PCB_GROUP* parentGroup = boardItem->GetParentGroup();
if( item->IsBOARD_ITEM() )
{
// Anything still on the clipboard didn't get copied and needs to be
// removed from the pasted groups.
BOARD_ITEM* boardItem = static_cast<BOARD_ITEM*>( item );
PCB_GROUP* parentGroup = boardItem->GetParentGroup();
if( parentGroup )
parentGroup->RemoveItem( boardItem );
if( parentGroup )
parentGroup->RemoveItem( boardItem );
}
return INSPECT_RESULT::CONTINUE;
},
@ -1430,9 +1433,8 @@ bool PCB_CONTROL::placeBoardItems( BOARD_COMMIT* aCommit, std::vector<BOARD_ITEM
{
selection.SetReferencePoint( VECTOR2I( 0, 0 ) );
}
else
else if( BOARD_ITEM* item = dynamic_cast<BOARD_ITEM*>( selection.GetTopLeftItem() ) )
{
BOARD_ITEM* item = static_cast<BOARD_ITEM*>( selection.GetTopLeftItem() );
selection.SetReferencePoint( item->GetPosition() );
}
@ -1734,14 +1736,14 @@ int PCB_CONTROL::UpdateMessagePanel( const TOOL_EVENT& aEvent )
// Pair selection broken into multiple, optional data, starting with the selected item
// names
BOARD_ITEM* a = static_cast<BOARD_ITEM*>( selection[0] );
BOARD_ITEM* b = static_cast<BOARD_ITEM*>( selection[1] );
BOARD_ITEM* a = dynamic_cast<BOARD_ITEM*>( selection[0] );
BOARD_ITEM* b = dynamic_cast<BOARD_ITEM*>( selection[1] );
msgItems.emplace_back( MSG_PANEL_ITEM( a->GetItemDescription( m_frame, false ),
b->GetItemDescription( m_frame, false ) ) );
BOARD_CONNECTED_ITEM* a_conn = dyn_cast<BOARD_CONNECTED_ITEM*>( a );
BOARD_CONNECTED_ITEM* b_conn = dyn_cast<BOARD_CONNECTED_ITEM*>( b );
BOARD_CONNECTED_ITEM* a_conn = dynamic_cast<BOARD_CONNECTED_ITEM*>( a );
BOARD_CONNECTED_ITEM* b_conn = dynamic_cast<BOARD_CONNECTED_ITEM*>( b );
if( a_conn && b_conn )
{

17
pcbnew/tools/pcb_grid_helper.cpp

@ -573,6 +573,9 @@ VECTOR2I PCB_GRID_HELPER::BestSnapAnchor( const VECTOR2I& aOrigin, const LSET& a
for( EDA_ITEM* item : aItems )
{
if( !item->IsBOARD_ITEM() )
continue;
BOARD_ITEM* boardItem = static_cast<BOARD_ITEM*>( item );
// Null items are allowed to arrive here as they represent geometry that isn't
@ -846,7 +849,7 @@ std::vector<BOARD_ITEM*>
PCB_GRID_HELPER::queryVisible( const BOX2I& aArea, const std::vector<BOARD_ITEM*>& aSkip ) const
{
std::set<BOARD_ITEM*> items;
std::vector<KIGFX::VIEW::LAYER_ITEM_PAIR> selectedItems;
std::vector<KIGFX::VIEW::LAYER_ITEM_PAIR> visibleItems;
PCB_TOOL_BASE* currentTool = static_cast<PCB_TOOL_BASE*>( m_toolMgr->GetCurrentTool() );
KIGFX::VIEW* view = m_toolMgr->GetView();
@ -854,10 +857,13 @@ PCB_GRID_HELPER::queryVisible( const BOX2I& aArea, const std::vector<BOARD_ITEM*
const std::set<int>& activeLayers = settings->GetHighContrastLayers();
bool isHighContrast = settings->GetHighContrast();
view->Query( aArea, selectedItems );
view->Query( aArea, visibleItems );
for( const auto& [ viewItem, layer ] : selectedItems )
for( const auto& [ viewItem, layer ] : visibleItems )
{
if( !viewItem->IsBOARD_ITEM() )
continue;
BOARD_ITEM* boardItem = static_cast<BOARD_ITEM*>( viewItem );
if( currentTool->IsFootprintEditor() )
@ -911,7 +917,8 @@ struct PCB_INTERSECTABLE
// Clang wants this constructor
PCB_INTERSECTABLE( BOARD_ITEM* aItem, INTERSECTABLE_GEOM aSeg ) :
Item( aItem ), Geometry( std::move( aSeg ) )
Item( aItem ),
Geometry( std::move( aSeg ) )
{
}
};
@ -1737,7 +1744,7 @@ PCB_GRID_HELPER::ANCHOR* PCB_GRID_HELPER::nearestAnchor( const VECTOR2I& aPos, i
ecoord distToNearestItem = std::numeric_limits<ecoord>::max();
for( EDA_ITEM* const item : anchor->items )
{
if( !item )
if( !item || !item->IsBOARD_ITEM() )
continue;
std::optional<ecoord> distToThisItem =

2
pcbnew/tools/pcb_point_editor.cpp

@ -2171,7 +2171,7 @@ int PCB_POINT_EDITOR::OnSelectionChange( const TOOL_EVENT& aEvent )
PCB_BASE_EDIT_FRAME* editFrame = getEditFrame<PCB_BASE_EDIT_FRAME>();
const PCB_SELECTION& selection = m_selectionTool->GetSelection();
if( selection.Size() != 1 || selection.Front()->GetEditFlags() )
if( selection.Size() != 1 || selection.Front()->GetEditFlags() || !selection.Front()->IsBOARD_ITEM() )
return 0;
BOARD_ITEM* item = static_cast<BOARD_ITEM*>( selection.Front() );

43
pcbnew/tools/pcb_selection_tool.cpp

@ -724,6 +724,9 @@ PCB_SELECTION& PCB_SELECTION_TOOL::RequestSelection( CLIENT_SELECTION_FILTER aCl
for( EDA_ITEM* item : m_selection )
{
if( !item->IsBOARD_ITEM() )
continue;
BOARD_ITEM* boardItem = static_cast<BOARD_ITEM*>( item );
bool lockedDescendant = false;
@ -1164,6 +1167,9 @@ bool PCB_SELECTION_TOOL::selectMultiple()
for( const KIGFX::VIEW::LAYER_ITEM_PAIR& candidate : candidates )
{
if( !candidate.first->IsBOARD_ITEM() )
continue;
BOARD_ITEM* item = static_cast<BOARD_ITEM*>( candidate.first );
if( item && Selectable( item ) && item->HitTest( selectionRect, !greedySelection )
@ -1191,6 +1197,9 @@ bool PCB_SELECTION_TOOL::selectMultiple()
for( EDA_ITEM* i : collector )
{
if( !i->IsBOARD_ITEM() )
continue;
BOARD_ITEM* item = static_cast<BOARD_ITEM*>( i );
if( m_subtractive || ( m_exclusive_or && item->IsSelected() ) )
@ -1286,12 +1295,14 @@ int PCB_SELECTION_TOOL::SelectAll( const TOOL_EVENT& aEvent )
getView()->Query( selectionBox,
[&]( KIGFX::VIEW_ITEM* viewItem ) -> bool
{
BOARD_ITEM* item = static_cast<BOARD_ITEM*>( viewItem );
if( viewItem->IsBOARD_ITEM() )
{
BOARD_ITEM* item = static_cast<BOARD_ITEM*>( viewItem );
if( !item || !Selectable( item ) || !itemPassesFilter( item, true ) )
return true;
if( item && Selectable( item ) && itemPassesFilter( item, true ) )
collection.Append( item );
}
collection.Append( item );
return true;
} );
@ -1317,12 +1328,14 @@ int PCB_SELECTION_TOOL::UnselectAll( const TOOL_EVENT& aEvent )
getView()->Query( selectionBox,
[&]( KIGFX::VIEW_ITEM* viewItem ) -> bool
{
BOARD_ITEM* item = static_cast<BOARD_ITEM*>( viewItem );
if( viewItem->IsBOARD_ITEM() )
{
BOARD_ITEM* item = static_cast<BOARD_ITEM*>( viewItem );
if( !item || !Selectable( item ) )
return true;
if( item && Selectable( item ) )
unselect( item );
}
unselect( item );
return true;
} );
@ -2565,6 +2578,9 @@ int PCB_SELECTION_TOOL::filterSelection( const TOOL_EVENT& aEvent )
// re-select items from the saved selection according to the dialog options
for( EDA_ITEM* i : selection )
{
if( !i->IsBOARD_ITEM() )
continue;
BOARD_ITEM* item = static_cast<BOARD_ITEM*>( i );
bool include = itemIsIncludedByFilter( *item, board, opts );
@ -2587,6 +2603,9 @@ void PCB_SELECTION_TOOL::FilterCollectedItems( GENERAL_COLLECTOR& aCollector, bo
for( EDA_ITEM* i : aCollector )
{
if( !i->IsBOARD_ITEM() )
continue;
BOARD_ITEM* item = static_cast<BOARD_ITEM*>( i );
if( !itemPassesFilter( item, aMultiSelect ) )
@ -3088,7 +3107,7 @@ bool PCB_SELECTION_TOOL::Selectable( const BOARD_ITEM* aItem, bool checkVisibili
void PCB_SELECTION_TOOL::select( EDA_ITEM* aItem )
{
if( !aItem || aItem->IsSelected() )
if( !aItem || aItem->IsSelected() || !aItem->IsBOARD_ITEM() )
return;
if( aItem->Type() == PCB_PAD_T )
@ -3860,10 +3879,10 @@ void PCB_SELECTION_TOOL::FilterCollectorForFootprints( GENERAL_COLLECTOR& aColle
{
FOOTPRINT* fp = nullptr;
if( item->Type() != PCB_FOOTPRINT_T )
fp = static_cast<BOARD_ITEM*>( item )->GetParentFootprint();
else
if( item->Type() == PCB_FOOTPRINT_T )
fp = static_cast<FOOTPRINT*>( item );
else if( item->IsBOARD_ITEM() )
fp = static_cast<BOARD_ITEM*>( item )->GetParentFootprint();
// If the selection contains items that are not footprints, then don't restrict
// whether we deselect the item or not.

9
pcbnew/widgets/pcb_properties_panel.cpp

@ -164,7 +164,11 @@ wxPGProperty* PCB_PROPERTIES_PANEL::createPGProperty( const PROPERTY_BASE* aProp
PROPERTY_BASE* PCB_PROPERTIES_PANEL::getPropertyFromEvent( const wxPropertyGridEvent& aEvent ) const
{
PCB_SELECTION_TOOL* selectionTool = m_frame->GetToolManager()->GetTool<PCB_SELECTION_TOOL>();
const SELECTION& selection = selectionTool->GetSelection();
const SELECTION& selection = selectionTool->GetSelection();
if( !selection.Front()->IsBOARD_ITEM() )
return nullptr;
BOARD_ITEM* firstItem = static_cast<BOARD_ITEM*>( selection.Front() );
wxCHECK_MSG( firstItem, nullptr,
@ -225,6 +229,9 @@ void PCB_PROPERTIES_PANEL::valueChanged( wxPropertyGridEvent& aEvent )
for( EDA_ITEM* edaItem : selection )
{
if( !edaItem->IsBOARD_ITEM() )
continue;
BOARD_ITEM* item = static_cast<BOARD_ITEM*>( edaItem );
changes.Modify( item );
item->Set( property, newValue );

Loading…
Cancel
Save