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_net_code_to_subgraphs_map.clear();
m_net_name_to_subgraphs_map.clear();
m_item_to_subgraph_map.clear();
m_local_label_cache.clear();
m_global_label_cache.clear();
m_last_net_code = 1;
@ -670,6 +671,7 @@ void CONNECTION_GRAPH::buildConnectionGraph()
subgraph->AddItem( item );
connection->SetSubgraphCode( subgraph->m_code );
m_item_to_subgraph_map[item] = subgraph;
std::list<SCH_ITEM*> members;
@ -703,6 +705,7 @@ void CONNECTION_GRAPH::buildConnectionGraph()
if( connected_conn->SubgraphCode() == 0 )
{
connected_conn->SetSubgraphCode( subgraph->m_code );
m_item_to_subgraph_map[connected_item] = subgraph;
subgraph->AddItem( connected_item );
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 error_count = 0;

View File

@ -284,6 +284,16 @@ public:
CONNECTION_SUBGRAPH* FindSubgraphByName( const wxString& aNetName,
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
static bool m_allowRealTime;
@ -317,6 +327,8 @@ private:
std::unordered_map<wxString,
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;
int m_last_net_code;

View File

@ -29,6 +29,7 @@
#include <kiway_express.h>
#include <macros.h>
#include <eda_dde.h>
#include <connection_graph.h>
#include <sch_edit_frame.h>
#include <general.h>
#include <lib_item.h>
@ -187,10 +188,14 @@ void SCH_EDIT_FRAME::ExecuteRemoteCommand( const char* cmdline )
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 );
SetStatusText( _( "Selected net: " ) + UnescapeString( m_SelectedNetName ) );
SetStatusText( _( "Selected net: " ) + UnescapeString( netName ) );
return;
}

View File

