Integration of netclasses into Eeschema.

This is mostly architecture, with the hookup of the Schematic Setup
dialog's Net Classes page.  Things like assigning to a net on the
canvas to follow.

Fixes https://gitlab.com/kicad/code/kicad/issues/2132

Fixes https://gitlab.com/kicad/code/kicad/issues/4581
This commit is contained in:
Jeff Young 2020-07-06 11:51:04 +01:00
parent b917e9aa72
commit 3939b31027
33 changed files with 824 additions and 559 deletions

View File

@ -48,10 +48,12 @@ enum {
};
PANEL_SETUP_NETCLASSES::PANEL_SETUP_NETCLASSES( PAGED_DIALOG* aParent, NETCLASSES* aNetclasses ) :
PANEL_SETUP_NETCLASSES::PANEL_SETUP_NETCLASSES( PAGED_DIALOG* aParent, NETCLASSES* aNetclasses,
const std::vector<wxString>& aCandidateNetNames ) :
PANEL_SETUP_NETCLASSES_BASE( aParent->GetTreebook() ),
m_Parent( aParent ),
m_Netclasses( aNetclasses )
m_netclasses( aNetclasses ),
m_candidateNetNames( aCandidateNetNames )
{
m_netclassesDirty = true;
@ -147,20 +149,19 @@ static void netclassToGridRow( EDA_UNITS aUnits, wxGrid* aGrid, int aRow, const
bool PANEL_SETUP_NETCLASSES::TransferDataToWindow()
{
NETCLASSPTR netclass = m_Netclasses->GetDefault();
std::map<wxString, wxString> netToNetclassMap;
std::map<wxString, wxString> staleNetMap;
for( const wxString& candidate : m_candidateNetNames )
netToNetclassMap[ candidate ] = "Default";
if( m_netclassGrid->GetNumberRows() )
m_netclassGrid->DeleteRows( 0, m_netclassGrid->GetNumberRows() );
m_netclassGrid->AppendRows( (int) m_Netclasses->GetCount() + 1 ); // + 1 for default netclass
m_netclassGrid->AppendRows((int) m_netclasses->GetCount() + 1 ); // + 1 for default netclass
// enter the Default NETCLASS.
netclassToGridRow( m_Parent->GetUserUnits(), m_netclassGrid, 0, netclass );
for( const wxString& net : *netclass )
netToNetclassMap[ net ] = netclass->GetName();
netclassToGridRow( m_Parent->GetUserUnits(), m_netclassGrid, 0, m_netclasses->GetDefault() );
// make the Default NETCLASS name read-only
wxGridCellAttr* cellAttr = m_netclassGrid->GetOrCreateCellAttr( 0, GRID_NAME );
@ -170,42 +171,60 @@ bool PANEL_SETUP_NETCLASSES::TransferDataToWindow()
// enter other netclasses
int row = 1;
for( NETCLASSES::iterator i = m_Netclasses->begin(); i != m_Netclasses->end(); ++i, ++row )
for( NETCLASSES::iterator i = m_netclasses->begin(); i != m_netclasses->end(); ++i, ++row )
{
netclass = i->second;
NETCLASSPTR netclass = i->second;
netclassToGridRow( m_Parent->GetUserUnits(), m_netclassGrid, row, netclass );
for( const wxString& net : *netclass )
netToNetclassMap[ net ] = i->second->GetName();
{
// While we currently only store shortNames as members, legacy versions stored
// fully-qualified names so we don't know which kind we're going to find.
wxString shortName = net.AfterLast( '/' );
if( netToNetclassMap.count( shortName ) )
netToNetclassMap[ shortName ] = i->second->GetName();
else
staleNetMap[ shortName ] = i->second->GetName();
}
}
if( m_membershipGrid->GetNumberRows() )
m_membershipGrid->DeleteRows( 0, m_membershipGrid->GetNumberRows() );
// add all the nets discovered in the netclass membership lists
// add currently-assigned and candidate netnames to membership lists
for( const std::pair<const wxString, wxString>& ii : netToNetclassMap )
{
if( !ii.first.IsEmpty() )
addNet( UnescapeString( ii.first ), ii.second );
}
addNet( UnescapeString( ii.first ), ii.second, false );
for( const std::pair<const wxString, wxString>& ii : staleNetMap )
addNet( UnescapeString( ii.first ), ii.second, true );
return true;
}
void PANEL_SETUP_NETCLASSES::addNet( const wxString& netName, const wxString& netclass )
void PANEL_SETUP_NETCLASSES::addNet( const wxString& netName, const wxString& netclass,
bool aStale )
{
int i = m_membershipGrid->GetNumberRows();
m_membershipGrid->AppendRows( 1 );
m_membershipGrid->SetCellValue( i, 0, netName );
if( aStale )
{
wxColour color = wxSystemSettings::GetColour( wxSYS_COLOUR_GRAYTEXT );
m_membershipGrid->SetCellTextColour( i, 0, color );
}
m_membershipGrid->SetCellValue( i, 1, netclass );
}
/* Populates drop-downs with the list of net classes
/*
* Populates drop-downs with the list of net classes
*/
void PANEL_SETUP_NETCLASSES::rebuildNetclassDropdowns()
{
@ -255,28 +274,33 @@ bool PANEL_SETUP_NETCLASSES::TransferDataFromWindow()
if( !validateData() )
return false;
// Remove all netclasses from board. We'll copy new list after
m_Netclasses->Clear();
m_netclasses->Clear();
// Copy the default NetClass:
gridRowToNetclass( m_Parent->GetUserUnits(), m_netclassGrid, 0, m_Netclasses->GetDefault() );
gridRowToNetclass( m_Parent->GetUserUnits(), m_netclassGrid, 0, m_netclasses->GetDefault() );
// Copy other NetClasses :
for( int row = 1; row < m_netclassGrid->GetNumberRows(); ++row )
{
NETCLASSPTR nc = std::make_shared<NETCLASS>( m_netclassGrid->GetCellValue( row, GRID_NAME ) );
if( m_Netclasses->Add( nc ) )
if( m_netclasses->Add( nc ) )
gridRowToNetclass( m_Parent->GetUserUnits(), m_netclassGrid, row, nc );
}
// Now read all nets and push them in the corresponding netclass net buffer
for( int row = 0; row < m_membershipGrid->GetNumberRows(); ++row )
{
NETCLASSPTR nc = m_Netclasses->Find( m_membershipGrid->GetCellValue( row, 1 ) );
const wxString& netname = m_membershipGrid->GetCellValue( row, 0 );
const wxString& classname = m_membershipGrid->GetCellValue( row, 1 );
if( classname != "Default" )
{
const NETCLASSPTR& nc = m_netclasses->Find( classname );
if( nc )
nc->Add( m_membershipGrid->GetCellValue( row, 0 ) );
nc->Add( EscapeString( netname, CTX_NETNAME ) );
}
}
return true;
@ -541,9 +565,9 @@ bool PANEL_SETUP_NETCLASSES::validateData()
void PANEL_SETUP_NETCLASSES::ImportSettingsFrom( NETCLASSES* aNetclasses )
{
NETCLASSES* savedSettings = m_Netclasses;
NETCLASSES* savedSettings = m_netclasses;
m_Netclasses = aNetclasses;
m_netclasses = aNetclasses;
TransferDataToWindow();
rebuildNetclassDropdowns();
@ -551,7 +575,7 @@ void PANEL_SETUP_NETCLASSES::ImportSettingsFrom( NETCLASSES* aNetclasses )
m_netclassGrid->ForceRefresh();
m_membershipGrid->ForceRefresh();
m_Netclasses = savedSettings;
m_netclasses = savedSettings;
}

View File

@ -36,7 +36,8 @@ class PANEL_SETUP_NETCLASSES : public PANEL_SETUP_NETCLASSES_BASE
{
private:
PAGED_DIALOG* m_Parent;
NETCLASSES* m_Netclasses;
NETCLASSES* m_netclasses;
std::vector<wxString> m_candidateNetNames;
int* m_originalColWidths;
bool m_netclassesDirty; // The netclass drop-down menus need rebuilding
@ -60,7 +61,7 @@ private:
void rebuildNetclassDropdowns();
void addNet( const wxString& netName, const wxString& netclass );
void addNet( const wxString& netName, const wxString& netclass, bool aStale );
void doApplyFilters( bool aShowAll );
void doAssignments( bool aAssignAll );
@ -68,7 +69,8 @@ private:
void AdjustMembershipGridColumns( int aWidth );
public:
PANEL_SETUP_NETCLASSES( PAGED_DIALOG* aParent, NETCLASSES* aNetclasses );
PANEL_SETUP_NETCLASSES( PAGED_DIALOG* aParent, NETCLASSES* aNetclasses,
const std::vector<wxString>& aCandidateNetNames );
~PANEL_SETUP_NETCLASSES( ) override;
bool TransferDataToWindow() override;

View File

@ -26,7 +26,7 @@
#define PCBNEW
#endif
#include <base_units.h>
#include <kicad_string.h>
const int netSettingsSchemaVersion = 0;
@ -64,16 +64,20 @@ NET_SETTINGS::NET_SETTINGS( JSON_SETTINGS* aParent, const std::string& aPath ) :
{ "diff_pair_via_gap", Iu2Millimeter( netclass->GetDiffPairViaGap() ) }
};
nlohmann::json nets = nlohmann::json::array();
if( idx > 0 )
{
nlohmann::json membersJson = nlohmann::json::array();
for( NETCLASS::const_iterator i = netclass->begin(); i != netclass->end(); ++i )
if( !i->empty() )
nets.push_back( std::string( i->ToUTF8() ) );
netJson["nets"] = nets;
for( const auto& ii : *netclass )
{
if( !ii.empty() )
membersJson.push_back( std::string( ii.ToUTF8() ) );
}
netJson["nets"] = membersJson;
ret.push_back( netJson );
}
}
return ret;
},
@ -83,6 +87,7 @@ NET_SETTINGS::NET_SETTINGS( JSON_SETTINGS* aParent, const std::string& aPath ) :
return;
m_NetClasses.Clear();
m_NetClassAssignments.clear();
NETCLASSPTR netclass;
NETCLASSPTR defaultClass = m_NetClasses.GetDefault();
@ -132,8 +137,14 @@ NET_SETTINGS::NET_SETTINGS( JSON_SETTINGS* aParent, const std::string& aPath ) :
if( netclass != defaultClass )
m_NetClasses.Add( netclass );
for( const wxString& net : *netclass )
m_NetClassAssignments[ net ] = netclass->GetName();
}
}, {} ) );
ResolveNetClassAssignments();
},
{} ) );
}
@ -146,3 +157,259 @@ NET_SETTINGS::~NET_SETTINGS()
m_parent = nullptr;
}
}
static bool isSuperSub( wxChar c )
{
return c == '_' || c == '^';
};
bool NET_SETTINGS::ParseBusVector( const wxString& aBus, wxString* aName,
std::vector<wxString>* aMemberList )
{
auto isDigit = []( wxChar c )
{
static wxString digits( wxT( "0123456789" ) );
return digits.Contains( c );
};
size_t busLen = aBus.length();
size_t i = 0;
wxString prefix;
wxString suffix;
wxString tmp;
long begin = 0;
long end = 0;
int braceNesting = 0;
prefix.reserve( busLen );
// Parse prefix
//
for( ; i < busLen; ++i )
{
if( aBus[i] == '{' )
{
if( i > 0 && isSuperSub( aBus[i-1] ) )
braceNesting++;
else
return false;
}
else if( aBus[i] == '}' )
{
braceNesting--;
}
if( aBus[i] == ' ' || aBus[i] == ']' )
return false;
if( aBus[i] == '[' )
break;
prefix += aBus[i];
}
// Parse start number
//
i++; // '[' character
if( i >= busLen )
return false;
for( ; i < busLen; ++i )
{
if( aBus[i] == '.' && i + 1 < busLen && aBus[i+1] == '.' )
{
tmp.ToLong( &begin );
i += 2;
break;
}
if( !isDigit( aBus[i] ) )
return false;
tmp += aBus[i];
}
// Parse end number
//
tmp = wxEmptyString;
if( i >= busLen )
return false;
for( ; i < busLen; ++i )
{
if( aBus[i] == ']' )
{
tmp.ToLong( &end );
++i;
break;
}
if( !isDigit( aBus[i] ) )
return false;
tmp += aBus[i];
}
// Parse suffix
//
for( ; i < busLen; ++i )
{
if( aBus[i] == '}' )
{
braceNesting--;
suffix += aBus[i];
}
else if( aBus[i] == '~' )
{
suffix += aBus[i];
}
else
{
return false;
}
}
if( braceNesting != 0 )
return false;
if( begin == end )
return false;
else if( begin > end )
std::swap( begin, end );
if( aName )
*aName = prefix;
if( aMemberList )
{
for( long idx = begin; idx <= end; ++idx )
{
wxString str = prefix;
str << idx;
str << suffix;
aMemberList->emplace_back( str );
}
}
return true;
}
bool NET_SETTINGS::ParseBusGroup( wxString aGroup, wxString* aName,
std::vector<wxString>* aMemberList )
{
size_t groupLen = aGroup.length();
size_t i = 0;
wxString prefix;
wxString suffix;
wxString tmp;
int braceNesting = 0;
prefix.reserve( groupLen );
// Parse prefix
//
for( ; i < groupLen; ++i )
{
if( aGroup[i] == '{' )
{
if( i > 0 && isSuperSub( aGroup[i-1] ) )
braceNesting++;
else
break;
}
else if( aGroup[i] == '}' )
{
braceNesting--;
}
if( aGroup[i] == ' ' || aGroup[i] == '[' || aGroup[i] == ']' )
return false;
prefix += aGroup[i];
}
if( braceNesting != 0 )
return false;
if( aName )
*aName = prefix;
// Parse members
//
i++; // '{' character
if( i >= groupLen )
return false;
for( ; i < groupLen; ++i )
{
if( aGroup[i] == '{' )
{
if( i > 0 && isSuperSub( aGroup[i-1] ) )
braceNesting++;
else
return false;
}
else if( aGroup[i] == '}' )
{
if( braceNesting )
braceNesting--;
else
{
if( aMemberList )
aMemberList->push_back( tmp );
return true;
}
}
if( aGroup[i] == ' ' )
{
if( aMemberList )
aMemberList->push_back( tmp );
tmp.Clear();
continue;
}
tmp += aGroup[i];
}
return false;
}
void NET_SETTINGS::ResolveNetClassAssignments()
{
std::map<wxString, wxString> existing = m_NetClassAssignments;
m_NetClassAssignments.clear();
for( const auto& ii : existing )
{
m_NetClassAssignments[ ii.first ] = ii.second;
wxString unescaped = UnescapeString( ii.first );
wxString prefix;
std::vector<wxString> members;
if( ParseBusVector( unescaped, &prefix, &members ) )
{
prefix = wxEmptyString;
}
else if( ParseBusGroup( unescaped, &prefix, &members ) )
{
if( !prefix.IsEmpty() )
prefix += wxT( "." );
}
for( wxString& member : members )
m_NetClassAssignments[ prefix + member ] = ii.second;
}
}

