Minor schematic net navigator improvements.

- Expand tree and highlight object selected with net highlight tool.
- Expand tree and highlight object that are currently highlighted with the
  selection tool.
- Use more descriptive object text rather than menu entry text for tree
  strings.
- Rebuild tree on unit changes.
This commit is contained in:
Wayne Stambaugh 2023-06-09 14:34:40 -04:00
parent 3a2cc8f56f
commit e9dc00cda3
5 changed files with 268 additions and 46 deletions

View File

@ -24,49 +24,123 @@
#include <tool/tool_manager.h> #include <tool/tool_manager.h>
#include <kiface_base.h> #include <kiface_base.h>
#include <sch_edit_frame.h> #include <sch_edit_frame.h>
#include <sch_line.h>
#include <sch_junction.h>
#include <sch_sheet_pin.h>
#include <schematic.h> #include <schematic.h>
#include <connection_graph.h> #include <connection_graph.h>
#include <widgets/wx_aui_utils.h> #include <widgets/wx_aui_utils.h>
#include <tools/ee_actions.h> #include <tools/ee_actions.h>
class NET_NAVIGATOR_ITEM_DATA : public wxTreeItemData static wxString GetNetNavigatorItemText( const SCH_ITEM* aItem,
const SCH_SHEET_PATH& aSheetPath,
UNITS_PROVIDER* aUnitsProvider )
{ {
public: wxString retv;
NET_NAVIGATOR_ITEM_DATA( const SCH_SHEET_PATH& aSheetPath, const SCH_ITEM* aItem ) :
m_sheetPath( aSheetPath ), wxCHECK( aItem && aUnitsProvider, retv );
m_item( aItem )
switch( aItem->Type() )
{ {
case SCH_LINE_T:
{
const SCH_LINE* line = static_cast<const SCH_LINE*>( aItem );
wxCHECK( line, retv );
if( aItem->GetLayer() == LAYER_WIRE )
{
retv.Printf( _( "Wire from %s, %s to %s, %s" ),
aUnitsProvider->MessageTextFromValue( line->GetStartPoint().x ),
aUnitsProvider->MessageTextFromValue( line->GetStartPoint().y ),
aUnitsProvider->MessageTextFromValue( line->GetEndPoint().x ),
aUnitsProvider->MessageTextFromValue( line->GetEndPoint().y ) );
}
else if( aItem->GetLayer() == LAYER_BUS )
{
retv.Printf( _( "Bus from %s, %s to %s, %s" ),
aUnitsProvider->MessageTextFromValue( line->GetStartPoint().x ),
aUnitsProvider->MessageTextFromValue( line->GetStartPoint().y ),
aUnitsProvider->MessageTextFromValue( line->GetEndPoint().x ),
aUnitsProvider->MessageTextFromValue( line->GetEndPoint().y ) );
}
else
{
retv = _( "Graphic line not connectable" );
}
break;
}
case SCH_PIN_T:
{
const SCH_PIN* pin = static_cast<const SCH_PIN*>( aItem );
wxCHECK( pin, retv );
SCH_SYMBOL* symbol = pin->GetParentSymbol();
wxCHECK( symbol, retv );
retv.Printf( _( "Symbol %s pin %s" ), symbol->GetRef( &aSheetPath, true ),
pin->GetNumber() );
break;
}
case SCH_SHEET_PIN_T:
{
const SCH_SHEET_PIN* pin = static_cast<const SCH_SHEET_PIN*>( aItem );
wxCHECK( pin, retv );
SCH_SHEET* sheet = pin->GetParent();
wxCHECK( sheet, retv );
retv.Printf( _( "Sheet %s pin %s" ), sheet->GetName(), pin->GetText() );
break;
}
case SCH_LABEL_T:
{
const SCH_LABEL* label = static_cast<const SCH_LABEL*>( aItem );
wxCHECK( label, retv );
retv.Printf( _( "Label %s at %s, %s" ), label->GetText(),
aUnitsProvider->MessageTextFromValue( label->GetPosition().x ),
aUnitsProvider->MessageTextFromValue( label->GetPosition().y ) );
break;
}
case SCH_GLOBAL_LABEL_T:
{
const SCH_GLOBALLABEL* label = static_cast<const SCH_GLOBALLABEL*>( aItem );
wxCHECK( label, retv );
retv.Printf( _( "Global label %s at %s, %s" ), label->GetText(),
aUnitsProvider->MessageTextFromValue( label->GetPosition().x ),
aUnitsProvider->MessageTextFromValue( label->GetPosition().y ) );
break;
}
case SCH_HIER_LABEL_T:
{
const SCH_HIERLABEL* label = static_cast<const SCH_HIERLABEL*>( aItem );
wxCHECK( label, retv );
retv.Printf( _( "Hierarchical label %s at %s, %s" ), label->GetText(),
aUnitsProvider->MessageTextFromValue( label->GetPosition().x ),
aUnitsProvider->MessageTextFromValue( label->GetPosition().y ) );
break;
}
case SCH_JUNCTION_T:
{
const SCH_JUNCTION* junction = static_cast<const SCH_JUNCTION*>( aItem );
wxCHECK( junction, retv );
retv.Printf( _( "Junction at %s, %s" ),
aUnitsProvider->MessageTextFromValue( junction->GetPosition().x ),
aUnitsProvider->MessageTextFromValue( junction->GetPosition().y ) );
break;
}
default:
retv.Printf( _( "Unhandled item type %d" ), aItem->Type() );
} }
NET_NAVIGATOR_ITEM_DATA() : return retv;
m_item( nullptr ) }
{
}
SCH_SHEET_PATH& GetSheetPath() { return m_sheetPath; }
const SCH_ITEM* GetItem() const { return m_item; }
bool operator==( const NET_NAVIGATOR_ITEM_DATA& aRhs ) const
{
return ( m_sheetPath == aRhs.m_sheetPath ) && ( m_item == aRhs.m_item );
}
NET_NAVIGATOR_ITEM_DATA& operator=( const NET_NAVIGATOR_ITEM_DATA& aItemData )
{
if( this == &aItemData )
return *this;
m_sheetPath = aItemData.m_sheetPath;
m_item = aItemData.m_item;
return *this;
}
private:
SCH_SHEET_PATH m_sheetPath;
const SCH_ITEM* m_item;
};
void SCH_EDIT_FRAME::MakeNetNavigatorNode( const wxString& aNetName, wxTreeItemId aParentId, void SCH_EDIT_FRAME::MakeNetNavigatorNode( const wxString& aNetName, wxTreeItemId aParentId,
@ -107,26 +181,31 @@ void SCH_EDIT_FRAME::MakeNetNavigatorNode( const wxString& aNetName, wxTreeItemI
for( const SCH_ITEM* item : subGraph->GetItems() ) for( const SCH_ITEM* item : subGraph->GetItems() )
{ {
SCH_ITEM_SET& connectedItems = const_cast<SCH_ITEM*>( item )->ConnectedItems( sheetPath );
wxLogDebug( wxS( "Item \"%s\" has %zu connected items." ),
item->GetItemDescription( this ), connectedItems.size() );
itemData = new NET_NAVIGATOR_ITEM_DATA( sheetPath, item ); itemData = new NET_NAVIGATOR_ITEM_DATA( sheetPath, item );
wxTreeItemId id = m_netNavigator->AppendItem( sheetId, item->GetItemDescription( this ), wxTreeItemId id = m_netNavigator->AppendItem( sheetId,
GetNetNavigatorItemText( item, sheetPath,
this ),
-1, -1, itemData ); -1, -1, itemData );
if( aSelection && *aSelection == *itemData ) if( aSelection && *aSelection == *itemData )
{ {
expandId = sheetId; expandId = sheetId;
m_netNavigator->EnsureVisible( id );
m_netNavigator->SelectItem( id ); m_netNavigator->SelectItem( id );
} }
} }
} }
if( expandId != m_netNavigator->GetRootItem() ) if( !aSelection )
m_netNavigator->Expand( aParentId ); m_netNavigator->Expand( aParentId );
m_netNavigator->Expand( expandId );
} }
void SCH_EDIT_FRAME::RefreshNetNavigator() void SCH_EDIT_FRAME::RefreshNetNavigator( const NET_NAVIGATOR_ITEM_DATA* aSelection )
{ {
wxCHECK( m_netNavigator, /* void */ ); wxCHECK( m_netNavigator, /* void */ );
@ -170,7 +249,55 @@ void SCH_EDIT_FRAME::RefreshNetNavigator()
{ {
wxTreeItemId rootId = m_netNavigator->AddRoot( m_highlightedConn, 0 ); wxTreeItemId rootId = m_netNavigator->AddRoot( m_highlightedConn, 0 );
MakeNetNavigatorNode( m_highlightedConn, rootId ); MakeNetNavigatorNode( m_highlightedConn, rootId, aSelection );
}
}
void SCH_EDIT_FRAME::SelectNetNavigatorItem( const NET_NAVIGATOR_ITEM_DATA* aSelection )
{
wxCHECK( m_netNavigator, /* void */ );
// Maybe in the future we can do something like collapse the tree for an empty selection.
// For now, leave the tree selection in its current state.
if( !aSelection )
return;
wxTreeItemIdValue sheetCookie;
NET_NAVIGATOR_ITEM_DATA* itemData = nullptr;
wxTreeItemId rootId = m_netNavigator->GetRootItem();
wxTreeItemId sheetId = m_netNavigator->GetFirstChild( rootId, sheetCookie );
while( sheetId.IsOk() )
{
if( m_netNavigator->ItemHasChildren( sheetId ) )
{
wxTreeItemIdValue itemCookie;
wxTreeItemId itemId = m_netNavigator->GetFirstChild( sheetId, itemCookie );
while( itemId.IsOk() )
{
itemData = dynamic_cast<NET_NAVIGATOR_ITEM_DATA*>( m_netNavigator->GetItemData( itemId ) );
wxCHECK2( itemData, continue );
if( *itemData == *aSelection )
{
if( !m_netNavigator->IsVisible( itemId ) )
{
m_netNavigator->CollapseAll();
m_netNavigator->EnsureVisible( itemId );
}
m_netNavigator->SelectItem( itemId );
return;
}
itemId = m_netNavigator->GetNextSibling( itemId );
}
sheetId = m_netNavigator->GetNextSibling( sheetId );
}
} }
} }
@ -200,6 +327,18 @@ void SCH_EDIT_FRAME::onNetNavigatorSelection( wxTreeEvent& aEvent )
if( m_netNavigator->GetItemParent( id ) != m_netNavigator->GetRootItem() if( m_netNavigator->GetItemParent( id ) != m_netNavigator->GetRootItem()
&& itemData->GetItem() ) && itemData->GetItem() )
{ {
// Make sure we didn't remove the item and/or the screen it resides on before we access it.
const SCH_ITEM* item = itemData->GetItem();
// Don't search for child items in screen r-tree.
item = ( ( item->Type() == SCH_SHEET_PIN_T ) || ( item->Type() == SCH_PIN_T ) ) ?
static_cast<const SCH_ITEM*>( item->GetParent() ) : item;
const SCH_SCREEN* screen = itemData->GetSheetPath().LastScreen();
wxCHECK( screen, /* void */ );
wxCHECK( screen->Items().contains( item, true ), /* void */ );
FocusOnLocation( itemData->GetItem()->GetBoundingBox().Centre() ); FocusOnLocation( itemData->GetItem()->GetBoundingBox().Centre() );
} }

