From f4a3062684f485d1e83e6a146f63dfc813c30278 Mon Sep 17 00:00:00 2001 From: Mike Williams Date: Tue, 20 Sep 2022 09:35:47 -0400 Subject: [PATCH] PCB: Select Unconnected Selects the all unconnected items for each selected routable item. --- pcbnew/pcb_edit_frame.cpp | 2 ++ pcbnew/tools/pcb_actions.cpp | 6 ++++ pcbnew/tools/pcb_actions.h | 3 ++ pcbnew/tools/pcb_selection_tool.cpp | 49 +++++++++++++++++++++++++++++ pcbnew/tools/pcb_selection_tool.h | 5 +++ 5 files changed, 65 insertions(+) diff --git a/pcbnew/pcb_edit_frame.cpp b/pcbnew/pcb_edit_frame.cpp index 39e4b2d38a..05b8a1f965 100644 --- a/pcbnew/pcb_edit_frame.cpp +++ b/pcbnew/pcb_edit_frame.cpp @@ -833,6 +833,8 @@ void PCB_EDIT_FRAME::setupUIConditions() ENABLE( SELECTION_CONDITIONS::OnlyTypes( { PCB_TRACE_T, PCB_ARC_T, PCB_VIA_T } ) ) ); mgr->SetConditions( PCB_ACTIONS::deselectNet, ENABLE( SELECTION_CONDITIONS::OnlyTypes( { PCB_TRACE_T, PCB_ARC_T, PCB_VIA_T } ) ) ); + mgr->SetConditions( PCB_ACTIONS::selectUnconnected, + ENABLE( SELECTION_CONDITIONS::OnlyTypes( { PCB_FOOTPRINT_T, PCB_PAD_T, PCB_TRACE_T, PCB_ARC_T, PCB_VIA_T } ) ) ); mgr->SetConditions( PCB_ACTIONS::selectSameSheet, ENABLE( SELECTION_CONDITIONS::OnlyTypes( { PCB_FOOTPRINT_T } ) ) ); mgr->SetConditions( PCB_ACTIONS::selectOnSchematic, diff --git a/pcbnew/tools/pcb_actions.cpp b/pcbnew/tools/pcb_actions.cpp index 4b87e6c8f4..b26584432b 100644 --- a/pcbnew/tools/pcb_actions.cpp +++ b/pcbnew/tools/pcb_actions.cpp @@ -1314,6 +1314,12 @@ TOOL_ACTION PCB_ACTIONS::deselectNet( "pcbnew.InteractiveSelection.DeselectNet", _( "Deselect All Tracks in Net" ), _( "Deselects all tracks & vias belonging to the same net." ) ); +TOOL_ACTION PCB_ACTIONS::selectUnconnected( "pcbnew.InteractiveSelection.SelectUnconnected", + AS_GLOBAL, + 'O', "", + _( "Select All Unconnected Footprints" ), + _( "Selects all unconnected footprints belonging to each selected net." ) ); + TOOL_ACTION PCB_ACTIONS::selectOnSheetFromEeschema( "pcbnew.InteractiveSelection.SelectOnSheet", AS_GLOBAL, 0, "", _( "Sheet" ), diff --git a/pcbnew/tools/pcb_actions.h b/pcbnew/tools/pcb_actions.h index 3be38a9308..2b823cde63 100644 --- a/pcbnew/tools/pcb_actions.h +++ b/pcbnew/tools/pcb_actions.h @@ -88,6 +88,9 @@ public: /// Remove all connections belonging to a single net from the active selection static TOOL_ACTION deselectNet; + /// Select unconnected footprints from ratsnest of selection + static TOOL_ACTION selectUnconnected; + /// Select all components on sheet from Eeschema crossprobing. static TOOL_ACTION selectOnSheetFromEeschema; diff --git a/pcbnew/tools/pcb_selection_tool.cpp b/pcbnew/tools/pcb_selection_tool.cpp index 5a34c89b1c..7f8fee789d 100644 --- a/pcbnew/tools/pcb_selection_tool.cpp +++ b/pcbnew/tools/pcb_selection_tool.cpp @@ -61,6 +61,7 @@ using namespace std::placeholders; #include #include #include +#include #include #include #include @@ -87,6 +88,8 @@ public: // Add( PCB_ACTIONS::deselectNet ); Add( PCB_ACTIONS::selectSameSheet ); Add( PCB_ACTIONS::selectOnSchematic ); + + Add( PCB_ACTIONS::selectUnconnected ); } private: @@ -1397,6 +1400,51 @@ void PCB_SELECTION_TOOL::selectAllConnectedTracks( } +int PCB_SELECTION_TOOL::selectUnconnected( const TOOL_EVENT& aEvent ) +{ + // Get all pads + std::vector pads; + + for( EDA_ITEM* item : m_selection.GetItems() ) + { + if( item->Type() == PCB_FOOTPRINT_T ) + { + for( PAD* pad : static_cast( item )->Pads() ) + pads.push_back( pad ); + } + else if( item->Type() == PCB_PAD_T ) + { + pads.push_back( static_cast( item ) ); + } + } + + // Select every footprint on the end of the ratsnest for each pad in our selection + std::shared_ptr conn = board()->GetConnectivity(); + + for( PAD* pad : pads ) + { + for( const CN_EDGE& edge : conn->GetRatsnestForPad( pad ) ) + { + BOARD_CONNECTED_ITEM* sourceParent = edge.GetSourceNode()->Parent(); + BOARD_CONNECTED_ITEM* targetParent = edge.GetTargetNode()->Parent(); + + if( sourceParent == pad ) + { + if( targetParent->Type() == PCB_PAD_T ) + select( static_cast( targetParent )->GetParent() ); + } + else if( targetParent == pad ) + { + if( sourceParent->Type() == PCB_PAD_T ) + select( static_cast( sourceParent )->GetParent() ); + } + } + } + + return 0; +} + + void PCB_SELECTION_TOOL::SelectAllItemsOnNet( int aNetCode, bool aSelect ) { std::shared_ptr conn = board()->GetConnectivity(); @@ -2988,6 +3036,7 @@ void PCB_SELECTION_TOOL::setTransitions() Go( &PCB_SELECTION_TOOL::unrouteSelected, PCB_ACTIONS::unrouteSelected.MakeEvent() ); Go( &PCB_SELECTION_TOOL::selectNet, PCB_ACTIONS::selectNet.MakeEvent() ); Go( &PCB_SELECTION_TOOL::selectNet, PCB_ACTIONS::deselectNet.MakeEvent() ); + Go( &PCB_SELECTION_TOOL::selectUnconnected, PCB_ACTIONS::selectUnconnected.MakeEvent() ); Go( &PCB_SELECTION_TOOL::syncSelection, PCB_ACTIONS::syncSelection.MakeEvent() ); Go( &PCB_SELECTION_TOOL::syncSelectionWithNets, PCB_ACTIONS::syncSelectionWithNets.MakeEvent() ); diff --git a/pcbnew/tools/pcb_selection_tool.h b/pcbnew/tools/pcb_selection_tool.h index 826f943e7e..667e6f34fc 100644 --- a/pcbnew/tools/pcb_selection_tool.h +++ b/pcbnew/tools/pcb_selection_tool.h @@ -298,6 +298,11 @@ private: */ int selectNet( const TOOL_EVENT& aEvent ); + /** + * Select nearest unconnected footprints on same net as selected items. + */ + int selectUnconnected( const TOOL_EVENT& aEvent ); + enum STOP_CONDITION { /**