diff --git a/common/dialogs/panel_setup_netclasses.cpp b/common/dialogs/panel_setup_netclasses.cpp index 0259788425..2f4a6e6ba0 100644 --- a/common/dialogs/panel_setup_netclasses.cpp +++ b/common/dialogs/panel_setup_netclasses.cpp @@ -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& 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 netToNetclassMap; + std::map 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& ii : netToNetclassMap ) - { - if( !ii.first.IsEmpty() ) - addNet( UnescapeString( ii.first ), ii.second ); - } + addNet( UnescapeString( ii.first ), ii.second, false ); + + for( const std::pair& 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( 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( nc ) - nc->Add( m_membershipGrid->GetCellValue( row, 0 ) ); + if( classname != "Default" ) + { + const NETCLASSPTR& nc = m_netclasses->Find( classname ); + + if( nc ) + 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; } diff --git a/common/dialogs/panel_setup_netclasses.h b/common/dialogs/panel_setup_netclasses.h index a1d6e8953c..534b027d19 100644 --- a/common/dialogs/panel_setup_netclasses.h +++ b/common/dialogs/panel_setup_netclasses.h @@ -35,12 +35,13 @@ class NETCLASSES; class PANEL_SETUP_NETCLASSES : public PANEL_SETUP_NETCLASSES_BASE { private: - PAGED_DIALOG* m_Parent; - NETCLASSES* m_Netclasses; + PAGED_DIALOG* m_Parent; + NETCLASSES* m_netclasses; + std::vector m_candidateNetNames; - int* m_originalColWidths; - bool m_netclassesDirty; // The netclass drop-down menus need rebuilding - wxSize m_membershipSize; // The size needed to show the membership list + int* m_originalColWidths; + bool m_netclassesDirty; // The netclass drop-down menus need rebuilding + wxSize m_membershipSize; // The size needed to show the membership list private: void OnAddNetclassClick( wxCommandEvent& event ) override; @@ -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& aCandidateNetNames ); ~PANEL_SETUP_NETCLASSES( ) override; bool TransferDataToWindow() override; diff --git a/common/project/net_settings.cpp b/common/project/net_settings.cpp index 209e281dfa..abb51234d0 100644 --- a/common/project/net_settings.cpp +++ b/common/project/net_settings.cpp @@ -26,7 +26,7 @@ #define PCBNEW #endif #include - +#include const int netSettingsSchemaVersion = 0; @@ -64,15 +64,19 @@ 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() ) ); + for( const auto& ii : *netclass ) + { + if( !ii.empty() ) + membersJson.push_back( std::string( ii.ToUTF8() ) ); + } - netJson["nets"] = nets; - - ret.push_back( netJson ); + 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* 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* 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 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 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; + } +} \ No newline at end of file diff --git a/eeschema/connection_graph.cpp b/eeschema/connection_graph.cpp index 910ee7f24b..3b09792749 100644 --- a/eeschema/connection_graph.cpp +++ b/eeschema/connection_graph.cpp @@ -25,10 +25,8 @@ #include #include #include - #include #include -#include #include #include #include @@ -39,11 +37,10 @@ #include #include #include - -#include #include #include + 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( aItem ); - name = power_object->GetDefaultNetName( m_sheet ); + SCH_PIN* pin = static_cast( 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( aItem )->GetShownText(); + name = EscapeString( static_cast( aItem )->GetShownText(), CTX_NETNAME ); break; } @@ -812,13 +809,13 @@ void CONNECTION_GRAPH::buildConnectionGraph() case SCH_HIER_LABEL_T: { auto text = static_cast( driver ); - connection->ConfigureFromLabel( text->GetShownText() ); + connection->ConfigureFromLabel( EscapeString( text->GetShownText(), CTX_NETNAME ) ); break; } case SCH_SHEET_PIN_T: { auto pin = static_cast( 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( driver ); - if( text->GetShownText() == test_name ) + if( EscapeString( text->GetShownText(), CTX_NETNAME ) == test_name ) { match = true; break; @@ -1836,7 +1833,7 @@ std::shared_ptr CONNECTION_GRAPH::getDefaultConnection( SCH_ITEM c = std::make_shared( 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( item )->GetShownText(); - conn.ConfigureFromLabel( text ); + SCH_TEXT* text = static_cast( 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 ) { diff --git a/eeschema/cross-probing.cpp b/eeschema/cross-probing.cpp index 41550ddb4d..c2c0b13752 100644 --- a/eeschema/cross-probing.cpp +++ b/eeschema/cross-probing.cpp @@ -41,10 +41,12 @@ #include #include #include +#include +#include #include #include #include - +#include 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,19 +467,18 @@ void SCH_EDIT_FRAME::KiwayMailIn( KIWAY_EXPRESS& mail ) return; } - { - NETLIST_EXPORTER_KICAD exporter( &Schematic() ); - STRING_FORMATTER formatter; + NETLIST_EXPORTER_KICAD exporter( &Schematic() ); + STRING_FORMATTER formatter; - // TODO remove once real-time connectivity is a given - if( !ADVANCED_CFG::GetCfg().m_realTimeConnectivity || !CONNECTION_GRAPH::m_allowRealTime ) - // Ensure the netlist data is up to date: - RecalculateConnections( NO_CLEANUP ); + // TODO remove once real-time connectivity is a given + if( !ADVANCED_CFG::GetCfg().m_realTimeConnectivity || !CONNECTION_GRAPH::m_allowRealTime ) + // Ensure the netlist data is up to date: + RecalculateConnections( NO_CLEANUP ); - exporter.Format( &formatter, GNL_ALL | GNL_OPT_KICAD ); + exporter.Format( &formatter, GNL_ALL | GNL_OPT_KICAD ); - payload = formatter.GetString(); - } + payload = formatter.GetString(); + } break; case MAIL_BACKANNOTATE_FOOTPRINTS: @@ -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& 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: diff --git a/eeschema/dialogs/dialog_edit_label.cpp b/eeschema/dialogs/dialog_edit_label.cpp index 13a4d6ea82..1d8e59e06a 100644 --- a/eeschema/dialogs/dialog_edit_label.cpp +++ b/eeschema/dialogs/dialog_edit_label.cpp @@ -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( item ); existingLabels.insert( UnescapeString( textItem->GetText() ) ); diff --git a/eeschema/dialogs/dialog_sch_import_settings.cpp b/eeschema/dialogs/dialog_sch_import_settings.cpp index 0cf5b11129..db82a039d1 100644 --- a/eeschema/dialogs/dialog_sch_import_settings.cpp +++ b/eeschema/dialogs/dialog_sch_import_settings.cpp @@ -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 ); } diff --git a/eeschema/dialogs/dialog_sch_import_settings_base.cpp b/eeschema/dialogs/dialog_sch_import_settings_base.cpp index 0fbd0fe91f..31e52bfd26 100644 --- a/eeschema/dialogs/dialog_sch_import_settings_base.cpp +++ b/eeschema/dialogs/dialog_sch_import_settings_base.cpp @@ -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 ); diff --git a/eeschema/dialogs/dialog_sch_import_settings_base.fbp b/eeschema/dialogs/dialog_sch_import_settings_base.fbp index f66662df3e..58ab7a0032 100644 --- a/eeschema/dialogs/dialog_sch_import_settings_base.fbp +++ b/eeschema/dialogs/dialog_sch_import_settings_base.fbp @@ -378,7 +378,7 @@ 0 1 - m_formattingOpt + m_FormattingOpt 1 @@ -442,7 +442,7 @@ 0 1 - m_fieldNameTemplatesOpt + m_FieldNameTemplatesOpt 1 @@ -506,7 +506,7 @@ 0 1 - m_pinMapOpt + m_PinMapOpt 1 @@ -593,6 +593,70 @@ + + 5 + wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Net classes + + 0 + + + 0 + + 1 + m_NetClassesOpt + 1 + + + public + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + diff --git a/eeschema/dialogs/dialog_sch_import_settings_base.h b/eeschema/dialogs/dialog_sch_import_settings_base.h index a4888d7d79..d4f2a3dbbb 100644 --- a/eeschema/dialogs/dialog_sch_import_settings_base.h +++ b/eeschema/dialogs/dialog_sch_import_settings_base.h @@ -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(); diff --git a/eeschema/dialogs/dialog_schematic_setup.cpp b/eeschema/dialogs/dialog_schematic_setup.cpp index 9f00ff1dc5..091ed61aa5 100644 --- a/eeschema/dialogs/dialog_schematic_setup.cpp +++ b/eeschema/dialogs/dialog_schematic_setup.cpp @@ -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 ); } diff --git a/eeschema/netlist_object.cpp b/eeschema/netlist_object.cpp index 17df2fdfb3..a2cc33d4b3 100644 --- a/eeschema/netlist_object.cpp +++ b/eeschema/netlist_object.cpp @@ -37,10 +37,12 @@ #include #include #include +#include #if defined(DEBUG) #include + 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 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 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(); diff --git a/eeschema/sch_connection.cpp b/eeschema/sch_connection.cpp index add71ef2b6..613c9edab3 100644 --- a/eeschema/sch_connection.cpp +++ b/eeschema/sch_connection.cpp @@ -25,11 +25,11 @@ #include #include #include +#include #include #include - /** * * 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* 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* 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(); diff --git a/eeschema/sch_connection.h b/eeschema/sch_connection.h index 24a4232064..c9ab585c8d 100644 --- a/eeschema/sch_connection.h +++ b/eeschema/sch_connection.h @@ -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* 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* aMemberList ); - /** * Adds information about the connection object to aList */ diff --git a/eeschema/sch_eagle_plugin.cpp b/eeschema/sch_eagle_plugin.cpp index ed8d35c76d..81eaf7df1a 100644 --- a/eeschema/sch_eagle_plugin.cpp +++ b/eeschema/sch_eagle_plugin.cpp @@ -48,7 +48,7 @@ #include #include #include -#include +#include #include #include #include @@ -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 = "{"; diff --git a/eeschema/sch_edit_frame.h b/eeschema/sch_edit_frame.h index b15df416ca..a616077fa6 100644 --- a/eeschema/sch_edit_frame.h +++ b/eeschema/sch_edit_frame.h @@ -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 m_projectFileParams; - std::vector 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 ); diff --git a/eeschema/sch_screen.h b/eeschema/sch_screen.h index 8eb87bd59f..763540b487 100644 --- a/eeschema/sch_screen.h +++ b/eeschema/sch_screen.h @@ -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 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; diff --git a/eeschema/sch_validators.cpp b/eeschema/sch_validators.cpp index 02f484a41c..da144fe515 100644 --- a/eeschema/sch_validators.cpp +++ b/eeschema/sch_validators.cpp @@ -28,8 +28,8 @@ */ #include -#include #include +#include #include @@ -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' ) ) diff --git a/eeschema/schematic.cpp b/eeschema/schematic.cpp index b27df4a090..31ce069691 100644 --- a/eeschema/schematic.cpp +++ b/eeschema/schematic.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -163,4 +164,76 @@ std::shared_ptr SCHEMATIC::GetBusAlias( const wxString& aLabel ) cons } +std::vector SCHEMATIC::GetNetClassAssignmentCandidates() +{ + std::vector 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( 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( item )->GetShownText(); + + wxString busPrefix; + std::vector 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& 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; +} + diff --git a/eeschema/schematic.h b/eeschema/schematic.h index cc11b1defb..7c72505ba0 100644 --- a/eeschema/schematic.h +++ b/eeschema/schematic.h @@ -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 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 GetNetClassAssignmentCandidates(); + #if defined(DEBUG) void Show( int nestLevel, std::ostream& os ) const override {} #endif diff --git a/eeschema/tools/sch_drawing_tools.cpp b/eeschema/tools/sch_drawing_tools.cpp index 27abe8a9c4..b11cfd0665 100644 --- a/eeschema/tools/sch_drawing_tools.cpp +++ b/eeschema/tools/sch_drawing_tools.cpp @@ -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(); } } diff --git a/eeschema/tools/sch_line_wire_bus_tool.cpp b/eeschema/tools/sch_line_wire_bus_tool.cpp index 8db259c33a..16326391ac 100644 --- a/eeschema/tools/sch_line_wire_bus_tool.cpp +++ b/eeschema/tools/sch_line_wire_bus_tool.cpp @@ -134,9 +134,9 @@ private: SCH_CONNECTION* connection = bus->Connection( frame->GetCurrentSheet() ); - if( !connection || !connection->IsBus() || connection->Members().empty() ) + 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; } diff --git a/include/mail_type.h b/include/mail_type.h index bb5d0f2819..5c7a384ccc 100644 --- a/include/mail_type.h +++ b/include/mail_type.h @@ -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 * * 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 }; diff --git a/include/project/net_settings.h b/include/project/net_settings.h index b755ff726d..0244ac0726 100644 --- a/include/project/net_settings.h +++ b/include/project/net_settings.h @@ -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 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* 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* 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. }; diff --git a/pcbnew/class_board.cpp b/pcbnew/class_board.cpp index f3e1aaba9b..1f1b806644 100644 --- a/pcbnew/class_board.cpp +++ b/pcbnew/class_board.cpp @@ -1277,82 +1277,61 @@ int BOARD::SortedNetnamesList( wxArrayString& aNames, bool aSortbyPadsCount ) } +std::vector BOARD::GetNetClassAssignmentCandidates() +{ + std::vector 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(); - NETCLASSPTR defaultNetClass = netClasses.GetDefault(); - - // set all NETs to the default NETCLASS, then later override some - // as we go through the NETCLASSes. - - for( NETINFO_LIST::iterator net( m_NetInfo.begin() ), netEnd( m_NetInfo.end() ); - net != netEnd; ++net ) + if( m_project ) { - net->SetClass( defaultNetClass ); - } + NET_SETTINGS* netSettings = m_project->GetProjectFile().m_NetSettings.get(); + NETCLASSES& netClasses = netSettings->m_NetClasses; + NETCLASSPTR defaultNetClass = netClasses.GetDefault(); - // 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 ) + for( NETINFO_ITEM* net : m_NetInfo ) { - const wxString& netname = *member; + const wxString& netname = net->GetNetname(); + const wxString& shortname = net->GetShortNetname(); - // 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 ) + if( netSettings->m_NetClassAssignments.count( netname ) ) { - net->SetClass( netclass ); + 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 ); } } + + BOARD_DESIGN_SETTINGS& bds = GetDesignSettings(); + + // Set initial values for custom track width & via size to match the default netclass settings + bds.UseCustomTrackViaSize( false ); + bds.SetCustomTrackWidth( defaultNetClass->GetTrackWidth() ); + bds.SetCustomViaSize( defaultNetClass->GetViaDiameter() ); + bds.SetCustomViaDrill( defaultNetClass->GetViaDrill() ); + bds.SetCustomDiffPairWidth( defaultNetClass->GetDiffPairWidth() ); + bds.SetCustomDiffPairGap( defaultNetClass->GetDiffPairGap() ); + bds.SetCustomDiffPairViaGap( defaultNetClass->GetDiffPairViaGap() ); } - // 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(); - - // Set initial values for custom track width & via size to match the default netclass settings - bds.UseCustomTrackViaSize( false ); - bds.SetCustomTrackWidth( defaultNetClass->GetTrackWidth() ); - bds.SetCustomViaSize( defaultNetClass->GetViaDiameter() ); - bds.SetCustomViaDrill( defaultNetClass->GetViaDrill() ); - bds.SetCustomDiffPairWidth( defaultNetClass->GetDiffPairWidth() ); - bds.SetCustomDiffPairGap( defaultNetClass->GetDiffPairGap() ); - bds.SetCustomDiffPairViaGap( defaultNetClass->GetDiffPairViaGap() ); - InvokeListeners( &BOARD_LISTENER::OnBoardNetSettingsChanged, *this ); } diff --git a/pcbnew/class_board.h b/pcbnew/class_board.h index fd32e406f4..d04efef384 100644 --- a/pcbnew/class_board.h +++ b/pcbnew/class_board.h @@ -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 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 diff --git a/pcbnew/cross-probing.cpp b/pcbnew/cross-probing.cpp index 335a83273e..e9061c80f1 100644 --- a/pcbnew/cross-probing.cpp +++ b/pcbnew/cross-probing.cpp @@ -197,11 +197,17 @@ void PCB_EDIT_FRAME::ExecuteRemoteCommand( const char* cmdline ) } else if( strcmp( idcmd, "$CLEAR" ) == 0 ) { - renderSettings->SetHighlight( false ); - view->UpdateAllLayersColor(); + if( renderSettings->IsHighlightEnabled() ) + { + renderSettings->SetHighlight( false ); + view->UpdateAllLayersColor(); + } - pcb->ResetNetHighLight(); - SetMsgPanel( pcb ); + if( pcb->IsHighLightNetON() ) + { + pcb->ResetNetHighLight(); + SetMsgPanel( pcb ); + } GetCanvas()->Refresh(); return; diff --git a/pcbnew/dialogs/dialog_board_setup.cpp b/pcbnew/dialogs/dialog_board_setup.cpp index 3d85f211e7..3e40f38cfd 100644 --- a/pcbnew/dialogs/dialog_board_setup.cpp +++ b/pcbnew/dialogs/dialog_board_setup.cpp @@ -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() ); /* diff --git a/pcbnew/dialogs/dialog_import_settings_base.cpp b/pcbnew/dialogs/dialog_import_settings_base.cpp index f4b61d53cb..f3e2722191 100644 --- a/pcbnew/dialogs/dialog_import_settings_base.cpp +++ b/pcbnew/dialogs/dialog_import_settings_base.cpp @@ -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 ); diff --git a/pcbnew/dialogs/dialog_import_settings_base.fbp b/pcbnew/dialogs/dialog_import_settings_base.fbp index 9127f8c55c..f4bef5ea2d 100644 --- a/pcbnew/dialogs/dialog_import_settings_base.fbp +++ b/pcbnew/dialogs/dialog_import_settings_base.fbp @@ -434,7 +434,7 @@ 0 0 wxID_ANY - Text && Graphics default properties + Text and graphics default properties 0 @@ -498,7 +498,7 @@ 0 0 wxID_ANY - Design Rules + Design rules 0 @@ -562,71 +562,7 @@ 0 0 wxID_ANY - Net Classes - - 0 - - - 0 - - 1 - m_NetclassesOpt - 1 - - - public - 1 - - Resizable - 1 - - - ; forward_declare - 0 - - - wxFILTER_NONE - wxDefaultValidator - - - - - - - - 5 - wxBOTTOM|wxRIGHT|wxLEFT - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - Predefined Track and Via dimensions + Predefined track and via dimensions 0 @@ -690,7 +626,7 @@ 0 0 wxID_ANY - Solder Mask/Paste defaults + Solder mask/paste defaults 0 @@ -785,6 +721,70 @@ + + 5 + wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Net classes + + 0 + + + 0 + + 1 + m_NetclassesOpt + 1 + + + public + 1 + + Resizable + 1 + + + ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + diff --git a/pcbnew/dialogs/dialog_import_settings_base.h b/pcbnew/dialogs/dialog_import_settings_base.h index 1bc736845d..6f4feab09a 100644 --- a/pcbnew/dialogs/dialog_import_settings_base.h +++ b/pcbnew/dialogs/dialog_import_settings_base.h @@ -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(); diff --git a/pcbnew/netinfo_list.cpp b/pcbnew/netinfo_list.cpp index a0170e412b..655d1706ae 100644 --- a/pcbnew/netinfo_list.cpp +++ b/pcbnew/netinfo_list.cpp @@ -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 { diff --git a/pcbnew/netlist_reader/netlist.cpp b/pcbnew/netlist_reader/netlist.cpp index b0e9bff033..483d1c889e 100644 --- a/pcbnew/netlist_reader/netlist.cpp +++ b/pcbnew/netlist_reader/netlist.cpp @@ -31,8 +31,9 @@ using namespace std::placeholders; #include -#include -#include +//#include +#include +//#include #include #include "pcb_netlist.h" #include "netlist_reader.h" @@ -42,7 +43,7 @@ using namespace std::placeholders; #include #include #include -#include +//#include #include #include "board_netlist_updater.h" #include @@ -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 );