View File

@ -2364,12 +2364,36 @@ wxTreeCtrl* SCH_EDIT_FRAME::createHighlightedNetNavigator()
} }
void SCH_EDIT_FRAME::SetHighlightedConnection( const wxString& aConnection ) void SCH_EDIT_FRAME::SetHighlightedConnection( const wxString& aConnection,
const NET_NAVIGATOR_ITEM_DATA* aSelection )
{ {
bool refreshNetNavigator = aConnection != m_highlightedConn; bool refreshNetNavigator = aConnection != m_highlightedConn;
m_highlightedConn = aConnection; m_highlightedConn = aConnection;
if( refreshNetNavigator ) if( refreshNetNavigator )
RefreshNetNavigator(); RefreshNetNavigator( aSelection );
}
void SCH_EDIT_FRAME::unitsChangeRefresh()
{
if( m_netNavigator && !m_highlightedConn.IsEmpty() )
{
NET_NAVIGATOR_ITEM_DATA itemData;
wxTreeItemId selection = m_netNavigator->GetSelection();
bool refreshSelection = selection.IsOk() && ( selection != m_netNavigator->GetRootItem() );
if( refreshSelection )
{
NET_NAVIGATOR_ITEM_DATA* tmp =
dynamic_cast<NET_NAVIGATOR_ITEM_DATA*>( m_netNavigator->GetItemData( selection ) );
wxCHECK( tmp, /* void */ );
itemData = *tmp;
}
m_netNavigator->DeleteAllItems();
RefreshNetNavigator( refreshSelection ? &itemData : nullptr );
}
} }

