← Back to team overview

kicad-developers team mailing list archive

Re: Selection tool that selects components and local connections

 

Found some coding style errors that were fixed in this.

And in accordance with previous patches/features ive sent a youtube vid is now attached.

https://youtu.be/fISB7S5YFvo

- Kristoffer

On 2017-03-03 00:52, Kristoffer Ödmark wrote:
Hello

These two patches adds crossprobing to the schematic sheet in the same
way that crossprobing behaves when selecting components in eeschema. Ie
it selects all items that are only present on a specific sheet.

I have only tested on linux for now.

-Kristoffer

On 2017-02-11 13:36, Chris Pavlina wrote:
Merged. This looks very useful. Thank you for your contribution!

On Sat, Feb 11, 2017 at 01:25:24PM +0100, Kristoffer Ödmark wrote:
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 d19f17536e88be3ebd1a65d850c5fb7f619c3a11 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Kristoffer=20=C3=96dmark?= <kristoffer.odmark90@xxxxxxxxx>
Date: Fri, 3 Mar 2017 00:42:23 +0100
Subject: [PATCH] CrossProbes Schematics from eeschema to pcbnew

Adds a similar crossprobe as modules has in pcbnew. When clicking a
sheet in eeschema, the items that are exclusive in that scheet will be
selected in pcbnew if using the GAL canvas.

	modified:   ./eeschema/controle.cpp
	modified:   ./eeschema/cross-probing.cpp
	modified:   ./include/tool/selection.h
	modified:   ./pcbnew/cross-probing.cpp
	modified:   ./pcbnew/tools/pcb_actions.h
	modified:   ./pcbnew/tools/selection_tool.cpp
	modified:   ./pcbnew/tools/selection_tool.h
---
 eeschema/controle.cpp           |  1 +
 eeschema/cross-probing.cpp      |  5 +++
 include/tool/selection.h        |  2 ++
 pcbnew/cross-probing.cpp        | 12 +++++++
 pcbnew/tools/pcb_actions.h      |  3 ++
 pcbnew/tools/selection_tool.cpp | 74 ++++++++++++++++++++++++++++++++++++++---
 pcbnew/tools/selection_tool.h   |  8 ++++-
 7 files changed, 99 insertions(+), 6 deletions(-)

