Keep track of driver changes so the view can be updated.
Also make renaming of nets a bit more stable. Fixes https://gitlab.com/kicad/code/kicad/issues/6018
This commit is contained in:
parent
229194c76b
commit
81e1bc9df0
|
@ -110,9 +110,9 @@ bool CONNECTION_SUBGRAPH::ResolveDrivers( bool aCreateMarkers )
|
||||||
// We have multiple options, and they are all hierarchical
|
// We have multiple options, and they are all hierarchical
|
||||||
// sheet pins. Let's prefer outputs over inputs.
|
// sheet pins. Let's prefer outputs over inputs.
|
||||||
|
|
||||||
for( auto c : candidates )
|
for( SCH_ITEM* c : candidates )
|
||||||
{
|
{
|
||||||
auto p = static_cast<SCH_SHEET_PIN*>( c );
|
SCH_SHEET_PIN* p = static_cast<SCH_SHEET_PIN*>( c );
|
||||||
|
|
||||||
if( p->GetShape() == PINSHEETLABEL_SHAPE::PS_OUTPUT )
|
if( p->GetShape() == PINSHEETLABEL_SHAPE::PS_OUTPUT )
|
||||||
{
|
{
|
||||||
|
@ -123,6 +123,21 @@ bool CONNECTION_SUBGRAPH::ResolveDrivers( bool aCreateMarkers )
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// See if a previous driver is still a candidate
|
||||||
|
void* previousDriver = nullptr;
|
||||||
|
|
||||||
|
for( SCH_ITEM* member : m_items )
|
||||||
|
{
|
||||||
|
if( SCH_CONNECTION* mc = member->Connection( &m_sheet ) )
|
||||||
|
{
|
||||||
|
if( mc->GetLastDriver() )
|
||||||
|
{
|
||||||
|
previousDriver = mc->GetLastDriver();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// For all other driver types, sort by name
|
// For all other driver types, sort by name
|
||||||
std::sort( candidates.begin(), candidates.end(),
|
std::sort( candidates.begin(), candidates.end(),
|
||||||
[&]( SCH_ITEM* a, SCH_ITEM* b ) -> bool
|
[&]( SCH_ITEM* a, SCH_ITEM* b ) -> bool
|
||||||
|
@ -134,7 +149,12 @@ bool CONNECTION_SUBGRAPH::ResolveDrivers( bool aCreateMarkers )
|
||||||
if( ac->IsBus() && bc->IsBus() )
|
if( ac->IsBus() && bc->IsBus() )
|
||||||
return bc->IsSubsetOf( ac );
|
return bc->IsSubsetOf( ac );
|
||||||
|
|
||||||
return GetNameForDriver( a ) < GetNameForDriver( b );
|
if( a == previousDriver )
|
||||||
|
return true;
|
||||||
|
else if( b == previousDriver )
|
||||||
|
return false;
|
||||||
|
else
|
||||||
|
return GetNameForDriver( a ) < GetNameForDriver( b );
|
||||||
} );
|
} );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -750,7 +770,7 @@ void CONNECTION_GRAPH::buildConnectionGraph()
|
||||||
* you regenerate.
|
* you regenerate.
|
||||||
*
|
*
|
||||||
* Right now, we are clearing out the old connections up in
|
* Right now, we are clearing out the old connections up in
|
||||||
* UpdateItemConnectivity(), but that is useful information, so maybe we
|
* updateItemConnectivity(), but that is useful information, so maybe we
|
||||||
* need to just set the dirty flag or something.
|
* need to just set the dirty flag or something.
|
||||||
*
|
*
|
||||||
* That way, ResolveDrivers() can check what the driver of the subgraph was
|
* That way, ResolveDrivers() can check what the driver of the subgraph was
|
||||||
|
|
|
@ -98,7 +98,7 @@ void SCH_CONNECTION::SetDriver( SCH_ITEM* aItem )
|
||||||
|
|
||||||
recacheName();
|
recacheName();
|
||||||
|
|
||||||
for( const auto& member : m_members )
|
for( const std::shared_ptr<SCH_CONNECTION>& member : m_members )
|
||||||
member->SetDriver( aItem );
|
member->SetDriver( aItem );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -109,7 +109,7 @@ void SCH_CONNECTION::SetSheet( SCH_SHEET_PATH aSheet )
|
||||||
|
|
||||||
recacheName();
|
recacheName();
|
||||||
|
|
||||||
for( const auto& member : m_members )
|
for( const std::shared_ptr<SCH_CONNECTION>& member : m_members )
|
||||||
member->SetSheet( aSheet );
|
member->SetSheet( aSheet );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -203,6 +203,7 @@ void SCH_CONNECTION::Reset()
|
||||||
m_prefix.Empty();
|
m_prefix.Empty();
|
||||||
m_bus_prefix.Empty();
|
m_bus_prefix.Empty();
|
||||||
m_suffix .Empty();
|
m_suffix .Empty();
|
||||||
|
m_lastDriver = m_driver;
|
||||||
m_driver = nullptr;
|
m_driver = nullptr;
|
||||||
m_members.clear();
|
m_members.clear();
|
||||||
m_dirty = true;
|
m_dirty = true;
|
||||||
|
@ -220,6 +221,7 @@ void SCH_CONNECTION::Clone( SCH_CONNECTION& aOther )
|
||||||
{
|
{
|
||||||
m_graph = aOther.m_graph;
|
m_graph = aOther.m_graph;
|
||||||
m_type = aOther.Type();
|
m_type = aOther.Type();
|
||||||
|
m_lastDriver = aOther.GetLastDriver();
|
||||||
m_driver = aOther.Driver();
|
m_driver = aOther.Driver();
|
||||||
m_sheet = aOther.Sheet();
|
m_sheet = aOther.Sheet();
|
||||||
m_name = aOther.m_name;
|
m_name = aOther.m_name;
|
||||||
|
@ -270,6 +272,19 @@ bool SCH_CONNECTION::IsDriver() const
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool SCH_CONNECTION::HasDriverChanged() const
|
||||||
|
{
|
||||||
|
return m_driver != m_lastDriver;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SCH_CONNECTION::ClearDriverChanged()
|
||||||
|
{
|
||||||
|
m_lastDriver = m_driver;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
wxString SCH_CONNECTION::Name( bool aIgnoreSheet ) const
|
wxString SCH_CONNECTION::Name( bool aIgnoreSheet ) const
|
||||||
{
|
{
|
||||||
wxASSERT( !m_cached_name.IsEmpty() );
|
wxASSERT( !m_cached_name.IsEmpty() );
|
||||||
|
|
|
@ -101,23 +101,12 @@ public:
|
||||||
*/
|
*/
|
||||||
void Clone( SCH_CONNECTION& aOther );
|
void Clone( SCH_CONNECTION& aOther );
|
||||||
|
|
||||||
SCH_ITEM* Parent() const
|
SCH_ITEM* Parent() const { return m_parent; }
|
||||||
{
|
|
||||||
return m_parent;
|
|
||||||
}
|
|
||||||
|
|
||||||
SCH_ITEM* Driver() const
|
|
||||||
{
|
|
||||||
return m_driver;
|
|
||||||
}
|
|
||||||
|
|
||||||
SCH_SHEET_PATH Sheet() const
|
|
||||||
{
|
|
||||||
return m_sheet;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
SCH_ITEM* Driver() const { return m_driver; }
|
||||||
void SetDriver( SCH_ITEM* aItem );
|
void SetDriver( SCH_ITEM* aItem );
|
||||||
|
|
||||||
|
SCH_SHEET_PATH Sheet() const { return m_sheet; }
|
||||||
void SetSheet( SCH_SHEET_PATH aSheet );
|
void SetSheet( SCH_SHEET_PATH aSheet );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -138,28 +127,16 @@ public:
|
||||||
return ( m_type == CONNECTION_TYPE::NET );
|
return ( m_type == CONNECTION_TYPE::NET );
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsDirty() const
|
bool IsDirty() const { return m_dirty; }
|
||||||
{
|
void SetDirty() { m_dirty = true; }
|
||||||
return m_dirty;
|
void ClearDirty() { m_dirty = false; }
|
||||||
}
|
|
||||||
|
|
||||||
void SetDirty()
|
bool HasDriverChanged() const;
|
||||||
{
|
void ClearDriverChanged();
|
||||||
m_dirty = true;
|
void* GetLastDriver() const { return m_lastDriver; }
|
||||||
}
|
|
||||||
|
|
||||||
void ClearDirty()
|
|
||||||
{
|
|
||||||
m_dirty = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
wxString Name( bool aIgnoreSheet = false ) const;
|
wxString Name( bool aIgnoreSheet = false ) const;
|
||||||
|
|
||||||
const wxString& RawName() const
|
|
||||||
{
|
|
||||||
return m_name;
|
|
||||||
}
|
|
||||||
|
|
||||||
wxString LocalName() const { return m_local_name; }
|
wxString LocalName() const { return m_local_name; }
|
||||||
|
|
||||||
wxString FullLocalName() const
|
wxString FullLocalName() const
|
||||||
|
@ -173,29 +150,15 @@ public:
|
||||||
recacheName();
|
recacheName();
|
||||||
}
|
}
|
||||||
|
|
||||||
wxString Prefix() const
|
wxString Prefix() const { return m_prefix; }
|
||||||
{
|
|
||||||
return m_prefix;
|
|
||||||
}
|
|
||||||
|
|
||||||
wxString BusPrefix() const
|
|
||||||
{
|
|
||||||
return m_bus_prefix;
|
|
||||||
}
|
|
||||||
|
|
||||||
wxString Suffix() const
|
|
||||||
{
|
|
||||||
return m_suffix;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetPrefix( const wxString& aPrefix );
|
void SetPrefix( const wxString& aPrefix );
|
||||||
|
|
||||||
|
wxString BusPrefix() const { return m_bus_prefix; }
|
||||||
|
|
||||||
|
wxString Suffix() const { return m_suffix; }
|
||||||
void SetSuffix( const wxString& aSuffix );
|
void SetSuffix( const wxString& aSuffix );
|
||||||
|
|
||||||
CONNECTION_TYPE Type() const
|
CONNECTION_TYPE Type() const { return m_type; }
|
||||||
{
|
|
||||||
return m_type;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetType( CONNECTION_TYPE aType )
|
void SetType( CONNECTION_TYPE aType )
|
||||||
{
|
{
|
||||||
|
@ -203,55 +166,21 @@ public:
|
||||||
recacheName();
|
recacheName();
|
||||||
}
|
}
|
||||||
|
|
||||||
int NetCode() const
|
int NetCode() const { return m_net_code; }
|
||||||
{
|
void SetNetCode( int aCode ) { m_net_code = aCode; }
|
||||||
return m_net_code;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetNetCode( int aCode )
|
int BusCode() const { return m_bus_code; }
|
||||||
{
|
void SetBusCode( int aCode ) { m_bus_code = aCode; }
|
||||||
m_net_code = aCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
int BusCode() const
|
int SubgraphCode() const { return m_subgraph_code; }
|
||||||
{
|
void SetSubgraphCode( int aCode ) { m_subgraph_code = aCode; }
|
||||||
return m_bus_code;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetBusCode( int aCode )
|
long VectorStart() const { return m_vector_start; }
|
||||||
{
|
long VectorEnd() const { return m_vector_end; }
|
||||||
m_bus_code = aCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
int SubgraphCode() const
|
long VectorIndex() const { return m_vector_index; }
|
||||||
{
|
|
||||||
return m_subgraph_code;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetSubgraphCode( int aCode )
|
wxString VectorPrefix() const { return m_vector_prefix; }
|
||||||
{
|
|
||||||
m_subgraph_code = aCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
long VectorStart() const
|
|
||||||
{
|
|
||||||
return m_vector_start;
|
|
||||||
}
|
|
||||||
|
|
||||||
long VectorEnd() const
|
|
||||||
{
|
|
||||||
return m_vector_end;
|
|
||||||
}
|
|
||||||
|
|
||||||
long VectorIndex() const
|
|
||||||
{
|
|
||||||
return m_vector_index;
|
|
||||||
}
|
|
||||||
|
|
||||||
wxString VectorPrefix() const
|
|
||||||
{
|
|
||||||
return m_vector_prefix;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector< std::shared_ptr< SCH_CONNECTION > >& Members()
|
std::vector< std::shared_ptr< SCH_CONNECTION > >& Members()
|
||||||
{
|
{
|
||||||
|
@ -311,6 +240,9 @@ private:
|
||||||
|
|
||||||
SCH_ITEM* m_parent; ///< The SCH_ITEM this connection is owned by
|
SCH_ITEM* m_parent; ///< The SCH_ITEM this connection is owned by
|
||||||
|
|
||||||
|
void* m_lastDriver; ///< WEAK POINTER (there is no guarantee it is still allocated)
|
||||||
|
///< Equality comparisons are OK, but that's pretty much it
|
||||||
|
|
||||||
SCH_ITEM* m_driver; ///< The SCH_ITEM that drives this connection's net
|
SCH_ITEM* m_driver; ///< The SCH_ITEM that drives this connection's net
|
||||||
|
|
||||||
CONNECTION_TYPE m_type; ///< @see enum CONNECTION_TYPE
|
CONNECTION_TYPE m_type; ///< @see enum CONNECTION_TYPE
|
||||||
|
|
|
@ -47,6 +47,7 @@
|
||||||
#include <sch_edit_frame.h>
|
#include <sch_edit_frame.h>
|
||||||
#include <sch_iref.h>
|
#include <sch_iref.h>
|
||||||
#include <sch_painter.h>
|
#include <sch_painter.h>
|
||||||
|
#include <sch_view.h>
|
||||||
#include <sch_sheet.h>
|
#include <sch_sheet.h>
|
||||||
#include <schematic.h>
|
#include <schematic.h>
|
||||||
#include <settings/settings_manager.h>
|
#include <settings/settings_manager.h>
|
||||||
|
@ -714,6 +715,21 @@ void SCH_EDIT_FRAME::OnModify()
|
||||||
if( ADVANCED_CFG::GetCfg().m_realTimeConnectivity && CONNECTION_GRAPH::m_allowRealTime )
|
if( ADVANCED_CFG::GetCfg().m_realTimeConnectivity && CONNECTION_GRAPH::m_allowRealTime )
|
||||||
RecalculateConnections( NO_CLEANUP );
|
RecalculateConnections( NO_CLEANUP );
|
||||||
|
|
||||||
|
GetCanvas()->GetView()->UpdateAllItemsConditionally( KIGFX::REPAINT,
|
||||||
|
[]( KIGFX::VIEW_ITEM* aItem )
|
||||||
|
{
|
||||||
|
SCH_ITEM* item = dynamic_cast<SCH_ITEM*>( aItem );
|
||||||
|
SCH_CONNECTION* connection = item ? item->Connection() : nullptr;
|
||||||
|
|
||||||
|
if( connection && connection->HasDriverChanged() )
|
||||||
|
{
|
||||||
|
connection->ClearDriverChanged();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
} );
|
||||||
|
|
||||||
GetCanvas()->Refresh();
|
GetCanvas()->Refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue