← Back to team overview

kicad-developers team mailing list archive

Re: Selection tool that selects components and local connections

 

Sure! here comes!

- Kristoffer

On 2017-02-11 03:02, Chris Pavlina wrote:
Can you update this again?

On Fri, Feb 10, 2017 at 01:45:10PM +0100, Kristoffer Ödmark wrote:
Updated the patch to fit on current master.


On 2017-02-08 21:14, Kristoffer Ödmark wrote:
I tried reverting back to master and found the same strange bugs on
windows, so i do not think my patch causes them.

example of bug:
https://snag.gy/EesP2n.jpg

On 2017-02-08 19:17, Kristoffer Ödmark wrote:
Hello again!

Since my groupselection required changes to the file format to be
useful. I have now created a selection tool that selects all footprints
belonging on the same sheet or "deeper".

It also finds all nets that only have connections between components on
the same or deeper sheet and selects them.

It gives some functionality of the group selection idea and does not
break file format or any previous workflow.

Tested on linux, saw some strange right-click meny errors on windows,
but the functionality works there as well when using the shortcut key 'P'

Attaching patch

Video:
https://www.youtube.com/watch?v=DUskyc7t_HA&feature=youtu.be

- Kristoffer



>From 69d076ca2052907affd62b64521936072f10c36f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Kristoffer=20=C3=96dmark?= <kristoffer.odmark90@xxxxxxxxx>
Date: Wed, 8 Feb 2017 17:32:41 +0100
Subject: [PATCH 1/2] Enables selection of components and tracks on same sheet.

Modifies the selection menu to be adaptive and disable selection options
that are not possible.

Adds a new selection option that is only available when selecting
modules, this tool will select all footprints on the same sheet level or
belonging to subsheets. It will also search for nets that are only
connecting between modules on the same sheet or lower and select every
segment and via belonging to it.

	modified:   tools/common_actions.cpp
	modified:   tools/common_actions.h
	modified:   tools/selection_tool.cpp
	modified:   tools/selection_tool.h
---
 pcbnew/tools/common_actions.cpp |   4 ++
 pcbnew/tools/common_actions.h   |   2 +
 pcbnew/tools/selection_tool.cpp | 133 +++++++++++++++++++++++++++++++++++++++-
 pcbnew/tools/selection_tool.h   |   3 +
 4 files changed, 139 insertions(+), 3 deletions(-)

diff --git a/pcbnew/tools/common_actions.cpp b/pcbnew/tools/common_actions.cpp
index 36915b82c..e01bd900f 100644
--- a/pcbnew/tools/common_actions.cpp
+++ b/pcbnew/tools/common_actions.cpp
@@ -66,6 +66,10 @@ TOOL_ACTION COMMON_ACTIONS::selectNet( "pcbnew.InteractiveSelection.SelectNet",
         AS_GLOBAL, 0,
         _( "Whole Net" ), _( "Selects all tracks & vias belonging to the same net." ) );
 
+TOOL_ACTION COMMON_ACTIONS::selectSameSheet( "pcbnew.InteractiveSelection.SelectSameSheet",
+        AS_GLOBAL,  'P',
+        _( "Same Sheet" ), _( "Selects all modules and tracks in the same schematic sheet" ) );
+
 TOOL_ACTION COMMON_ACTIONS::find( "pcbnew.InteractiveSelection.Find",
         AS_GLOBAL, 0, //TOOL_ACTION::LegacyHotKey( HK_FIND_ITEM ), // handled by wxWidgets
         _( "Find Item" ), _( "Searches the document for an item" ), find_xpm );
diff --git a/pcbnew/tools/common_actions.h b/pcbnew/tools/common_actions.h
index f5172f748..11b8b7251 100644
--- a/pcbnew/tools/common_actions.h
+++ b/pcbnew/tools/common_actions.h
@@ -66,6 +66,8 @@ public:
     /// Selects all connections belonging to a single net.
     static TOOL_ACTION selectNet;
 
+    /// Selects all components on the same sheet.
+    static TOOL_ACTION selectSameSheet;
     // Edit Tool
     /// Activation of the edit tool
     static TOOL_ACTION editActivate;
diff --git a/pcbnew/tools/selection_tool.cpp b/pcbnew/tools/selection_tool.cpp
index 760e3a1ea..6392c6927 100644
--- a/pcbnew/tools/selection_tool.cpp
+++ b/pcbnew/tools/selection_tool.cpp
@@ -62,9 +62,28 @@ public:
         Add( COMMON_ACTIONS::selectConnection );
         Add( COMMON_ACTIONS::selectCopper );
         Add( COMMON_ACTIONS::selectNet );
+        Add( COMMON_ACTIONS::selectSameSheet );
     }
 
 private:
+
+    void update() override
+    {
+        SELECTION_TOOL* selTool = getToolManager()->GetTool<SELECTION_TOOL>();
+
+        // lines like this make me really think about a better name for SELECTION_CONDITIONS class
+        bool selEnabled =  ( SELECTION_CONDITIONS::OnlyType( PCB_VIA_T )
+                || SELECTION_CONDITIONS::OnlyType( PCB_TRACE_T ) )
+                              ( selTool->GetSelection() );
+
+        bool sheetSelEnabled = ( SELECTION_CONDITIONS::OnlyType( PCB_MODULE_T ) )
+                              ( selTool->GetSelection() );
+
+        Enable( getMenuId( COMMON_ACTIONS::selectNet ), selEnabled );
+        Enable( getMenuId( COMMON_ACTIONS::selectCopper ), selEnabled );
+        Enable( getMenuId( COMMON_ACTIONS::selectConnection ), selEnabled );
+        Enable( getMenuId( COMMON_ACTIONS::selectSameSheet ), sheetSelEnabled );
+    }
     CONTEXT_MENU* create() const override
     {
         return new SELECT_MENU();
@@ -92,9 +111,10 @@ bool SELECTION_TOOL::Init()
 {
     using S_C = SELECTION_CONDITIONS;
 
-    // can show the select menu as long as there is something the
-    // subitems can be run on
-    auto showSelectMenuFunctor = ( S_C::HasType( PCB_VIA_T ) || S_C::HasType( PCB_TRACE_T ) );
+    auto showSelectMenuFunctor = ( S_C::OnlyType( PCB_VIA_T ) ||
+            S_C::OnlyType( PCB_TRACE_T ) ||
+            S_C::OnlyType( PCB_MODULE_T ) ) &&
+            S_C::Count( 1 );
 
     auto selectMenu = std::make_shared<SELECT_MENU>();
     selectMenu->SetTool( this );
@@ -458,6 +478,7 @@ void SELECTION_TOOL::SetTransitions()
     Go( &SELECTION_TOOL::selectConnection, COMMON_ACTIONS::selectConnection.MakeEvent() );
     Go( &SELECTION_TOOL::selectCopper, COMMON_ACTIONS::selectCopper.MakeEvent() );
     Go( &SELECTION_TOOL::selectNet, COMMON_ACTIONS::selectNet.MakeEvent() );
+    Go( &SELECTION_TOOL::selectSameSheet, COMMON_ACTIONS::selectSameSheet.MakeEvent() );
 }
 
 
@@ -686,6 +707,112 @@ int SELECTION_TOOL::selectNet( const TOOL_EVENT& aEvent )
     return 0;
 }
 
+int SELECTION_TOOL::selectSameSheet( const TOOL_EVENT& aEvent )
+{
+    if( !selectCursor( true ) )
+        return 0;
+
+    // this function currently only supports modules since they are only
+    // on one sheet.
+    auto item = m_selection.Front();
+    if( item->Type() != PCB_MODULE_T )
+        return 0;
+    if( !item )
+        return 0;
+    auto mod = dynamic_cast<MODULE*>( item );
+
+    clearSelection();
+
+    // get the lowest subsheet name for this.
+    wxString sheetPath = mod->GetPath();
+    sheetPath = sheetPath.BeforeLast( '/' );
+    sheetPath = sheetPath.AfterLast( '/' );
+
+    auto modules = board()->m_Modules.GetFirst();
+    std::list<MODULE*> modList;
+
+    // store all modules that are on that sheet
+    for( MODULE* item = modules; item; item = item->Next() )
+    {
+        if ( item != NULL && item->GetPath().Contains( sheetPath ) )
+        {
+            modList.push_back( item );
+        }
+    }
+
+    //Generate a list of all pads, and of all nets they belong to.
+    std::list<int> netcodeList;
+    for( MODULE* mod : modList )
+    {
+        for( D_PAD* pad = mod->Pads().GetFirst(); pad; pad = pad->Next() )
+        {
+            if( pad->IsConnected() )
+            {
+                netcodeList.push_back( pad->GetNetCode() );
+            }
+        }
+    }
+
+    // remove all duplicates
+    netcodeList.sort();
+    netcodeList.unique();
+
+    // now we need to find all modules that are connected to each of these nets
+    // then we need to determine if these modules are in the list of modules
+    // belonging to this sheet ( modList )
+    RN_DATA* ratsnest = getModel<BOARD>()->GetRatsnest();
+    std::list<int> removeCodeList;
+    for( int netCode : netcodeList )
+    {
+        std::list<BOARD_CONNECTED_ITEM*> netPads;
+        ratsnest->GetNetItems( netCode, netPads, (RN_ITEM_TYPE)( RN_PADS ) );
+        for( BOARD_CONNECTED_ITEM* item : netPads )
+        {
+            bool found = ( std::find( modList.begin(), modList.end(), item->GetParent() ) != modList.end() );
+            if( !found )
+            {
+                // if we cannot find the module of the pad in the modList
+                // then we can assume that that module is not located in the same
+                // schematic, therefore invalidate this netcode.
+                removeCodeList.push_back( netCode );
+                break;
+            }
+        }
+    }
+
+    // remove all duplicates
+    removeCodeList.sort();
+    removeCodeList.unique();
+
+    for( int removeCode : removeCodeList )
+    {
+        netcodeList.remove( removeCode );
+    }
+
+    std::list<BOARD_CONNECTED_ITEM*> localConnectionList;
+    for( int netCode : netcodeList )
+    {
+        ratsnest->GetNetItems( netCode, localConnectionList, (RN_ITEM_TYPE)( RN_TRACKS | RN_VIAS ) );
+    }
+
+    for( BOARD_ITEM* i : modList )
+    {
+        if( i != NULL )
+            select( i );
+    }
+    for( BOARD_CONNECTED_ITEM* i : localConnectionList )
+    {
+        if( i != NULL )
+            select( i );
+    }
+
+    // Inform other potentially interested tools
+    if( m_selection.Size() > 0 )
+        m_toolMgr->ProcessEvent( SelectedEvent );
+
+    return 0;
+}
+
 
 void SELECTION_TOOL::findCallback( BOARD_ITEM* aItem )
 {
diff --git a/pcbnew/tools/selection_tool.h b/pcbnew/tools/selection_tool.h
index 4157677ef..1d711d7c5 100644
--- a/pcbnew/tools/selection_tool.h
+++ b/pcbnew/tools/selection_tool.h
@@ -281,6 +281,9 @@ private:
      */
     void selectAllItemsOnNet( int aNetCode );
 
+    ///> Selects all modules belonging to same sheet.
+    int selectSameSheet( const TOOL_EVENT& aEvent );
+
     ///> Find dialog callback.
     void findCallback( BOARD_ITEM* aItem );
 
-- 
2.11.0


Follow ups

References