View File

@ -25,10 +25,8 @@
#include <vector>
#include <unordered_map>
#include <profile.h>
#include <common.h>
#include <erc.h>
#include <macros.h>
#include <sch_bus_entry.h>
#include <sch_component.h>
#include <sch_edit_frame.h>
@ -39,11 +37,10 @@
#include <sch_sheet_path.h>
#include <sch_text.h>
#include <schematic.h>
#include <advanced_config.h>
#include <connection_graph.h>
#include <widgets/ui_common.h>
bool CONNECTION_SUBGRAPH::ResolveDrivers( bool aCreateMarkers )
{
PRIORITY highest_priority = PRIORITY::INVALID;
@ -236,8 +233,8 @@ wxString CONNECTION_SUBGRAPH::GetNameForDriver( SCH_ITEM* aItem ) const
{
case SCH_PIN_T:
{
auto power_object = static_cast<SCH_PIN*>( aItem );
name = power_object->GetDefaultNetName( m_sheet );
SCH_PIN* pin = static_cast<SCH_PIN*>( aItem );
name = pin->GetDefaultNetName( m_sheet );
break;
}
@ -246,7 +243,7 @@ wxString CONNECTION_SUBGRAPH::GetNameForDriver( SCH_ITEM* aItem ) const
case SCH_HIER_LABEL_T:
case SCH_SHEET_PIN_T:
{
name = static_cast<SCH_TEXT*>( aItem )->GetShownText();
name = EscapeString( static_cast<SCH_TEXT*>( aItem )->GetShownText(), CTX_NETNAME );
break;
}
@ -812,13 +809,13 @@ void CONNECTION_GRAPH::buildConnectionGraph()
case SCH_HIER_LABEL_T:
{
auto text = static_cast<SCH_TEXT*>( driver );
connection->ConfigureFromLabel( text->GetShownText() );
connection->ConfigureFromLabel( EscapeString( text->GetShownText(), CTX_NETNAME ) );
break;
}
case SCH_SHEET_PIN_T:
{
auto pin = static_cast<SCH_SHEET_PIN*>( driver );
connection->ConfigureFromLabel( pin->GetShownText() );
connection->ConfigureFromLabel( EscapeString( pin->GetShownText(), CTX_NETNAME ) );
break;
}
case SCH_PIN_T:
@ -1218,7 +1215,7 @@ void CONNECTION_GRAPH::buildConnectionGraph()
auto text = static_cast<SCH_TEXT*>( driver );
if( text->GetShownText() == test_name )
if( EscapeString( text->GetShownText(), CTX_NETNAME ) == test_name )
{
match = true;
break;
@ -1836,7 +1833,7 @@ std::shared_ptr<SCH_CONNECTION> CONNECTION_GRAPH::getDefaultConnection( SCH_ITEM
c = std::make_shared<SCH_CONNECTION>( aItem, aSheet );
c->SetGraph( this );
c->ConfigureFromLabel( text->GetShownText() );
c->ConfigureFromLabel( EscapeString( text->GetShownText(), CTX_NETNAME ) );
break;
}
@ -2097,8 +2094,8 @@ bool CONNECTION_GRAPH::ercCheckBusToNetConflicts( const CONNECTION_SUBGRAPH* aSu
case SCH_SHEET_PIN_T:
case SCH_HIER_LABEL_T:
{
auto text = static_cast<SCH_TEXT*>( item )->GetShownText();
conn.ConfigureFromLabel( text );
SCH_TEXT* text = static_cast<SCH_TEXT*>( item );
conn.ConfigureFromLabel( EscapeString( text->GetShownText(), CTX_NETNAME ) );
if( conn.IsBus() )
bus_item = ( !bus_item ) ? item : bus_item;
@ -2440,7 +2437,7 @@ bool CONNECTION_GRAPH::ercCheckLabels( const CONNECTION_SUBGRAPH* aSubgraph )
if( !m_schematic->ErcSettings().IsTestEnabled( ERCE_GLOBLABEL ) && is_global )
return true;
wxString name = text->GetShownText();
wxString name = EscapeString( text->GetShownText(), CTX_NETNAME );
if( is_global )
{

View File

@ -41,10 +41,12 @@
#include <schematic.h>
#include <reporter.h>
#include <netlist_exporters/netlist_exporter_kicad.h>
#include <project/project_file.h>
#include <project/net_settings.h>
#include <tools/ee_actions.h>
#include <tools/sch_editor_control.h>
#include <advanced_config.h>
#include <netclass.h>
SCH_ITEM* SCH_EDITOR_CONTROL::FindComponentAndItem( const wxString& aReference,
bool aSearchHierarchy,
@ -450,6 +452,7 @@ void SCH_EDIT_FRAME::KiwayMailIn( KIWAY_EXPRESS& mail )
break;
case MAIL_SCH_GET_NETLIST:
{
if( payload.find( "quiet-annotate" ) != std::string::npos )
{
Schematic().GetSheets().AnnotatePowerSymbols();
@ -464,7 +467,6 @@ void SCH_EDIT_FRAME::KiwayMailIn( KIWAY_EXPRESS& mail )
return;
}
{
NETLIST_EXPORTER_KICAD exporter( &Schematic() );
STRING_FORMATTER formatter;
@ -498,8 +500,47 @@ void SCH_EDIT_FRAME::KiwayMailIn( KIWAY_EXPRESS& mail )
GetCanvas()->GetView()->UpdateAllItems( KIGFX::ALL );
GetCanvas()->Refresh();
break;
}
break;
case MAIL_SCH_CLEAN_NETCLASSES:
{
NET_SETTINGS& netSettings = Prj().GetProjectFile().NetSettings();
netSettings.m_NetClassAssignments.clear();
// Establish the set of nets which is currently valid
for( const wxString& name : Schematic().GetNetClassAssignmentCandidates() )
netSettings.m_NetClassAssignments[ name ] = "Default";
// Copy their netclass assignments, dropping any assignments to non-current nets.
for( auto& ii : netSettings.m_NetClasses )
{
for( const wxString& member : *ii.second )
{
if( netSettings.m_NetClassAssignments.count( member ) )
netSettings.m_NetClassAssignments[ member ] = ii.first;
}
ii.second->Clear();
}
// Update the membership lists to contain only the current nets.
for( const std::pair<const wxString, wxString>& ii : netSettings.m_NetClassAssignments )
{
if( ii.second == "Default" )
continue;
NETCLASSPTR netclass = netSettings.m_NetClasses.Find( ii.second );
if( netclass )
netclass->Add( ii.first );
}
netSettings.ResolveNetClassAssignments();
}
break;
case MAIL_IMPORT_FILE:
{
// Extract file format type and path (plugin type and path separated with \n)
@ -528,6 +569,7 @@ void SCH_EDIT_FRAME::KiwayMailIn( KIWAY_EXPRESS& mail )
case MAIL_SCH_SAVE:
if( SaveProject() )
payload = "success";
break;
case MAIL_SCH_UPDATE:

View File

@ -278,7 +278,7 @@ bool DIALOG_LABEL_EDITOR::TransferDataToWindow()
for( SCH_SCREEN* screen = allScreens.GetFirst(); screen; screen = allScreens.GetNext() )
{
for( auto item : screen->Items().OfType( m_CurrentText->Type() ) )
for( SCH_ITEM* item : screen->Items().OfType( m_CurrentText->Type() ) )
{
auto textItem = static_cast<const SCH_TEXT*>( item );
existingLabels.insert( UnescapeString( textItem->GetText() ) );

View File

@ -82,8 +82,9 @@ bool DIALOG_SCH_IMPORT_SETTINGS::TransferDataFromWindow()
void DIALOG_SCH_IMPORT_SETTINGS::OnSelectAll( wxCommandEvent& event )
{
m_formattingOpt->SetValue( true );
m_fieldNameTemplatesOpt->SetValue( true );
m_pinMapOpt->SetValue( true );
m_FormattingOpt->SetValue( true );
m_FieldNameTemplatesOpt->SetValue( true );
m_PinMapOpt->SetValue( true );
m_SeveritiesOpt->SetValue( true );
m_NetClassesOpt->SetValue( true );
}

View File

@ -45,18 +45,21 @@ DIALOG_SCH_IMPORT_SETTINGS_BASE::DIALOG_SCH_IMPORT_SETTINGS_BASE( wxWindow* pare
importLabel->Wrap( -1 );
bmiddleSizer->Add( importLabel, 0, wxTOP|wxBOTTOM|wxRIGHT, 5 );
m_formattingOpt = new wxCheckBox( this, wxID_ANY, _("Formatting preferences"), wxDefaultPosition, wxDefaultSize, 0 );
bmiddleSizer->Add( m_formattingOpt, 0, wxALL, 5 );
m_FormattingOpt = new wxCheckBox( this, wxID_ANY, _("Formatting preferences"), wxDefaultPosition, wxDefaultSize, 0 );
bmiddleSizer->Add( m_FormattingOpt, 0, wxALL, 5 );
m_fieldNameTemplatesOpt = new wxCheckBox( this, wxID_ANY, _("Field name templates"), wxDefaultPosition, wxDefaultSize, 0 );
bmiddleSizer->Add( m_fieldNameTemplatesOpt, 0, wxBOTTOM|wxRIGHT|wxLEFT, 5 );
m_FieldNameTemplatesOpt = new wxCheckBox( this, wxID_ANY, _("Field name templates"), wxDefaultPosition, wxDefaultSize, 0 );
bmiddleSizer->Add( m_FieldNameTemplatesOpt, 0, wxBOTTOM|wxRIGHT|wxLEFT, 5 );
m_pinMapOpt = new wxCheckBox( this, wxID_ANY, _("Pin conflict map"), wxDefaultPosition, wxDefaultSize, 0 );
bmiddleSizer->Add( m_pinMapOpt, 0, wxBOTTOM|wxRIGHT|wxLEFT, 5 );
m_PinMapOpt = new wxCheckBox( this, wxID_ANY, _("Pin conflict map"), wxDefaultPosition, wxDefaultSize, 0 );
bmiddleSizer->Add( m_PinMapOpt, 0, wxBOTTOM|wxRIGHT|wxLEFT, 5 );
m_SeveritiesOpt = new wxCheckBox( this, wxID_ANY, _("Violation severities"), wxDefaultPosition, wxDefaultSize, 0 );
bmiddleSizer->Add( m_SeveritiesOpt, 0, wxRIGHT|wxLEFT, 5 );
m_NetClassesOpt = new wxCheckBox( this, wxID_ANY, _("Net classes"), wxDefaultPosition, wxDefaultSize, 0 );
bmiddleSizer->Add( m_NetClassesOpt, 0, wxALL, 5 );
m_MainSizer->Add( bmiddleSizer, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 10 );

View File

@ -378,7 +378,7 @@
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_formattingOpt</property>
<property name="name">m_FormattingOpt</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
@ -442,7 +442,7 @@
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_fieldNameTemplatesOpt</property>
<property name="name">m_FieldNameTemplatesOpt</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
@ -506,7 +506,7 @@
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_pinMapOpt</property>
<property name="name">m_PinMapOpt</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
@ -593,6 +593,70 @@
<property name="window_style"></property>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxALL</property>
<property name="proportion">0</property>
<object class="wxCheckBox" expanded="1">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="checked">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Net classes</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_NetClassesOpt</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">public</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass">; ; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
<property name="validator_variable"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
</object>
</object>
</object>
</object>
<object class="sizeritem" expanded="1">

View File

@ -52,10 +52,11 @@ class DIALOG_SCH_IMPORT_SETTINGS_BASE : public DIALOG_SHIM
public:
wxCheckBox* m_formattingOpt;
wxCheckBox* m_fieldNameTemplatesOpt;
wxCheckBox* m_pinMapOpt;
wxCheckBox* m_FormattingOpt;
wxCheckBox* m_FieldNameTemplatesOpt;
wxCheckBox* m_PinMapOpt;
wxCheckBox* m_SeveritiesOpt;
wxCheckBox* m_NetClassesOpt;
DIALOG_SCH_IMPORT_SETTINGS_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Import Settings"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
~DIALOG_SCH_IMPORT_SETTINGS_BASE();

View File

@ -41,19 +41,22 @@ DIALOG_SCHEMATIC_SETUP::DIALOG_SCHEMATIC_SETUP( SCH_EDIT_FRAME* aFrame ) :
m_frame( aFrame ),
m_severities( nullptr )
{
PROJECT_FILE& project = aFrame->Prj().GetProjectFile();
SCHEMATIC& schematic = aFrame->Schematic();
m_formatting = new PANEL_SETUP_FORMATTING( m_treebook, aFrame );
m_fieldNameTemplates = new PANEL_EESCHEMA_TEMPLATE_FIELDNAMES( aFrame, m_treebook, false );
m_pinMap = new PANEL_SETUP_PINMAP( m_treebook, aFrame );
m_pinToPinError = ERC_ITEM::Create( ERCE_PIN_TO_PIN_WARNING );
m_severities = new PANEL_SETUP_SEVERITIES( this, ERC_ITEM::GetItemsWithSeverities(),
m_frame->Schematic().ErcSettings().m_Severities,
schematic.ErcSettings().m_Severities,
m_pinToPinError );
m_textVars = new PANEL_TEXT_VARIABLES( m_treebook, &Prj() );
PROJECT_FILE& project = aFrame->Prj().GetProjectFile();
m_netclasses = new PANEL_SETUP_NETCLASSES( this, &project.NetSettings().m_NetClasses );
m_netclasses = new PANEL_SETUP_NETCLASSES( this, &project.NetSettings().m_NetClasses,
schematic.GetNetClassAssignmentCandidates() );
/*
* WARNING: If you change page names you MUST update calls to ShowSchematicSetupDialog().
@ -143,17 +146,20 @@ void DIALOG_SCHEMATIC_SETUP::OnAuxiliaryAction( wxCommandEvent& event )
file.m_SchematicSettings->m_TemplateFieldNames = &templateMgr;
file.m_SchematicSettings->LoadFromFile();
if( importDlg.m_formattingOpt->GetValue() )
if( importDlg.m_FormattingOpt->GetValue() )
m_formatting->ImportSettingsFrom( *file.m_SchematicSettings );
if( importDlg.m_fieldNameTemplatesOpt->GetValue() )
if( importDlg.m_FieldNameTemplatesOpt->GetValue() )
m_fieldNameTemplates->ImportSettingsFrom( file.m_SchematicSettings->m_TemplateFieldNames );
if( importDlg.m_pinMapOpt->GetValue() )
if( importDlg.m_PinMapOpt->GetValue() )
m_pinMap->ImportSettingsFrom( file.m_ErcSettings->m_PinMap );
if( importDlg.m_SeveritiesOpt->GetValue() )
m_severities->ImportSettingsFrom( file.m_ErcSettings->m_Severities );
if( importDlg.m_NetClassesOpt->GetValue() )
m_netclasses->ImportSettingsFrom( &file.m_NetSettings->m_NetClasses );
m_frame->GetSettingsManager()->UnloadProject( otherPrj, false );
}

View File

@ -37,10 +37,12 @@
#include <netlist_object.h>
#include <sch_edit_frame.h>
#include <schematic.h>
#include <project/net_settings.h>
#if defined(DEBUG)
#include <iostream>
const char* ShowType( NETLIST_ITEM aType )
{
const char* ret;
@ -248,7 +250,7 @@ void NETLIST_OBJECT::ConvertBusToNetListItems( NETLIST_OBJECT_LIST& aNetListItem
bool self_set = false;
std::vector<wxString> bus_contents_vec;
if( alias || SCH_CONNECTION::ParseBusGroup( m_Label, &group_name, &bus_contents_vec ) )
if( alias || NET_SETTINGS::ParseBusGroup( m_Label, &group_name, &bus_contents_vec ) )
{
if( alias )
{
@ -267,7 +269,7 @@ void NETLIST_OBJECT::ConvertBusToNetListItems( NETLIST_OBJECT_LIST& aNetListItem
std::vector<wxString> members;
// Nested bus vector inside a bus group
if( SCH_CONNECTION::ParseBusVector( bus_member, &prefix, &members ) )
if( NET_SETTINGS::ParseBusVector( bus_member, &prefix, &members ) )
{
long begin, end;
@ -314,7 +316,7 @@ void NETLIST_OBJECT::ConvertBusToNetListItems( NETLIST_OBJECT_LIST& aNetListItem
}
}
}
else if( SCH_CONNECTION::ParseBusVector( m_Label, &group_name, &bus_contents_vec ) )
else if( NET_SETTINGS::ParseBusVector( m_Label, &group_name, &bus_contents_vec ) )
{
long begin = conn.VectorStart();
long end = conn.VectorEnd();

View File

@ -25,11 +25,11 @@
#include <sch_component.h>
#include <sch_pin.h>
#include <sch_screen.h>
#include <project/net_settings.h>
#include <advanced_config.h>
#include <sch_connection.h>
/**
*
* Buses can be defined in multiple ways. A bus vector consists of a prefix and
@ -131,7 +131,7 @@ void SCH_CONNECTION::ConfigureFromLabel( const wxString& aLabel )
wxString unescaped = UnescapeString( aLabel );
if( ParseBusVector( unescaped, &prefix, &members ) )
if( NET_SETTINGS::ParseBusVector( unescaped, &prefix, &members ) )
{
m_type = CONNECTION_TYPE::BUS;
m_vector_prefix = prefix;
@ -150,7 +150,7 @@ void SCH_CONNECTION::ConfigureFromLabel( const wxString& aLabel )
m_members.push_back( member );
}
}
else if( ParseBusGroup( unescaped, &prefix, &members ) )
else if( NET_SETTINGS::ParseBusGroup( unescaped, &prefix, &members ) )
{
m_type = CONNECTION_TYPE::BUS_GROUP;
@ -357,7 +357,7 @@ void SCH_CONNECTION::AppendInfoToMsgPanel( MSG_PANEL_ITEMS& aList ) const
aList.push_back( MSG_PANEL_ITEM( msg, members, RED ) );
}
else if( ParseBusGroup( m_name, &group_name, &group_members ) )
else if( NET_SETTINGS::ParseBusGroup( m_name, &group_name, &group_members ) )
{
for( const auto& group_member : group_members )
{
@ -406,7 +406,10 @@ void SCH_CONNECTION::AppendDebugInfoToMsgPanel( MSG_PANEL_ITEMS& aList ) const
bool SCH_CONNECTION::IsBusLabel( const wxString& aLabel )
{
return ParseBusVector( aLabel, nullptr, nullptr ) || ParseBusGroup( aLabel, nullptr, nullptr );
const wxString& unescaped = UnescapeString( aLabel );
return NET_SETTINGS::ParseBusVector( unescaped, nullptr, nullptr )
|| NET_SETTINGS::ParseBusGroup( unescaped, nullptr, nullptr );
}
@ -419,232 +422,6 @@ bool SCH_CONNECTION::MightBeBusLabel( const wxString& aLabel )
}
static bool isSuperSub( wxChar c )
{
return c == '_' || c == '^';
};
bool SCH_CONNECTION::ParseBusVector( const wxString& aBus, wxString* aName,
std::vector<wxString>* aMemberList )
{
auto isDigit = []( wxChar c )
{
static wxString digits( wxT( "0123456789" ) );
return digits.Contains( c );
};
size_t busLen = aBus.length();
size_t i = 0;
wxString prefix;
wxString suffix;
wxString tmp;
long begin = 0;
long end = 0;
int braceNesting = 0;
prefix.reserve( busLen );
// Parse prefix
//
for( ; i < busLen; ++i )
{
if( aBus[i] == '{' )
{
if( i > 0 && isSuperSub( aBus[i-1] ) )
braceNesting++;
else
return false;
}
else if( aBus[i] == '}' )
{
braceNesting--;
}
if( aBus[i] == ' ' || aBus[i] == ']' )
return false;
if( aBus[i] == '[' )
break;
prefix += aBus[i];
}
// Parse start number
//
i++; // '[' character
if( i >= busLen )
return false;
for( ; i < busLen; ++i )
{
if( aBus[i] == '.' && i + 1 < busLen && aBus[i+1] == '.' )
{
tmp.ToLong( &begin );
i += 2;
break;
}
if( !isDigit( aBus[i] ) )
return false;
tmp += aBus[i];
}
// Parse end number
//
tmp = wxEmptyString;
if( i >= busLen )
return false;
for( ; i < busLen; ++i )
{
if( aBus[i] == ']' )
{
tmp.ToLong( &end );
++i;
break;
}
if( !isDigit( aBus[i] ) )
return false;
tmp += aBus[i];
}
// Parse suffix
//
for( ; i < busLen; ++i )
{
if( aBus[i] == '}' )
{
braceNesting--;
suffix += aBus[i];
}
else if( aBus[i] == '~' )
{
suffix += aBus[i];
}
else
{
return false;
}
}
if( braceNesting != 0 )
return false;
if( begin == end )
return false;
else if( begin > end )
std::swap( begin, end );
if( aName )
*aName = prefix;
if( aMemberList )
{
for( long idx = begin; idx <= end; ++idx )
{
wxString str = prefix;
str << idx;
str << suffix;
aMemberList->emplace_back( str );
}
}
return true;
}
bool SCH_CONNECTION::ParseBusGroup( wxString aGroup, wxString* aName,
std::vector<wxString>* aMemberList )
{
size_t groupLen = aGroup.length();
size_t i = 0;
wxString prefix;
wxString suffix;
wxString tmp;
int braceNesting = 0;
prefix.reserve( groupLen );
// Parse prefix
//
for( ; i < groupLen; ++i )
{
if( aGroup[i] == '{' )
{
if( i > 0 && isSuperSub( aGroup[i-1] ) )
braceNesting++;
else
break;
}
else if( aGroup[i] == '}' )
{
braceNesting--;
}
if( aGroup[i] == ' ' || aGroup[i] == '[' || aGroup[i] == ']' )
return false;
prefix += aGroup[i];
}
if( braceNesting != 0 )
return false;
if( aName )
*aName = prefix;
// Parse members
//
i++; // '{' character
if( i >= groupLen )
return false;
for( ; i < groupLen; ++i )
{
if( aGroup[i] == '{' )
{
if( i > 0 && isSuperSub( aGroup[i-1] ) )
braceNesting++;
else
return false;
}
else if( aGroup[i] == '}' )
{
if( braceNesting )
braceNesting--;
else
{
if( aMemberList )
aMemberList->push_back( tmp );
return true;
}
}
if( aGroup[i] == ' ' )
{
if( aMemberList )
aMemberList->push_back( tmp );
tmp.Clear();
continue;
}
tmp += aGroup[i];
}
return false;
}
const std::vector< std::shared_ptr< SCH_CONNECTION > > SCH_CONNECTION::AllMembers() const
{
std::vector< std::shared_ptr< SCH_CONNECTION > > ret( m_members );
@ -657,6 +434,12 @@ const std::vector< std::shared_ptr< SCH_CONNECTION > > SCH_CONNECTION::AllMember
}
static bool isSuperSub( wxChar c )
{
return c == '_' || c == '^';
};
wxString SCH_CONNECTION::PrintBusForUI( const wxString& aGroup )
{
size_t groupLen = aGroup.length();

View File

@ -275,29 +275,6 @@ public:
*/
bool IsMemberOfBus( SCH_CONNECTION* aOther ) const;
/**
* Parses a bus vector (e.g. A[7..0]) into name, begin, and end.
* Ensures that begin and end are positive and that end > begin.
*
* @param aBus is a bus vector label string
* @param aName out is the bus name, e.g. "A"
* @param aMemberList is a list of member strings, e.g. "A7", "A6", and so on
* @return true if aBus was successfully parsed
*/
static bool ParseBusVector( const wxString& aBus, wxString* aName,
std::vector<wxString>* aMemberList );
/**
* Parses a bus group label into the name and a list of components
*
* @param aGroup is the input label, e.g. "USB{DP DM}"
* @param name is the output group name, e.g. "USB"
* @param aMemberList is a list of member strings, e.g. "DP", "DM"
* @return true if aGroup was successfully parsed
*/
static bool ParseBusGroup( wxString aGroup, wxString* name,
std::vector<wxString>* aMemberList );
/**
* Adds information about the connection object to aList
*/

View File

@ -48,7 +48,7 @@
#include <project.h>
#include <sch_bus_entry.h>
#include <sch_component.h>
#include <sch_connection.h>
#include <project/net_settings.h>
#include <sch_edit_frame.h>
#include <sch_junction.h>
#include <sch_legacy_plugin.h>
@ -2608,7 +2608,7 @@ wxString SCH_EAGLE_PLUGIN::fixSymbolName( const wxString& aName )
wxString SCH_EAGLE_PLUGIN::translateEagleBusName( const wxString& aEagleName ) const
{
if( SCH_CONNECTION::ParseBusVector( aEagleName, nullptr, nullptr ) )
if( NET_SETTINGS::ParseBusVector( aEagleName, nullptr, nullptr ) )
return aEagleName;
wxString ret = "{";

View File

@ -125,8 +125,6 @@ private:
SCHEMATIC* m_schematic; ///< The currently loaded schematic
const SCH_CONNECTION* m_highlightedConn; ///< The highlighted net or bus, or nullptr
std::vector<PARAM_CFG*> m_projectFileParams;
std::vector<PARAM_CFG*> m_configSettings;
wxPageSetupDialogData m_pageSetupData;
SCH_ITEM* m_item_to_repeat; ///< Last item to insert by the repeat command.
wxString m_netListerCommand; ///< Command line to call a custom net list
@ -142,11 +140,6 @@ private:
/// Use netcodes (net number) as net names when generating spice net lists.
bool m_spiceAjustPassiveValues;
/* these are PROJECT specific, not schematic editor specific
wxString m_userLibraryPath;
wxArrayString m_componentLibFiles;
*/
static PINSHEETLABEL_SHAPE m_lastSheetPinType; ///< Last sheet pin type.
protected:
@ -731,7 +724,8 @@ public:
* it can happens when the edited sheet used an existying file, or becomes a new instance
* of a already existing sheet.
*/
bool EditSheetProperties( SCH_SHEET* aSheet, SCH_SHEET_PATH* aHierarchy, bool* aClearAnnotationNewItems );
bool EditSheetProperties( SCH_SHEET* aSheet, SCH_SHEET_PATH* aHierarchy,
bool* aClearAnnotationNewItems );
void InitSheet( SCH_SHEET* aSheet, const wxString& aNewFilename );

View File

@ -94,31 +94,27 @@ class SCH_SCREEN : public BASE_SCREEN
{
private:
wxString m_fileName; ///< File used to load the screen.
wxString m_fileName; // File used to load the screen.
int m_refCount; ///< Number of sheets referencing this screen.
///< Delete when it goes to zero.
/** the list of scheet paths sharing this screen
* used in some annotation calculations to update alternate references
* Note: a screen having a m_refCount = 1 (only one sheet path using it)
* can have many scheet paths sharing this screen, if this sheet is inside
* an other sheet having many instances (one sheet path by parent sheet instance).
int m_refCount; // Number of sheets referencing this screen.
// Delete when it goes to zero.
/**
* The list of sheet paths sharing this screen. Used in some annotation calculations to
* update alternate references.
*
* Note: a screen having a m_refCount = 1 (only one sheet path using it) can have many
* sheet paths sharing this screen if it is inside another sheet having many instances.
*/
std::vector<SCH_SHEET_PATH> m_clientSheetPathList;
/// The size of the paper to print or plot on
PAGE_INFO m_paper; // keep with the MVC 'model' if this class gets split
PAGE_INFO m_paper; // The size of the paper to print or plot on
TITLE_BLOCK m_titles;
/// Origin of the auxiliary axis, which is used in exports mostly, but not yet in EESCHEMA
wxPoint m_aux_origin;
wxPoint m_aux_origin; // Origin used for drill & place files by PCBNew
EE_RTREE m_rtree;
int m_modification_sync; ///< inequality with PART_LIBS::GetModificationHash()
///< will trigger ResolveAll().
int m_modification_sync; // inequality with PART_LIBS::GetModificationHash() will
// trigger ResolveAll().
/// List of bus aliases stored in this screen
std::unordered_set< std::shared_ptr< BUS_ALIAS > > m_aliases;

View File

@ -28,8 +28,8 @@
*/
#include <wx/combo.h>
#include <sch_connection.h>
#include <sch_validators.h>
#include <project/net_settings.h>
#include <template_fieldnames.h>
@ -252,11 +252,11 @@ bool SCH_NETNAME_VALIDATOR::Validate( wxWindow *aParent )
wxString SCH_NETNAME_VALIDATOR::IsValid( const wxString& str ) const
{
if( SCH_CONNECTION::ParseBusGroup( str, nullptr, nullptr ) )
if( NET_SETTINGS::ParseBusGroup( str, nullptr, nullptr ) )
return wxString();
if( ( str.Contains( '[' ) || str.Contains( ']' ) ) &&
!SCH_CONNECTION::ParseBusVector( str, nullptr, nullptr ) )
!NET_SETTINGS::ParseBusVector( str, nullptr, nullptr ) )
return _( "Signal name contains '[' or ']' but is not a valid vector bus name" );
if( str.Contains( '\r' ) || str.Contains( '\n' ) )

View File

@ -22,6 +22,7 @@
#include <erc_settings.h>
#include <project.h>
#include <project/project_file.h>
#include <project/net_settings.h>
#include <schematic.h>
#include <sch_screen.h>
@ -163,4 +164,76 @@ std::shared_ptr<BUS_ALIAS> SCHEMATIC::GetBusAlias( const wxString& aLabel ) cons
}
std::vector<wxString> SCHEMATIC::GetNetClassAssignmentCandidates()
{
std::vector<wxString> names;
SCH_SCREENS allScreens( Root() );
for( SCH_SCREEN* screen = allScreens.GetFirst(); screen; screen = allScreens.GetNext() )
{
for( SCH_ITEM* item : screen->Items() )
{
switch( item->Type() )
{
case SCH_PIN_T:
{
SCH_PIN* pin = static_cast<SCH_PIN*>( item );
if( pin->IsPowerConnection() )
names.emplace_back( pin->GetName() );
}
break;
case SCH_LABEL_T:
case SCH_GLOBAL_LABEL_T:
case SCH_HIER_LABEL_T:
case SCH_SHEET_PIN_T:
{
wxString unescaped = static_cast<SCH_TEXT*>( item )->GetShownText();
wxString busPrefix;
std::vector<wxString> busMembers;
if( NET_SETTINGS::ParseBusVector( unescaped, nullptr, nullptr ) )
{
// Allow netclass assignment to an entire vector.
names.emplace_back( unescaped );
}
else if( NET_SETTINGS::ParseBusGroup( unescaped, &busPrefix, &busMembers ) )
{
// Named bus groups generate a net prefix, unnamed ones don't
if( !busPrefix.IsEmpty() )
busPrefix += wxT( "." );
for( const wxString& member : busMembers )
{
// Handle alias inside bus group member list
if( const std::shared_ptr<BUS_ALIAS>& alias = GetBusAlias( member ) )
{
for( const wxString& alias_member : alias->Members() )
names.emplace_back( busPrefix + alias_member );
}
else
{
names.emplace_back( busPrefix + member );
}
}
}
else
{
names.emplace_back( EscapeString( unescaped, CTX_NETNAME ) );
}
}
break;
default:
break;
}
}
}
return names;
}

View File

@ -139,11 +139,18 @@ public:
ERC_SETTINGS& ErcSettings() const;
/**
* Returns a pointer to a bus alias object for the given label,
* or null if one doesn't exist
* Returns a pointer to a bus alias object for the given label, or null if one
* doesn't exist.
*/
std::shared_ptr<BUS_ALIAS> GetBusAlias( const wxString& aLabel ) const;
/**
* Returns a list of name candidates for netclass assignment. The list will include both
* composite names (buses) and atomic net names. Names are fetched from available labels,
* power pins, etc.
*/
std::vector<wxString> GetNetClassAssignmentCandidates();
#if defined(DEBUG)
void Show( int nestLevel, std::ostream& os ) const override {}
#endif

View File

@ -521,7 +521,6 @@ int SCH_DRAWING_TOOLS::SingleClickPlace( const TOOL_EVENT& aEvent )
m_frame->SaveCopyForRepeatItem( newItem );
m_frame->SchematicCleanUp();
m_frame->TestDanglingEnds();
m_frame->OnModify();
}
}

View File

@ -136,7 +136,7 @@ private:
if( !connection || !connection->IsBus() || connection->Members().empty() )
{
Append( ID_POPUP_SCH_UNFOLD_BUS, _( "Bus has no connections" ), wxEmptyString );
Append( ID_POPUP_SCH_UNFOLD_BUS, _( "Bus has no members" ), wxEmptyString );
Enable( ID_POPUP_SCH_UNFOLD_BUS, false );
return;
}

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2014 CERN
* Copyright (C) 1992-2014 KiCad Developers, see CHANGELOG.TXT for contributors.
* Copyright (C) 1992-2020 KiCad Developers, see CHANGELOG.TXT for contributors.
* @author Maciej Suminski <maciej.suminski@cern.ch>
*
* This program is free software; you can redistribute it and/or
@ -36,17 +36,19 @@
*/
enum MAIL_T
{
MAIL_CROSS_PROBE, ///< PCB<->SCH, CVPCB->SCH cross-probing.
MAIL_BACKANNOTATE_FOOTPRINTS, ///< CVPCB->SCH footprint stuffing
MAIL_SCH_SAVE, ///< CVPCB->SCH save the schematic
MAIL_EESCHEMA_NETLIST, ///< SCH->CVPCB netlist immediately after launching CVPCB
MAIL_PCB_UPDATE, ///< SCH->PCB forward update
MAIL_SCH_UPDATE, ///< PCB->SCH forward update
MAIL_IMPORT_FILE, ///< Import a different format file
MAIL_SCH_GET_NETLIST, ///< Fetch a netlist from schematics
MAIL_PCB_GET_NETLIST, ///< Fetch a netlist from PCB layout
MAIL_SCH_REFRESH, ///< The the schematic editor to refresh the display.
MAIL_CROSS_PROBE, // PCB<->SCH, CVPCB->SCH cross-probing.
MAIL_BACKANNOTATE_FOOTPRINTS, // CVPCB->SCH footprint stuffing
MAIL_SCH_SAVE, // CVPCB->SCH save the schematic
MAIL_EESCHEMA_NETLIST, // SCH->CVPCB netlist immediately after launching CVPCB
MAIL_PCB_UPDATE, // SCH->PCB forward update
MAIL_SCH_UPDATE, // PCB->SCH forward update
MAIL_IMPORT_FILE, // Import a different format file
MAIL_SCH_GET_NETLIST, // Fetch a netlist from schematics
MAIL_PCB_GET_NETLIST, // Fetch a netlist from PCB layout
MAIL_SCH_REFRESH, // Tell the schematic editor to refresh the display.
MAIL_SCH_CLEAN_NETCLASSES, // Tell the schematic editor to clean stale nets out of
// the netclass membership lists
MAIL_LIB_EDIT,
MAIL_FP_EDIT
};

View File

@ -35,11 +35,44 @@ public:
virtual ~NET_SETTINGS();
public:
NETCLASSES m_NetClasses;
private:
NETCLASSPTR m_defaultClass;
// Runtime map of label to netclass-name for quick lookup. Includes both composite labels
// (buses) and atomic net names (including individual bus members).
std::map<wxString, wxString> m_NetClassAssignments;
public:
/**
* Parses a bus vector (e.g. A[7..0]) into name, begin, and end.
* Ensures that begin and end are positive and that end > begin.
*
* @param aBus is a bus vector label string
* @param aName out is the bus name, e.g. "A"
* @param aMemberList is a list of member strings, e.g. "A7", "A6", and so on
* @return true if aBus was successfully parsed
*/
static bool ParseBusVector( const wxString& aBus, wxString* aName,
std::vector<wxString>* aMemberList );
/**
* Parses a bus group label into the name and a list of components.
*
* @param aGroup is the input label, e.g. "USB{DP DM}"
* @param name is the output group name, e.g. "USB"
* @param aMemberList is a list of member strings, e.g. "DP", "DM"
* @return true if aGroup was successfully parsed
*/
static bool ParseBusGroup( wxString aGroup, wxString* name,
std::vector<wxString>* aMemberList );
/**
* Explodes the list of netclass assignments to include atomic members of composite labels
* (buses).
*/
void ResolveNetClassAssignments();
private:
// TODO: Add diff pairs, bus information, etc here.
};

View File

@ -1277,69 +1277,47 @@ int BOARD::SortedNetnamesList( wxArrayString& aNames, bool aSortbyPadsCount )
}
std::vector<wxString> BOARD::GetNetClassAssignmentCandidates()
{
std::vector<wxString> names;
for( NETINFO_ITEM* net : m_NetInfo )
{
if( !net->GetShortNetname().IsEmpty() )
names.emplace_back( net->GetShortNetname() );
}
return names;
}
void BOARD::SynchronizeNetsAndNetClasses()
{
NETCLASSES& netClasses = GetDesignSettings().GetNetClasses();
if( m_project )
{
NET_SETTINGS* netSettings = m_project->GetProjectFile().m_NetSettings.get();
NETCLASSES& netClasses = netSettings->m_NetClasses;
NETCLASSPTR defaultNetClass = netClasses.GetDefault();
// set all NETs to the default NETCLASS, then later override some
// as we go through the NETCLASSes.
for( NETINFO_ITEM* net : m_NetInfo )
{
const wxString& netname = net->GetNetname();
const wxString& shortname = net->GetShortNetname();
for( NETINFO_LIST::iterator net( m_NetInfo.begin() ), netEnd( m_NetInfo.end() );
net != netEnd; ++net )
if( netSettings->m_NetClassAssignments.count( netname ) )
{
const wxString& classname = netSettings->m_NetClassAssignments[ netname ];
net->SetClass( netClasses.Find( classname ) );
}
else if( netSettings->m_NetClassAssignments.count( shortname ) )
{
const wxString& classname = netSettings->m_NetClassAssignments[ shortname ];
net->SetClass( netClasses.Find( classname ) );
}
else
{
net->SetClass( defaultNetClass );
}
// Add netclass name and pointer to nets. If a net is in more than one netclass,
// set the net's name and pointer to only the first netclass. Subsequent
// and therefore bogus netclass memberships will be deleted in logic below this loop.
for( NETCLASSES::iterator clazz = netClasses.begin(); clazz != netClasses.end(); ++clazz )
{
NETCLASSPTR netclass = clazz->second;
for( NETCLASS::const_iterator member = netclass->begin(); member != netclass->end(); ++member )
{
const wxString& netname = *member;
// although this overall function seems to be adequately fast,
// FindNet( wxString ) uses now a fast binary search and is fast
// event for large net lists
NETINFO_ITEM* net = FindNet( netname );
if( net && net->GetClassName() == NETCLASS::Default )
{
net->SetClass( netclass );
}
}
}
// Finally, make sure that every NET is in a NETCLASS, even if that
// means the Default NETCLASS. And make sure that all NETCLASSes do not
// contain netnames that do not exist, by deleting all netnames from
// every netclass and re-adding them.
for( NETCLASSES::iterator clazz = netClasses.begin(); clazz != netClasses.end(); ++clazz )
{
NETCLASSPTR netclass = clazz->second;
netclass->Clear();
}
defaultNetClass->Clear();
for( NETINFO_LIST::iterator net( m_NetInfo.begin() ), netEnd( m_NetInfo.end() );
net != netEnd; ++net )
{
const wxString& classname = net->GetClassName();
// because of the std:map<> this should be fast, and because of
// prior logic, netclass should not be NULL.
NETCLASSPTR netclass = netClasses.Find( classname );
wxASSERT( netclass );
netclass->Add( net->GetNetname() );
}
BOARD_DESIGN_SETTINGS& bds = GetDesignSettings();
@ -1352,6 +1330,7 @@ void BOARD::SynchronizeNetsAndNetClasses()
bds.SetCustomDiffPairWidth( defaultNetClass->GetDiffPairWidth() );
bds.SetCustomDiffPairGap( defaultNetClass->GetDiffPairGap() );
bds.SetCustomDiffPairViaGap( defaultNetClass->GetDiffPairViaGap() );
}
InvokeListeners( &BOARD_LISTENER::OnBoardNetSettingsChanged, *this );
}

View File

@ -843,6 +843,13 @@ public:
*/
int SortedNetnamesList( wxArrayString& aNames, bool aSortbyPadsCount );
/**
* Function GetNetClassAssignmentCandidates
* Returns a list of name candidates for netclass assignment. Tokens may appear more
* than once if they were harvested from hierarchical nets (ie: /CLK, /sheet1/CLK).
*/
std::vector<wxString> GetNetClassAssignmentCandidates();
/**
* Function SynchronizeNetsAndNetClasses
* copies NETCLASS info to each NET, based on NET membership in a NETCLASS.
@ -852,6 +859,7 @@ public:
*/
void SynchronizeNetsAndNetClasses();
/***************************************************************************/
wxString GetClass() const override

View File

@ -196,12 +196,18 @@ void PCB_EDIT_FRAME::ExecuteRemoteCommand( const char* cmdline )
return;
}
else if( strcmp( idcmd, "$CLEAR" ) == 0 )
{
if( renderSettings->IsHighlightEnabled() )
{
renderSettings->SetHighlight( false );
view->UpdateAllLayersColor();
}
if( pcb->IsHighLightNetON() )
{
pcb->ResetNetHighLight();
SetMsgPanel( pcb );
}
GetCanvas()->Refresh();
return;

View File

@ -44,19 +44,23 @@ DIALOG_BOARD_SETUP::DIALOG_BOARD_SETUP( PCB_EDIT_FRAME* aFrame ) :
PAGED_DIALOG( aFrame, _( "Board Setup" ), _( "Import Settings from Another Board..." ) ),
m_frame( aFrame )
{
BOARD_DESIGN_SETTINGS& bds = aFrame->GetDesignSettings();
BOARD* board = aFrame->GetBoard();
BOARD_DESIGN_SETTINGS& bds = board->GetDesignSettings();
m_layers = new PANEL_SETUP_LAYERS( this, aFrame );
m_textAndGraphics = new PANEL_SETUP_TEXT_AND_GRAPHICS( this, aFrame );
m_constraints = new PANEL_SETUP_FEATURE_CONSTRAINTS( this, aFrame );
m_netclasses = new PANEL_SETUP_NETCLASSES( this, &bds.GetNetClasses() );
m_rules = new PANEL_SETUP_RULES( this, aFrame );
m_tracksAndVias = new PANEL_SETUP_TRACKS_AND_VIAS( this, aFrame, m_constraints );
m_maskAndPaste = new PANEL_SETUP_MASK_AND_PASTE( this, aFrame );
m_physicalStackup = new PANEL_SETUP_BOARD_STACKUP( this, aFrame, m_layers );
m_severities = new PANEL_SETUP_SEVERITIES( this, DRC_ITEM::GetItemsWithSeverities(),
bds.m_DRCSeverities );
m_netclasses = new PANEL_SETUP_NETCLASSES( this, &bds.GetNetClasses(),
board->GetNetClassAssignmentCandidates() );
m_textVars = new PANEL_TEXT_VARIABLES( m_treebook, &Prj() );
/*

View File

@ -48,24 +48,24 @@ DIALOG_IMPORT_SETTINGS_BASE::DIALOG_IMPORT_SETTINGS_BASE( wxWindow* parent, wxWi
m_LayersOpt = new wxCheckBox( this, wxID_ANY, _("Layers setup"), wxDefaultPosition, wxDefaultSize, 0 );
bmiddleSizer->Add( m_LayersOpt, 0, wxBOTTOM|wxRIGHT|wxLEFT, 5 );
m_TextAndGraphicsOpt = new wxCheckBox( this, wxID_ANY, _("Text && Graphics default properties"), wxDefaultPosition, wxDefaultSize, 0 );
m_TextAndGraphicsOpt = new wxCheckBox( this, wxID_ANY, _("Text and graphics default properties"), wxDefaultPosition, wxDefaultSize, 0 );
bmiddleSizer->Add( m_TextAndGraphicsOpt, 0, wxBOTTOM|wxRIGHT|wxLEFT, 5 );
m_ConstraintsOpt = new wxCheckBox( this, wxID_ANY, _("Design Rules"), wxDefaultPosition, wxDefaultSize, 0 );
m_ConstraintsOpt = new wxCheckBox( this, wxID_ANY, _("Design rules"), wxDefaultPosition, wxDefaultSize, 0 );
bmiddleSizer->Add( m_ConstraintsOpt, 0, wxBOTTOM|wxRIGHT|wxLEFT, 5 );
m_NetclassesOpt = new wxCheckBox( this, wxID_ANY, _("Net Classes"), wxDefaultPosition, wxDefaultSize, 0 );
bmiddleSizer->Add( m_NetclassesOpt, 0, wxBOTTOM|wxRIGHT|wxLEFT, 5 );
m_TracksAndViasOpt = new wxCheckBox( this, wxID_ANY, _("Predefined Track and Via dimensions"), wxDefaultPosition, wxDefaultSize, 0 );
m_TracksAndViasOpt = new wxCheckBox( this, wxID_ANY, _("Predefined track and via dimensions"), wxDefaultPosition, wxDefaultSize, 0 );
bmiddleSizer->Add( m_TracksAndViasOpt, 0, wxBOTTOM|wxRIGHT|wxLEFT, 5 );
m_MaskAndPasteOpt = new wxCheckBox( this, wxID_ANY, _("Solder Mask/Paste defaults"), wxDefaultPosition, wxDefaultSize, 0 );
m_MaskAndPasteOpt = new wxCheckBox( this, wxID_ANY, _("Solder mask/paste defaults"), wxDefaultPosition, wxDefaultSize, 0 );
bmiddleSizer->Add( m_MaskAndPasteOpt, 0, wxBOTTOM|wxRIGHT|wxLEFT, 5 );
m_SeveritiesOpt = new wxCheckBox( this, wxID_ANY, _("Violation severities"), wxDefaultPosition, wxDefaultSize, 0 );
bmiddleSizer->Add( m_SeveritiesOpt, 0, wxRIGHT|wxLEFT, 5 );
m_NetclassesOpt = new wxCheckBox( this, wxID_ANY, _("Net classes"), wxDefaultPosition, wxDefaultSize, 0 );
bmiddleSizer->Add( m_NetclassesOpt, 0, wxALL, 5 );
m_MainSizer->Add( bmiddleSizer, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 10 );

View File

@ -434,7 +434,7 @@
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Text &amp;&amp; Graphics default properties</property>
<property name="label">Text and graphics default properties</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
@ -498,7 +498,7 @@
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Design Rules</property>
<property name="label">Design rules</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
@ -562,71 +562,7 @@
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Net Classes</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_NetclassesOpt</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">public</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass">; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
<property name="validator_variable"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxBOTTOM|wxRIGHT|wxLEFT</property>
<property name="proportion">0</property>
<object class="wxCheckBox" expanded="1">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="checked">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Predefined Track and Via dimensions</property>
<property name="label">Predefined track and via dimensions</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
@ -690,7 +626,7 @@
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Solder Mask/Paste defaults</property>
<property name="label">Solder mask/paste defaults</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
@ -785,6 +721,70 @@
<property name="window_style"></property>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxALL</property>
<property name="proportion">0</property>
<object class="wxCheckBox" expanded="1">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="checked">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Net classes</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_NetclassesOpt</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">public</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass">; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
<property name="validator_variable"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
</object>
</object>
</object>
</object>
<object class="sizeritem" expanded="1">

View File

@ -55,10 +55,10 @@ class DIALOG_IMPORT_SETTINGS_BASE : public DIALOG_SHIM
wxCheckBox* m_LayersOpt;
wxCheckBox* m_TextAndGraphicsOpt;
wxCheckBox* m_ConstraintsOpt;
wxCheckBox* m_NetclassesOpt;
wxCheckBox* m_TracksAndViasOpt;
wxCheckBox* m_MaskAndPasteOpt;
wxCheckBox* m_SeveritiesOpt;
wxCheckBox* m_NetclassesOpt;
DIALOG_IMPORT_SETTINGS_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Import Settings"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
~DIALOG_IMPORT_SETTINGS_BASE();

View File

@ -136,26 +136,17 @@ void NETINFO_LIST::AppendNet( NETINFO_ITEM* aNewElement )
}
/**
* Compute and update the net_codes for PADS et and equipots (.m_NetCode member)
* net_codes are >= 1 (net_code = 0 means not connected)
* Update the net buffer
* m_Pcb->m_NbNodes and m_Pcb->m_NbNets are updated
* Be aware NETINFO_ITEM* BOARD::FindNet( const wxString& aNetname )
* when search a net by its net name does a binary search
* and expects to have a nets list sorted by an alphabetic case sensitive sort
* So do not change Build_Pads_Full_List() which build a sorted list of pads
*/
void NETINFO_LIST::buildListOfNets()
{
// Restore the initial state of NETINFO_ITEMs
for( NETINFO_LIST::iterator net( begin() ), netEnd( end() ); net != netEnd; ++net )
for( NETINFO_ITEM* net : *this )
net->Clear();
m_Parent->SynchronizeNetsAndNetClasses( );
m_Parent->SetAreasNetCodesFromNetNames();
}
#if defined(DEBUG)
void NETINFO_LIST::Show() const
{

View File

@ -31,8 +31,9 @@
using namespace std::placeholders;
#include <fctsys.h>
#include <pgm_base.h>
#include <confirm.h>
//#include <pgm_base.h>
#include <kiway.h>
//#include <confirm.h>
#include <pcb_edit_frame.h>
#include "pcb_netlist.h"
#include "netlist_reader.h"
@ -42,7 +43,7 @@ using namespace std::placeholders;
#include <class_board.h>
#include <class_module.h>
#include <ratsnest/ratsnest_data.h>
#include <pcbnew.h>
//#include <pcbnew.h>
#include <io_mgr.h>
#include "board_netlist_updater.h"
#include <tool/tool_manager.h>
@ -92,6 +93,9 @@ bool PCB_EDIT_FRAME::ReadNetlistFromFile( const wxString &aFilename,
void PCB_EDIT_FRAME::OnNetlistChanged( BOARD_NETLIST_UPDATER& aUpdater, bool* aRunDragCommand )
{
std::string dummyPayload;
Kiway().ExpressMail( FRAME_SCH, MAIL_SCH_CLEAN_NETCLASSES, dummyPayload, this );
BOARD* board = GetBoard();
SetMsgPanel( board );