@ -173,9 +173,9 @@ bool DIALOG_GLOBAL_EDIT_TEXT_AND_GRAPHICS::TransferDataToWindow()
m_netFilter->SetValue( g_netFilter );
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() )
{

View File

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

View File

@ -123,7 +123,7 @@ class SCH_EDIT_FRAME : public SCH_BASE_FRAME
private:
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_configSettings;
@ -382,8 +382,15 @@ public:
*/
void SendCrossProbeClearHighlight();
const wxString& GetSelectedNetName() const { return m_SelectedNetName; }
void SetSelectedNetName( const wxString& aNetName ) { m_SelectedNetName = aNetName; }
const SCH_CONNECTION* GetHighlightedConnection() const
{
return m_highlightedConn;
}
void SetHighlightedConnection( const SCH_CONNECTION* aConnection )
{
m_highlightedConn = aConnection;
}
/**
* 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;
SCH_LINE* wire = dynamic_cast<SCH_LINE*>( item );
wxString netName;
const SCH_CONNECTION* conn = nullptr;
if( wire )
{
item = nullptr;
if( wire->Connection( m_frame->GetCurrentSheet() ) )
netName = wire->Connection( m_frame->GetCurrentSheet() )->Name();
conn = wire->Connection( m_frame->GetCurrentSheet() );
}
if( item && item->Type() == SCH_PIN_T )
@ -712,9 +711,9 @@ int SCH_EDITOR_CONTROL::SimProbe( const TOOL_EVENT& aEvent )
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;
UpdateNetHighlighting( dummyEvent );
@ -727,9 +726,9 @@ int SCH_EDITOR_CONTROL::SimProbe( const TOOL_EVENT& aEvent )
if( 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;
UpdateNetHighlighting( dummyEvent );
@ -821,13 +820,12 @@ int SCH_EDITOR_CONTROL::SimTune( const TOOL_EVENT& aEvent )
static VECTOR2D CLEAR;
// TODO(JE) Probably use netcode rather than connection name here eventually
static bool highlightNet( TOOL_MANAGER* aToolMgr, const VECTOR2D& aPosition )
{
SCH_EDIT_FRAME* editFrame = static_cast<SCH_EDIT_FRAME*>( aToolMgr->GetToolHolder() );
EE_SELECTION_TOOL* selTool = aToolMgr->GetTool<EE_SELECTION_TOOL>();
SCH_EDITOR_CONTROL* editorControl = aToolMgr->GetTool<SCH_EDITOR_CONTROL>();
wxString netName;
SCH_CONNECTION* conn = nullptr;
bool retVal = true;
if( aPosition != CLEAR )
@ -846,30 +844,28 @@ static bool highlightNet( TOOL_MANAGER* aToolMgr, const VECTOR2D& aPosition )
{
if( item->Type() == SCH_FIELD_T )
comp = dynamic_cast<SCH_COMPONENT*>( item->GetParent() );
else
comp = dynamic_cast<SCH_COMPONENT*>( item );
}
if( comp && comp->GetPartRef() && comp->GetPartRef()->IsPower() )
netName = comp->GetPartRef()->GetName();
else if( item && item->Connection( editFrame->GetCurrentSheet() ) )
netName = item->Connection( editFrame->GetCurrentSheet() )->Name();
conn = comp->Connection( editFrame->GetCurrentSheet() );
else
conn = item->Connection( editFrame->GetCurrentSheet() );
}
}
}
if( netName.empty() )
if( !conn )
{
editFrame->SetStatusText( wxT( "" ) );
editFrame->SendCrossProbeClearHighlight();
}
else
{
editFrame->SendCrossProbeNetName( netName );
editFrame->SendCrossProbeNetName( conn->Name() );
editFrame->SetStatusText( wxString::Format( _( "Highlighted net: %s" ),
UnescapeString( netName ) ) );
UnescapeString( conn->Name() ) ) );
}
editFrame->SetSelectedNetName( netName );
editFrame->SetHighlightedConnection( conn );
TOOL_EVENT dummy;
editorControl->UpdateNetHighlighting( dummy );
@ -900,33 +896,67 @@ int SCH_EDITOR_CONTROL::UpdateNetHighlighting( const TOOL_EVENT& aEvent )
{
SCH_SCREEN* screen = m_frame->GetCurrentSheet().LastScreen();
std::vector<EDA_ITEM*> itemsToRedraw;
wxString selectedNetName = m_frame->GetSelectedNetName();
const SCH_CONNECTION* selectedConn = m_frame->GetHighlightedConnection();
if( !screen )
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() )
{
wxString itemConnectionName;
SCH_CONNECTION* itemConn = nullptr;
SCH_COMPONENT* comp = nullptr;
bool redraw = item->IsBrightened();
bool highlight = false;
if( item->Type() == SCH_COMPONENT_T )
comp = static_cast<SCH_COMPONENT*>( item );
if( comp && comp->GetPartRef() && comp->GetPartRef()->IsPower() )
{
itemConnectionName = comp->GetPartRef()->GetName();
}
itemConn = comp->Connection( m_frame->GetCurrentSheet() );
else
{
SCH_CONNECTION* connection = item->Connection( m_frame->GetCurrentSheet() );
itemConn = item->Connection( m_frame->GetCurrentSheet() );
if( connection )
itemConnectionName = connection->Name();
if( selectedIsNoNet && selectedSubgraph )
{
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();
else
item->ClearBrightened();
@ -946,7 +976,7 @@ int SCH_EDITOR_CONTROL::UpdateNetHighlighting( const TOOL_EVENT& aEvent )
SCH_CONNECTION* pin_conn =
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 );
redraw = true;
@ -973,15 +1003,13 @@ int SCH_EDITOR_CONTROL::UpdateNetHighlighting( const TOOL_EVENT& aEvent )
SCH_CONNECTION* pin_conn = pin->Connection( m_frame->GetCurrentSheet() );
bool redrawPin = pin->IsBrightened();
if( pin_conn && pin_conn->Name() == selectedNetName )
if( pin_conn && pin_conn->Name() == selectedName )
pin->SetBrightened();
else
pin->ClearBrightened();
redrawPin |= pin->IsBrightened();
if( redrawPin )
itemsToRedraw.push_back( pin );
redrawPin ^= pin->IsBrightened();
redraw |= redrawPin;
}
}