View File

@ -61,7 +61,7 @@ class DIALOG_SCH_FIND;
class wxFindReplaceData; class wxFindReplaceData;
class RESCUER; class RESCUER;
class HIERARCHY_PANE; class HIERARCHY_PANE;
class NET_NAVIGATOR_ITEM_DATA;
// @todo Move this to transform alone with all of the transform manipulation code. // @todo Move this to transform alone with all of the transform manipulation code.
/// enum used in RotationMiroir() /// enum used in RotationMiroir()
@ -98,6 +98,48 @@ enum SCH_CLEANUP_FLAGS
wxDECLARE_EVENT( EDA_EVT_SCHEMATIC_CHANGED, wxCommandEvent ); wxDECLARE_EVENT( EDA_EVT_SCHEMATIC_CHANGED, wxCommandEvent );
/**
* Tree view item data for the net navigator.
*/
class NET_NAVIGATOR_ITEM_DATA : public wxTreeItemData
{
public:
NET_NAVIGATOR_ITEM_DATA( const SCH_SHEET_PATH& aSheetPath, const SCH_ITEM* aItem ) :
m_sheetPath( aSheetPath ),
m_item( aItem )
{
}
NET_NAVIGATOR_ITEM_DATA() :
m_item( nullptr )
{
}
SCH_SHEET_PATH& GetSheetPath() { return m_sheetPath; }
const SCH_ITEM* GetItem() const { return m_item; }
bool operator==( const NET_NAVIGATOR_ITEM_DATA& aRhs ) const
{
return ( m_sheetPath == aRhs.m_sheetPath ) && ( m_item == aRhs.m_item );
}
NET_NAVIGATOR_ITEM_DATA& operator=( const NET_NAVIGATOR_ITEM_DATA& aItemData )
{
if( this == &aItemData )
return *this;
m_sheetPath = aItemData.m_sheetPath;
m_item = aItemData.m_item;
return *this;
}
private:
SCH_SHEET_PATH m_sheetPath;
const SCH_ITEM* m_item;
};
/** /**
* Schematic editor (Eeschema) main window. * Schematic editor (Eeschema) main window.
*/ */
@ -312,7 +354,8 @@ public:
return m_highlightedConn; return m_highlightedConn;
} }
void SetHighlightedConnection( const wxString& aConnection ); void SetHighlightedConnection( const wxString& aConnection,
const NET_NAVIGATOR_ITEM_DATA* aSelection = nullptr );
/** /**
* Check if we are ready to write a netlist file for the current schematic. * Check if we are ready to write a netlist file for the current schematic.
@ -864,11 +907,13 @@ public:
return wxS( "NetNavigator" ); return wxS( "NetNavigator" );
} }
void RefreshNetNavigator(); void RefreshNetNavigator( const NET_NAVIGATOR_ITEM_DATA* aSelection = nullptr );
void MakeNetNavigatorNode( const wxString& aNetName, wxTreeItemId aParentId, void MakeNetNavigatorNode( const wxString& aNetName, wxTreeItemId aParentId,
const NET_NAVIGATOR_ITEM_DATA* aSelection = nullptr ); const NET_NAVIGATOR_ITEM_DATA* aSelection = nullptr );
void SelectNetNavigatorItem( const NET_NAVIGATOR_ITEM_DATA* aSelection = nullptr );
void ToggleNetNavigator(); void ToggleNetNavigator();
DECLARE_EVENT_TABLE() DECLARE_EVENT_TABLE()
@ -896,6 +941,8 @@ protected:
void onCloseErcDialog( wxCommandEvent& aEvent ); void onCloseErcDialog( wxCommandEvent& aEvent );
void unitsChangeRefresh() override;
private: private:
// Called when resizing the Hierarchy Navigator panel // Called when resizing the Hierarchy Navigator panel
void OnResizeHierarchyNavigator( wxSizeEvent& aEvent ); void OnResizeHierarchyNavigator( wxSizeEvent& aEvent );

View File

@ -417,6 +417,16 @@ int EE_SELECTION_TOOL::Main( const TOOL_EVENT& aEvent )
collector[ 0 ]->DoHypertextAction( m_frame ); collector[ 0 ]->DoHypertextAction( m_frame );
selCancelled = true; selCancelled = true;
} }
else if( collector[0]->IsBrightened() )
{
if( SCH_EDIT_FRAME* schframe = dynamic_cast<SCH_EDIT_FRAME*>( m_frame ) )
{
NET_NAVIGATOR_ITEM_DATA itemData( schframe->GetCurrentSheet(),
collector[0] );
schframe->SelectNetNavigatorItem( &itemData );
}
}
} }
if( !selCancelled ) if( !selCancelled )

View File

@ -760,6 +760,7 @@ static bool highlightNet( TOOL_MANAGER* aToolMgr, const VECTOR2D& aPosition )
EE_SELECTION_TOOL* selTool = aToolMgr->GetTool<EE_SELECTION_TOOL>(); EE_SELECTION_TOOL* selTool = aToolMgr->GetTool<EE_SELECTION_TOOL>();
SCH_EDITOR_CONTROL* editorControl = aToolMgr->GetTool<SCH_EDITOR_CONTROL>(); SCH_EDITOR_CONTROL* editorControl = aToolMgr->GetTool<SCH_EDITOR_CONTROL>();
SCH_CONNECTION* conn = nullptr; SCH_CONNECTION* conn = nullptr;
SCH_ITEM* item = nullptr;
bool retVal = true; bool retVal = true;
if( aPosition != CLEAR ) if( aPosition != CLEAR )
@ -773,7 +774,7 @@ static bool highlightNet( TOOL_MANAGER* aToolMgr, const VECTOR2D& aPosition )
} }
else else
{ {
SCH_ITEM* item = static_cast<SCH_ITEM*>( selTool->GetNode( aPosition ) ); item = static_cast<SCH_ITEM*>( selTool->GetNode( aPosition ) );
SCH_SYMBOL* symbol = dynamic_cast<SCH_SYMBOL*>( item ); SCH_SYMBOL* symbol = dynamic_cast<SCH_SYMBOL*>( item );
if( item ) if( item )
@ -811,8 +812,9 @@ static bool highlightNet( TOOL_MANAGER* aToolMgr, const VECTOR2D& aPosition )
} }
else else
{ {
NET_NAVIGATOR_ITEM_DATA itemData( editFrame->GetCurrentSheet(), item );
editFrame->SetCrossProbeConnection( conn ); editFrame->SetCrossProbeConnection( conn );
editFrame->SetHighlightedConnection( connectionName ); editFrame->SetHighlightedConnection( connectionName, &itemData );
} }
editFrame->UpdateNetHighlightStatus(); editFrame->UpdateNetHighlightStatus();