Rework net highlighting to use connections instead of strings

Fixes https://gitlab.com/kicad/code/kicad/-/issues/1933
Fixes https://gitlab.com/kicad/code/kicad/-/issues/3921
This commit is contained in:
Jon Evans 2020-05-24 10:46:05 -04:00
parent a6e9efbe57
commit 1e69f592f6
7 changed files with 130 additions and 49 deletions

View File

@ -362,6 +362,7 @@ void CONNECTION_GRAPH::Reset()
m_bus_name_to_code_map.clear(); m_bus_name_to_code_map.clear();
m_net_code_to_subgraphs_map.clear(); m_net_code_to_subgraphs_map.clear();
m_net_name_to_subgraphs_map.clear(); m_net_name_to_subgraphs_map.clear();
m_item_to_subgraph_map.clear();
m_local_label_cache.clear(); m_local_label_cache.clear();
m_global_label_cache.clear(); m_global_label_cache.clear();
m_last_net_code = 1; m_last_net_code = 1;
@ -670,6 +671,7 @@ void CONNECTION_GRAPH::buildConnectionGraph()
subgraph->AddItem( item ); subgraph->AddItem( item );
connection->SetSubgraphCode( subgraph->m_code ); connection->SetSubgraphCode( subgraph->m_code );
m_item_to_subgraph_map[item] = subgraph;
std::list<SCH_ITEM*> members; std::list<SCH_ITEM*> members;
@ -703,6 +705,7 @@ void CONNECTION_GRAPH::buildConnectionGraph()
if( connected_conn->SubgraphCode() == 0 ) if( connected_conn->SubgraphCode() == 0 )
{ {
connected_conn->SetSubgraphCode( subgraph->m_code ); connected_conn->SetSubgraphCode( subgraph->m_code );
m_item_to_subgraph_map[connected_item] = subgraph;
subgraph->AddItem( connected_item ); subgraph->AddItem( connected_item );
std::copy_if( connected_item->ConnectedItems( sheet ).begin(), std::copy_if( connected_item->ConnectedItems( sheet ).begin(),
@ -1990,6 +1993,31 @@ CONNECTION_SUBGRAPH* CONNECTION_GRAPH::FindSubgraphByName(
} }
CONNECTION_SUBGRAPH* CONNECTION_GRAPH::FindFirstSubgraphByName( const wxString& aNetName )
{
if( !m_net_name_to_subgraphs_map.count( aNetName ) )
return nullptr;
wxASSERT( !m_net_name_to_subgraphs_map.at( aNetName ).empty() );
return m_net_name_to_subgraphs_map.at( aNetName )[0];
}
CONNECTION_SUBGRAPH* CONNECTION_GRAPH::GetSubgraphForItem( SCH_ITEM* aItem )
{
if( !m_item_to_subgraph_map.count( aItem ) )
return nullptr;
CONNECTION_SUBGRAPH* ret = m_item_to_subgraph_map.at( aItem );
while( ret->m_absorbed )
ret = ret->m_absorbed_by;
return ret;
}
int CONNECTION_GRAPH::RunERC() int CONNECTION_GRAPH::RunERC()
{ {
int error_count = 0; int error_count = 0;

View File

@ -284,6 +284,16 @@ public:
CONNECTION_SUBGRAPH* FindSubgraphByName( const wxString& aNetName, CONNECTION_SUBGRAPH* FindSubgraphByName( const wxString& aNetName,
const SCH_SHEET_PATH& aPath ); const SCH_SHEET_PATH& aPath );
/**
* Retrieves a subgraph for the given net name, if one exists.
* Searches every sheet
* @param aNetName is the full net name to search for
* @return the subgraph matching the query, or nullptr if none is found
*/
CONNECTION_SUBGRAPH* FindFirstSubgraphByName( const wxString& aNetName );
CONNECTION_SUBGRAPH* GetSubgraphForItem( SCH_ITEM* aItem );
// TODO(JE) Remove this when pressure valve is removed // TODO(JE) Remove this when pressure valve is removed
static bool m_allowRealTime; static bool m_allowRealTime;
@ -317,6 +327,8 @@ private:
std::unordered_map<wxString, std::unordered_map<wxString,
std::vector<CONNECTION_SUBGRAPH*>> m_net_name_to_subgraphs_map; std::vector<CONNECTION_SUBGRAPH*>> m_net_name_to_subgraphs_map;
std::map<SCH_ITEM*, CONNECTION_SUBGRAPH*> m_item_to_subgraph_map;
NET_MAP m_net_code_to_subgraphs_map; NET_MAP m_net_code_to_subgraphs_map;
int m_last_net_code; int m_last_net_code;

View File

@ -29,6 +29,7 @@
#include <kiway_express.h> #include <kiway_express.h>
#include <macros.h> #include <macros.h>
#include <eda_dde.h> #include <eda_dde.h>
#include <connection_graph.h>
#include <sch_edit_frame.h> #include <sch_edit_frame.h>
#include <general.h> #include <general.h>
#include <lib_item.h> #include <lib_item.h>
@ -187,10 +188,14 @@ void SCH_EDIT_FRAME::ExecuteRemoteCommand( const char* cmdline )
if( strcmp( idcmd, "$NET:" ) == 0 ) if( strcmp( idcmd, "$NET:" ) == 0 )
{ {
m_SelectedNetName = FROM_UTF8( text ); wxString netName = FROM_UTF8( text );
if( auto sg = Schematic().ConnectionGraph()->FindFirstSubgraphByName( netName ) )
m_highlightedConn = sg->m_driver_connection;
GetToolManager()->RunAction( EE_ACTIONS::updateNetHighlighting, true ); GetToolManager()->RunAction( EE_ACTIONS::updateNetHighlighting, true );
SetStatusText( _( "Selected net: " ) + UnescapeString( m_SelectedNetName ) ); SetStatusText( _( "Selected net: " ) + UnescapeString( netName ) );
return; return;
} }

View File

@ -173,9 +173,9 @@ bool DIALOG_GLOBAL_EDIT_TEXT_AND_GRAPHICS::TransferDataToWindow()
m_netFilter->SetValue( g_netFilter ); m_netFilter->SetValue( g_netFilter );
m_netFilterOpt->SetValue( true ); m_netFilterOpt->SetValue( true );
} }
else if( !m_parent->GetSelectedNetName().IsEmpty() ) else if( m_parent->GetHighlightedConnection() )
{ {
m_netFilter->SetValue( m_parent->GetSelectedNetName() ); m_netFilter->SetValue( m_parent->GetHighlightedConnection()->Name() );
} }
else if( selection.GetSize() ) else if( selection.GetSize() )
{ {

View File

@ -206,6 +206,7 @@ END_EVENT_TABLE()
SCH_EDIT_FRAME::SCH_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ): SCH_EDIT_FRAME::SCH_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ):
SCH_BASE_FRAME( aKiway, aParent, FRAME_SCH, wxT( "Eeschema" ), SCH_BASE_FRAME( aKiway, aParent, FRAME_SCH, wxT( "Eeschema" ),
wxDefaultPosition, wxDefaultSize, KICAD_DEFAULT_DRAWFRAME_STYLE, SCH_EDIT_FRAME_NAME ), wxDefaultPosition, wxDefaultSize, KICAD_DEFAULT_DRAWFRAME_STYLE, SCH_EDIT_FRAME_NAME ),
m_highlightedConn( nullptr ),
m_item_to_repeat( nullptr ) m_item_to_repeat( nullptr )
{ {
m_schematic = new SCHEMATIC( &Prj() ); m_schematic = new SCHEMATIC( &Prj() );

View File

@ -123,7 +123,7 @@ class SCH_EDIT_FRAME : public SCH_BASE_FRAME
private: private:
SCHEMATIC* m_schematic; ///< The currently loaded schematic SCHEMATIC* m_schematic; ///< The currently loaded schematic
wxString m_SelectedNetName; const SCH_CONNECTION* m_highlightedConn; ///< The highlighted net or bus, or nullptr
std::vector<PARAM_CFG*> m_projectFileParams; std::vector<PARAM_CFG*> m_projectFileParams;
std::vector<PARAM_CFG*> m_configSettings; std::vector<PARAM_CFG*> m_configSettings;
@ -382,8 +382,15 @@ public:
*/ */
void SendCrossProbeClearHighlight(); void SendCrossProbeClearHighlight();
const wxString& GetSelectedNetName() const { return m_SelectedNetName; } const SCH_CONNECTION* GetHighlightedConnection() const
void SetSelectedNetName( const wxString& aNetName ) { m_SelectedNetName = aNetName; } {
return m_highlightedConn;
}
void SetHighlightedConnection( const SCH_CONNECTION* aConnection )
{
m_highlightedConn = aConnection;
}
/** /**
* Create a flat list which stores all connected objects. * Create a flat list which stores all connected objects.

View File

@ -685,14 +685,13 @@ int SCH_EDITOR_CONTROL::SimProbe( const TOOL_EVENT& aEvent )
EDA_ITEM* item = collector.GetCount() == 1 ? collector[ 0 ] : nullptr; EDA_ITEM* item = collector.GetCount() == 1 ? collector[ 0 ] : nullptr;
SCH_LINE* wire = dynamic_cast<SCH_LINE*>( item ); SCH_LINE* wire = dynamic_cast<SCH_LINE*>( item );
wxString netName;
const SCH_CONNECTION* conn = nullptr;
if( wire ) if( wire )
{ {
item = nullptr; item = nullptr;
conn = wire->Connection( m_frame->GetCurrentSheet() );
if( wire->Connection( m_frame->GetCurrentSheet() ) )
netName = wire->Connection( m_frame->GetCurrentSheet() )->Name();
} }
if( item && item->Type() == SCH_PIN_T ) if( item && item->Type() == SCH_PIN_T )
@ -712,9 +711,9 @@ int SCH_EDITOR_CONTROL::SimProbe( const TOOL_EVENT& aEvent )
selectionTool->BrightenItem( m_pickerItem ); selectionTool->BrightenItem( m_pickerItem );
} }
if( m_frame->GetSelectedNetName() != netName ) if( m_frame->GetHighlightedConnection() != conn )
{ {
m_frame->SetSelectedNetName( netName ); m_frame->SetHighlightedConnection( conn );
TOOL_EVENT dummyEvent; TOOL_EVENT dummyEvent;
UpdateNetHighlighting( dummyEvent ); UpdateNetHighlighting( dummyEvent );
@ -727,9 +726,9 @@ int SCH_EDITOR_CONTROL::SimProbe( const TOOL_EVENT& aEvent )
if( m_pickerItem ) if( m_pickerItem )
m_toolMgr->GetTool<EE_SELECTION_TOOL>()->UnbrightenItem( m_pickerItem ); m_toolMgr->GetTool<EE_SELECTION_TOOL>()->UnbrightenItem( m_pickerItem );
if( !m_frame->GetSelectedNetName().IsEmpty() ) if( m_frame->GetHighlightedConnection() )
{ {
m_frame->SetSelectedNetName( wxEmptyString ); m_frame->SetHighlightedConnection( nullptr );
TOOL_EVENT dummyEvent; TOOL_EVENT dummyEvent;
UpdateNetHighlighting( dummyEvent ); UpdateNetHighlighting( dummyEvent );
@ -821,14 +820,13 @@ int SCH_EDITOR_CONTROL::SimTune( const TOOL_EVENT& aEvent )
static VECTOR2D CLEAR; static VECTOR2D CLEAR;
// TODO(JE) Probably use netcode rather than connection name here eventually
static bool highlightNet( TOOL_MANAGER* aToolMgr, const VECTOR2D& aPosition ) static bool highlightNet( TOOL_MANAGER* aToolMgr, const VECTOR2D& aPosition )
{ {
SCH_EDIT_FRAME* editFrame = static_cast<SCH_EDIT_FRAME*>( aToolMgr->GetToolHolder() ); SCH_EDIT_FRAME* editFrame = static_cast<SCH_EDIT_FRAME*>( aToolMgr->GetToolHolder() );
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>();
wxString netName; SCH_CONNECTION* conn = nullptr;
bool retVal = true; bool retVal = true;
if( aPosition != CLEAR ) if( aPosition != CLEAR )
{ {
@ -846,30 +844,28 @@ static bool highlightNet( TOOL_MANAGER* aToolMgr, const VECTOR2D& aPosition )
{ {
if( item->Type() == SCH_FIELD_T ) if( item->Type() == SCH_FIELD_T )
comp = dynamic_cast<SCH_COMPONENT*>( item->GetParent() ); comp = dynamic_cast<SCH_COMPONENT*>( item->GetParent() );
else
comp = dynamic_cast<SCH_COMPONENT*>( item );
}
if( comp && comp->GetPartRef() && comp->GetPartRef()->IsPower() ) if( comp && comp->GetPartRef() && comp->GetPartRef()->IsPower() )
netName = comp->GetPartRef()->GetName(); conn = comp->Connection( editFrame->GetCurrentSheet() );
else if( item && item->Connection( editFrame->GetCurrentSheet() ) ) else
netName = item->Connection( editFrame->GetCurrentSheet() )->Name(); conn = item->Connection( editFrame->GetCurrentSheet() );
}
} }
} }
if( netName.empty() ) if( !conn )
{ {
editFrame->SetStatusText( wxT( "" ) ); editFrame->SetStatusText( wxT( "" ) );
editFrame->SendCrossProbeClearHighlight(); editFrame->SendCrossProbeClearHighlight();
} }
else else
{ {
editFrame->SendCrossProbeNetName( netName ); editFrame->SendCrossProbeNetName( conn->Name() );
editFrame->SetStatusText( wxString::Format( _( "Highlighted net: %s" ), editFrame->SetStatusText( wxString::Format( _( "Highlighted net: %s" ),
UnescapeString( netName ) ) ); UnescapeString( conn->Name() ) ) );
} }
editFrame->SetSelectedNetName( netName ); editFrame->SetHighlightedConnection( conn );
TOOL_EVENT dummy; TOOL_EVENT dummy;
editorControl->UpdateNetHighlighting( dummy ); editorControl->UpdateNetHighlighting( dummy );
@ -900,33 +896,67 @@ int SCH_EDITOR_CONTROL::UpdateNetHighlighting( const TOOL_EVENT& aEvent )
{ {
SCH_SCREEN* screen = m_frame->GetCurrentSheet().LastScreen(); SCH_SCREEN* screen = m_frame->GetCurrentSheet().LastScreen();
std::vector<EDA_ITEM*> itemsToRedraw; std::vector<EDA_ITEM*> itemsToRedraw;
wxString selectedNetName = m_frame->GetSelectedNetName(); const SCH_CONNECTION* selectedConn = m_frame->GetHighlightedConnection();
if( !screen ) if( !screen )
return 0; return 0;
bool selectedIsBus = selectedConn ? selectedConn->IsBus() : false;
wxString selectedName = selectedConn ? selectedConn->Name() : "";
bool selectedIsNoNet = false;
CONNECTION_SUBGRAPH* selectedSubgraph = nullptr;
if( selectedConn && selectedConn->Driver() == nullptr )
{
selectedIsNoNet = true;
selectedSubgraph = m_frame->Schematic().ConnectionGraph()->GetSubgraphForItem(
selectedConn->Parent() );
}
for( SCH_ITEM* item : screen->Items() ) for( SCH_ITEM* item : screen->Items() )
{ {
wxString itemConnectionName; SCH_CONNECTION* itemConn = nullptr;
SCH_COMPONENT* comp = nullptr; SCH_COMPONENT* comp = nullptr;
bool redraw = item->IsBrightened(); bool redraw = item->IsBrightened();
bool highlight = false;
if( item->Type() == SCH_COMPONENT_T ) if( item->Type() == SCH_COMPONENT_T )
comp = static_cast<SCH_COMPONENT*>( item ); comp = static_cast<SCH_COMPONENT*>( item );
if( comp && comp->GetPartRef() && comp->GetPartRef()->IsPower() ) if( comp && comp->GetPartRef() && comp->GetPartRef()->IsPower() )
{ itemConn = comp->Connection( m_frame->GetCurrentSheet() );
itemConnectionName = comp->GetPartRef()->GetName();
}
else else
{ itemConn = item->Connection( m_frame->GetCurrentSheet() );
SCH_CONNECTION* connection = item->Connection( m_frame->GetCurrentSheet() );
if( connection ) if( selectedIsNoNet && selectedSubgraph )
itemConnectionName = connection->Name(); {
for( SCH_ITEM* subgraphItem : selectedSubgraph->m_items )
{
if( item == subgraphItem )
{
highlight = true;
break;
}
}
}
else if( selectedIsBus && itemConn && itemConn->IsNet() )
{
for( auto& member : selectedConn->Members() )
{
if( member->Name() == itemConn->Name() )
{
highlight = true;
break;
}
}
}
else if( selectedConn && itemConn && selectedName == itemConn->Name() )
{
highlight = true;
} }
if( !selectedNetName.IsEmpty() && itemConnectionName == selectedNetName ) if( highlight )
item->SetBrightened(); item->SetBrightened();
else else
item->ClearBrightened(); item->ClearBrightened();
@ -946,7 +976,7 @@ int SCH_EDITOR_CONTROL::UpdateNetHighlighting( const TOOL_EVENT& aEvent )
SCH_CONNECTION* pin_conn = SCH_CONNECTION* pin_conn =
comp->GetConnectionForPin( pin, m_frame->GetCurrentSheet() ); comp->GetConnectionForPin( pin, m_frame->GetCurrentSheet() );
if( comp && pin_conn && pin_conn->Name( false ) == selectedNetName ) if( comp && pin_conn && pin_conn->Name() == selectedName )
{ {
comp->BrightenPin( pin ); comp->BrightenPin( pin );
redraw = true; redraw = true;
@ -973,15 +1003,13 @@ int SCH_EDITOR_CONTROL::UpdateNetHighlighting( const TOOL_EVENT& aEvent )
SCH_CONNECTION* pin_conn = pin->Connection( m_frame->GetCurrentSheet() ); SCH_CONNECTION* pin_conn = pin->Connection( m_frame->GetCurrentSheet() );
bool redrawPin = pin->IsBrightened(); bool redrawPin = pin->IsBrightened();
if( pin_conn && pin_conn->Name() == selectedNetName ) if( pin_conn && pin_conn->Name() == selectedName )
pin->SetBrightened(); pin->SetBrightened();
else else
pin->ClearBrightened(); pin->ClearBrightened();
redrawPin |= pin->IsBrightened(); redrawPin ^= pin->IsBrightened();
redraw |= redrawPin;
if( redrawPin )
itemsToRedraw.push_back( pin );
} }
} }