diff --git a/eeschema/tools/ee_grid_helper.cpp b/eeschema/tools/ee_grid_helper.cpp index ac052c15dd..94fa22690f 100644 --- a/eeschema/tools/ee_grid_helper.cpp +++ b/eeschema/tools/ee_grid_helper.cpp @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -328,14 +329,31 @@ std::set EE_GRID_HELPER::queryVisible( const BOX2I& aArea, std::set items; std::vector selectedItems; - KIGFX::VIEW* view = m_toolMgr->GetView(); + EDA_DRAW_FRAME* frame = dynamic_cast( 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( 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 ); diff --git a/pcbnew/python/scripting/pcbnew_action_plugins.cpp b/pcbnew/python/scripting/pcbnew_action_plugins.cpp index 45b578263a..f19ac1306d 100644 --- a/pcbnew/python/scripting/pcbnew_action_plugins.cpp +++ b/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( item ) ); } diff --git a/pcbnew/python/scripting/pcbnew_scripting_helpers.cpp b/pcbnew/python/scripting/pcbnew_scripting_helpers.cpp index 9e3065e46e..9141a58db9 100644 --- a/pcbnew/python/scripting/pcbnew_scripting_helpers.cpp +++ b/pcbnew/python/scripting/pcbnew_scripting_helpers.cpp @@ -522,7 +522,8 @@ std::deque GetCurrentSelection() std::for_each( selection.begin(), selection.end(), [&items]( EDA_ITEM* item ) { - items.push_back( static_cast( item ) ); + if( item->IsBOARD_ITEM() ) + items.push_back( static_cast( item ) ); } ); } diff --git a/pcbnew/router/router_tool.cpp b/pcbnew/router/router_tool.cpp index 46e7be0a05..ea5600187c 100644 --- a/pcbnew/router/router_tool.cpp +++ b/pcbnew/router/router_tool.cpp @@ -2124,7 +2124,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. @@ -2150,6 +2150,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( selection.GetItem( idx ) )->Type() != PCB_FOOTPRINT_T ) return 0; diff --git a/pcbnew/tools/convert_tool.cpp b/pcbnew/tools/convert_tool.cpp index cd565597c8..32d497cd27 100644 --- a/pcbnew/tools/convert_tool.cpp +++ b/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( item ); outset_routine.ProcessItem( *board_item ); } diff --git a/pcbnew/tools/drawing_tool.cpp b/pcbnew/tools/drawing_tool.cpp index d6f6433dfc..bfc5c836b1 100644 --- a/pcbnew/tools/drawing_tool.cpp +++ b/pcbnew/tools/drawing_tool.cpp @@ -3465,6 +3465,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( it.first ); if( !( item->GetLayerSet() & lset ).any() ) @@ -3671,6 +3674,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( it.first ); if( !( item->GetLayerSet() & lset ).any() ) diff --git a/pcbnew/tools/edit_tool_move_fct.cpp b/pcbnew/tools/edit_tool_move_fct.cpp index 0efaa4f362..a1333328a6 100644 --- a/pcbnew/tools/edit_tool_move_fct.cpp +++ b/pcbnew/tools/edit_tool_move_fct.cpp @@ -538,7 +538,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( item )->Move( movement ); + item->Move( movement ); if( item->Type() == PCB_GENERATOR_T && sel_items.size() == 1 ) { @@ -626,6 +626,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; diff --git a/pcbnew/tools/pcb_control.cpp b/pcbnew/tools/pcb_control.cpp index 2330475ce2..3a21b930c5 100644 --- a/pcbnew/tools/pcb_control.cpp +++ b/pcbnew/tools/pcb_control.cpp @@ -1204,13 +1204,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( item ); - EDA_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( item ); + EDA_GROUP* parentGroup = boardItem->GetParentGroup(); - if( parentGroup ) - parentGroup->RemoveItem( boardItem ); + if( parentGroup ) + parentGroup->RemoveItem( boardItem ); + } return INSPECT_RESULT::CONTINUE; }, @@ -1602,9 +1605,8 @@ bool PCB_CONTROL::placeBoardItems( BOARD_COMMIT* aCommit, std::vector( selection.GetTopLeftItem() ) ) { - BOARD_ITEM* item = static_cast( selection.GetTopLeftItem() ); selection.SetReferencePoint( item->GetPosition() ); } @@ -1957,14 +1959,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( selection[0] ); - BOARD_ITEM* b = static_cast( selection[1] ); + BOARD_ITEM* a = dynamic_cast( selection[0] ); + BOARD_ITEM* b = dynamic_cast( 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( a ); - BOARD_CONNECTED_ITEM* b_conn = dyn_cast( b ); + BOARD_CONNECTED_ITEM* a_conn = dynamic_cast( a ); + BOARD_CONNECTED_ITEM* b_conn = dynamic_cast( b ); if( a_conn && b_conn ) { diff --git a/pcbnew/tools/pcb_grid_helper.cpp b/pcbnew/tools/pcb_grid_helper.cpp index 587d5623bb..e08d410d96 100644 --- a/pcbnew/tools/pcb_grid_helper.cpp +++ b/pcbnew/tools/pcb_grid_helper.cpp @@ -69,7 +69,7 @@ std::optional GetBoardIntersectable( const BOARD_ITEM& aItem { case PCB_SHAPE_T: { - PCB_SHAPE shape = static_cast( aItem ); + const PCB_SHAPE& shape = static_cast( aItem ); switch( shape.GetShape() ) { @@ -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( item ); // Null items are allowed to arrive here as they represent geometry that isn't @@ -846,7 +849,7 @@ std::vector PCB_GRID_HELPER::queryVisible( const BOX2I& aArea, const std::vector& aSkip ) const { std::set items; - std::vector selectedItems; + std::vector visibleItems; PCB_TOOL_BASE* currentTool = static_cast( m_toolMgr->GetCurrentTool() ); KIGFX::VIEW* view = m_toolMgr->GetView(); @@ -854,10 +857,13 @@ PCB_GRID_HELPER::queryVisible( const BOX2I& aArea, const std::vector& 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( viewItem ); if( currentTool->IsFootprintEditor() ) @@ -912,7 +918,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 for( EDA_ITEM* const item : anchor->items ) { - if( !item ) + if( !item || !item->IsBOARD_ITEM() ) continue; std::optional distToThisItem = diff --git a/pcbnew/tools/pcb_point_editor.cpp b/pcbnew/tools/pcb_point_editor.cpp index 816b844a4d..104fe59c34 100644 --- a/pcbnew/tools/pcb_point_editor.cpp +++ b/pcbnew/tools/pcb_point_editor.cpp @@ -1774,7 +1774,7 @@ int PCB_POINT_EDITOR::OnSelectionChange( const TOOL_EVENT& aEvent ) PCB_BASE_EDIT_FRAME* editFrame = getEditFrame(); 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( selection.Front() ); diff --git a/pcbnew/tools/pcb_selection_tool.cpp b/pcbnew/tools/pcb_selection_tool.cpp index 33320fb1a0..3781c77519 100644 --- a/pcbnew/tools/pcb_selection_tool.cpp +++ b/pcbnew/tools/pcb_selection_tool.cpp @@ -725,6 +725,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( item ); bool lockedDescendant = false; @@ -1166,6 +1169,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( candidate.first ); if( item && Selectable( item ) && item->HitTest( selectionRect, !greedySelection ) @@ -1207,6 +1213,9 @@ bool PCB_SELECTION_TOOL::selectMultiple() for( EDA_ITEM* i : collector ) { + if( !i->IsBOARD_ITEM() ) + continue; + BOARD_ITEM* item = static_cast( i ); if( m_subtractive || ( m_exclusive_or && item->IsSelected() ) ) @@ -1302,12 +1311,14 @@ int PCB_SELECTION_TOOL::SelectAll( const TOOL_EVENT& aEvent ) getView()->Query( selectionBox, [&]( KIGFX::VIEW_ITEM* viewItem ) -> bool { - BOARD_ITEM* item = static_cast( viewItem ); + if( viewItem->IsBOARD_ITEM() ) + { + BOARD_ITEM* item = static_cast( 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; } ); @@ -1333,12 +1344,14 @@ int PCB_SELECTION_TOOL::UnselectAll( const TOOL_EVENT& aEvent ) getView()->Query( selectionBox, [&]( KIGFX::VIEW_ITEM* viewItem ) -> bool { - BOARD_ITEM* item = static_cast( viewItem ); + if( viewItem->IsBOARD_ITEM() ) + { + BOARD_ITEM* item = static_cast( viewItem ); - if( !item || !Selectable( item ) ) - return true; + if( item && Selectable( item ) ) + unselect( item ); + } - unselect( item ); return true; } ); @@ -2626,6 +2639,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( i ); bool include = itemIsIncludedByFilter( *item, board, opts ); @@ -2648,6 +2664,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( i ); if( !itemPassesFilter( item, aMultiSelect ) ) @@ -3149,7 +3168,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 ) @@ -3921,10 +3940,10 @@ void PCB_SELECTION_TOOL::FilterCollectorForFootprints( GENERAL_COLLECTOR& aColle { FOOTPRINT* fp = nullptr; - if( item->Type() != PCB_FOOTPRINT_T ) - fp = static_cast( item )->GetParentFootprint(); - else + if( item->Type() == PCB_FOOTPRINT_T ) fp = static_cast( item ); + else if( item->IsBOARD_ITEM() ) + fp = static_cast( item )->GetParentFootprint(); // If the selection contains items that are not footprints, then don't restrict // whether we deselect the item or not. diff --git a/pcbnew/widgets/pcb_properties_panel.cpp b/pcbnew/widgets/pcb_properties_panel.cpp index c446602acf..7a6064e778 100644 --- a/pcbnew/widgets/pcb_properties_panel.cpp +++ b/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(); - const SELECTION& selection = selectionTool->GetSelection(); + const SELECTION& selection = selectionTool->GetSelection(); + + if( !selection.Front()->IsBOARD_ITEM() ) + return nullptr; + BOARD_ITEM* firstItem = static_cast( 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( edaItem ); changes.Modify( item ); item->Set( property, newValue );