diff --git a/eeschema/controle.cpp b/eeschema/controle.cpp
index a492b6408..af5c33ab7 100644
--- a/eeschema/controle.cpp
+++ b/eeschema/controle.cpp
@@ -87,6 +87,7 @@ SCH_ITEM* SCH_EDIT_FRAME::LocateAndShowItem( const wxPoint& aPosition, const KIC
         SendMessageToPCBNEW( item, component );
         break;
 
+    case SCH_SHEET_T:
     case SCH_COMPONENT_T:
         component = (SCH_COMPONENT*) item;
         SendMessageToPCBNEW( item, component );
diff --git a/eeschema/cross-probing.cpp b/eeschema/cross-probing.cpp
index 7bc8e6336..a08ec1527 100644
--- a/eeschema/cross-probing.cpp
+++ b/eeschema/cross-probing.cpp
@@ -129,6 +129,11 @@ std::string FormatProbeItem( EDA_ITEM* aComponent, SCH_COMPONENT* aPart )
         aPart = (SCH_COMPONENT*) aComponent;
         return StrPrintf( "$PART: %s", TO_UTF8( aPart->GetField( REFERENCE )->GetText() ) );
 
+    case SCH_SHEET_T:
+        aPart = (SCH_COMPONENT*)aComponent;
+        return StrPrintf( "$SHEET: %s", TO_UTF8( wxString::Format( wxT("%8.8lX"),
+                        (unsigned long) aPart->GetTimeStamp() ) ) );
+
     case LIB_PIN_T:
         {
             if( !aPart )
diff --git a/include/tool/selection.h b/include/tool/selection.h
index 9997812a6..4e972b30c 100644
--- a/include/tool/selection.h
+++ b/include/tool/selection.h
@@ -97,6 +97,8 @@ public:
     /// Returns the center point of the selection area bounding box.
     VECTOR2I GetCenter() const;
 
+    const BOX2I ViewBBox() const override;
+
     EDA_ITEM* operator[]( const int index ) const
     {
         if( index < 0 || (unsigned int) index >= m_items.size() )
diff --git a/pcbnew/cross-probing.cpp b/pcbnew/cross-probing.cpp
index be3e50472..e7f63c9c4 100644
--- a/pcbnew/cross-probing.cpp
+++ b/pcbnew/cross-probing.cpp
@@ -30,6 +30,7 @@
 
 #include <tools/pcb_actions.h>
 #include <tool/tool_manager.h>
+#include <tools/selection_tool.h>
 #include <pcb_draw_panel_gal.h>
 
 /* Execute a remote command send by Eeschema via a socket,
@@ -44,6 +45,7 @@ void PCB_EDIT_FRAME::ExecuteRemoteCommand( const char* cmdline )
     char        line[1024];
     wxString    msg;
     wxString    modName;
+    wxString    *sheetStamp;
     char*       idcmd;
     char*       text;
     MODULE*     module = NULL;
@@ -76,6 +78,16 @@ void PCB_EDIT_FRAME::ExecuteRemoteCommand( const char* cmdline )
         if( module )
             pos = module->GetPosition();
     }
+    else if( strcmp( idcmd, "$SHEET:" ) == 0 )
+    {
+        msg.Printf( _( "Selecting all from sheet '%s'" ), FROM_UTF8( text ) );
+        sheetStamp = new wxString( FROM_UTF8( text ) );
+        SetStatusText( msg );
+            GetToolManager()->RunAction( PCB_ACTIONS::selectOnSheet,
+                true,
+                static_cast<void*>( sheetStamp ) );
+        return;
+    }
     else if( strcmp( idcmd, "$PIN:" ) == 0 )
     {
         wxString pinName;
diff --git a/pcbnew/tools/pcb_actions.h b/pcbnew/tools/pcb_actions.h
index 1e8985fed..0ebb9a5ab 100644
--- a/pcbnew/tools/pcb_actions.h
+++ b/pcbnew/tools/pcb_actions.h
@@ -67,6 +67,9 @@ public:
     /// Selects all connections belonging to a single net.
     static TOOL_ACTION selectNet;
 
+    /// Selects all components on sheet.
+    static TOOL_ACTION selectOnSheet;
+
     /// Selects all components on the same sheet.
     static TOOL_ACTION selectSameSheet;
 
diff --git a/pcbnew/tools/selection_tool.cpp b/pcbnew/tools/selection_tool.cpp
index ee28eb32e..69678faf3 100644
--- a/pcbnew/tools/selection_tool.cpp
+++ b/pcbnew/tools/selection_tool.cpp
@@ -89,6 +89,10 @@ TOOL_ACTION PCB_ACTIONS::selectNet( "pcbnew.InteractiveSelection.SelectNet",
         AS_GLOBAL, 0,
         _( "Whole Net" ), _( "Selects all tracks & vias belonging to the same net." ) );
 
+TOOL_ACTION PCB_ACTIONS::selectOnSheet( "pcbnew.InteractiveSelection.SelectOnSheet",
+        AS_GLOBAL,  0,
+        _( "Sheet" ), _( "Selects all modules and tracks in the schematic sheet" ) );
+
 TOOL_ACTION PCB_ACTIONS::selectSameSheet( "pcbnew.InteractiveSelection.SelectSameSheet",
         AS_GLOBAL,  'P',
         _( "Same Sheet" ), _( "Selects all modules and tracks in the same schematic sheet" ) );
@@ -541,6 +545,7 @@ void SELECTION_TOOL::SetTransitions()
     Go( &SELECTION_TOOL::selectCopper, PCB_ACTIONS::selectCopper.MakeEvent() );
     Go( &SELECTION_TOOL::selectNet, PCB_ACTIONS::selectNet.MakeEvent() );
     Go( &SELECTION_TOOL::selectSameSheet, PCB_ACTIONS::selectSameSheet.MakeEvent() );
+    Go( &SELECTION_TOOL::selectOnSheet, PCB_ACTIONS::selectOnSheet.MakeEvent() );
 }
 
 
@@ -681,7 +686,7 @@ int SELECTION_TOOL::selectConnection( const TOOL_EVENT& aEvent )
 
 int SELECTION_TOOL::selectCopper( const TOOL_EVENT& aEvent )
 {
-    if( !selectCursor( ) )
+    if( !selectCursor() )
         return 0;
 
     // copy the selection, since we're going to iterate and modify
@@ -691,7 +696,7 @@ int SELECTION_TOOL::selectCopper( const TOOL_EVENT& aEvent )
     {
         auto item = static_cast<BOARD_ITEM*>( i );
         // only connected items can be traversed in the ratsnest
-        if ( item->IsConnected() )
+        if( item->IsConnected() )
         {
             auto& connItem = static_cast<BOARD_CONNECTED_ITEM&>( *item );
 
@@ -770,7 +775,7 @@ int SELECTION_TOOL::selectNet( const TOOL_EVENT& aEvent )
 
     return 0;
 }
-void SELECTION_TOOL::selectAllItemsOnSheet( wxString sheet )
+void SELECTION_TOOL::selectAllItemsOnSheet( wxString aSheet )
 {
     auto modules = board()->m_Modules.GetFirst();
     std::list<MODULE*> modList;
@@ -778,7 +783,7 @@ void SELECTION_TOOL::selectAllItemsOnSheet( wxString sheet )
     // store all modules that are on that sheet
     for( MODULE* mitem = modules; mitem; mitem = mitem->Next() )
     {
-        if ( mitem != NULL && mitem->GetPath().Contains( sheet ) )
+        if( mitem != NULL && mitem->GetPath().Contains( aSheet ) )
         {
             modList.push_back( mitem );
         }
@@ -851,6 +856,43 @@ void SELECTION_TOOL::selectAllItemsOnSheet( wxString sheet )
     }
 }
 
+void SELECTION_TOOL::zoomFitSelection( void )
+{
+	//Should recalculate the view to zoom in on the selection
+	auto selectionBox = m_selection.ViewBBox();
+    auto canvas = m_frame->GetGalCanvas();
+	auto view = getView();
+
+	VECTOR2D screenSize = view->ToWorld( canvas->GetClientSize(), false );
+
+	if( !( selectionBox.GetWidth() == 0 ) || !( selectionBox.GetHeight() == 0 ) )
+	{
+		VECTOR2D vsize = selectionBox.GetSize();
+		double scale = view->GetScale() / std::max( fabs( vsize.x / screenSize.x ),
+				fabs( vsize.y / screenSize.y ) );
+		view->SetScale( scale );
+		view->SetCenter( selectionBox.Centre() );
+		view->Add( &m_selection );
+	}
+
+	m_frame->GetGalCanvas()->ForceRefresh();
+}
+
+int SELECTION_TOOL::selectOnSheet( const TOOL_EVENT& aEvent )
+{
+    clearSelection();
+    wxString* sheet = aEvent.Parameter<wxString*>();
+    selectAllItemsOnSheet( *sheet );
+
+	zoomFitSelection();
+
+	if( m_selection.Size() > 0 )
+		m_toolMgr->ProcessEvent( SelectedEvent );
+
+
+    return 0;
+}
+
 int SELECTION_TOOL::selectSameSheet( const TOOL_EVENT& aEvent )
 {
     if( !selectCursor( true ) )
@@ -872,7 +914,7 @@ int SELECTION_TOOL::selectSameSheet( const TOOL_EVENT& aEvent )
     sheetPath = sheetPath.BeforeLast( '/' );
     sheetPath = sheetPath.AfterLast( '/' );
 
-    selectAllItemsOnSheet(sheetPath);
+    selectAllItemsOnSheet( sheetPath );
 
     // Inform other potentially interested tools
     if( m_selection.Size() > 0 )
@@ -1782,6 +1824,28 @@ VECTOR2I SELECTION::GetCenter() const
     return centre;
 }
 
+const BOX2I SELECTION::ViewBBox() const
+{
+    EDA_RECT eda_bbox;
+
+    if( Size() == 1 )
+	{
+		eda_bbox = Front()->GetBoundingBox();
+	}
+    else if( Size() > 1 )
+    {
+		eda_bbox = Front()->GetBoundingBox();
+        auto i = m_items.begin();
+        ++i;
+
+        for( ; i != m_items.end(); ++i )
+        {
+            eda_bbox.Merge( (*i)->GetBoundingBox() );
+        }
+    }
+	return BOX2I( eda_bbox.GetOrigin(), eda_bbox.GetSize() );
+}
+
 
 const KIGFX::VIEW_GROUP::ITEMS SELECTION::updateDrawList() const
 {
diff --git a/pcbnew/tools/selection_tool.h b/pcbnew/tools/selection_tool.h
index b0aeee22b..47d822dd3 100644
--- a/pcbnew/tools/selection_tool.h
+++ b/pcbnew/tools/selection_tool.h
@@ -120,6 +120,9 @@ public:
     ///> Sets up handlers for various events.
     void SetTransitions() override;
 
+    ///> Zooms the screen to center and fit the current selection.
+    void zoomFitSelection( void );
+
 private:
     /**
      * Function selectPoint()
@@ -180,7 +183,10 @@ private:
     /**
      * Selects all items with the given sheet timestamp name
      */
-    void selectAllItemsOnSheet( wxString sheet );
+    void selectAllItemsOnSheet( wxString aSheet );
+
+    ///> Selects all modules belonging to same sheet.
+    int selectOnSheet( const TOOL_EVENT& aEvent );
 
     ///> Selects all modules belonging to same sheet.
     int selectSameSheet( const TOOL_EVENT& aEvent );
-- 
2.12.0

>From 16fd303d3693585b624b7d95b8a3cd759caa85de Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Kristoffer=20=C3=96dmark?= <kristoffer.odmark90@xxxxxxxxx>
Date: Thu, 2 Mar 2017 22:07:45 +0100
Subject: [PATCH 1/2] Refactored out the function that selects items based on
 the sheetname

---
 pcbnew/tools/selection_tool.cpp | 48 ++++++++++++++++++++++-------------------
 pcbnew/tools/selection_tool.h   |  5 +++++
 2 files changed, 31 insertions(+), 22 deletions(-)

diff --git a/pcbnew/tools/selection_tool.cpp b/pcbnew/tools/selection_tool.cpp
index d0d418306..ee28eb32e 100644
--- a/pcbnew/tools/selection_tool.cpp
+++ b/pcbnew/tools/selection_tool.cpp
@@ -770,35 +770,15 @@ int SELECTION_TOOL::selectNet( const TOOL_EVENT& aEvent )
 
     return 0;
 }
-
-int SELECTION_TOOL::selectSameSheet( const TOOL_EVENT& aEvent )
+void SELECTION_TOOL::selectAllItemsOnSheet( wxString sheet )
 {
-    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* mitem = modules; mitem; mitem = mitem->Next() )
     {
-        if ( mitem != NULL && mitem->GetPath().Contains( sheetPath ) )
+        if ( mitem != NULL && mitem->GetPath().Contains( sheet ) )
         {
             modList.push_back( mitem );
         }
@@ -869,6 +849,30 @@ int SELECTION_TOOL::selectSameSheet( const TOOL_EVENT& aEvent )
         if( i != NULL )
             select( i );
     }
+}
+
+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( '/' );
+
+    selectAllItemsOnSheet(sheetPath);
 
     // Inform other potentially interested tools
     if( m_selection.Size() > 0 )
diff --git a/pcbnew/tools/selection_tool.h b/pcbnew/tools/selection_tool.h
index f158544cb..b0aeee22b 100644
--- a/pcbnew/tools/selection_tool.h
+++ b/pcbnew/tools/selection_tool.h
@@ -177,6 +177,11 @@ private:
      */
     void selectAllItemsOnNet( int aNetCode );
 
+    /**
+     * Selects all items with the given sheet timestamp name
+     */
+    void selectAllItemsOnSheet( wxString sheet );
+
     ///> Selects all modules belonging to same sheet.
     int selectSameSheet( const TOOL_EVENT& aEvent );
 
-- 
2.12.0


Follow ups

References