diff --git a/3d-viewer/3d_canvas/eda_3d_canvas.cpp b/3d-viewer/3d_canvas/eda_3d_canvas.cpp index 00cbc3ac0a..8ac055abdb 100644 --- a/3d-viewer/3d_canvas/eda_3d_canvas.cpp +++ b/3d-viewer/3d_canvas/eda_3d_canvas.cpp @@ -644,7 +644,7 @@ void EDA_3D_CANVAS::OnMouseMove( wxMouseEvent& event ) { return wxString::Format( _( "Net %s\tNet class %s" ), aItem->GetNet()->GetNetname(), - aItem->GetNet()->GetNetClassName() ); + aItem->GetNet()->GetNetClass()->GetName() ); }; if( rollOverItem ) diff --git a/common/dialogs/panel_setup_netclasses.cpp b/common/dialogs/panel_setup_netclasses.cpp index 36616a76ef..dc1808d2cc 100644 --- a/common/dialogs/panel_setup_netclasses.cpp +++ b/common/dialogs/panel_setup_netclasses.cpp @@ -33,13 +33,14 @@ #include #include #include +#include #include #include #include #include #include -#include #include +#include // PCBNEW columns of netclasses grid @@ -73,14 +74,14 @@ wxArrayString g_lineStyleNames; PANEL_SETUP_NETCLASSES::PANEL_SETUP_NETCLASSES( PAGED_DIALOG* aParent, EDA_DRAW_FRAME* aFrame, - NETCLASSES* aNetclasses, + std::shared_ptr aNetSettings, const std::vector& aNetNames, bool aIsEEschema ) : PANEL_SETUP_NETCLASSES_BASE( aParent->GetTreebook() ), m_frame( aFrame ), m_parent( aParent ), m_isEEschema( aIsEEschema ), - m_netclasses( aNetclasses ), + m_netSettings( aNetSettings ), m_netNames( aNetNames ), m_hoveredCol( -1 ) { @@ -104,7 +105,7 @@ PANEL_SETUP_NETCLASSES::PANEL_SETUP_NETCLASSES( PAGED_DIALOG* aParent, EDA_DRAW_ // Prevent Size events from firing before we are ready Freeze(); m_netclassGrid->BeginBatch(); - m_membershipGrid->BeginBatch(); + m_assignmentGrid->BeginBatch(); if( m_isEEschema ) { @@ -155,19 +156,13 @@ PANEL_SETUP_NETCLASSES::PANEL_SETUP_NETCLASSES( PAGED_DIALOG* aParent, EDA_DRAW_ // Membership combobox editors require a bit more room, so increase the row size of // all our grids for consistency m_netclassGrid->SetDefaultRowSize( m_netclassGrid->GetDefaultRowSize() + 4 ); - m_membershipGrid->SetDefaultRowSize( m_membershipGrid->GetDefaultRowSize() + 4 ); + m_assignmentGrid->SetDefaultRowSize( m_assignmentGrid->GetDefaultRowSize() + 4 ); m_netclassGrid->PushEventHandler( new GRID_TRICKS( m_netclassGrid ) ); - m_membershipGrid->PushEventHandler( new GRID_TRICKS( m_membershipGrid ) ); + m_assignmentGrid->PushEventHandler( new GRID_TRICKS( m_assignmentGrid ) ); m_netclassGrid->SetSelectionMode( wxGrid::wxGridSelectRows ); - m_membershipGrid->SetSelectionMode( wxGrid::wxGridSelectRows ); - - // Set up the net name column of the netclass membership grid to read-only - wxGridCellAttr* attr = new wxGridCellAttr; - attr->SetReadOnly( true ); - attr->SetRenderer( new GRID_CELL_ESCAPED_TEXT_RENDERER ); - m_membershipGrid->SetColAttr( 0, attr ); + m_assignmentGrid->SetSelectionMode( wxGrid::wxGridSelectRows ); COMMON_SETTINGS* cfg = Pgm().GetCommonSettings(); m_splitter->SetSashPosition( cfg->m_NetclassPanel.sash_pos ); @@ -175,6 +170,9 @@ PANEL_SETUP_NETCLASSES::PANEL_SETUP_NETCLASSES( PAGED_DIALOG* aParent, EDA_DRAW_ m_addButton->SetBitmap( KiBitmap( BITMAPS::small_plus ) ); m_removeButton->SetBitmap( KiBitmap( BITMAPS::small_trash ) ); + m_addAssignmentButton->SetBitmap( KiBitmap( BITMAPS::small_plus ) ); + m_removeAssignmentButton->SetBitmap( KiBitmap( BITMAPS::small_trash ) ); + // wxFormBuilder doesn't include this event... m_netclassGrid->Connect( wxEVT_GRID_CELL_CHANGING, wxGridEventHandler( PANEL_SETUP_NETCLASSES::OnNetclassGridCellChanging ), @@ -188,8 +186,10 @@ PANEL_SETUP_NETCLASSES::PANEL_SETUP_NETCLASSES( PAGED_DIALOG* aParent, EDA_DRAW_ m_frame->Bind( UNITS_CHANGED, &PANEL_SETUP_NETCLASSES::onUnitsChanged, this ); m_netclassGrid->EndBatch(); - m_membershipGrid->EndBatch(); + m_assignmentGrid->EndBatch(); Thaw(); + + m_matchingNets->SetFont( KIUI::GetInfoFont( this ) ); } @@ -202,7 +202,7 @@ PANEL_SETUP_NETCLASSES::~PANEL_SETUP_NETCLASSES() // Delete the GRID_TRICKS. m_netclassGrid->PopEventHandler( true ); - m_membershipGrid->PopEventHandler( true ); + m_assignmentGrid->PopEventHandler( true ); m_netclassGrid->Disconnect( wxEVT_GRID_CELL_CHANGING, wxGridEventHandler( PANEL_SETUP_NETCLASSES::OnNetclassGridCellChanging ), @@ -214,75 +214,71 @@ PANEL_SETUP_NETCLASSES::~PANEL_SETUP_NETCLASSES() void PANEL_SETUP_NETCLASSES::onUnitsChanged( wxCommandEvent& aEvent ) { - NETCLASSES tempNetClasses; - NETCLASSES* saveNetClasses = m_netclasses; + std::shared_ptr tempNetSettings = std::make_shared( nullptr, "" ); + std::shared_ptr saveNetSettings = m_netSettings; - m_netclasses = &tempNetClasses; // No, address of stack var does not escape function + m_netSettings = tempNetSettings; TransferDataFromWindow(); TransferDataToWindow(); - m_netclasses = saveNetClasses; + m_netSettings = saveNetSettings; aEvent.Skip(); } -static void netclassToGridRow( EDA_UNITS aUnits, wxGrid* aGrid, bool aIsEEschema, int aRow, - const NETCLASSPTR& nc ) -{ - aGrid->SetCellValue( aRow, GRID_NAME, nc->GetName() ); - - auto setCell = - [&]( int aCol, int aValue ) - { - aGrid->SetCellValue( aRow, aCol, StringFromValue( aUnits, aValue, true ) ); - }; - - if( aIsEEschema ) - { - setCell( GRID_WIREWIDTH - EESCHEMA_COL_OFFSET, nc->GetWireWidth() ); - setCell( GRID_BUSWIDTH - EESCHEMA_COL_OFFSET, nc->GetBusWidth() ); - - wxString colorAsString = nc->GetSchematicColor().ToWxString( wxC2S_CSS_SYNTAX ); - aGrid->SetCellValue( aRow, GRID_SCHEMATIC_COLOR - EESCHEMA_COL_OFFSET, colorAsString ); - - int lineStyleIdx = std::max( 0, nc->GetLineStyle() ); - - if( lineStyleIdx >= (int) g_lineStyleNames.size() ) - lineStyleIdx = 0; - - aGrid->SetCellValue( aRow, GRID_LINESTYLE - EESCHEMA_COL_OFFSET, - g_lineStyleNames[ lineStyleIdx ] ); - } - else - { - setCell( GRID_CLEARANCE, nc->GetClearance() ); - setCell( GRID_TRACKSIZE, nc->GetTrackWidth() ); - setCell( GRID_VIASIZE, nc->GetViaDiameter() ); - setCell( GRID_VIADRILL, nc->GetViaDrill() ); - setCell( GRID_uVIASIZE, nc->GetuViaDiameter() ); - setCell( GRID_uVIADRILL, nc->GetuViaDrill() ); - setCell( GRID_DIFF_PAIR_WIDTH, nc->GetDiffPairWidth() ); - setCell( GRID_DIFF_PAIR_GAP, nc->GetDiffPairGap() ); - } -} - - bool PANEL_SETUP_NETCLASSES::TransferDataToWindow() { - std::map netToNetclassMap; - std::map staleNetMap; + EDA_UNITS units = m_frame->GetUserUnits(); + int row = 0; - for( const wxString& candidate : m_netNames ) - netToNetclassMap[ candidate ] = wxEmptyString; + auto setCell = + [&]( int aRow, int aCol, int aValue ) + { + m_netclassGrid->SetCellValue( aRow, aCol, StringFromValue( units, aValue, true ) ); + }; + + auto netclassToGridRow = + [&]( int aRow, const std::shared_ptr& nc ) + { + m_netclassGrid->SetCellValue( aRow, GRID_NAME, nc->GetName() ); + + if( m_isEEschema ) + { + setCell( aRow, GRID_WIREWIDTH - EESCHEMA_COL_OFFSET, nc->GetWireWidth() ); + setCell( aRow, GRID_BUSWIDTH - EESCHEMA_COL_OFFSET, nc->GetBusWidth() ); + + wxString colorAsString = nc->GetSchematicColor().ToWxString( wxC2S_CSS_SYNTAX ); + m_netclassGrid->SetCellValue( aRow, GRID_SCHEMATIC_COLOR - EESCHEMA_COL_OFFSET, + colorAsString ); + + int lineStyleIdx = std::max( 0, nc->GetLineStyle() ); + + if( lineStyleIdx >= (int) g_lineStyleNames.size() ) + lineStyleIdx = 0; + + m_netclassGrid->SetCellValue( aRow, GRID_LINESTYLE - EESCHEMA_COL_OFFSET, + g_lineStyleNames[ lineStyleIdx ] ); + } + else + { + setCell( aRow, GRID_CLEARANCE, nc->GetClearance() ); + setCell( aRow, GRID_TRACKSIZE, nc->GetTrackWidth() ); + setCell( aRow, GRID_VIASIZE, nc->GetViaDiameter() ); + setCell( aRow, GRID_VIADRILL, nc->GetViaDrill() ); + setCell( aRow, GRID_uVIASIZE, nc->GetuViaDiameter() ); + setCell( aRow, GRID_uVIADRILL, nc->GetuViaDrill() ); + setCell( aRow, GRID_DIFF_PAIR_WIDTH, nc->GetDiffPairWidth() ); + setCell( aRow, GRID_DIFF_PAIR_GAP, nc->GetDiffPairGap() ); + } + }; m_netclassGrid->ClearRows(); - m_netclassGrid->AppendRows((int) m_netclasses->GetCount() + 1 ); // + 1 for default netclass // enter the Default NETCLASS. - netclassToGridRow( m_frame->GetUserUnits(), m_netclassGrid, m_isEEschema, 0, - m_netclasses->GetDefault() ); + m_netclassGrid->AppendRows( 1 ); + netclassToGridRow( row++, m_netSettings->m_DefaultNetClass ); // make the Default NETCLASS name read-only wxGridCellAttr* cellAttr = m_netclassGrid->GetOrCreateCellAttr( 0, GRID_NAME ); @@ -290,64 +286,32 @@ bool PANEL_SETUP_NETCLASSES::TransferDataToWindow() cellAttr->DecRef(); // enter other netclasses - int row = 1; + m_netclassGrid->AppendRows( (int) m_netSettings->m_NetClasses.size() ); - for( NETCLASSES::iterator i = m_netclasses->begin(); i != m_netclasses->end(); ++i, ++row ) + for( const auto& [ name, netclass ] : m_netSettings->m_NetClasses ) + netclassToGridRow( row++, netclass ); + + m_assignmentGrid->ClearRows(); + m_assignmentGrid->AppendRows( m_netSettings->m_NetClassPatternAssignments.size() ); + row = 0; + + for( const auto& [ matcher, netclassName ] : m_netSettings->m_NetClassPatternAssignments ) { - NETCLASSPTR netclass = i->second; - - netclassToGridRow( m_frame->GetUserUnits(), m_netclassGrid, m_isEEschema, row, netclass ); - - for( const wxString& net : *netclass ) - { - if( netToNetclassMap.count( net ) ) - netToNetclassMap[ net ] = i->second->GetName(); - else - staleNetMap[ net ] = i->second->GetName(); - } + m_assignmentGrid->SetCellValue( row, 0, matcher->GetPattern() ); + m_assignmentGrid->SetCellValue( row, 1, netclassName ); + row++; } - m_membershipGrid->ClearRows(); - - // add currently-assigned and candidate netnames to membership lists - for( const std::pair& ii : netToNetclassMap ) - addNet( ii.first, ii.second, false ); - - for( const std::pair& ii : staleNetMap ) - addNet( ii.first, ii.second, true ); - return true; } -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 ); - } - - if( netclass.IsEmpty() ) - m_membershipGrid->SetCellValue( i, 1, NETCLASS::Default ); - else - m_membershipGrid->SetCellValue( i, 1, netclass ); -} - - /* * Populates drop-downs with the list of net classes */ void PANEL_SETUP_NETCLASSES::rebuildNetclassDropdowns() { - m_membershipGrid->CommitPendingChanges( true ); + m_assignmentGrid->CommitPendingChanges( true ); wxArrayString netclassNames; @@ -361,49 +325,7 @@ void PANEL_SETUP_NETCLASSES::rebuildNetclassDropdowns() wxGridCellAttr* attr = new wxGridCellAttr; attr->SetEditor( new wxGridCellChoiceEditor( netclassNames ) ); - m_membershipGrid->SetColAttr( 1, attr ); - - m_assignNetClass->Set( netclassNames ); - - netclassNames.Insert( wxEmptyString, 0 ); - m_netClassFilter->Set( netclassNames ); -} - - -static void gridRowToNetclass( EDA_UNITS aUnits, wxGrid* grid, bool aIsEEschema, int row, - const NETCLASSPTR& nc ) -{ - nc->SetName( grid->GetCellValue( row, GRID_NAME ) ); - - auto getCell = - [&]( int aCol ) -> long long int - { - return ValueFromString( aUnits, grid->GetCellValue( row, aCol ) ); - }; - - if( aIsEEschema ) - { - nc->SetWireWidth( getCell( GRID_WIREWIDTH - EESCHEMA_COL_OFFSET ) ); - nc->SetBusWidth( getCell( GRID_BUSWIDTH - EESCHEMA_COL_OFFSET ) ); - - wxString colorValue = grid->GetCellValue( row, GRID_SCHEMATIC_COLOR - EESCHEMA_COL_OFFSET ); - nc->SetSchematicColor( wxColour( colorValue ) ); - - wxString lineStyle = grid->GetCellValue( row, GRID_LINESTYLE - EESCHEMA_COL_OFFSET ); - nc->SetLineStyle( g_lineStyleNames.Index( lineStyle ) ); - wxASSERT_MSG( nc->GetLineStyle() >= 0, "Line style name not found." ); - } - else - { - nc->SetClearance( getCell( GRID_CLEARANCE ) ); - nc->SetTrackWidth( getCell( GRID_TRACKSIZE ) ); - nc->SetViaDiameter( getCell( GRID_VIASIZE ) ); - nc->SetViaDrill( getCell( GRID_VIADRILL ) ); - nc->SetuViaDiameter( getCell( GRID_uVIASIZE ) ); - nc->SetuViaDrill( getCell( GRID_uVIADRILL ) ); - nc->SetDiffPairWidth( getCell( GRID_DIFF_PAIR_WIDTH ) ); - nc->SetDiffPairGap( getCell( GRID_DIFF_PAIR_GAP ) ); - } + m_assignmentGrid->SetColAttr( 1, attr ); } @@ -412,34 +334,76 @@ bool PANEL_SETUP_NETCLASSES::TransferDataFromWindow() if( !Validate() ) return false; - m_netclasses->Clear(); + EDA_UNITS units = m_frame->GetUserUnits(); + int row = 0; + + auto getCell = + [&]( int aRow, int aCol ) -> long long int + { + return ValueFromString( units, m_netclassGrid->GetCellValue( aRow, aCol ) ); + }; + + auto getCellStr = + [&]( int aRow, int aCol ) -> wxString + { + return m_netclassGrid->GetCellValue( aRow, aCol ); + }; + + auto gridRowToNetclass = + [&]( int row, const std::shared_ptr& nc ) + { + nc->SetName( m_netclassGrid->GetCellValue( row, GRID_NAME ) ); + + if( m_isEEschema ) + { + nc->SetWireWidth( getCell( row, GRID_WIREWIDTH - EESCHEMA_COL_OFFSET ) ); + nc->SetBusWidth( getCell( row, GRID_BUSWIDTH - EESCHEMA_COL_OFFSET ) ); + + wxString color = getCellStr( row, GRID_SCHEMATIC_COLOR - EESCHEMA_COL_OFFSET ); + nc->SetSchematicColor( wxColour( color ) ); + + wxString lineStyle = getCellStr( row, GRID_LINESTYLE - EESCHEMA_COL_OFFSET ); + nc->SetLineStyle( g_lineStyleNames.Index( lineStyle ) ); + wxASSERT_MSG( nc->GetLineStyle() >= 0, "Line style name not found." ); + } + else + { + nc->SetClearance( getCell( row, GRID_CLEARANCE ) ); + nc->SetTrackWidth( getCell( row, GRID_TRACKSIZE ) ); + nc->SetViaDiameter( getCell( row, GRID_VIASIZE ) ); + nc->SetViaDrill( getCell( row, GRID_VIADRILL ) ); + nc->SetuViaDiameter( getCell( row, GRID_uVIASIZE ) ); + nc->SetuViaDrill( getCell( row, GRID_uVIADRILL ) ); + nc->SetDiffPairWidth( getCell( row, GRID_DIFF_PAIR_WIDTH ) ); + nc->SetDiffPairGap( getCell( row, GRID_DIFF_PAIR_GAP ) ); + } + }; + + m_netSettings->m_NetClasses.clear(); // Copy the default NetClass: - gridRowToNetclass( m_frame->GetUserUnits(), m_netclassGrid, m_isEEschema, 0, - m_netclasses->GetDefault() ); + gridRowToNetclass( row++, m_netSettings->m_DefaultNetClass ); // Copy other NetClasses: - for( int row = 1; row < m_netclassGrid->GetNumberRows(); ++row ) + for( row = 1; row < m_netclassGrid->GetNumberRows(); ++row ) { auto nc = std::make_shared( m_netclassGrid->GetCellValue( row, GRID_NAME ) ); - - if( m_netclasses->Add( nc ) ) - gridRowToNetclass( m_frame->GetUserUnits(), m_netclassGrid, m_isEEschema, row, nc ); + gridRowToNetclass( row, nc ); + m_netSettings->m_NetClasses[ nc->GetName() ] = nc; } - // Now read all nets and push them in the corresponding netclass net buffer - for( int row = 0; row < m_membershipGrid->GetNumberRows(); ++row ) + m_netSettings->m_NetClassPatternAssignments.clear(); + + for( row = 0; row < m_assignmentGrid->GetNumberRows(); ++row ) { - const wxString& netname = m_membershipGrid->GetCellValue( row, 0 ); - const wxString& classname = m_membershipGrid->GetCellValue( row, 1 ); + wxString pattern = m_assignmentGrid->GetCellValue( row, 0 ); + wxString netclass = m_assignmentGrid->GetCellValue( row, 1 ); - if( classname != NETCLASS::Default ) - { - const NETCLASSPTR& nc = m_netclasses->Find( classname ); - - if( nc ) - nc->Add( netname ); - } + m_netSettings->m_NetClassPatternAssignments.push_back( + { + std::make_unique( pattern, CTX_NETCLASS ), + netclass + } ); } return true; @@ -486,10 +450,10 @@ void PANEL_SETUP_NETCLASSES::OnNetclassGridCellChanging( wxGridEvent& event ) if( !oldName.IsEmpty() ) { - for( int row = 0; row < m_membershipGrid->GetNumberRows(); ++row ) + for( int row = 0; row < m_assignmentGrid->GetNumberRows(); ++row ) { - if( m_membershipGrid->GetCellValue( row, 1 ) == oldName ) - m_membershipGrid->SetCellValue( row, 1, newName ); + if( m_assignmentGrid->GetCellValue( row, 1 ) == oldName ) + m_assignmentGrid->SetCellValue( row, 1, newName ); } } @@ -575,7 +539,7 @@ void PANEL_SETUP_NETCLASSES::OnAddNetclassClick( wxCommandEvent& event ) } else { - for( int col = GRID_FIRST_PCBNEW; col < GRID_END; col++ ) + for( int col = GRID_FIRST_PCBNEW; col < GRID_FIRST_EESCHEMA; col++ ) m_netclassGrid->SetCellValue( row, col, m_netclassGrid->GetCellValue( 0, col ) ); } @@ -609,10 +573,10 @@ void PANEL_SETUP_NETCLASSES::OnRemoveNetclassClick( wxCommandEvent& event ) // reset the net class to default for members of the removed class wxString classname = m_netclassGrid->GetCellValue( curRow, GRID_NAME ); - for( int row = 0; row < m_membershipGrid->GetNumberRows(); ++row ) + for( int row = 0; row < m_assignmentGrid->GetNumberRows(); ++row ) { - if( m_membershipGrid->GetCellValue( row, 1 ) == classname ) - m_membershipGrid->SetCellValue( row, 1, NETCLASS::Default ); + if( m_assignmentGrid->GetCellValue( row, 1 ) == classname ) + m_assignmentGrid->SetCellValue( row, 1, NETCLASS::Default ); } m_netclassGrid->DeleteRows( curRow, 1 ); @@ -647,98 +611,63 @@ void PANEL_SETUP_NETCLASSES::OnSizeNetclassGrid( wxSizeEvent& event ) } -void PANEL_SETUP_NETCLASSES::AdjustMembershipGridColumns( int aWidth ) +void PANEL_SETUP_NETCLASSES::OnAddAssignmentClick( wxCommandEvent& event ) +{ + if( !m_assignmentGrid->CommitPendingChanges() ) + return; + + int row = m_assignmentGrid->GetNumberRows(); + m_assignmentGrid->AppendRows(); + + m_assignmentGrid->SetCellValue( row, 1, m_netSettings->m_DefaultNetClass->GetName() ); + + m_assignmentGrid->MakeCellVisible( row, 0 ); + m_assignmentGrid->SetGridCursor( row, 0 ); + + m_assignmentGrid->EnableCellEditControl( true ); + m_assignmentGrid->ShowCellEditControl(); +} + + +void PANEL_SETUP_NETCLASSES::OnRemoveAssignmentClick( wxCommandEvent& event ) +{ + if( !m_assignmentGrid->CommitPendingChanges() ) + return; + + int curRow = m_assignmentGrid->GetGridCursorRow(); + + if( curRow < 0 ) + { + return; + } + + m_assignmentGrid->DeleteRows( curRow, 1 ); + + m_assignmentGrid->MakeCellVisible( std::max( 0, curRow-1 ), m_assignmentGrid->GetGridCursorCol() ); + m_assignmentGrid->SetGridCursor( std::max( 0, curRow-1 ), m_assignmentGrid->GetGridCursorCol() ); +} + + +void PANEL_SETUP_NETCLASSES::AdjustAssignmentGridColumns( int aWidth ) { // Account for scroll bars - aWidth -= ( m_membershipGrid->GetSize().x - m_membershipGrid->GetClientSize().x ); + aWidth -= ( m_assignmentGrid->GetSize().x - m_assignmentGrid->GetClientSize().x ); // Set className column width to original className width from netclasses grid int classNameWidth = m_originalColWidths[ 0 ]; - m_membershipGrid->SetColSize( 1, m_originalColWidths[ 0 ] ); - m_membershipGrid->SetColSize( 0, std::max( aWidth - classNameWidth, classNameWidth ) ); + m_assignmentGrid->SetColSize( 1, m_originalColWidths[ 0 ] ); + m_assignmentGrid->SetColSize( 0, std::max( aWidth - classNameWidth, classNameWidth ) ); } -void PANEL_SETUP_NETCLASSES::onmembershipPanelSize( wxSizeEvent& event ) +void PANEL_SETUP_NETCLASSES::OnSizeAssignmentGrid( wxSizeEvent& event ) { - // When a class name choice widget is selected (activated), in - // wxGrid m_membershipGrid, resizing its wxGrid parent is not taken in account - // by the widget until it is deselected and stay in the old position. - // So we deselect it if this is the case - // Note also this is made here, not in OnSizeMembershipGrid because on Linux - // there are a lot of wxSizeEvent send to m_membershipGrid when opening a choice widget - int c_row = m_membershipGrid->GetGridCursorRow(); - int c_col = m_membershipGrid->GetGridCursorCol(); - - if( c_row >= 0 && c_col == 1 ) // this means the class name choice widget is selected (opened) - m_membershipGrid->SetGridCursor( c_row, 0 ); // Close it + AdjustAssignmentGridColumns( event.GetSize().GetX()); event.Skip(); } -void PANEL_SETUP_NETCLASSES::OnSizeMembershipGrid( wxSizeEvent& event ) -{ - AdjustMembershipGridColumns( event.GetSize().GetX() ); - - event.Skip(); -} - - -void PANEL_SETUP_NETCLASSES::doApplyFilters( bool aShowAll ) -{ - if( !m_membershipGrid->CommitPendingChanges() ) - return; - - wxString netClassFilter = m_netClassFilter->GetStringSelection(); - wxString netFilter = m_netNameFilter->GetValue().MakeLower(); - - if( !netFilter.IsEmpty() ) - netFilter = wxT( "*" ) + netFilter + wxT( "*" ); - - for( int row = 0; row < m_membershipGrid->GetNumberRows(); ++row ) - { - wxString net = m_membershipGrid->GetCellValue( row, 0 ); - wxString netClass = m_membershipGrid->GetCellValue( row, 1 ); - bool show = true; - - if( !aShowAll ) - { - if( !netFilter.IsEmpty() && !net.MakeLower().Matches( netFilter ) ) - show = false; - - if( !netClassFilter.IsEmpty() && netClass != netClassFilter ) - show = false; - } - - if( show ) - m_membershipGrid->ShowRow( row ); - else - m_membershipGrid->HideRow( row ); - } -} - - -void PANEL_SETUP_NETCLASSES::doAssignments( bool aAssignAll ) -{ - if( !m_membershipGrid->CommitPendingChanges() ) - return; - - wxArrayInt selectedRows = m_membershipGrid->GetSelectedRows(); - - for( int row = 0; row < m_membershipGrid->GetNumberRows(); ++row ) - { - if( !m_membershipGrid->IsRowShown( row ) ) - continue; - - if( !aAssignAll && selectedRows.Index( row ) == wxNOT_FOUND ) - continue; - - m_membershipGrid->SetCellValue( row, 1, m_assignNetClass->GetStringSelection() ); - } -} - - void PANEL_SETUP_NETCLASSES::OnUpdateUI( wxUpdateUIEvent& event ) { if( m_netclassesDirty ) @@ -746,12 +675,50 @@ void PANEL_SETUP_NETCLASSES::OnUpdateUI( wxUpdateUIEvent& event ) rebuildNetclassDropdowns(); m_netclassesDirty = false; } + + int row = m_assignmentGrid->GetGridCursorRow(); + wxString pattern = m_assignmentGrid->GetCellValue( row, 0 ); + + if( m_assignmentGrid->GetGridCursorCol() == 0 && m_assignmentGrid->IsCellEditControlShown() ) + { + wxGridCellEditor* cellEditor = m_assignmentGrid->GetCellEditor( row, 0 ); + + if( wxTextEntry* txt = dynamic_cast( cellEditor->GetControl() ) ) + pattern = txt->GetValue(); + + cellEditor->DecRef(); + } + + if( pattern != m_lastPattern ) + { + m_matchingNets->Clear(); + + if( !pattern.IsEmpty() ) + { + EDA_COMBINED_MATCHER matcher( pattern, CTX_NETCLASS ); + + m_matchingNets->Report( wxString::Format( _( "Nets matching '%s':" ), + pattern ) ); + + for( const wxString& net : m_netNames ) + { + int matches; + int offset; + + if( matcher.Find( net, matches, offset ) && offset == 0 ) + m_matchingNets->Report( net ); + } + } + + m_matchingNets->Flush(); + m_lastPattern = pattern; + } } bool PANEL_SETUP_NETCLASSES::Validate() { - if( !m_netclassGrid->CommitPendingChanges() || !m_membershipGrid->CommitPendingChanges() ) + if( !m_netclassGrid->CommitPendingChanges() || !m_assignmentGrid->CommitPendingChanges() ) return false; wxString msg; @@ -771,19 +738,19 @@ bool PANEL_SETUP_NETCLASSES::Validate() } -void PANEL_SETUP_NETCLASSES::ImportSettingsFrom( NETCLASSES* aNetclasses ) +void PANEL_SETUP_NETCLASSES::ImportSettingsFrom( const std::shared_ptr& aNetSettings ) { - NETCLASSES* savedSettings = m_netclasses; + std::shared_ptr savedSettings = m_netSettings; - m_netclasses = aNetclasses; + m_netSettings = aNetSettings; TransferDataToWindow(); rebuildNetclassDropdowns(); m_netclassGrid->ForceRefresh(); - m_membershipGrid->ForceRefresh(); + m_assignmentGrid->ForceRefresh(); - m_netclasses = savedSettings; + m_netSettings = savedSettings; } diff --git a/common/dialogs/panel_setup_netclasses_base.cpp b/common/dialogs/panel_setup_netclasses_base.cpp index 3671b503ae..1bf0a0175e 100644 --- a/common/dialogs/panel_setup_netclasses_base.cpp +++ b/common/dialogs/panel_setup_netclasses_base.cpp @@ -1,10 +1,11 @@ /////////////////////////////////////////////////////////////////////////// -// C++ code generated with wxFormBuilder (version 3.9.0 Aug 10 2021) +// C++ code generated with wxFormBuilder (version 3.10.1-0-g8feb16b) // http://www.wxformbuilder.org/ // // PLEASE DO *NOT* EDIT THIS FILE! /////////////////////////////////////////////////////////////////////////// +#include "dialogs/wx_html_report_box.h" #include "widgets/wx_grid.h" #include "panel_setup_netclasses_base.h" @@ -29,7 +30,7 @@ PANEL_SETUP_NETCLASSES_BASE::PANEL_SETUP_NETCLASSES_BASE( wxWindow* parent, wxWi m_netclassGrid = new WX_GRID( m_netclassesPane, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxBORDER_DEFAULT|wxHSCROLL|wxTAB_TRAVERSAL|wxVSCROLL ); // Grid - m_netclassGrid->CreateGrid( 1, 13 ); + m_netclassGrid->CreateGrid( 3, 13 ); m_netclassGrid->EnableEditing( true ); m_netclassGrid->EnableGridLines( true ); m_netclassGrid->EnableDragGridSize( false ); @@ -70,20 +71,20 @@ PANEL_SETUP_NETCLASSES_BASE::PANEL_SETUP_NETCLASSES_BASE( wxWindow* parent, wxWi buttonBoxSizer = new wxBoxSizer( wxHORIZONTAL ); m_addButton = new wxBitmapButton( m_netclassesPane, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( -1,-1 ), wxBU_AUTODRAW|0 ); - buttonBoxSizer->Add( m_addButton, 0, wxLEFT, 2 ); + buttonBoxSizer->Add( m_addButton, 0, wxBOTTOM|wxLEFT, 2 ); buttonBoxSizer->Add( 5, 0, 0, wxEXPAND|wxRIGHT|wxLEFT, 5 ); m_removeButton = new wxBitmapButton( m_netclassesPane, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( -1,-1 ), wxBU_AUTODRAW|0 ); - buttonBoxSizer->Add( m_removeButton, 0, wxRIGHT|wxLEFT, 5 ); + buttonBoxSizer->Add( m_removeButton, 0, wxBOTTOM|wxRIGHT|wxLEFT, 5 ); buttonBoxSizer->Add( 0, 0, 1, wxEXPAND, 5 ); m_colorDefaultHelpText = new wxStaticText( m_netclassesPane, wxID_ANY, _("Set color to transparent to use KiCad default color."), wxDefaultPosition, wxDefaultSize, 0 ); m_colorDefaultHelpText->Wrap( -1 ); - buttonBoxSizer->Add( m_colorDefaultHelpText, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT, 5 ); + buttonBoxSizer->Add( m_colorDefaultHelpText, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM, 10 ); bUpperSizer->Add( buttonBoxSizer, 0, wxEXPAND|wxTOP|wxBOTTOM, 5 ); @@ -94,141 +95,71 @@ PANEL_SETUP_NETCLASSES_BASE::PANEL_SETUP_NETCLASSES_BASE( wxWindow* parent, wxWi bUpperSizer->Fit( m_netclassesPane ); m_membershipPane = new wxPanel( m_splitter, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); wxBoxSizer* bLowerSizer; - bLowerSizer = new wxBoxSizer( wxHORIZONTAL ); + bLowerSizer = new wxBoxSizer( wxVERTICAL ); - wxBoxSizer* bLeft; - bLeft = new wxBoxSizer( wxVERTICAL ); + m_staticText5 = new wxStaticText( m_membershipPane, wxID_ANY, _("Netclass assignments:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText5->Wrap( -1 ); + bLowerSizer->Add( m_staticText5, 0, wxTOP|wxEXPAND, 8 ); - wxStaticBoxSizer* sbFilters; - sbFilters = new wxStaticBoxSizer( new wxStaticBox( m_membershipPane, wxID_ANY, _("Filter Nets") ), wxVERTICAL ); + wxBoxSizer* bColumns; + bColumns = new wxBoxSizer( wxHORIZONTAL ); - wxBoxSizer* bSizer9; - bSizer9 = new wxBoxSizer( wxHORIZONTAL ); + wxBoxSizer* bSizer14; + bSizer14 = new wxBoxSizer( wxVERTICAL ); - m_ncfilterLabel = new wxStaticText( sbFilters->GetStaticBox(), wxID_ANY, _("Net class filter:"), wxDefaultPosition, wxDefaultSize, 0 ); - m_ncfilterLabel->Wrap( -1 ); - m_ncfilterLabel->SetMinSize( wxSize( 120,-1 ) ); - - bSizer9->Add( m_ncfilterLabel, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); - - wxArrayString m_netClassFilterChoices; - m_netClassFilter = new wxChoice( sbFilters->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, m_netClassFilterChoices, 0 ); - m_netClassFilter->SetSelection( 0 ); - bSizer9->Add( m_netClassFilter, 1, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); - - - sbFilters->Add( bSizer9, 0, wxEXPAND, 5 ); - - wxBoxSizer* bSizer101; - bSizer101 = new wxBoxSizer( wxHORIZONTAL ); - - m_filterLabel = new wxStaticText( sbFilters->GetStaticBox(), wxID_ANY, _("Net name filter:"), wxDefaultPosition, wxDefaultSize, 0 ); - m_filterLabel->Wrap( -1 ); - m_filterLabel->SetMinSize( wxSize( 120,-1 ) ); - - bSizer101->Add( m_filterLabel, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); - - m_netNameFilter = new wxTextCtrl( sbFilters->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER ); - bSizer101->Add( m_netNameFilter, 1, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); - - - sbFilters->Add( bSizer101, 0, wxEXPAND, 5 ); - - wxBoxSizer* bSizer131; - bSizer131 = new wxBoxSizer( wxHORIZONTAL ); - - m_showAllButton = new wxButton( sbFilters->GetStaticBox(), wxID_ANY, _("Show All Nets"), wxDefaultPosition, wxDefaultSize, 0 ); - bSizer131->Add( m_showAllButton, 1, wxLEFT|wxTOP, 5 ); - - - bSizer131->Add( 0, 0, 0, wxEXPAND|wxRIGHT|wxLEFT, 5 ); - - m_filterNetsButton = new wxButton( sbFilters->GetStaticBox(), wxID_ANY, _("Apply Filters"), wxDefaultPosition, wxDefaultSize, 0 ); - bSizer131->Add( m_filterNetsButton, 1, wxRIGHT|wxTOP, 5 ); - - - sbFilters->Add( bSizer131, 1, wxEXPAND|wxTOP|wxBOTTOM, 6 ); - - - bLeft->Add( sbFilters, 0, wxEXPAND|wxBOTTOM, 5 ); - - - bLeft->Add( 0, 0, 1, wxEXPAND, 5 ); - - wxStaticBoxSizer* sbEdit; - sbEdit = new wxStaticBoxSizer( new wxStaticBox( m_membershipPane, wxID_ANY, _("Assign Net Class") ), wxVERTICAL ); - - wxBoxSizer* bSizer11; - bSizer11 = new wxBoxSizer( wxHORIZONTAL ); - - m_assignLabel = new wxStaticText( sbEdit->GetStaticBox(), wxID_ANY, _("New net class:"), wxDefaultPosition, wxDefaultSize, 0 ); - m_assignLabel->Wrap( -1 ); - m_assignLabel->SetMinSize( wxSize( 120,-1 ) ); - - bSizer11->Add( m_assignLabel, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxRIGHT, 5 ); - - wxArrayString m_assignNetClassChoices; - m_assignNetClass = new wxChoice( sbEdit->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, m_assignNetClassChoices, 0 ); - m_assignNetClass->SetSelection( 0 ); - bSizer11->Add( m_assignNetClass, 1, wxBOTTOM|wxRIGHT|wxLEFT, 5 ); - - - sbEdit->Add( bSizer11, 0, wxEXPAND, 5 ); - - wxBoxSizer* bSizer12; - bSizer12 = new wxBoxSizer( wxHORIZONTAL ); - - m_assignAllButton = new wxButton( sbEdit->GetStaticBox(), wxID_ANY, _("Assign To All Listed Nets"), wxDefaultPosition, wxDefaultSize, 0 ); - bSizer12->Add( m_assignAllButton, 1, wxBOTTOM|wxLEFT|wxTOP, 5 ); - - - bSizer12->Add( 0, 0, 0, wxEXPAND|wxRIGHT|wxLEFT, 5 ); - - m_assignSelectedButton = new wxButton( sbEdit->GetStaticBox(), wxID_ANY, _("Assign To Selected Nets"), wxDefaultPosition, wxDefaultSize, 0 ); - bSizer12->Add( m_assignSelectedButton, 1, wxBOTTOM|wxRIGHT|wxTOP, 5 ); - - - sbEdit->Add( bSizer12, 0, wxEXPAND|wxTOP, 6 ); - - - bLeft->Add( sbEdit, 0, wxEXPAND|wxTOP, 8 ); - - - bLowerSizer->Add( bLeft, 1, wxEXPAND|wxTOP|wxRIGHT, 5 ); - - wxBoxSizer* bRight; - bRight = new wxBoxSizer( wxVERTICAL ); - - m_membershipGrid = new WX_GRID( m_membershipPane, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxBORDER_DEFAULT ); + m_assignmentGrid = new WX_GRID( m_membershipPane, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxBORDER_DEFAULT ); // Grid - m_membershipGrid->CreateGrid( 0, 2 ); - m_membershipGrid->EnableEditing( true ); - m_membershipGrid->EnableGridLines( true ); - m_membershipGrid->EnableDragGridSize( false ); - m_membershipGrid->SetMargins( 0, 0 ); + m_assignmentGrid->CreateGrid( 5, 2 ); + m_assignmentGrid->EnableEditing( true ); + m_assignmentGrid->EnableGridLines( true ); + m_assignmentGrid->EnableDragGridSize( false ); + m_assignmentGrid->SetMargins( 0, 0 ); // Columns - m_membershipGrid->EnableDragColMove( false ); - m_membershipGrid->EnableDragColSize( true ); - m_membershipGrid->SetColLabelValue( 0, _("Net") ); - m_membershipGrid->SetColLabelValue( 1, _("Net Class") ); - m_membershipGrid->SetColLabelSize( 24 ); - m_membershipGrid->SetColLabelAlignment( wxALIGN_CENTER, wxALIGN_CENTER ); + m_assignmentGrid->SetColSize( 0, 400 ); + m_assignmentGrid->SetColSize( 1, 160 ); + m_assignmentGrid->EnableDragColMove( false ); + m_assignmentGrid->EnableDragColSize( true ); + m_assignmentGrid->SetColLabelValue( 0, _("Pattern") ); + m_assignmentGrid->SetColLabelValue( 1, _("Net Class") ); + m_assignmentGrid->SetColLabelSize( 24 ); + m_assignmentGrid->SetColLabelAlignment( wxALIGN_CENTER, wxALIGN_CENTER ); // Rows - m_membershipGrid->EnableDragRowSize( true ); - m_membershipGrid->SetRowLabelSize( 0 ); - m_membershipGrid->SetRowLabelAlignment( wxALIGN_CENTER, wxALIGN_CENTER ); + m_assignmentGrid->EnableDragRowSize( true ); + m_assignmentGrid->SetRowLabelSize( 0 ); + m_assignmentGrid->SetRowLabelAlignment( wxALIGN_CENTER, wxALIGN_CENTER ); // Label Appearance // Cell Defaults - m_membershipGrid->SetDefaultCellAlignment( wxALIGN_LEFT, wxALIGN_TOP ); - bRight->Add( m_membershipGrid, 1, wxEXPAND|wxBOTTOM|wxLEFT, 5 ); + m_assignmentGrid->SetDefaultCellAlignment( wxALIGN_LEFT, wxALIGN_TOP ); + bSizer14->Add( m_assignmentGrid, 1, wxEXPAND, 5 ); - bLowerSizer->Add( bRight, 1, wxEXPAND|wxTOP|wxLEFT, 5 ); + bColumns->Add( bSizer14, 3, wxEXPAND, 5 ); + + m_matchingNets = new WX_HTML_REPORT_BOX( m_membershipPane, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHW_SCROLLBAR_AUTO ); + bColumns->Add( m_matchingNets, 2, wxEXPAND|wxLEFT, 15 ); + + + bLowerSizer->Add( bColumns, 1, wxEXPAND|wxTOP, 3 ); + + wxBoxSizer* buttonBoxSizer1; + buttonBoxSizer1 = new wxBoxSizer( wxHORIZONTAL ); + + m_addAssignmentButton = new wxBitmapButton( m_membershipPane, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( -1,-1 ), wxBU_AUTODRAW|0 ); + buttonBoxSizer1->Add( m_addAssignmentButton, 0, 0, 2 ); + + + buttonBoxSizer1->Add( 5, 0, 0, wxEXPAND|wxRIGHT|wxLEFT, 5 ); + + m_removeAssignmentButton = new wxBitmapButton( m_membershipPane, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( -1,-1 ), wxBU_AUTODRAW|0 ); + buttonBoxSizer1->Add( m_removeAssignmentButton, 0, wxRIGHT|wxLEFT, 5 ); + + + bLowerSizer->Add( buttonBoxSizer1, 0, wxEXPAND|wxTOP, 5 ); m_membershipPane->SetSizer( bLowerSizer ); @@ -251,12 +182,10 @@ PANEL_SETUP_NETCLASSES_BASE::PANEL_SETUP_NETCLASSES_BASE( wxWindow* parent, wxWi m_addButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_SETUP_NETCLASSES_BASE::OnAddNetclassClick ), NULL, this ); m_removeButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_SETUP_NETCLASSES_BASE::OnRemoveNetclassClick ), NULL, this ); m_membershipPane->Connect( wxEVT_SIZE, wxSizeEventHandler( PANEL_SETUP_NETCLASSES_BASE::onmembershipPanelSize ), NULL, this ); - m_netNameFilter->Connect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( PANEL_SETUP_NETCLASSES_BASE::OnApplyFilters ), NULL, this ); - m_showAllButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_SETUP_NETCLASSES_BASE::OnShowAll ), NULL, this ); - m_filterNetsButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_SETUP_NETCLASSES_BASE::OnApplyFilters ), NULL, this ); - m_assignAllButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_SETUP_NETCLASSES_BASE::OnAssignAll ), NULL, this ); - m_assignSelectedButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_SETUP_NETCLASSES_BASE::OnAssignSelected ), NULL, this ); - m_membershipGrid->Connect( wxEVT_SIZE, wxSizeEventHandler( PANEL_SETUP_NETCLASSES_BASE::OnSizeMembershipGrid ), NULL, this ); + m_assignmentGrid->Connect( wxEVT_SIZE, wxSizeEventHandler( PANEL_SETUP_NETCLASSES_BASE::OnSizeAssignmentGrid ), NULL, this ); + m_assignmentGrid->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( PANEL_SETUP_NETCLASSES_BASE::OnUpdateUI ), NULL, this ); + m_addAssignmentButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_SETUP_NETCLASSES_BASE::OnAddAssignmentClick ), NULL, this ); + m_removeAssignmentButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_SETUP_NETCLASSES_BASE::OnRemoveAssignmentClick ), NULL, this ); } PANEL_SETUP_NETCLASSES_BASE::~PANEL_SETUP_NETCLASSES_BASE() @@ -267,11 +196,9 @@ PANEL_SETUP_NETCLASSES_BASE::~PANEL_SETUP_NETCLASSES_BASE() m_addButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_SETUP_NETCLASSES_BASE::OnAddNetclassClick ), NULL, this ); m_removeButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_SETUP_NETCLASSES_BASE::OnRemoveNetclassClick ), NULL, this ); m_membershipPane->Disconnect( wxEVT_SIZE, wxSizeEventHandler( PANEL_SETUP_NETCLASSES_BASE::onmembershipPanelSize ), NULL, this ); - m_netNameFilter->Disconnect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( PANEL_SETUP_NETCLASSES_BASE::OnApplyFilters ), NULL, this ); - m_showAllButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_SETUP_NETCLASSES_BASE::OnShowAll ), NULL, this ); - m_filterNetsButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_SETUP_NETCLASSES_BASE::OnApplyFilters ), NULL, this ); - m_assignAllButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_SETUP_NETCLASSES_BASE::OnAssignAll ), NULL, this ); - m_assignSelectedButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_SETUP_NETCLASSES_BASE::OnAssignSelected ), NULL, this ); - m_membershipGrid->Disconnect( wxEVT_SIZE, wxSizeEventHandler( PANEL_SETUP_NETCLASSES_BASE::OnSizeMembershipGrid ), NULL, this ); + m_assignmentGrid->Disconnect( wxEVT_SIZE, wxSizeEventHandler( PANEL_SETUP_NETCLASSES_BASE::OnSizeAssignmentGrid ), NULL, this ); + m_assignmentGrid->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( PANEL_SETUP_NETCLASSES_BASE::OnUpdateUI ), NULL, this ); + m_addAssignmentButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_SETUP_NETCLASSES_BASE::OnAddAssignmentClick ), NULL, this ); + m_removeAssignmentButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_SETUP_NETCLASSES_BASE::OnRemoveAssignmentClick ), NULL, this ); } diff --git a/common/dialogs/panel_setup_netclasses_base.fbp b/common/dialogs/panel_setup_netclasses_base.fbp index 35d86d653a..8bb31c5888 100644 --- a/common/dialogs/panel_setup_netclasses_base.fbp +++ b/common/dialogs/panel_setup_netclasses_base.fbp @@ -1,6 +1,6 @@ - + C++ @@ -262,7 +262,7 @@ "Default" wxALIGN_CENTER - 1 + 3 1 WX_GRID; widgets/wx_grid.h; forward_declare @@ -285,7 +285,7 @@ none 2 - wxLEFT + wxBOTTOM|wxLEFT 0 1 @@ -369,7 +369,7 @@ 5 - wxRIGHT|wxLEFT + wxBOTTOM|wxRIGHT|wxLEFT 0 1 @@ -452,8 +452,8 @@ - 5 - wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT + 10 + wxALIGN_CENTER_VERTICAL|wxBOTTOM 0 1 @@ -573,818 +573,184 @@ bLowerSizer - wxHORIZONTAL + wxVERTICAL none - 5 - wxEXPAND|wxTOP|wxRIGHT - 1 - + 8 + wxTOP|wxEXPAND + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Netclass assignments: + 0 + + 0 + + + 0 - bLeft - wxVERTICAL - none - - 5 - wxEXPAND|wxBOTTOM - 0 - - wxID_ANY - Filter Nets - - sbFilters - wxVERTICAL - 1 - none - - 5 - wxEXPAND - 0 - - - bSizer9 - wxHORIZONTAL - none - - 5 - wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - Net class filter: - 0 - - 0 - - - 0 - 120,-1 - 1 - m_ncfilterLabel - 1 - - - protected - 1 - - Resizable - 1 - - - ; forward_declare - 0 - - - - - -1 - - - - 5 - wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT - 1 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - - 0 - - - 0 - - 1 - m_netClassFilter - 1 - - - protected - 1 - - Resizable - 0 - 1 - - - ; forward_declare - 0 - - - wxFILTER_NONE - wxDefaultValidator - - - - - - - - - - 5 - wxEXPAND - 0 - - - bSizer101 - wxHORIZONTAL - none - - 5 - wxALL|wxALIGN_CENTER_VERTICAL - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - Net name filter: - 0 - - 0 - - - 0 - 120,-1 - 1 - m_filterLabel - 1 - - - protected - 1 - - Resizable - 1 - - - ; forward_declare - 0 - - - - - -1 - - - - 5 - wxALIGN_CENTER_VERTICAL|wxALL - 1 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - - 0 - - - - 0 - - 1 - m_netNameFilter - 1 - - - protected - 1 - - Resizable - 1 - - wxTE_PROCESS_ENTER - ; forward_declare - 0 - - - wxFILTER_NONE - wxDefaultValidator - - - - - - OnApplyFilters - - - - - - 6 - wxEXPAND|wxTOP|wxBOTTOM - 1 - - - bSizer131 - wxHORIZONTAL - none - - 5 - wxLEFT|wxTOP - 1 - - 1 - 1 - 1 - 1 - - - - - 0 - - - - - 1 - 0 - 1 - - 1 - - 0 - 0 - - Dock - 0 - Left - 1 - - 1 - - - 0 - 0 - wxID_ANY - Show All Nets - - 0 - - 0 - - - 0 - - 1 - m_showAllButton - 1 - - - protected - 1 - - - - Resizable - 1 - - - ; forward_declare - 0 - - - wxFILTER_NONE - wxDefaultValidator - - - - - OnShowAll - - - - 5 - wxEXPAND|wxRIGHT|wxLEFT - 0 - - 0 - protected - 0 - - - - 5 - wxRIGHT|wxTOP - 1 - - 1 - 1 - 1 - 1 - - - - - 0 - - - - - 1 - 0 - 1 - - 1 - - 0 - 0 - - Dock - 0 - Left - 1 - - 1 - - - 0 - 0 - wxID_ANY - Apply Filters - - 0 - - 0 - - - 0 - - 1 - m_filterNetsButton - 1 - - - protected - 1 - - - - Resizable - 1 - - - ; forward_declare - 0 - - - wxFILTER_NONE - wxDefaultValidator - - - - - OnApplyFilters - - - - - - - - 5 - wxEXPAND - 1 - - 0 - protected - 0 - - - - 8 - wxEXPAND|wxTOP - 0 - - wxID_ANY - Assign Net Class - - sbEdit - wxVERTICAL - 1 - none - - 5 - wxEXPAND - 0 - - - bSizer11 - wxHORIZONTAL - none - - 5 - wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxRIGHT - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - New net class: - 0 - - 0 - - - 0 - 120,-1 - 1 - m_assignLabel - 1 - - - protected - 1 - - Resizable - 1 - - - ; forward_declare - 0 - - - - - -1 - - - - 5 - wxBOTTOM|wxRIGHT|wxLEFT - 1 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - - 0 - - - 0 - - 1 - m_assignNetClass - 1 - - - protected - 1 - - Resizable - 0 - 1 - - - ; forward_declare - 0 - - - wxFILTER_NONE - wxDefaultValidator - - - - - - - - - - 6 - wxEXPAND|wxTOP - 0 - - - bSizer12 - wxHORIZONTAL - none - - 5 - wxBOTTOM|wxLEFT|wxTOP - 1 - - 1 - 1 - 1 - 1 - - - - - 0 - - - - - 1 - 0 - 1 - - 1 - - 0 - 0 - - Dock - 0 - Left - 1 - - 1 - - - 0 - 0 - wxID_ANY - Assign To All Listed Nets - - 0 - - 0 - - - 0 - - 1 - m_assignAllButton - 1 - - - protected - 1 - - - - Resizable - 1 - - - ; forward_declare - 0 - - - wxFILTER_NONE - wxDefaultValidator - - - - - OnAssignAll - - - - 5 - wxEXPAND|wxRIGHT|wxLEFT - 0 - - 0 - protected - 0 - - - - 5 - wxBOTTOM|wxRIGHT|wxTOP - 1 - - 1 - 1 - 1 - 1 - - - - - 0 - - - - - 1 - 0 - 1 - - 1 - - 0 - 0 - - Dock - 0 - Left - 1 - - 1 - - - 0 - 0 - wxID_ANY - Assign To Selected Nets - - 0 - - 0 - - - 0 - - 1 - m_assignSelectedButton - 1 - - - protected - 1 - - - - Resizable - 1 - - - ; forward_declare - 0 - - - wxFILTER_NONE - wxDefaultValidator - - - - - OnAssignSelected - - - - - - + 1 + m_staticText5 + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + + + -1 - 5 - wxEXPAND|wxTOP|wxLEFT + 3 + wxEXPAND|wxTOP 1 - bRight - wxVERTICAL + bColumns + wxHORIZONTAL none - + 5 - wxEXPAND|wxBOTTOM|wxLEFT - 1 - + wxEXPAND + 3 + + + bSizer14 + wxVERTICAL + none + + 5 + wxEXPAND + 1 + + 1 + 1 + 1 + 1 + + + + + 0 + 0 + + + + 1 + + + wxALIGN_LEFT + + wxALIGN_TOP + 0 + 1 + wxALIGN_CENTER + 24 + "Pattern" "Net Class" + wxALIGN_CENTER + 2 + 400,160 + + 1 + 0 + Dock + 0 + Left + 0 + 1 + 0 + 1 + 1 + 1 + + 1 + + + 1 + 0 + 0 + wxID_ANY + + + + 0 + 0 + + 0 + + + 0 + -1,-1 + 1 + m_assignmentGrid + 1 + + + protected + 1 + + Resizable + wxALIGN_CENTER + 0 + + wxALIGN_CENTER + + 5 + 1 + + WX_GRID; widgets/wx_grid.h; forward_declare + 0 + + + + wxBORDER_DEFAULT + OnSizeAssignmentGrid + OnUpdateUI + + + + + + 15 + wxEXPAND|wxLEFT + 2 + 1 1 1 @@ -1393,58 +759,33 @@ - 0 - 0 1 - - - wxALIGN_LEFT - - wxALIGN_TOP 0 1 - wxALIGN_CENTER - 24 - "Net" "Net Class" - wxALIGN_CENTER - 2 - 1 0 Dock 0 Left - 0 - 1 - 0 - 1 - 1 1 1 - - 1 0 0 wxID_ANY - - - - 0 - 0 0 0 - -1,-1 + 1 - m_membershipGrid + m_matchingNets 1 @@ -1452,21 +793,184 @@ 1 Resizable - wxALIGN_CENTER - 0 - - wxALIGN_CENTER - - 0 1 - WX_GRID; widgets/wx_grid.h; forward_declare + wxHW_SCROLLBAR_AUTO + WX_HTML_REPORT_BOX; dialogs/wx_html_report_box.h; forward_declare 0 - wxBORDER_DEFAULT - OnSizeMembershipGrid + + + + + + + 5 + wxEXPAND|wxTOP + 0 + + + buttonBoxSizer1 + wxHORIZONTAL + none + + 2 + + 0 + + 1 + 1 + 1 + 1 + + + + + 0 + + + + + 1 + 0 + 1 + + 1 + + 0 + 0 + + Dock + 0 + Left + 1 + + 1 + + + 0 + 0 + wxID_ANY + Add Net Class + + 0 + + 0 + + + 0 + -1,-1 + 1 + m_addAssignmentButton + 1 + + + protected + 1 + + + + Resizable + 1 + -1,-1 + + ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + OnAddAssignmentClick + + + + 5 + wxEXPAND|wxRIGHT|wxLEFT + 0 + + 0 + protected + 5 + + + + 5 + wxRIGHT|wxLEFT + 0 + + 1 + 1 + 1 + 1 + + + + + 0 + + + + + 1 + 0 + 1 + + 1 + + 0 + 0 + + Dock + 0 + Left + 1 + + 1 + + + 0 + 0 + wxID_ANY + Delete Net Class + + 0 + + 0 + + + 0 + -1,-1 + 1 + m_removeAssignmentButton + 1 + + + protected + 1 + + + + Resizable + 1 + -1,-1 + + ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + OnRemoveAssignmentClick diff --git a/common/dialogs/panel_setup_netclasses_base.h b/common/dialogs/panel_setup_netclasses_base.h index b0bd39cf51..8dbe66510b 100644 --- a/common/dialogs/panel_setup_netclasses_base.h +++ b/common/dialogs/panel_setup_netclasses_base.h @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////// -// C++ code generated with wxFormBuilder (version 3.9.0 Aug 10 2021) +// C++ code generated with wxFormBuilder (version 3.10.1-0-g8feb16b) // http://www.wxformbuilder.org/ // // PLEASE DO *NOT* EDIT THIS FILE! @@ -11,6 +11,7 @@ #include #include class WX_GRID; +class WX_HTML_REPORT_BOX; #include #include @@ -26,9 +27,7 @@ class WX_GRID; #include #include #include -#include -#include -#include +#include #include /////////////////////////////////////////////////////////////////////////// @@ -48,17 +47,11 @@ class PANEL_SETUP_NETCLASSES_BASE : public wxPanel wxBitmapButton* m_removeButton; wxStaticText* m_colorDefaultHelpText; wxPanel* m_membershipPane; - wxStaticText* m_ncfilterLabel; - wxChoice* m_netClassFilter; - wxStaticText* m_filterLabel; - wxTextCtrl* m_netNameFilter; - wxButton* m_showAllButton; - wxButton* m_filterNetsButton; - wxStaticText* m_assignLabel; - wxChoice* m_assignNetClass; - wxButton* m_assignAllButton; - wxButton* m_assignSelectedButton; - WX_GRID* m_membershipGrid; + wxStaticText* m_staticText5; + WX_GRID* m_assignmentGrid; + WX_HTML_REPORT_BOX* m_matchingNets; + wxBitmapButton* m_addAssignmentButton; + wxBitmapButton* m_removeAssignmentButton; // Virtual event handlers, override them in your derived class virtual void OnUpdateUI( wxUpdateUIEvent& event ) { event.Skip(); } @@ -66,11 +59,9 @@ class PANEL_SETUP_NETCLASSES_BASE : public wxPanel virtual void OnAddNetclassClick( wxCommandEvent& event ) { event.Skip(); } virtual void OnRemoveNetclassClick( wxCommandEvent& event ) { event.Skip(); } virtual void onmembershipPanelSize( wxSizeEvent& event ) { event.Skip(); } - virtual void OnApplyFilters( wxCommandEvent& event ) { event.Skip(); } - virtual void OnShowAll( wxCommandEvent& event ) { event.Skip(); } - virtual void OnAssignAll( wxCommandEvent& event ) { event.Skip(); } - virtual void OnAssignSelected( wxCommandEvent& event ) { event.Skip(); } - virtual void OnSizeMembershipGrid( wxSizeEvent& event ) { event.Skip(); } + virtual void OnSizeAssignmentGrid( wxSizeEvent& event ) { event.Skip(); } + virtual void OnAddAssignmentClick( wxCommandEvent& event ) { event.Skip(); } + virtual void OnRemoveAssignmentClick( wxCommandEvent& event ) { event.Skip(); } public: diff --git a/common/dialogs/wx_html_report_box.cpp b/common/dialogs/wx_html_report_box.cpp index e18b7599e2..e9f65807e8 100644 --- a/common/dialogs/wx_html_report_box.cpp +++ b/common/dialogs/wx_html_report_box.cpp @@ -1,7 +1,7 @@ /* * This program source code file is part of KiCad, a free EDA CAD application. * - * Copyright (C) 2020 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2020-2022 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -28,7 +28,8 @@ WX_HTML_REPORT_BOX::WX_HTML_REPORT_BOX( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style ) : HTML_WINDOW( parent, id, pos, size, style ), - m_units( EDA_UNITS::MILLIMETRES ), m_immediateMode( false ) + m_units( EDA_UNITS::MILLIMETRES ), + m_immediateMode( false ) { Flush(); diff --git a/common/netclass.cpp b/common/netclass.cpp index 538a9f9f56..eba591f18e 100644 --- a/common/netclass.cpp +++ b/common/netclass.cpp @@ -3,7 +3,7 @@ * * Copyright (C) 2009 SoftPLC Corporation, Dick Hollenbeck * Copyright (C) 2009 Jean-Pierre Charras, jean-pierre.charras@inpg.fr - * Copyright (C) 2009-2020 KiCad Developers, see change_log.txt for contributors. + * Copyright (C) 2009-2022 KiCad Developers, see change_log.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -76,90 +76,3 @@ NETCLASS::~NETCLASS() } -NETCLASSES::NETCLASSES() -{ - m_default = std::make_shared( NETCLASS::Default ); -} - - -NETCLASSES::~NETCLASSES() -{ -} - - -bool NETCLASSES::Add( const NETCLASSPTR& aNetClass ) -{ - const wxString& name = aNetClass->GetName(); - - if( name == NETCLASS::Default ) - { - m_default = aNetClass; - return true; - } - - // Test for an existing netclass: - if( !Find( name ) ) - { - // name not found, take ownership - m_NetClasses[name] = aNetClass; - - return true; - } - else - { - // name already exists - // do not "take ownership" and return false telling caller such. - return false; - } -} - - -NETCLASSPTR NETCLASSES::Remove( const wxString& aNetName ) -{ - NETCLASS_MAP::iterator found = m_NetClasses.find( aNetName ); - - if( found != m_NetClasses.end() ) - { - std::shared_ptr netclass = found->second; - m_NetClasses.erase( found ); - return netclass; - } - - return NETCLASSPTR(); -} - - -NETCLASSPTR NETCLASSES::Find( const wxString& aName ) const -{ - if( aName == NETCLASS::Default ) - return GetDefault(); - - NETCLASS_MAP::const_iterator found = m_NetClasses.find( aName ); - - if( found == m_NetClasses.end() ) - return NETCLASSPTR(); - else - return found->second; -} - - -#if defined(DEBUG) - -void NETCLASS::Show( int nestLevel, std::ostream& os ) const -{ - // for now, make it look like XML: - //NestedSpace( nestLevel, os ) - - os << '<' << GetClass().Lower().mb_str() << ">\n"; - - for( const_iterator i = begin(); i!=end(); ++i ) - { - // NestedSpace( nestLevel+1, os ) << *i; - os << TO_UTF8( *i ); - } - - // NestedSpace( nestLevel, os ) - os << "\n"; -} - -#endif diff --git a/common/project/net_settings.cpp b/common/project/net_settings.cpp index 55c410525c..a8547a6b65 100644 --- a/common/project/net_settings.cpp +++ b/common/project/net_settings.cpp @@ -2,7 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2020 CERN - * Copyright (C) 2021 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2021-2022 KiCad Developers, see AUTHORS.txt for contributors. * @author Jon Evans * * This program is free software: you can redistribute it and/or modify it @@ -21,7 +21,6 @@ #include - #include #include #include @@ -32,7 +31,8 @@ // const int netSettingsSchemaVersion = 0; // const int netSettingsSchemaVersion = 1; // new overbar syntax -const int netSettingsSchemaVersion = 2; // exclude buses from netclass members +// const int netSettingsSchemaVersion = 2; // exclude buses from netclass members +const int netSettingsSchemaVersion = 3; // netclass assignment patterns static OPT getInPcbUnits( const nlohmann::json& aObj, const std::string& aKey, @@ -55,84 +55,123 @@ static int getInSchUnits( const nlohmann::json& aObj, const std::string& aKey, i NET_SETTINGS::NET_SETTINGS( JSON_SETTINGS* aParent, const std::string& aPath ) : - NESTED_SETTINGS( "net_settings", netSettingsSchemaVersion, aParent, aPath ), - m_NetClasses() + NESTED_SETTINGS( "net_settings", netSettingsSchemaVersion, aParent, aPath ) { + m_DefaultNetClass = std::make_shared( NETCLASS::Default ); + m_DefaultNetClass->SetDescription( _( "This is the default net class." ) ); + + auto saveNetclass = + []( nlohmann::json& json_array, const std::shared_ptr& nc ) + { + // Note: we're in common/, but we do happen to know which of these + // fields are used in which units system. + nlohmann::json nc_json = { + { "name", nc->GetName().ToUTF8() }, + { "wire_width", SchIu2Mils( nc->GetWireWidth() ) }, + { "bus_width", SchIu2Mils( nc->GetBusWidth() ) }, + { "line_style", nc->GetLineStyle() }, + { "schematic_color", nc->GetSchematicColor() }, + { "pcb_color", nc->GetPcbColor() } + }; + + auto saveInPcbUnits = + []( nlohmann::json& json, const std::string& aKey, int aValue ) + { + json.push_back( { aKey, PcbIu2mm( aValue ) } ); + }; + + if( nc->HasClearance() ) + saveInPcbUnits( nc_json, "clearance", nc->GetClearance() ); + + if( nc->HasTrackWidth() ) + saveInPcbUnits( nc_json, "track_width", nc->GetTrackWidth() ); + + if( nc->HasViaDiameter() ) + saveInPcbUnits( nc_json, "via_diameter", nc->GetViaDiameter() ); + + if( nc->HasViaDrill() ) + saveInPcbUnits( nc_json, "via_drill", nc->GetViaDrill() ); + + if( nc->HasuViaDiameter() ) + saveInPcbUnits( nc_json, "microvia_diameter", nc->GetuViaDiameter() ); + + if( nc->HasuViaDrill() ) + saveInPcbUnits( nc_json, "microvia_drill", nc->GetuViaDrill() ); + + if( nc->HasDiffPairWidth() ) + saveInPcbUnits( nc_json, "diff_pair_width", nc->GetDiffPairWidth() ); + + if( nc->HasDiffPairGap() ) + saveInPcbUnits( nc_json, "diff_pair_gap", nc->GetDiffPairGap() ); + + if( nc->HasDiffPairViaGap() ) + saveInPcbUnits( nc_json, "diff_pair_via_gap", nc->GetDiffPairViaGap() ); + + json_array.push_back( nc_json ); + }; + + auto readNetClass = + []( const nlohmann::json& entry ) + { + wxString name = entry["name"]; + + std::shared_ptr nc = std::make_shared( name ); + + if( auto value = getInPcbUnits( entry, "clearance" ) ) + nc->SetClearance( *value ); + + if( auto value = getInPcbUnits( entry, "track_width" ) ) + nc->SetTrackWidth( *value ); + + if( auto value = getInPcbUnits( entry, "via_diameter" ) ) + nc->SetViaDiameter( *value ); + + if( auto value = getInPcbUnits( entry, "via_drill" ) ) + nc->SetViaDrill( *value ); + + if( auto value = getInPcbUnits( entry, "microvia_diameter" ) ) + nc->SetuViaDiameter( *value ); + + if( auto value = getInPcbUnits( entry, "microvia_drill" ) ) + nc->SetuViaDrill( *value ); + + if( auto value = getInPcbUnits( entry, "diff_pair_width" ) ) + nc->SetDiffPairWidth( *value ); + + if( auto value = getInPcbUnits( entry, "diff_pair_gap" ) ) + nc->SetDiffPairGap( *value ); + + if( auto value = getInPcbUnits( entry, "diff_pair_via_gap" ) ) + nc->SetDiffPairViaGap( *value ); + + nc->SetWireWidth( getInSchUnits( entry, "wire_width", nc->GetWireWidth() ) ); + nc->SetBusWidth( getInSchUnits( entry, "bus_width", nc->GetBusWidth() ) ); + + if( entry.contains( "line_style" ) && entry["line_style"].is_number() ) + nc->SetLineStyle( entry["line_style"].get() ); + + if( entry.contains( "pcb_color" ) && entry["pcb_color"].is_string() ) + nc->SetPcbColor( entry["pcb_color"].get() ); + + if( entry.contains( "schematic_color" ) + && entry["schematic_color"].is_string() ) + { + nc->SetSchematicColor( entry["schematic_color"].get() ); + } + + return nc; + }; + m_params.emplace_back( new PARAM_LAMBDA( "classes", [&]() -> nlohmann::json { nlohmann::json ret = nlohmann::json::array(); - NETCLASSPTR nc = m_NetClasses.GetDefault(); - NETCLASSES::const_iterator nc_ii = m_NetClasses.begin(); + if( m_DefaultNetClass ) + saveNetclass( ret, m_DefaultNetClass ); - for( unsigned int idx = 0; idx <= m_NetClasses.GetCount(); idx++ ) - { - if( idx > 0 ) - { - nc = nc_ii->second; - ++nc_ii; - } - - // Note: we're in common/, but we do happen to know which of these fields - // are used in which units system. - nlohmann::json nc_json = { - { "name", nc->GetName().ToUTF8() }, - { "wire_width", SchIu2Mils( nc->GetWireWidth() ) }, - { "bus_width", SchIu2Mils( nc->GetBusWidth() ) }, - { "line_style", nc->GetLineStyle() }, - { "schematic_color", nc->GetSchematicColor() }, - { "pcb_color", nc->GetPcbColor() } - }; - - auto saveInPcbUnits = - []( nlohmann::json& json, const std::string& aKey, int aValue ) - { - json.push_back( { aKey, PcbIu2mm( aValue ) } ); - }; - - if( nc->HasClearance() ) - saveInPcbUnits( nc_json, "clearance", nc->GetClearance() ); - - if( nc->HasTrackWidth() ) - saveInPcbUnits( nc_json, "track_width", nc->GetTrackWidth() ); - - if( nc->HasViaDiameter() ) - saveInPcbUnits( nc_json, "via_diameter", nc->GetViaDiameter() ); - - if( nc->HasViaDrill() ) - saveInPcbUnits( nc_json, "via_drill", nc->GetViaDrill() ); - - if( nc->HasuViaDiameter() ) - saveInPcbUnits( nc_json, "microvia_diameter", nc->GetuViaDiameter() ); - - if( nc->HasuViaDrill() ) - saveInPcbUnits( nc_json, "microvia_drill", nc->GetuViaDrill() ); - - if( nc->HasDiffPairWidth() ) - saveInPcbUnits( nc_json, "diff_pair_width", nc->GetDiffPairWidth() ); - - if( nc->HasDiffPairGap() ) - saveInPcbUnits( nc_json, "diff_pair_gap", nc->GetDiffPairGap() ); - - if( nc->HasDiffPairViaGap() ) - saveInPcbUnits( nc_json, "diff_pair_via_gap", nc->GetDiffPairViaGap() ); - - if( idx > 0 ) // No need to store members of Default nc - { - nlohmann::json membersJson = nlohmann::json::array(); - - for( const wxString& member : *nc ) - { - if( !member.empty() ) - membersJson.push_back( member ); - } - - nc_json["nets"] = membersJson; - } - - ret.push_back( nc_json ); - } + for( const auto& [ name, netclass ] : m_NetClasses ) + saveNetclass( ret, netclass ); return ret; }, @@ -141,95 +180,19 @@ NET_SETTINGS::NET_SETTINGS( JSON_SETTINGS* aParent, const std::string& aPath ) : if( !aJson.is_array() ) return; - m_NetClasses.Clear(); - m_NetClassAssignments.clear(); - NETCLASSPTR nc; - NETCLASSPTR defaultClass = m_NetClasses.GetDefault(); + m_NetClasses.clear(); for( const nlohmann::json& entry : aJson ) { if( !entry.is_object() || !entry.contains( "name" ) ) continue; - wxString name = entry["name"]; + std::shared_ptr nc = readNetClass( entry ); - if( name == defaultClass->GetName() ) - nc = defaultClass; + if( nc->GetName() == NETCLASS::Default ) + m_DefaultNetClass = nc; else - nc = std::make_shared( name ); - - if( auto value = getInPcbUnits( entry, "clearance" ) ) - nc->SetClearance( *value ); - - if( auto value = getInPcbUnits( entry, "track_width" ) ) - nc->SetTrackWidth( *value ); - - if( auto value = getInPcbUnits( entry, "via_diameter" ) ) - nc->SetViaDiameter( *value ); - - if( auto value = getInPcbUnits( entry, "via_drill" ) ) - nc->SetViaDrill( *value ); - - if( auto value = getInPcbUnits( entry, "microvia_diameter" ) ) - nc->SetuViaDiameter( *value ); - - if( auto value = getInPcbUnits( entry, "microvia_drill" ) ) - nc->SetuViaDrill( *value ); - - if( auto value = getInPcbUnits( entry, "diff_pair_width" ) ) - nc->SetDiffPairWidth( *value ); - - if( auto value = getInPcbUnits( entry, "diff_pair_gap" ) ) - nc->SetDiffPairGap( *value ); - - if( auto value = getInPcbUnits( entry, "diff_pair_via_gap" ) ) - nc->SetDiffPairViaGap( *value ); - - nc->SetWireWidth( getInSchUnits( entry, "wire_width", nc->GetWireWidth() ) ); - nc->SetBusWidth( getInSchUnits( entry, "bus_width", nc->GetBusWidth() ) ); - - if( entry.contains( "line_style" ) && entry["line_style"].is_number() ) - nc->SetLineStyle( entry["line_style"].get() ); - - if( entry.contains( "nets" ) && entry["nets"].is_array() ) - { - for( const auto& net : entry["nets"].items() ) - { - wxString netname = net.value().get(); - - if( m_schemaVersion < 2 ) - { - // Strip out buses from older 5.99 implementations. They were - // a world of hurt, never fully functional, and are functionally - // replaced by assigning a netclass to a bus on the canvas. - wxString unescaped = UnescapeString( netname ); - wxString prefix; - std::vector members; - - if( ParseBusVector( unescaped, &prefix, &members ) ) - continue; - else if( ParseBusGroup( unescaped, &prefix, &members ) ) - continue; - } - - nc->Add( netname ); - } - } - - if( entry.contains( "pcb_color" ) && entry["pcb_color"].is_string() ) - nc->SetPcbColor( entry["pcb_color"].get() ); - - if( entry.contains( "schematic_color" ) - && entry["schematic_color"].is_string() ) - { - nc->SetSchematicColor( entry["schematic_color"].get() ); - } - - if( nc != defaultClass ) - m_NetClasses.Add( nc ); - - for( const wxString& net : *nc ) - m_NetClassAssignments[ net ] = nc->GetName(); + m_NetClasses[ nc->GetName() ] = nc; } }, {} ) ); @@ -239,10 +202,10 @@ NET_SETTINGS::NET_SETTINGS( JSON_SETTINGS* aParent, const std::string& aPath ) : { nlohmann::json ret = {}; - for( const auto& pair : m_PcbNetColors ) + for( const auto& [ netname, color ] : m_NetColorAssignments ) { - std::string key( pair.first.ToUTF8() ); - ret[key] = pair.second; + std::string key( netname.ToUTF8() ); + ret[key] = color; } return ret; @@ -252,17 +215,91 @@ NET_SETTINGS::NET_SETTINGS( JSON_SETTINGS* aParent, const std::string& aPath ) : if( !aJson.is_object() ) return; - m_PcbNetColors.clear(); + m_NetColorAssignments.clear(); for( const auto& pair : aJson.items() ) { wxString key( pair.key().c_str(), wxConvUTF8 ); - m_PcbNetColors[key] = pair.value().get(); + m_NetColorAssignments[key] = pair.value().get(); + } + }, + {} ) ); + + m_params.emplace_back( new PARAM_LAMBDA( "netclass_assignments", + [&]() -> nlohmann::json + { + nlohmann::json ret = {}; + + for( const auto& [ netname, netclassName ] : m_NetClassLabelAssignments ) + { + std::string key( netname.ToUTF8() ); + ret[key] = netclassName; + } + + return ret; + }, + [&]( const nlohmann::json& aJson ) + { + if( !aJson.is_object() ) + return; + + m_NetClassLabelAssignments.clear(); + + for( const auto& pair : aJson.items() ) + { + wxString key( pair.key().c_str(), wxConvUTF8 ); + m_NetClassLabelAssignments[key] = pair.value().get(); + } + }, + {} ) ); + + m_params.emplace_back( new PARAM_LAMBDA( "netclass_patterns", + [&]() -> nlohmann::json + { + nlohmann::json ret = nlohmann::json::array(); + + for( const auto& [ matcher, netclassName ] : m_NetClassPatternAssignments ) + { + nlohmann::json pattern_json = { + { "pattern", matcher->GetPattern().ToUTF8() }, + { "netclass", netclassName.ToUTF8() } + }; + + ret.push_back( pattern_json ); + } + + return ret; + }, + [&]( const nlohmann::json& aJson ) + { + if( !aJson.is_array() ) + return; + + m_NetClassPatternAssignments.clear(); + + for( const nlohmann::json& entry : aJson ) + { + if( !entry.is_object() ) + continue; + + if( entry.contains( "pattern" ) && entry["pattern"].is_string() + && entry.contains( "netclass" ) && entry["netclass"].is_string() ) + { + wxString pattern = entry["pattern"].get(); + wxString netclass = entry["netclass"].get(); + + m_NetClassPatternAssignments.push_back( + { + std::make_unique( pattern, CTX_NETCLASS ), + netclass + } ); + } } }, {} ) ); registerMigration( 0, 1, std::bind( &NET_SETTINGS::migrateSchema0to1, this ) ); + registerMigration( 2, 3, std::bind( &NET_SETTINGS::migrateSchema2to3, this ) ); } @@ -299,16 +336,67 @@ bool NET_SETTINGS::migrateSchema0to1() } -const wxString& NET_SETTINGS::GetNetclassName( const wxString& aNetName ) const +bool NET_SETTINGS::migrateSchema2to3() { - static wxString defaultNetname = NETCLASS::Default; + if( m_internals->contains( "classes" ) && m_internals->At( "classes" ).is_array() ) + { + nlohmann::json patterns = nlohmann::json::array(); - auto it = m_NetClassAssignments.find( aNetName ); + for( auto& netClass : m_internals->At( "classes" ).items() ) + { + if( netClass.value().contains( "name" ) + && netClass.value().contains( "nets" ) + && netClass.value()["nets"].is_array() ) + { + wxString netClassName = netClass.value()["name"].get(); - if( it == m_NetClassAssignments.end() ) - return defaultNetname; - else - return it->second; + for( auto& net : netClass.value()["nets"].items() ) + { + nlohmann::json pattern_json = { + { "pattern", net.value().get() }, + { "netclass", netClassName } + }; + + patterns.push_back( pattern_json ); + } + } + } + + m_internals->SetFromString( "netclass_patterns", patterns ); + } + + return true; +} + + +std::shared_ptr NET_SETTINGS::GetEffectiveNetClass( const wxString& aNetName ) const +{ + auto getNetclass = + [&]( const wxString& netclass ) + { + auto ii = m_NetClasses.find( netclass ); + + if( ii == m_NetClasses.end() ) + return m_DefaultNetClass; + else + return ii->second; + }; + + auto it = m_NetClassLabelAssignments.find( aNetName ); + + if( it != m_NetClassLabelAssignments.end() ) + return getNetclass( it->second ); + + for( const auto& [ matcher, netclassName ] : m_NetClassPatternAssignments ) + { + int matches; + int offset; + + if( matcher->Find( aNetName, matches, offset ) && offset == 0 ) + return getNetclass( netclassName ); + } + + return m_DefaultNetClass; } @@ -534,15 +622,3 @@ bool NET_SETTINGS::ParseBusGroup( const wxString& aGroup, wxString* aName, return false; } - - -void NET_SETTINGS::RebuildNetClassAssignments() -{ - m_NetClassAssignments.clear(); - - for( const std::pair& netclass : m_NetClasses ) - { - for( const wxString& net : *netclass.second ) - m_NetClassAssignments[ net ] = netclass.second->GetName(); - } -} diff --git a/common/settings/json_settings.cpp b/common/settings/json_settings.cpp index 59922cfd41..9541e4026e 100644 --- a/common/settings/json_settings.cpp +++ b/common/settings/json_settings.cpp @@ -2,7 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2020 Jon Evans - * Copyright (C) 2020-2021 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2020-2022 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -682,7 +682,7 @@ template bool JSON_SETTINGS::fromLegacy( wxConfigBase*, const std::string&, const std::string& ); template bool JSON_SETTINGS::fromLegacy( wxConfigBase*, const std::string&, - const std::string& ); + const std::string& ); template bool JSON_SETTINGS::fromLegacy( wxConfigBase*, const std::string&, const std::string& ); @@ -749,7 +749,7 @@ void JSON_SETTINGS::AddNestedSettings( NESTED_SETTINGS* aSettings ) void JSON_SETTINGS::ReleaseNestedSettings( NESTED_SETTINGS* aSettings ) { - if( !aSettings ) + if( !aSettings || !m_manager ) return; auto it = std::find_if( m_nested_settings.begin(), m_nested_settings.end(), diff --git a/eeschema/CMakeLists.txt b/eeschema/CMakeLists.txt index 8fa8a59f0b..0772a01921 100644 --- a/eeschema/CMakeLists.txt +++ b/eeschema/CMakeLists.txt @@ -57,6 +57,8 @@ set( EESCHEMA_SCH_PLUGINS_CADSTAR set( EESCHEMA_DLGS dialogs/dialog_annotate.cpp dialogs/dialog_annotate_base.cpp + dialogs/dialog_assign_netclass.cpp + dialogs/dialog_assign_netclass_base.cpp dialogs/dialog_bom.cpp dialogs/dialog_bom_base.cpp dialogs/dialog_bus_manager.cpp diff --git a/eeschema/connection_graph.cpp b/eeschema/connection_graph.cpp index 91dd5cad0b..4a8023e8f8 100644 --- a/eeschema/connection_graph.cpp +++ b/eeschema/connection_graph.cpp @@ -41,6 +41,8 @@ #include #include #include +#include +#include #include #include #include @@ -332,6 +334,31 @@ const wxString CONNECTION_SUBGRAPH::GetNameForDriver( SCH_ITEM* aItem ) const } +const wxString CONNECTION_SUBGRAPH::GetNetclassForDriver( SCH_ITEM* aItem ) const +{ + wxString netclass; + + aItem->RunOnChildren( + [&]( SCH_ITEM* aChild ) + { + if( aChild->Type() == SCH_FIELD_T ) + { + SCH_FIELD* field = static_cast( aChild ); + + if( field->GetCanonicalName() == wxT( "Netclass" ) ) + { + netclass = field->GetText(); + return false; + } + } + + return true; + } ); + + return netclass; +} + + void CONNECTION_SUBGRAPH::Absorb( CONNECTION_SUBGRAPH* aOther ) { wxASSERT( m_sheet == aOther->m_sheet ); @@ -492,7 +519,7 @@ void CONNECTION_GRAPH::Recalculate( const SCH_SHEET_LIST& aSheetList, bool aUnco PROF_TIMER build_graph( "buildConnectionGraph" ); - buildConnectionGraph(); + buildConnectionGraph( aChangedItemHandler ); if( wxLog::IsAllowedTraceMask( ConnProfileMask ) ) build_graph.Show(); @@ -1203,29 +1230,32 @@ void CONNECTION_GRAPH::processSubGraphs() // Also check the main driving connection connections_to_check.push_back( std::make_shared( *connection ) ); - auto add_connections_to_check = [&] ( CONNECTION_SUBGRAPH* aSubgraph ) { - for( SCH_ITEM* possible_driver : aSubgraph->m_items ) - { - if( possible_driver == aSubgraph->m_driver ) - continue; - - auto c = getDefaultConnection( possible_driver, aSubgraph ); - - if( c ) + auto add_connections_to_check = + [&] ( CONNECTION_SUBGRAPH* aSubgraph ) { - if( c->Type() != aSubgraph->m_driver_connection->Type() ) - continue; + for( SCH_ITEM* possible_driver : aSubgraph->m_items ) + { + if( possible_driver == aSubgraph->m_driver ) + continue; - if( c->Name( true ) == aSubgraph->m_driver_connection->Name( true ) ) - continue; + auto c = getDefaultConnection( possible_driver, aSubgraph ); - connections_to_check.push_back( c ); - wxLogTrace( ConnTrace, - "%lu (%s): Adding secondary driver %s", aSubgraph->m_code, - aSubgraph->m_driver_connection->Name( true ), c->Name( true ) ); - } - } - }; + if( c ) + { + if( c->Type() != aSubgraph->m_driver_connection->Type() ) + continue; + + if( c->Name( true ) == aSubgraph->m_driver_connection->Name( true ) ) + continue; + + connections_to_check.push_back( c ); + wxLogTrace( ConnTrace, + "%lu (%s): Adding secondary driver %s", aSubgraph->m_code, + aSubgraph->m_driver_connection->Name( true ), + c->Name( true ) ); + } + } + }; // Now add other strong drivers // The actual connection attached to these items will have been overwritten @@ -1354,7 +1384,7 @@ void CONNECTION_GRAPH::processSubGraphs() // on some portion of the items. -void CONNECTION_GRAPH::buildConnectionGraph() +void CONNECTION_GRAPH::buildConnectionGraph( std::function* aChangedItemHandler ) { // Recache all bus aliases for later use wxCHECK_RET( m_schematic, wxT( "Connection graph cannot be built without schematic pointer" ) ); @@ -1548,62 +1578,62 @@ void CONNECTION_GRAPH::buildConnectionGraph() auto updateItemConnectionsTask = - [&]( CONNECTION_SUBGRAPH* subgraph ) -> size_t - { - // Make sure weakly-driven single-pin nets get the unconnected_ prefix - if( !subgraph->m_strong_driver && subgraph->m_drivers.size() == 1 && - subgraph->m_driver->Type() == SCH_PIN_T ) + [&]( CONNECTION_SUBGRAPH* subgraph ) -> size_t { - SCH_PIN* pin = static_cast( subgraph->m_driver ); - wxString name = pin->GetDefaultNetName( subgraph->m_sheet, true ); - - subgraph->m_driver_connection->ConfigureFromLabel( name ); - } - - subgraph->m_dirty = false; - subgraph->UpdateItemConnections(); - - // No other processing to do on buses - if( subgraph->m_driver_connection->IsBus() ) - return 0; - - // As a visual aid, we can check sheet pins that are driven by themselves to see - // if they should be promoted to buses - - if( subgraph->m_driver->Type() == SCH_SHEET_PIN_T ) - { - SCH_SHEET_PIN* pin = static_cast( subgraph->m_driver ); - - if( SCH_SHEET* sheet = pin->GetParent() ) + // Make sure weakly-driven single-pin nets get the unconnected_ prefix + if( !subgraph->m_strong_driver && subgraph->m_drivers.size() == 1 && + subgraph->m_driver->Type() == SCH_PIN_T ) { - wxString pinText = pin->GetText(); - SCH_SCREEN* screen = sheet->GetScreen(); + SCH_PIN* pin = static_cast( subgraph->m_driver ); + wxString name = pin->GetDefaultNetName( subgraph->m_sheet, true ); - for( SCH_ITEM* item : screen->Items().OfType( SCH_HIER_LABEL_T ) ) - { - SCH_HIERLABEL* label = static_cast( item ); - - if( label->GetText() == pinText ) - { - SCH_SHEET_PATH path = subgraph->m_sheet; - path.push_back( sheet ); - - SCH_CONNECTION* parent_conn = label->Connection( &path ); - - if( parent_conn && parent_conn->IsBus() ) - subgraph->m_driver_connection->SetType( CONNECTION_TYPE::BUS ); - - break; - } - } - - if( subgraph->m_driver_connection->IsBus() ) - return 0; + subgraph->m_driver_connection->ConfigureFromLabel( name ); } - } - return 1; - }; + subgraph->m_dirty = false; + subgraph->UpdateItemConnections(); + + // No other processing to do on buses + if( subgraph->m_driver_connection->IsBus() ) + return 0; + + // As a visual aid, we can check sheet pins that are driven by themselves to see + // if they should be promoted to buses + + if( subgraph->m_driver->Type() == SCH_SHEET_PIN_T ) + { + SCH_SHEET_PIN* pin = static_cast( subgraph->m_driver ); + + if( SCH_SHEET* sheet = pin->GetParent() ) + { + wxString pinText = pin->GetText(); + SCH_SCREEN* screen = sheet->GetScreen(); + + for( SCH_ITEM* item : screen->Items().OfType( SCH_HIER_LABEL_T ) ) + { + SCH_HIERLABEL* label = static_cast( item ); + + if( label->GetText() == pinText ) + { + SCH_SHEET_PATH path = subgraph->m_sheet; + path.push_back( sheet ); + + SCH_CONNECTION* parent_conn = label->Connection( &path ); + + if( parent_conn && parent_conn->IsBus() ) + subgraph->m_driver_connection->SetType( CONNECTION_TYPE::BUS ); + + break; + } + } + + if( subgraph->m_driver_connection->IsBus() ) + return 0; + } + } + + return 1; + }; GetKiCadThreadPool().parallelize_loop( 0, m_driver_subgraphs.size(), [&]( const int a, const int b) @@ -1623,6 +1653,51 @@ void CONNECTION_GRAPH::buildConnectionGraph() m_net_name_to_subgraphs_map[subgraph->m_driver_connection->Name()].push_back( subgraph ); } + + std::shared_ptr& netSettings = m_schematic->Prj().GetProjectFile().m_NetSettings; + std::map oldAssignments = netSettings->m_NetClassLabelAssignments; + + netSettings->m_NetClassLabelAssignments.clear(); + + auto dirtySubgraphs = + [&]( const std::vector& subgraphs ) + { + if( aChangedItemHandler ) + { + for( const CONNECTION_SUBGRAPH* subgraph : subgraphs ) + { + for( SCH_ITEM* item : subgraph->m_items ) + (*aChangedItemHandler)( item ); + } + } + }; + + auto checkNetclassDrivers = + [&]( const std::vector& subgraphs ) + { + for( const CONNECTION_SUBGRAPH* subgraph : subgraphs ) + { + for( SCH_ITEM* item : subgraph->m_items ) + { + const wxString netclass = subgraph->GetNetclassForDriver( item ); + + if( !netclass.IsEmpty() ) + { + const wxString netname = subgraph->GetNetName(); + + netSettings->m_NetClassLabelAssignments[ netname ] = netclass; + + if( oldAssignments[ netname ] != netclass ) + dirtySubgraphs( subgraphs ); + + return; + } + } + } + }; + + for( const auto& [ netname, subgraphs ] : m_net_name_to_subgraphs_map ) + checkNetclassDrivers( subgraphs ); } @@ -2291,6 +2366,15 @@ int CONNECTION_GRAPH::RunERC() error_count += ercCheckHierSheets(); } + if( settings.IsTestEnabled( ERCE_NETCLASS_CONFLICT ) ) + { + for( const auto& [ netname, subgraphs ] : m_net_name_to_subgraphs_map ) + { + if( !ercCheckNetclassConflicts( subgraphs ) ) + error_count++; + } + } + return error_count; } @@ -2368,6 +2452,44 @@ bool CONNECTION_GRAPH::ercCheckMultipleDrivers( const CONNECTION_SUBGRAPH* aSubg } +bool CONNECTION_GRAPH::ercCheckNetclassConflicts( const std::vector& subgraphs ) +{ + wxString firstNetclass; + SCH_ITEM* firstNetclassDriver = nullptr; + + for( const CONNECTION_SUBGRAPH* subgraph : subgraphs ) + { + for( SCH_ITEM* item : subgraph->m_items ) + { + const wxString netclass = subgraph->GetNetclassForDriver( item ); + + if( netclass.IsEmpty() ) + continue; + + if( netclass != firstNetclass ) + { + if( !firstNetclassDriver ) + { + firstNetclass = netclass; + firstNetclassDriver = item; + continue; + } + + std::shared_ptr ercItem = ERC_ITEM::Create( ERCE_NETCLASS_CONFLICT ); + ercItem->SetItems( firstNetclassDriver, item ); + + SCH_MARKER* marker = new SCH_MARKER( ercItem, item->GetPosition() ); + subgraph->m_sheet.LastScreen()->Append( marker ); + + return false; + } + } + } + + return true; +} + + bool CONNECTION_GRAPH::ercCheckBusToNetConflicts( const CONNECTION_SUBGRAPH* aSubgraph ) { const SCH_SHEET_PATH& sheet = aSubgraph->m_sheet; diff --git a/eeschema/connection_graph.h b/eeschema/connection_graph.h index 6ab784fc24..68563c6ff0 100644 --- a/eeschema/connection_graph.h +++ b/eeschema/connection_graph.h @@ -116,6 +116,8 @@ public: const wxString GetNameForDriver( SCH_ITEM* aItem ) const; + const wxString GetNetclassForDriver( SCH_ITEM* aItem ) const; + /// Combines another subgraph on the same sheet into this one. void Absorb( CONNECTION_SUBGRAPH* aOther ); @@ -390,7 +392,7 @@ private: * and then the connection for the chosen driver is propagated to all the * other items in the subgraph. */ - void buildConnectionGraph(); + void buildConnectionGraph( std::function* aChangedItemHandler ); /** * Generates individual item subgraphs on a per-sheet basis @@ -475,6 +477,8 @@ private: */ bool ercCheckMultipleDrivers( const CONNECTION_SUBGRAPH* aSubgraph ); + bool ercCheckNetclassConflicts( const std::vector& subgraphs ); + /** * Checks one subgraph for conflicting connections between net and bus labels * diff --git a/eeschema/cross-probing.cpp b/eeschema/cross-probing.cpp index f0cb57f03b..51992eae18 100644 --- a/eeschema/cross-probing.cpp +++ b/eeschema/cross-probing.cpp @@ -607,42 +607,6 @@ void SCH_EDIT_FRAME::KiwayMailIn( KIWAY_EXPRESS& mail ) } 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 ); - } - } - break; - case MAIL_IMPORT_FILE: { // Extract file format type and path (plugin type and path separated with \n) diff --git a/eeschema/dialogs/dialog_assign_netclass.cpp b/eeschema/dialogs/dialog_assign_netclass.cpp new file mode 100644 index 0000000000..c6ca490545 --- /dev/null +++ b/eeschema/dialogs/dialog_assign_netclass.cpp @@ -0,0 +1,104 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2022 KiCad Developers, see AUTHORS.txt for contributors. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include +#include +#include +#include +#include +#include + + +DIALOG_ASSIGN_NETCLASS::DIALOG_ASSIGN_NETCLASS( SCH_EDIT_FRAME* aParent, const wxString aNetName ) : + DIALOG_ASSIGN_NETCLASS_BASE( aParent ), + m_frame( aParent ) +{ + std::shared_ptr& netSettings = m_frame->Prj().GetProjectFile().m_NetSettings; + + m_netclassCtrl->Append( NETCLASS::Default ); + + for( const auto& [ name, netclass ] : netSettings->m_NetClasses ) + m_netclassCtrl->Append( name ); + + if( m_netclassCtrl->GetCount() > 1 ) + m_netclassCtrl->SetSelection( 1 ); // First non-Default netclass + else + m_netclassCtrl->SetSelection( 0 ); // Default netclass + + m_patternCtrl->SetValue( aNetName ); + m_matchingNets->SetFont( KIUI::GetInfoFont( this ) ); + m_info->SetFont( KIUI::GetInfoFont( this ).Italic() ); + + SetupStandardButtons(); + + finishDialogSettings(); +} + + +bool DIALOG_ASSIGN_NETCLASS::TransferDataFromWindow() +{ + std::shared_ptr& netSettings = m_frame->Prj().GetProjectFile().m_NetSettings; + + if( m_patternCtrl->GetValue().IsEmpty() ) + return true; + + netSettings->m_NetClassPatternAssignments.push_back( + { + std::make_unique( m_patternCtrl->GetValue(), CTX_NETCLASS ), + m_netclassCtrl->GetStringSelection() + } ); + + return true; +} + + +void DIALOG_ASSIGN_NETCLASS::OnUpdateUI( wxUpdateUIEvent& event ) +{ + wxString pattern = m_patternCtrl->GetValue(); + + if( pattern != m_lastPattern ) + { + m_matchingNets->Clear(); + + if( !pattern.IsEmpty() ) + { + EDA_COMBINED_MATCHER matcher( pattern, CTX_NETCLASS ); + + m_matchingNets->Report( _( "Currently matching nets:" ) ); + + for( const wxString& net : m_frame->Schematic().GetNetClassAssignmentCandidates() ) + { + int matches; + int offset; + + if( matcher.Find( net, matches, offset ) && offset == 0 ) + m_matchingNets->Report( net ); + } + } + + m_matchingNets->Flush(); + m_lastPattern = pattern; + } +} + + diff --git a/eeschema/dialogs/dialog_assign_netclass.h b/eeschema/dialogs/dialog_assign_netclass.h new file mode 100644 index 0000000000..e26ddc1f78 --- /dev/null +++ b/eeschema/dialogs/dialog_assign_netclass.h @@ -0,0 +1,49 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2022 KiCad Developers, see AUTHORS.txt for contributors. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef DIALOG_ASSIGN_NETCLASS_H +#define DIALOG_ASSIGN_NETCLASS_H + +#include + + +class SCH_EDIT_FRAME; + + +class DIALOG_ASSIGN_NETCLASS : public DIALOG_ASSIGN_NETCLASS_BASE +{ +public: + DIALOG_ASSIGN_NETCLASS( SCH_EDIT_FRAME* aParent, const wxString aNetName ); + ~DIALOG_ASSIGN_NETCLASS() override {} + +private: + void OnUpdateUI( wxUpdateUIEvent &event ) override; + + bool TransferDataFromWindow() override; + +private: + SCH_EDIT_FRAME* m_frame; + wxString m_lastPattern; +}; + +#endif //DIALOG_ASSIGN_NETCLASS_H diff --git a/eeschema/dialogs/dialog_assign_netclass_base.cpp b/eeschema/dialogs/dialog_assign_netclass_base.cpp new file mode 100644 index 0000000000..16d71c45a8 --- /dev/null +++ b/eeschema/dialogs/dialog_assign_netclass_base.cpp @@ -0,0 +1,95 @@ +/////////////////////////////////////////////////////////////////////////// +// C++ code generated with wxFormBuilder (version 3.10.1-0-g8feb16b) +// http://www.wxformbuilder.org/ +// +// PLEASE DO *NOT* EDIT THIS FILE! +/////////////////////////////////////////////////////////////////////////// + +#include "dialogs/wx_html_report_box.h" + +#include "dialog_assign_netclass_base.h" + +/////////////////////////////////////////////////////////////////////////// + +DIALOG_ASSIGN_NETCLASS_BASE::DIALOG_ASSIGN_NETCLASS_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style ) +{ + this->SetSizeHints( wxDefaultSize, wxDefaultSize ); + + wxBoxSizer* bMainSizer; + bMainSizer = new wxBoxSizer( wxVERTICAL ); + + wxBoxSizer* bUpperSizer; + bUpperSizer = new wxBoxSizer( wxHORIZONTAL ); + + stPatternLabel = new wxStaticText( this, wxID_ANY, wxT("Pattern:"), wxDefaultPosition, wxDefaultSize, 0 ); + stPatternLabel->Wrap( -1 ); + bUpperSizer->Add( stPatternLabel, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 10 ); + + m_patternCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + m_patternCtrl->SetMinSize( wxSize( 240,-1 ) ); + + bUpperSizer->Add( m_patternCtrl, 1, wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL, 5 ); + + stNetclassLabel = new wxStaticText( this, wxID_ANY, wxT("Net class:"), wxDefaultPosition, wxDefaultSize, 0 ); + stNetclassLabel->Wrap( -1 ); + bUpperSizer->Add( stNetclassLabel, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 30 ); + + m_netclassCtrl = new wxComboBox( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, wxCB_READONLY ); + bUpperSizer->Add( m_netclassCtrl, 0, wxALL, 5 ); + + + bMainSizer->Add( bUpperSizer, 0, wxEXPAND|wxALL, 5 ); + + wxBoxSizer* bLowerSizer; + bLowerSizer = new wxBoxSizer( wxVERTICAL ); + + m_matchingNets = new WX_HTML_REPORT_BOX( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHW_SCROLLBAR_AUTO ); + m_matchingNets->SetMinSize( wxSize( -1,200 ) ); + + bLowerSizer->Add( m_matchingNets, 2, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 ); + + m_info = new wxStaticText( this, wxID_ANY, wxT("Note: complete netclass assignments can be edited in Schemtaic Setup > Project."), wxDefaultPosition, wxDefaultSize, 0 ); + m_info->Wrap( -1 ); + bLowerSizer->Add( m_info, 0, wxTOP|wxRIGHT|wxLEFT, 5 ); + + m_staticline1 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL ); + bLowerSizer->Add( m_staticline1, 0, wxEXPAND|wxTOP, 10 ); + + + bMainSizer->Add( bLowerSizer, 1, wxEXPAND|wxRIGHT|wxLEFT, 10 ); + + wxBoxSizer* bSizerButtons; + bSizerButtons = new wxBoxSizer( wxHORIZONTAL ); + + + bSizerButtons->Add( 20, 0, 1, wxEXPAND, 5 ); + + m_sdbSizerStdButtons = new wxStdDialogButtonSizer(); + m_sdbSizerStdButtonsOK = new wxButton( this, wxID_OK ); + m_sdbSizerStdButtons->AddButton( m_sdbSizerStdButtonsOK ); + m_sdbSizerStdButtonsCancel = new wxButton( this, wxID_CANCEL ); + m_sdbSizerStdButtons->AddButton( m_sdbSizerStdButtonsCancel ); + m_sdbSizerStdButtons->Realize(); + + bSizerButtons->Add( m_sdbSizerStdButtons, 0, wxALL, 5 ); + + + bMainSizer->Add( bSizerButtons, 0, wxEXPAND|wxALL, 5 ); + + + this->SetSizer( bMainSizer ); + this->Layout(); + bMainSizer->Fit( this ); + + this->Centre( wxBOTH ); + + // Connect Events + this->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_ASSIGN_NETCLASS_BASE::OnUpdateUI ) ); +} + +DIALOG_ASSIGN_NETCLASS_BASE::~DIALOG_ASSIGN_NETCLASS_BASE() +{ + // Disconnect Events + this->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_ASSIGN_NETCLASS_BASE::OnUpdateUI ) ); + +} diff --git a/eeschema/dialogs/dialog_assign_netclass_base.fbp b/eeschema/dialogs/dialog_assign_netclass_base.fbp new file mode 100644 index 0000000000..4c45483206 --- /dev/null +++ b/eeschema/dialogs/dialog_assign_netclass_base.fbp @@ -0,0 +1,557 @@ + + + + + ; + C++ + 1 + source_name + 0 + 0 + res + UTF-8 + connect + dialog_assign_netclass_base + 1000 + none + + + 0 + DIALOG_ASSIGN_NETCLASS_BASE + + . + + 1 + 1 + 1 + 1 + UI + 0 + 0 + 0 + + 0 + wxAUI_MGR_DEFAULT + + wxBOTH + + 1 + 1 + impl_virtual + + + + 0 + wxID_ANY + + + DIALOG_ASSIGN_NETCLASS_BASE + + + wxDEFAULT_DIALOG_STYLE + DIALOG_SHIM; dialog_shim.h; forward_declare + Add Netclass Assignment + + 0 + + + + OnUpdateUI + + + bMainSizer + wxVERTICAL + none + + 5 + wxEXPAND|wxALL + 0 + + + bUpperSizer + wxHORIZONTAL + none + + 10 + wxALIGN_CENTER_VERTICAL|wxLEFT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Pattern: + 0 + + 0 + + + 0 + + 1 + stPatternLabel + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + + + -1 + + + + 5 + wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + + 0 + 240,-1 + 1 + m_patternCtrl + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + 30 + wxALIGN_CENTER_VERTICAL|wxLEFT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Net class: + 0 + + 0 + + + 0 + + 1 + stNetclassLabel + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + + + -1 + + + + 5 + wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + 0 + + 1 + m_netclassCtrl + 1 + + + protected + 1 + + Resizable + -1 + 1 + + wxCB_READONLY + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + + + 10 + wxEXPAND|wxRIGHT|wxLEFT + 1 + + + bLowerSizer + wxVERTICAL + none + + 5 + wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT + 2 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + 0 + -1,200 + 1 + m_matchingNets + 1 + + + protected + 1 + + Resizable + 1 + + wxHW_SCROLLBAR_AUTO + WX_HTML_REPORT_BOX; dialogs/wx_html_report_box.h; forward_declare + 0 + + + + + + + + 5 + wxTOP|wxRIGHT|wxLEFT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Note: complete netclass assignments can be edited in Schemtaic Setup > Project. + 0 + + 0 + + + 0 + + 1 + m_info + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + + + -1 + + + + 10 + wxEXPAND|wxTOP + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + 0 + + 1 + m_staticline1 + 1 + + + protected + 1 + + Resizable + 1 + + wxLI_HORIZONTAL + ; ; forward_declare + 0 + + + + + + + + + + 5 + wxEXPAND|wxALL + 0 + + + bSizerButtons + wxHORIZONTAL + none + + 5 + wxEXPAND + 1 + + 0 + protected + 20 + + + + 5 + wxALL + 0 + + 0 + 1 + 0 + 0 + 0 + 1 + 0 + 0 + + m_sdbSizerStdButtons + protected + + + + + + + + diff --git a/eeschema/dialogs/dialog_assign_netclass_base.h b/eeschema/dialogs/dialog_assign_netclass_base.h new file mode 100644 index 0000000000..9814358097 --- /dev/null +++ b/eeschema/dialogs/dialog_assign_netclass_base.h @@ -0,0 +1,62 @@ +/////////////////////////////////////////////////////////////////////////// +// C++ code generated with wxFormBuilder (version 3.10.1-0-g8feb16b) +// http://www.wxformbuilder.org/ +// +// PLEASE DO *NOT* EDIT THIS FILE! +/////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include +#include +class WX_HTML_REPORT_BOX; + +#include "dialog_shim.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/////////////////////////////////////////////////////////////////////////// + + +/////////////////////////////////////////////////////////////////////////////// +/// Class DIALOG_ASSIGN_NETCLASS_BASE +/////////////////////////////////////////////////////////////////////////////// +class DIALOG_ASSIGN_NETCLASS_BASE : public DIALOG_SHIM +{ + private: + + protected: + wxStaticText* stPatternLabel; + wxTextCtrl* m_patternCtrl; + wxStaticText* stNetclassLabel; + wxComboBox* m_netclassCtrl; + WX_HTML_REPORT_BOX* m_matchingNets; + wxStaticText* m_info; + wxStaticLine* m_staticline1; + wxStdDialogButtonSizer* m_sdbSizerStdButtons; + wxButton* m_sdbSizerStdButtonsOK; + wxButton* m_sdbSizerStdButtonsCancel; + + // Virtual event handlers, override them in your derived class + virtual void OnUpdateUI( wxUpdateUIEvent& event ) { event.Skip(); } + + + public: + + DIALOG_ASSIGN_NETCLASS_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Add Netclass Assignment"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxDEFAULT_DIALOG_STYLE ); + + ~DIALOG_ASSIGN_NETCLASS_BASE(); + +}; + diff --git a/eeschema/dialogs/dialog_field_properties.cpp b/eeschema/dialogs/dialog_field_properties.cpp index 8ffd584350..73cfe2d852 100644 --- a/eeschema/dialogs/dialog_field_properties.cpp +++ b/eeschema/dialogs/dialog_field_properties.cpp @@ -461,6 +461,8 @@ DIALOG_SCH_FIELD_PROPERTIES::DIALOG_SCH_FIELD_PROPERTIES( SCH_BASE_FRAME* aParen DIALOG_FIELD_PROPERTIES( aParent, aTitle, aField ), m_field( aField ) { + static KICAD_T labelTypes[] = { SCH_LABEL_LOCATE_ANY_T, EOT }; + m_isSheetFilename = false; if( aField->GetParent() && aField->GetParent()->Type() == SCH_SYMBOL_T ) @@ -488,6 +490,10 @@ DIALOG_SCH_FIELD_PROPERTIES::DIALOG_SCH_FIELD_PROPERTIES( SCH_BASE_FRAME* aParen break; } } + else if( aField->GetParent() && aField->GetParent()->IsType( labelTypes ) ) + { + m_fieldId = LABELUSERFIELD_V; + } // show text variable cross-references in a human-readable format m_text = aField->Schematic()->ConvertKIIDsToRefs( aField->GetText() ); @@ -496,14 +502,7 @@ DIALOG_SCH_FIELD_PROPERTIES::DIALOG_SCH_FIELD_PROPERTIES( SCH_BASE_FRAME* aParen m_isPower = false; - wxString translated_fieldname; - - if( m_field->GetId() < MANDATORY_FIELDS ) - translated_fieldname = TEMPLATE_FIELDNAME::GetDefaultFieldName( m_field->GetId(), DO_TRANSLATE ); - else - translated_fieldname = m_field->GetName(); - - m_textLabel->SetLabel( translated_fieldname + ":" ); + m_textLabel->SetLabel( aField->GetName() + ":" ); m_position = m_field->GetPosition(); diff --git a/eeschema/dialogs/dialog_schematic_setup.cpp b/eeschema/dialogs/dialog_schematic_setup.cpp index 3e3d9b8c7c..0cfa488fd1 100644 --- a/eeschema/dialogs/dialog_schematic_setup.cpp +++ b/eeschema/dialogs/dialog_schematic_setup.cpp @@ -1,7 +1,7 @@ /* * This program source code file is part of KiCad, a free EDA CAD application. * - * Copyright (C) 2020-2021 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2020-2022 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -60,7 +60,7 @@ DIALOG_SCHEMATIC_SETUP::DIALOG_SCHEMATIC_SETUP( SCH_EDIT_FRAME* aFrame ) : m_textVars = new PANEL_TEXT_VARIABLES( m_treebook, &Prj() ); - m_netclasses = new PANEL_SETUP_NETCLASSES( this, aFrame, &project.NetSettings().m_NetClasses, + m_netclasses = new PANEL_SETUP_NETCLASSES( this, aFrame, project.NetSettings(), schematic.GetNetClassAssignmentCandidates(), true ); /* @@ -152,7 +152,7 @@ void DIALOG_SCHEMATIC_SETUP::OnAuxiliaryAction( wxCommandEvent& event ) m_severities->ImportSettingsFrom( file.m_ErcSettings->m_Severities ); if( importDlg.m_NetClassesOpt->GetValue() ) - m_netclasses->ImportSettingsFrom( &file.m_NetSettings->m_NetClasses ); + m_netclasses->ImportSettingsFrom( file.m_NetSettings ); m_frame->GetSettingsManager()->UnloadProject( otherPrj, false ); } diff --git a/eeschema/eeschema_config.cpp b/eeschema/eeschema_config.cpp index 43ac0a0235..b898586f88 100644 --- a/eeschema/eeschema_config.cpp +++ b/eeschema/eeschema_config.cpp @@ -86,8 +86,6 @@ void SCH_EDIT_FRAME::ShowSchematicSetupDialog( const wxString& aInitialPage ) if( dlg.ShowQuasiModal() == wxID_OK ) { - Prj().GetProjectFile().NetSettings().RebuildNetClassAssignments(); - SaveProjectSettings(); Kiway().CommonSettingsChanged( false, true ); @@ -112,11 +110,11 @@ int SCH_EDIT_FRAME::GetSchematicJunctionSize() { std::vector& sizeMultipliers = eeconfig()->m_Drawing.junction_size_mult_list; - NETCLASSPTR defaultNetclass = Prj().GetProjectFile().NetSettings().m_NetClasses.GetDefault(); - int sizeChoice = Schematic().Settings().m_JunctionSizeChoice; - int junctionSize = defaultNetclass->GetWireWidth() * sizeMultipliers[ sizeChoice ]; + const std::shared_ptr& netSettings = Prj().GetProjectFile().NetSettings(); + int sizeChoice = Schematic().Settings().m_JunctionSizeChoice; + int dotSize = netSettings->m_DefaultNetClass->GetWireWidth() * sizeMultipliers[ sizeChoice ]; - return std::max( junctionSize, 1 ); + return std::max( dotSize, 1 ); } diff --git a/eeschema/erc_item.cpp b/eeschema/erc_item.cpp index a6ab57bf59..6fbb89a93e 100644 --- a/eeschema/erc_item.cpp +++ b/eeschema/erc_item.cpp @@ -110,6 +110,10 @@ ERC_ITEM ERC_ITEM::multipleNetNames( ERCE_DRIVER_CONFLICT, _( "More than one name given to this bus or net" ), wxT( "multiple_net_names" ) ); +ERC_ITEM ERC_ITEM::netclassConflict( ERCE_NETCLASS_CONFLICT, + _( "Conflicting netclass assignments" ), + wxT( "conflicting_netclasses" ) ); + ERC_ITEM ERC_ITEM::netNotBusMember( ERCE_BUS_ENTRY_CONFLICT, _( "Net is graphically connected to a bus but not a bus member" ), wxT( "net_not_bus_member" ) ); @@ -219,6 +223,7 @@ std::shared_ptr ERC_ITEM::Create( int aErrorCode ) case ERCE_BUS_LABEL_ERROR: return std::make_shared( busLabelSyntax ); case ERCE_BUS_TO_BUS_CONFLICT: return std::make_shared( busToBusConflict ); case ERCE_BUS_TO_NET_CONFLICT: return std::make_shared( busToNetConflict ); + case ERCE_NETCLASS_CONFLICT: return std::make_shared( netclassConflict ); case ERCE_GLOBLABEL: return std::make_shared( globalLabelDangling ); case ERCE_UNRESOLVED_VARIABLE: return std::make_shared( unresolvedVariable ); case ERCE_WIRE_DANGLING: return std::make_shared( wireDangling ); diff --git a/eeschema/erc_item.h b/eeschema/erc_item.h index 9ffcddd798..51c9187325 100644 --- a/eeschema/erc_item.h +++ b/eeschema/erc_item.h @@ -88,6 +88,7 @@ private: static ERC_ITEM differentUnitNet; static ERC_ITEM busDefinitionConflict; static ERC_ITEM multipleNetNames; + static ERC_ITEM netclassConflict; static ERC_ITEM netNotBusMember; static ERC_ITEM busLabelSyntax; static ERC_ITEM busToBusConflict; diff --git a/eeschema/erc_settings.h b/eeschema/erc_settings.h index 1fe1f55433..5fb6ec2541 100644 --- a/eeschema/erc_settings.h +++ b/eeschema/erc_settings.h @@ -61,6 +61,7 @@ enum ERCE_T ///< one net. ERCE_BUS_TO_NET_CONFLICT, ///< A bus wire is graphically connected to a net port/pin ///< (or vice versa). + ERCE_NETCLASS_CONFLICT, ///< Multiple labels assign different netclasses to same net. ERCE_GLOBLABEL, ///< A global label is unique. ERCE_UNRESOLVED_VARIABLE, ///< A text variable could not be resolved. ERCE_WIRE_DANGLING, ///< Some wires are not connected to anything else. diff --git a/eeschema/fields_grid_table.cpp b/eeschema/fields_grid_table.cpp index 27ec0db289..f3e51fe453 100644 --- a/eeschema/fields_grid_table.cpp +++ b/eeschema/fields_grid_table.cpp @@ -261,12 +261,13 @@ void FIELDS_GRID_TABLE::initGrid( WX_GRID* aGrid ) if( editFrame ) { // Load the combobox with existing existingNetclassNames - NET_SETTINGS& netSettings = editFrame->Schematic().Prj().GetProjectFile().NetSettings(); + PROJECT_FILE& projectFile = editFrame->Prj().GetProjectFile(); + const std::shared_ptr& settings = projectFile.NetSettings(); - existingNetclasses.push_back( netSettings.m_NetClasses.GetDefault()->GetName() ); + existingNetclasses.push_back( settings->m_DefaultNetClass->GetName() ); - for( const std::pair& pair : netSettings.m_NetClasses ) - existingNetclasses.push_back( pair.second->GetName() ); + for( const auto& [ name, netclass ] : settings->m_NetClasses ) + existingNetclasses.push_back( name ); } m_netclassAttr = new wxGridCellAttr; diff --git a/eeschema/sch_bus_entry.cpp b/eeschema/sch_bus_entry.cpp index af9f7d2f5a..fabe3881f3 100644 --- a/eeschema/sch_bus_entry.cpp +++ b/eeschema/sch_bus_entry.cpp @@ -176,16 +176,9 @@ const EDA_RECT SCH_BUS_ENTRY_BASE::GetBoundingBox() const COLOR4D SCH_BUS_ENTRY_BASE::GetBusEntryColor() const { if( m_stroke.GetColor() != COLOR4D::UNSPECIFIED ) - { m_lastResolvedColor = m_stroke.GetColor(); - } else if( IsConnectable() && !IsConnectivityDirty() ) - { - NETCLASSPTR netclass = NetClass(); - - if( netclass ) - m_lastResolvedColor = netclass->GetSchematicColor(); - } + m_lastResolvedColor = GetEffectiveNetClass()->GetSchematicColor(); return m_lastResolvedColor; } @@ -208,16 +201,9 @@ void SCH_BUS_ENTRY_BASE::SetBusEntryColor( const COLOR4D& aColor ) PLOT_DASH_TYPE SCH_BUS_ENTRY_BASE::GetLineStyle() const { if( m_stroke.GetPlotStyle() != PLOT_DASH_TYPE::DEFAULT ) - { m_lastResolvedLineStyle = m_stroke.GetPlotStyle(); - } else if( IsConnectable() && !IsConnectivityDirty() ) - { - NETCLASSPTR netclass = NetClass(); - - if( netclass ) - m_lastResolvedLineStyle = static_cast( netclass->GetLineStyle() ); - } + m_lastResolvedLineStyle = (PLOT_DASH_TYPE) GetEffectiveNetClass()->GetLineStyle(); return m_lastResolvedLineStyle; } @@ -233,16 +219,9 @@ void SCH_BUS_ENTRY_BASE::SetLineStyle( PLOT_DASH_TYPE aStyle ) int SCH_BUS_WIRE_ENTRY::GetPenWidth() const { if( m_stroke.GetWidth() > 0 ) - { m_lastResolvedWidth = m_stroke.GetWidth(); - } else if( IsConnectable() && !IsConnectivityDirty() ) - { - NETCLASSPTR netclass = NetClass(); - - if( netclass ) - m_lastResolvedWidth = netclass->GetWireWidth(); - } + m_lastResolvedWidth = GetEffectiveNetClass()->GetWireWidth(); return m_lastResolvedWidth; } @@ -251,16 +230,9 @@ int SCH_BUS_WIRE_ENTRY::GetPenWidth() const int SCH_BUS_BUS_ENTRY::GetPenWidth() const { if( m_stroke.GetWidth() > 0 ) - { m_lastResolvedWidth = m_stroke.GetWidth(); - } else if( IsConnectable() && !IsConnectivityDirty() ) - { - NETCLASSPTR netclass = NetClass(); - - if( netclass ) - m_lastResolvedWidth = netclass->GetBusWidth(); - } + m_lastResolvedWidth = GetEffectiveNetClass()->GetBusWidth(); return m_lastResolvedWidth; } @@ -538,16 +510,7 @@ void SCH_BUS_ENTRY_BASE::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, conn->AppendInfoToMsgPanel( aList ); if( !conn->IsBus() ) - { - NET_SETTINGS& netSettings = Schematic()->Prj().GetProjectFile().NetSettings(); - wxString netname = conn->Name(); - wxString netclassName = netSettings.m_NetClasses.GetDefaultPtr()->GetName(); - - if( netSettings.m_NetClassAssignments.count( netname ) ) - netclassName = netSettings.m_NetClassAssignments[ netname ]; - - aList.emplace_back( _( "Assigned Netclass" ), netclassName ); - } + aList.emplace_back( _( "Resolved Netclass" ), GetEffectiveNetClass()->GetName() ); } } diff --git a/eeschema/sch_edit_frame.cpp b/eeschema/sch_edit_frame.cpp index ff8276c79d..cbb397e4f7 100644 --- a/eeschema/sch_edit_frame.cpp +++ b/eeschema/sch_edit_frame.cpp @@ -1271,56 +1271,6 @@ bool SCH_EDIT_FRAME::isAutoSaveRequired() const } -static void inheritNetclass( const SCH_SHEET_PATH& aSheetPath, SCH_LABEL_BASE* aItem ) -{ - if( CONNECTION_SUBGRAPH::GetDriverPriority( aItem ) == CONNECTION_SUBGRAPH::PRIORITY::NONE ) - return; - - // Netclasses are assigned to subgraphs by association with their netname. However, when - // a new label is attached to an existing subgraph (with an existing netclass association), - // the association will be lost as the label will drive its name on to the graph. - // - // Here we find the previous driver of the subgraph and if it had a netclass we associate - // the new netname with that netclass as well. - // - SCHEMATIC* schematic = aItem->Schematic(); - CONNECTION_SUBGRAPH* subgraph = schematic->ConnectionGraph()->GetSubgraphForItem( aItem ); - - std::map& netclassAssignments = - schematic->Prj().GetProjectFile().NetSettings().m_NetClassAssignments; - - if( subgraph ) - { - SCH_ITEM* previousDriver = nullptr; - CONNECTION_SUBGRAPH::PRIORITY priority = CONNECTION_SUBGRAPH::PRIORITY::INVALID; - - for( SCH_ITEM* item : subgraph->m_drivers ) - { - if( item == aItem ) - continue; - - CONNECTION_SUBGRAPH::PRIORITY p = CONNECTION_SUBGRAPH::GetDriverPriority( item ); - - if( p > priority ) - { - priority = p; - previousDriver = item; - } - } - - if( previousDriver ) - { - wxString path = aSheetPath.PathHumanReadable(); - wxString oldDrivenName = path + subgraph->GetNameForDriver( previousDriver ); - wxString drivenName = path + subgraph->GetNameForDriver( aItem ); - - if( netclassAssignments.count( oldDrivenName ) ) - netclassAssignments[ drivenName ] = netclassAssignments[ oldDrivenName ]; - } - } -} - - void SCH_EDIT_FRAME::AddItemToScreenAndUndoList( SCH_SCREEN* aScreen, SCH_ITEM* aItem, bool aUndoAppend ) { @@ -1376,12 +1326,7 @@ void SCH_EDIT_FRAME::AddItemToScreenAndUndoList( SCH_SCREEN* aScreen, SCH_ITEM* // Update connectivity info for new item if( !aItem->IsMoving() ) - { RecalculateConnections( LOCAL_CLEANUP ); - - if( SCH_LABEL_BASE* label = dynamic_cast( aItem ) ) - inheritNetclass( GetCurrentSheet(), label ); - } } aItem->ClearFlags( IS_NEW ); diff --git a/eeschema/sch_item.cpp b/eeschema/sch_item.cpp index bcc553cac3..f2c6a25f0f 100644 --- a/eeschema/sch_item.cpp +++ b/eeschema/sch_item.cpp @@ -163,22 +163,24 @@ SCH_CONNECTION* SCH_ITEM::Connection( const SCH_SHEET_PATH* aSheet ) const } -NETCLASSPTR SCH_ITEM::NetClass( const SCH_SHEET_PATH* aSheet ) const +std::shared_ptr SCH_ITEM::GetEffectiveNetClass( const SCH_SHEET_PATH* aSheet ) const { - if( m_connection_map.size() ) + static std::shared_ptr nullNetclass = std::make_shared( wxEmptyString ); + + SCHEMATIC* schematic = Schematic(); + + if( schematic ) { - SCH_CONNECTION* connection = Connection( aSheet ); + std::shared_ptr& netSettings = schematic->Prj().GetProjectFile().m_NetSettings; + SCH_CONNECTION* connection = Connection( aSheet ); if( connection ) - { - NET_SETTINGS& netSettings = Schematic()->Prj().GetProjectFile().NetSettings(); - const wxString& netclassName = netSettings.GetNetclassName( connection->Name() ); - - return netSettings.m_NetClasses.Find( netclassName ); - } + return netSettings->GetEffectiveNetClass( connection->Name() ); + else + return netSettings->m_DefaultNetClass; } - return nullptr; + return nullNetclass; } diff --git a/eeschema/sch_item.h b/eeschema/sch_item.h index d2e5ceee49..8ff242ed61 100644 --- a/eeschema/sch_item.h +++ b/eeschema/sch_item.h @@ -405,7 +405,7 @@ public: virtual void SetLastResolvedState( const SCH_ITEM* aItem ) { } - NETCLASSPTR NetClass( const SCH_SHEET_PATH* aSheet = nullptr ) const; + std::shared_ptr GetEffectiveNetClass( const SCH_SHEET_PATH* aSheet = nullptr ) const; /** * Return whether the fields have been automatically placed. diff --git a/eeschema/sch_junction.cpp b/eeschema/sch_junction.cpp index 8547e32043..44af91e3da 100644 --- a/eeschema/sch_junction.cpp +++ b/eeschema/sch_junction.cpp @@ -91,13 +91,8 @@ SHAPE_CIRCLE SCH_JUNCTION::getEffectiveShape() const // connected wire width: if( !IsConnectivityDirty() ) { - NETCLASSPTR netclass = NetClass(); - - if( netclass ) - { - m_lastResolvedDiameter = std::max( m_lastResolvedDiameter, - KiROUND( netclass->GetWireWidth() * 1.7 ) ); - } + m_lastResolvedDiameter = std::max( m_lastResolvedDiameter, + GetEffectiveNetClass()->GetWireWidth() * 1.7 ); } } @@ -183,16 +178,9 @@ void SCH_JUNCTION::SetDiameter( int aDiameter ) COLOR4D SCH_JUNCTION::GetJunctionColor() const { if( m_color != COLOR4D::UNSPECIFIED ) - { m_lastResolvedColor = m_color; - } else if( !IsConnectivityDirty() ) - { - NETCLASSPTR netclass = NetClass(); - - if( netclass ) - m_lastResolvedColor = netclass->GetSchematicColor(); - } + m_lastResolvedColor = GetEffectiveNetClass()->GetSchematicColor(); return m_lastResolvedColor; } diff --git a/eeschema/sch_label.cpp b/eeschema/sch_label.cpp index 691ad99b25..adc5e6cacd 100644 --- a/eeschema/sch_label.cpp +++ b/eeschema/sch_label.cpp @@ -472,11 +472,10 @@ bool SCH_LABEL_BASE::ResolveTextVar( wxString* token, int aDepth ) const if( connection ) { - NET_SETTINGS& netSettings = Schematic()->Prj().GetProjectFile().NetSettings(); - *token = netSettings.m_NetClasses.GetDefaultPtr()->GetName(); + PROJECT_FILE& projectFile = Schematic()->Prj().GetProjectFile(); + std::shared_ptr& netSettings = projectFile.NetSettings(); - if( netSettings.m_NetClassAssignments.count( connection->Name() ) ) - *token = netSettings.m_NetClassAssignments[ connection->Name() ]; + *token = UnescapeString( netSettings->GetEffectiveNetClass( connection->Name() )->GetName() ); } return true; @@ -842,14 +841,8 @@ void SCH_LABEL_BASE::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vectorIsBus() ) { - NET_SETTINGS& netSettings = Schematic()->Prj().GetProjectFile().NetSettings(); - const wxString& netname = conn->Name( true ); - - if( netSettings.m_NetClassAssignments.count( netname ) ) - { - const wxString& netclassName = netSettings.m_NetClassAssignments[ netname ]; - aList.emplace_back( _( "Assigned Netclass" ), netclassName ); - } + aList.emplace_back( _( "Resolved Netclass" ), + UnescapeString( GetEffectiveNetClass()->GetName() ) ); } } } @@ -1140,7 +1133,16 @@ void SCH_DIRECTIVE_LABEL::AutoplaceFields( SCH_SCREEN* aScreen, bool aManual ) wxString SCH_DIRECTIVE_LABEL::GetSelectMenuText( EDA_UNITS aUnits ) const { - return wxString::Format( _( "Directive Label" ), ShortenedShownText() ); + if( m_fields.empty() ) + { + return _( "Directive Label" ); + } + else + { + return wxString::Format( _( "Directive Label [%s %s]" ), + m_fields[0].GetName(), + m_fields[0].GetShownText() ); + } } diff --git a/eeschema/sch_line.cpp b/eeschema/sch_line.cpp index 2afbfef765..2124d9b1c6 100644 --- a/eeschema/sch_line.cpp +++ b/eeschema/sch_line.cpp @@ -23,6 +23,7 @@ */ #include +#include #include #include #include @@ -236,23 +237,11 @@ void SCH_LINE::SetLineColor( const double r, const double g, const double b, con COLOR4D SCH_LINE::GetLineColor() const { if( m_stroke.GetColor() != COLOR4D::UNSPECIFIED ) - { m_lastResolvedColor = m_stroke.GetColor(); - } - else if( IsConnectable() ) - { - if( !IsConnectivityDirty() ) - { - NETCLASSPTR netclass = NetClass(); - - if( netclass ) - m_lastResolvedColor = netclass->GetSchematicColor(); - } - } - else - { + else if( !IsConnectable() ) m_lastResolvedColor = COLOR4D::UNSPECIFIED; - } + else if( !IsConnectivityDirty() ) + m_lastResolvedColor = GetEffectiveNetClass()->GetSchematicColor(); return m_lastResolvedColor; } @@ -283,23 +272,11 @@ PLOT_DASH_TYPE SCH_LINE::GetLineStyle() const PLOT_DASH_TYPE SCH_LINE::GetEffectiveLineStyle() const { if( m_stroke.GetPlotStyle() != PLOT_DASH_TYPE::DEFAULT ) - { m_lastResolvedLineStyle = m_stroke.GetPlotStyle(); - } - else if( IsConnectable() ) - { - if( !IsConnectivityDirty() ) - { - NETCLASSPTR netclass = NetClass(); - - if( netclass ) - m_lastResolvedLineStyle = static_cast( netclass->GetLineStyle() ); - } - } - else - { + else if( !IsConnectable() ) m_lastResolvedLineStyle = PLOT_DASH_TYPE::SOLID; - } + else if( !IsConnectivityDirty() ) + m_lastResolvedLineStyle = (PLOT_DASH_TYPE) GetEffectiveNetClass()->GetLineStyle(); return m_lastResolvedLineStyle; } @@ -315,7 +292,6 @@ void SCH_LINE::SetLineWidth( const int aSize ) int SCH_LINE::GetPenWidth() const { SCHEMATIC* schematic = Schematic(); - NETCLASSPTR netclass; switch ( m_layer ) { @@ -330,37 +306,17 @@ int SCH_LINE::GetPenWidth() const case LAYER_WIRE: if( m_stroke.GetWidth() > 0 ) - { m_lastResolvedWidth = m_stroke.GetWidth(); - } else if( !IsConnectivityDirty() ) - { - netclass = NetClass(); - - if( !netclass && schematic ) - netclass = schematic->Prj().GetProjectFile().NetSettings().m_NetClasses.GetDefault(); - - if( netclass ) - m_lastResolvedWidth = netclass->GetWireWidth(); - } + m_lastResolvedWidth = GetEffectiveNetClass()->GetWireWidth(); return m_lastResolvedWidth; case LAYER_BUS: if( m_stroke.GetWidth() > 0 ) - { m_lastResolvedWidth = m_stroke.GetWidth(); - } else if( !IsConnectivityDirty() ) - { - netclass = NetClass(); - - if( !netclass && schematic ) - netclass = schematic->Prj().GetProjectFile().NetSettings().m_NetClasses.GetDefault(); - - if( netclass ) - m_lastResolvedWidth = netclass->GetBusWidth(); - } + m_lastResolvedWidth = GetEffectiveNetClass()->GetBusWidth(); return m_lastResolvedWidth; } @@ -922,14 +878,8 @@ void SCH_LINE::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vectorIsBus() ) { - NET_SETTINGS& netSettings = Schematic()->Prj().GetProjectFile().NetSettings(); - wxString netname = conn->Name(); - wxString netclassName = netSettings.m_NetClasses.GetDefaultPtr()->GetName(); - - if( netSettings.m_NetClassAssignments.count( netname ) ) - netclassName = netSettings.m_NetClassAssignments[ netname ]; - - aList.emplace_back( _( "Assigned Netclass" ), netclassName ); + aList.emplace_back( _( "Resolved Netclass" ), + UnescapeString( GetEffectiveNetClass()->GetName() ) ); } } } diff --git a/eeschema/sch_validators.h b/eeschema/sch_validators.h index e012be8509..30dbab04e6 100644 --- a/eeschema/sch_validators.h +++ b/eeschema/sch_validators.h @@ -40,6 +40,8 @@ #define SHEETFILENAME_V 101 // overlap with REFERENCE_FIELD and VALUE_FIELD #define SHEETUSERFIELD_V 102 +#define LABELUSERFIELD_V 200 + /** * A text control validator used for validating the text allowed in library and * schematic symbol fields. diff --git a/eeschema/tools/sch_editor_control.cpp b/eeschema/tools/sch_editor_control.cpp index 643365d977..16666de18b 100644 --- a/eeschema/tools/sch_editor_control.cpp +++ b/eeschema/tools/sch_editor_control.cpp @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -1152,53 +1153,9 @@ int SCH_EDITOR_CONTROL::AssignNetclass( const TOOL_EVENT& aEvent ) netNames.Add( conn->Name() ); } - NET_SETTINGS& netSettings = m_frame->Schematic().Prj().GetProjectFile().NetSettings(); - wxString netclassName = netSettings.GetNetclassName( netNames.front() ); + DIALOG_ASSIGN_NETCLASS dlg( m_frame, netNames.front() ); - wxArrayString headers; - std::vector items; - - headers.Add( _( "Netclasses" ) ); - - wxArrayString defaultItem; - defaultItem.Add( _( "Default" ) ); - items.emplace_back( defaultItem ); - - for( const std::pair& ii : netSettings.m_NetClasses ) - { - wxArrayString item; - item.Add( ii.first ); - items.emplace_back( item ); - } - - EDA_LIST_DIALOG dlg( m_frame, _( "Assign Netclass" ), headers, items, netclassName ); - dlg.SetListLabel( _( "Select netclass:" ) ); - - if( dlg.ShowModal() == wxID_OK ) - { - netclassName = dlg.GetTextSelection(); - - for( const wxString& netName : netNames ) - { - // Remove from old netclass membership list - if( netSettings.m_NetClassAssignments.count( netName ) ) - { - const wxString oldNetclassName = netSettings.m_NetClassAssignments[netName]; - NETCLASSPTR oldNetclass = netSettings.m_NetClasses.Find( oldNetclassName ); - - if( oldNetclass ) - oldNetclass->Remove( netName ); - } - - // Add to new netclass membership list - NETCLASSPTR newNetclass = netSettings.m_NetClasses.Find( netclassName ); - - if( newNetclass ) - newNetclass->Add( netName ); - - netSettings.m_NetClassAssignments[netName] = netclassName; - } - } + dlg.ShowModal(); } highlightNet( m_toolMgr, CLEAR ); diff --git a/include/board_design_settings.h b/include/board_design_settings.h index 46c65edaa5..895f03199f 100644 --- a/include/board_design_settings.h +++ b/include/board_design_settings.h @@ -2,7 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2009-2019 Jean-Pierre Charras, jp.charras at wanadoo.fr - * Copyright (C) 1992-2021 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -28,6 +28,7 @@ #include #include +#include #include #include #include @@ -245,19 +246,6 @@ public: */ bool Ignore( int aDRCErrorCode ); - NETCLASSES& GetNetClasses() const - { - return *m_netClasses; - } - - void SetNetClasses( NETCLASSES* aNetClasses ) - { - if( aNetClasses ) - m_netClasses = aNetClasses; - else - m_netClasses = &m_internalNetClasses; - } - ZONE_SETTINGS& GetDefaultZoneSettings() { return m_defaultZoneSettings; @@ -268,14 +256,6 @@ public: m_defaultZoneSettings = aSettings; } - /** - * @return the default netclass. - */ - inline NETCLASS* GetDefault() const - { - return GetNetClasses().GetDefaultPtr(); - } - /** * @return the current net class name. */ @@ -318,16 +298,6 @@ public: */ int GetSmallestClearanceValue() const; - /** - * @return the current micro via size that is the current netclass value. - */ - int GetCurrentMicroViaSize(); - - /** - * @return the current micro via drill that is the current netclass value. - */ - int GetCurrentMicroViaDrill(); - /** * @return the current track width list index. */ @@ -719,8 +689,10 @@ public: double m_SolderPasteMarginRatio; // Solder mask margin ratio value of pad size // The final margin is the sum of these 2 values + std::shared_ptr m_NetSettings; + // Variables used in footprint editing (default value in item/footprint creation) - std::vector m_DefaultFPTextItems; + std::vector m_DefaultFPTextItems; // Arrays of default values for the various layer classes. int m_LineThickness[ LAYER_CLASS_COUNT ]; @@ -786,12 +758,6 @@ private: */ BOARD_STACKUP m_stackup; - /// Net classes that are loaded from the board file before these were stored in the project - NETCLASSES m_internalNetClasses; - - /// This will point to m_internalNetClasses until it is repointed to the project after load - NETCLASSES* m_netClasses; - /// The default settings that will be used for new zones ZONE_SETTINGS m_defaultZoneSettings; }; diff --git a/include/dialogs/panel_setup_netclasses.h b/include/dialogs/panel_setup_netclasses.h index f27f677703..4c53e39fe5 100644 --- a/include/dialogs/panel_setup_netclasses.h +++ b/include/dialogs/panel_setup_netclasses.h @@ -29,13 +29,14 @@ #include #include -class NETCLASSES; +class NET_SETTINGS; class PANEL_SETUP_NETCLASSES : public PANEL_SETUP_NETCLASSES_BASE { public: - PANEL_SETUP_NETCLASSES( PAGED_DIALOG* aParent, EDA_DRAW_FRAME* aFrame, NETCLASSES* aNetclasses, + PANEL_SETUP_NETCLASSES( PAGED_DIALOG* aParent, EDA_DRAW_FRAME* aFrame, + std::shared_ptr aSettings, const std::vector& aNetNames, bool isEEschema ); ~PANEL_SETUP_NETCLASSES( ) override; @@ -44,21 +45,18 @@ public: bool Validate() override; - void ImportSettingsFrom( NETCLASSES* aBoard ); + void ImportSettingsFrom( const std::shared_ptr& aNetSettings ); private: void OnAddNetclassClick( wxCommandEvent& event ) override; void OnRemoveNetclassClick( wxCommandEvent& event ) override; void OnSizeNetclassGrid( wxSizeEvent& event ) override; - void OnSizeMembershipGrid( wxSizeEvent& event ) override; - void onmembershipPanelSize( wxSizeEvent& event ) override; + void OnSizeAssignmentGrid( wxSizeEvent& event ) override; + void OnAddAssignmentClick( wxCommandEvent& event ) override; + void OnRemoveAssignmentClick( wxCommandEvent& event ) override; void OnUpdateUI( wxUpdateUIEvent &event ) override; void OnNetclassGridCellChanging( wxGridEvent& event ); void OnNetclassGridMouseEvent( wxMouseEvent& event ); - void OnShowAll( wxCommandEvent& event ) override { doApplyFilters( true ); } - void OnApplyFilters( wxCommandEvent& event ) override { doApplyFilters( false ); } - void OnAssignAll( wxCommandEvent& event ) override { doAssignments( true ); } - void OnAssignSelected( wxCommandEvent& event ) override { doAssignments( false ); } void onUnitsChanged( wxCommandEvent& aEvent ); @@ -66,22 +64,20 @@ private: void rebuildNetclassDropdowns(); - void addNet( const wxString& netName, const wxString& netclass, bool aStale ); - void doApplyFilters( bool aShowAll ); - void doAssignments( bool aAssignAll ); - void AdjustNetclassGridColumns( int aWidth ); - void AdjustMembershipGridColumns( int aWidth ); + void AdjustAssignmentGridColumns( int aWidth ); - EDA_DRAW_FRAME* m_frame; - PAGED_DIALOG* m_parent; - bool m_isEEschema; - NETCLASSES* m_netclasses; - std::vector m_netNames; +private: + EDA_DRAW_FRAME* m_frame; + PAGED_DIALOG* m_parent; + bool m_isEEschema; + std::shared_ptr m_netSettings; + std::vector m_netNames; int* m_originalColWidths; bool m_netclassesDirty; // The netclass drop-down menus need rebuilding int m_hoveredCol; // Column being hovered over, for tooltips + wxString m_lastPattern; }; #endif //PANEL_SETUP_NETCLASSES_H diff --git a/include/mail_type.h b/include/mail_type.h index 2cfeb3e0ba..193b4f0d19 100644 --- a/include/mail_type.h +++ b/include/mail_type.h @@ -50,8 +50,6 @@ enum MAIL_T MAIL_PCB_GET_NETLIST, // Fetch a netlist from PCB layout MAIL_PCB_UPDATE_LINKS, // Update the schematic symbol paths in the PCB's footprints 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/netclass.h b/include/netclass.h index 7d1bd01353..3e4cf54107 100644 --- a/include/netclass.h +++ b/include/netclass.h @@ -3,7 +3,7 @@ * * Copyright (C) 2009 SoftPLC Corporation, Dick Hollenbeck * Copyright (C) 2009 Jean-Pierre Charras, jean-pierre.charras@inpg.fr - * Copyright (C) 2009-2020 KiCad Developers, see change_log.txt for contributors. + * Copyright (C) 2009-2022 KiCad Developers, see change_log.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -65,58 +65,6 @@ public: const wxString GetName() const { return m_Name; } void SetName( const wxString& aName ) { m_Name = aName; } - /** - * Return the number of nets in this NETCLASS, i.e. using these rules. - */ - unsigned GetCount() const - { - return m_Members.size(); - } - - /** - * Empties the collection of members. - */ - void Clear() - { - m_Members.clear(); - } - - /** - * Adds \a aNetname to this NETCLASS if it is not already in this NETCLASS. - * - * It is harmless to try and add a second identical name. - */ - void Add( const wxString& aNetname ) - { - m_Members.insert( aNetname ); - } - - typedef STRINGSET::iterator iterator; - iterator begin() { return m_Members.begin(); } - iterator end() { return m_Members.end(); } - - typedef STRINGSET::const_iterator const_iterator; - const_iterator begin() const { return m_Members.begin(); } - const_iterator end() const { return m_Members.end(); } - - /** - * Remove NET \a aName from the collection of members. - */ - void Remove( iterator aName ) - { - m_Members.erase( aName ); - } - - /** - * Remove NET \a aName from the collection of members. - */ - void Remove( const wxString& aName ) - { - m_Members.erase( aName ); - } - - STRINGSET& NetNames() { return m_Members; } ///< for SWIG - const wxString& GetDescription() const { return m_Description; } void SetDescription( const wxString& aDesc ) { m_Description = aDesc; } @@ -171,16 +119,10 @@ public: int GetLineStyle() const { return m_lineStyle; } void SetLineStyle( int aStyle ) { m_lineStyle = aStyle; } -#if defined(DEBUG) - void Show( int nestLevel, std::ostream& os ) const; -#endif - protected: wxString m_Name; ///< Name of the net class wxString m_Description; ///< what this NETCLASS is for. - STRINGSET m_Members; ///< names of NET members of this class - /// The units on these parameters is Internal Units (1 nm) OPT m_Clearance; ///< clearance when routing @@ -205,93 +147,5 @@ protected: }; -DECL_SPTR_FOR_SWIG( NETCLASSPTR, NETCLASS ) -DECL_MAP_FOR_SWIG( NETCLASS_MAP, wxString, NETCLASSPTR ) - - -/** - * A container for NETCLASS instances. - * - * It owns all its NETCLASSes. This container will always have a default NETCLASS with the - * name given by const NETCLASS::Default. - */ -class NETCLASSES -{ -public: - NETCLASSES(); - ~NETCLASSES(); - - /** - * Destroy any contained NETCLASS instances except the default one, and clears any - * members from the default one. - */ - void Clear() - { - m_NetClasses.clear(); - m_default->Clear(); - } - - typedef NETCLASS_MAP::iterator iterator; - iterator begin() { return m_NetClasses.begin(); } - iterator end() { return m_NetClasses.end(); } - - typedef NETCLASS_MAP::const_iterator const_iterator; - const_iterator begin() const { return m_NetClasses.begin(); } - const_iterator end() const { return m_NetClasses.end(); } - - /** - * @return the number of netclasses excluding the default one. - */ - unsigned GetCount() const - { - return m_NetClasses.size(); - } - - /** - * @return the default net class. - */ - NETCLASSPTR GetDefault() const - { - return m_default; - } - - NETCLASS* GetDefaultPtr() const - { - return m_default.get(); - } - - /** - * Add \a aNetclass and puts it into this NETCLASSES container. - * - * @param aNetclass is netclass to add - * @return true if the name within aNetclass is unique and it could be inserted OK, - * else false because the name was not unique. - */ - bool Add( const NETCLASSPTR& aNetclass ); - - /** - * Remove a #NETCLASS from this container but does not destroy/delete it. - * - * @param aNetName is the name of the net to delete, and it may not be NETCLASS::Default. - * @return a pointer to the #NETCLASS associated with \a aNetName if found and removed, - * else NULL. - */ - NETCLASSPTR Remove( const wxString& aNetName ); - - /** - * Search this container for a NETCLASS given by \a aName. - * - * @param aName is the name of the #NETCLASS to search for. - * @return a pointer to the #NETCLASS if found, else NULL. - */ - NETCLASSPTR Find( const wxString& aName ) const; - - /// Provide public access to m_NetClasses so it gets swigged. - NETCLASS_MAP& NetClasses() { return m_NetClasses; } - -private: - NETCLASS_MAP m_NetClasses; // All the netclasses EXCEPT the default one - NETCLASSPTR m_default; -}; #endif // CLASS_NETCLASS_H diff --git a/include/project/net_settings.h b/include/project/net_settings.h index 4200ddcf9d..b7d7cee379 100644 --- a/include/project/net_settings.h +++ b/include/project/net_settings.h @@ -2,7 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2020 CERN - * Copyright (C) 2021 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2021-2022 KiCad Developers, see AUTHORS.txt for contributors. * @author Jon Evans * * This program is free software: you can redistribute it and/or modify it @@ -24,6 +24,7 @@ #include #include +#include /** * NET_SETTINGS stores various net-related settings in a project context. These settings are @@ -37,11 +38,13 @@ public: virtual ~NET_SETTINGS(); public: - NETCLASSES m_NetClasses; + std::map> m_NetClasses; + std::shared_ptr m_DefaultNetClass; - // 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; + std::vector, wxString>> + m_NetClassPatternAssignments; + + std::map m_NetClassLabelAssignments; /** * A map of fully-qualified net names to colors used in the board context. @@ -49,10 +52,10 @@ public: * Only nets that the user has assigned custom colors to will be in this list. * Nets that no longer exist will be deleted during a netlist read in Pcbnew. */ - std::map m_PcbNetColors; + std::map m_NetColorAssignments; public: - const wxString& GetNetclassName( const wxString& aNetName ) const; + std::shared_ptr GetEffectiveNetClass( const wxString& aNetName ) const; /** * Parse a bus vector (e.g. A[7..0]) into name, begin, and end. @@ -78,13 +81,9 @@ public: static bool ParseBusGroup( const wxString& aGroup, wxString* name, std::vector* aMemberList ); - /** - * Rebuild netclass assignments from the netclass membership lists. - */ - void RebuildNetClassAssignments(); - private: bool migrateSchema0to1(); + bool migrateSchema2to3(); // TODO: Add diff pairs, bus information, etc. }; diff --git a/include/project/project_file.h b/include/project/project_file.h index 9269ec14e9..2d52a42225 100644 --- a/include/project/project_file.h +++ b/include/project/project_file.h @@ -93,9 +93,9 @@ public: return m_boards; } - NET_SETTINGS& NetSettings() + std::shared_ptr& NetSettings() { - return *m_NetSettings; + return m_NetSettings; } protected: diff --git a/pcbnew/board.cpp b/pcbnew/board.cpp index 83122f2881..5b75188886 100644 --- a/pcbnew/board.cpp +++ b/pcbnew/board.cpp @@ -105,8 +105,8 @@ BOARD::BOARD() : BOARD_DESIGN_SETTINGS& bds = GetDesignSettings(); // Initialize default netclass. - NETCLASS* defaultClass = bds.GetDefault(); - defaultClass->SetDescription( _( "This is the default net class." ) ); + bds.m_NetSettings->m_DefaultNetClass = std::make_shared( NETCLASS::Default ); + bds.m_NetSettings->m_DefaultNetClass->SetDescription( _( "This is the default net class." ) ); bds.UseCustomTrackViaSize( false ); @@ -181,10 +181,14 @@ void BOARD::SetProject( PROJECT* aProject ) // list at this point. If we loaded anything into it from a legacy board file then we // want to transfer it over to the project netclasses list. if( m_LegacyNetclassesLoaded ) - project.NetSettings().m_NetClasses = GetDesignSettings().GetNetClasses(); + { + std::shared_ptr legacySettings = GetDesignSettings().m_NetSettings; + project.NetSettings()->m_DefaultNetClass = legacySettings->m_DefaultNetClass; + project.NetSettings()->m_NetClasses = legacySettings->m_NetClasses; + } // Now update the DesignSettings' netclass pointer to point into the project. - GetDesignSettings().SetNetClasses( &project.NetSettings().m_NetClasses ); + GetDesignSettings().m_NetSettings = project.NetSettings(); } } @@ -1500,19 +1504,11 @@ void BOARD::SynchronizeNetsAndNetClasses() if( !m_project ) return; - NET_SETTINGS* netSettings = m_project->GetProjectFile().m_NetSettings.get(); - NETCLASSES& netClasses = netSettings->m_NetClasses; - NETCLASSPTR defaultNetClass = netClasses.GetDefault(); + BOARD_DESIGN_SETTINGS& bds = GetDesignSettings(); + std::shared_ptr& defaultNetClass = bds.m_NetSettings->m_DefaultNetClass; for( NETINFO_ITEM* net : m_NetInfo ) - { - const wxString& netname = net->GetNetname(); - const wxString& netclassName = netSettings->GetNetclassName( netname ); - - net->SetNetClass( netClasses.Find( netclassName ) ); - } - - BOARD_DESIGN_SETTINGS& bds = GetDesignSettings(); + net->SetNetClass( bds.m_NetSettings->GetEffectiveNetClass( net->GetNetname() ) ); // Set initial values for custom track width & via size to match the default // netclass settings diff --git a/pcbnew/board_connected_item.cpp b/pcbnew/board_connected_item.cpp index 835ff6551c..363edcda97 100644 --- a/pcbnew/board_connected_item.cpp +++ b/pcbnew/board_connected_item.cpp @@ -3,7 +3,7 @@ * * Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck - * Copyright (C) 1992-2021 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -63,17 +63,6 @@ bool BOARD_CONNECTED_ITEM::SetNetCode( int aNetCode, bool aNoAssert ) } -NETCLASS* BOARD_CONNECTED_ITEM::GetEffectiveNetclass() const -{ - // NB: we must check the net first, as when it is 0 GetNetClass() will return the - // orphaned net netclass, not the default netclass. - if( !m_netinfo || m_netinfo->GetNetCode() == 0 ) - return GetBoard()->GetDesignSettings().GetDefault(); - else - return GetNetClass(); -} - - int BOARD_CONNECTED_ITEM::GetOwnClearance( PCB_LAYER_ID aLayer, wxString* aSource ) const { DRC_CONSTRAINT constraint; @@ -105,21 +94,18 @@ int BOARD_CONNECTED_ITEM::GetNetCode() const // Note: do NOT return a std::shared_ptr from this. It is used heavily in DRC, and the // std::shared_ptr stuff shows up large in performance profiling. -NETCLASS* BOARD_CONNECTED_ITEM::GetNetClass() const +NETCLASS* BOARD_CONNECTED_ITEM::GetEffectiveNetClass() const { if( m_netinfo && m_netinfo->GetNetClass() ) return m_netinfo->GetNetClass(); else - return GetBoard()->GetDesignSettings().GetDefault(); + return GetBoard()->GetDesignSettings().m_NetSettings->m_DefaultNetClass.get(); } wxString BOARD_CONNECTED_ITEM::GetNetClassName() const { - if( m_netinfo ) - return m_netinfo->GetNetClassName(); - else - return wxEmptyString; + return GetEffectiveNetClass()->GetName(); } diff --git a/pcbnew/board_connected_item.h b/pcbnew/board_connected_item.h index ac92448116..5c6d193d86 100644 --- a/pcbnew/board_connected_item.h +++ b/pcbnew/board_connected_item.h @@ -3,7 +3,7 @@ * * Copyright (C) 2012 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck - * Copyright (C) 1992-2021 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -156,25 +156,12 @@ public: * @note Do **not** return a std::shared_ptr from this. It is used heavily in DRC, and the * std::shared_ptr stuff shows up large in performance profiling. */ - virtual NETCLASS* GetNetClass() const; + virtual NETCLASS* GetEffectiveNetClass() const; /** - * Return the NETCLASS for this item, or the default netclass if none is defined. - * - * @note Do **not** return a std::shared_ptr from this. It is used heavily in DRC, and the - * std::shared_ptr stuff shows up large in performance profiling. + * Returns the name of the effective netclass. Primarily for the use of the property system. */ - virtual NETCLASS* GetEffectiveNetclass() const; - - /** - * Returns the netclass of the zone. - * - * If the net is not found (can happen when a netlist is reread) and the net name does not - * exist, return the default net class (should not return a null pointer). - * - * @return the net class name of this item. - */ - virtual wxString GetNetClassName() const; + wxString GetNetClassName() const; void SetLocalRatsnestVisible( bool aVisible ) { diff --git a/pcbnew/board_design_settings.cpp b/pcbnew/board_design_settings.cpp index 7c8c23aa5a..8343f51481 100644 --- a/pcbnew/board_design_settings.cpp +++ b/pcbnew/board_design_settings.cpp @@ -33,7 +33,6 @@ #include #include #include -#include #include const int bdsSchemaVersion = 2; @@ -46,11 +45,11 @@ BOARD_DESIGN_SETTINGS::BOARD_DESIGN_SETTINGS( JSON_SETTINGS* aParent, const std: // initialized by the board file parser before NESTED_SETTINGS::LoadFromFile is called. m_resetParamsIfMissing = false; - // Create a default NETCLASS list so that things don't break horribly if there's no project + // Create a default NET_SETTINGS so that things don't break horribly if there's no project // loaded. This also is used during file load for legacy boards that have netclasses stored // in the file. After load, this information will be moved to the project and the pointer // updated. - m_netClasses = &m_internalNetClasses; + m_NetSettings = std::make_shared( nullptr, "" ); m_HasStackup = false; // no stackup defined by default @@ -883,15 +882,9 @@ void BOARD_DESIGN_SETTINGS::initFromOther( const BOARD_DESIGN_SETTINGS& aOther ) m_boardThickness = aOther.m_boardThickness; m_currentNetClassName = aOther.m_currentNetClassName; m_stackup = aOther.m_stackup; - - // Only take the pointer from the other if it isn't the default - if( aOther.m_netClasses == &aOther.m_internalNetClasses ) - m_netClasses = &m_internalNetClasses; - else - m_netClasses = aOther.m_netClasses; - - m_Pad_Master = std::make_unique( *aOther.m_Pad_Master ); - m_defaultZoneSettings = aOther.m_defaultZoneSettings; + m_NetSettings = aOther.m_NetSettings; + m_Pad_Master = std::make_unique( *aOther.m_Pad_Master ); + m_defaultZoneSettings = aOther.m_defaultZoneSettings; } @@ -1049,31 +1042,15 @@ int BOARD_DESIGN_SETTINGS::GetBiggestClearanceValue() const int BOARD_DESIGN_SETTINGS::GetSmallestClearanceValue() const { - int clearance = GetDefault()->GetClearance(); + int clearance = m_NetSettings->m_DefaultNetClass->GetClearance(); - for( const std::pair& netclass : GetNetClasses().NetClasses() ) - clearance = std::min( clearance, netclass.second->GetClearance() ); + for( const auto& [ name, netclass ] : m_NetSettings->m_NetClasses ) + clearance = std::min( clearance, netclass->GetClearance() ); return clearance; } -int BOARD_DESIGN_SETTINGS::GetCurrentMicroViaSize() -{ - NETCLASSPTR netclass = GetNetClasses().Find( m_currentNetClassName ); - - return netclass->GetuViaDiameter(); -} - - -int BOARD_DESIGN_SETTINGS::GetCurrentMicroViaDrill() -{ - NETCLASSPTR netclass = GetNetClasses().Find( m_currentNetClassName ); - - return netclass->GetuViaDrill(); -} - - void BOARD_DESIGN_SETTINGS::SetViaSizeIndex( unsigned aIndex ) { m_viaSizeIndex = std::min( aIndex, (unsigned) m_ViasDimensionsList.size() ); @@ -1086,7 +1063,7 @@ int BOARD_DESIGN_SETTINGS::GetCurrentViaSize() const if( m_useCustomTrackVia ) return m_customViaSize.m_Diameter; else if( m_viaSizeIndex == 0 ) - return GetNetClasses().GetDefaultPtr()->GetViaDiameter(); + return m_NetSettings->m_DefaultNetClass->GetViaDiameter(); else return m_ViasDimensionsList[ m_viaSizeIndex ].m_Diameter; } @@ -1099,7 +1076,7 @@ int BOARD_DESIGN_SETTINGS::GetCurrentViaDrill() const if( m_useCustomTrackVia ) drill = m_customViaSize.m_Drill; else if( m_viaSizeIndex == 0 ) - drill = GetNetClasses().GetDefaultPtr()->GetViaDrill(); + drill = m_NetSettings->m_DefaultNetClass->GetViaDrill(); else drill = m_ViasDimensionsList[ m_viaSizeIndex ].m_Drill; @@ -1119,7 +1096,7 @@ int BOARD_DESIGN_SETTINGS::GetCurrentTrackWidth() const if( m_useCustomTrackVia ) return m_customTrackWidth; else if( m_trackWidthIndex == 0 ) - return GetNetClasses().GetDefaultPtr()->GetTrackWidth(); + return m_NetSettings->m_DefaultNetClass->GetTrackWidth(); else return m_TrackWidthList[ m_trackWidthIndex ]; } @@ -1145,10 +1122,10 @@ int BOARD_DESIGN_SETTINGS::GetCurrentDiffPairWidth() const } else if( m_diffPairIndex == 0 ) { - if( GetNetClasses().GetDefaultPtr()->HasDiffPairWidth() ) - return GetNetClasses().GetDefaultPtr()->GetDiffPairWidth(); + if( m_NetSettings->m_DefaultNetClass->HasDiffPairWidth() ) + return m_NetSettings->m_DefaultNetClass->GetDiffPairWidth(); else - return GetNetClasses().GetDefaultPtr()->GetTrackWidth(); + return m_NetSettings->m_DefaultNetClass->GetTrackWidth(); } else { @@ -1165,10 +1142,10 @@ int BOARD_DESIGN_SETTINGS::GetCurrentDiffPairGap() const } else if( m_diffPairIndex == 0 ) { - if( GetNetClasses().GetDefaultPtr()->HasDiffPairGap() ) - return GetNetClasses().GetDefaultPtr()->GetDiffPairGap(); + if( m_NetSettings->m_DefaultNetClass->HasDiffPairGap() ) + return m_NetSettings->m_DefaultNetClass->GetDiffPairGap(); else - return GetNetClasses().GetDefaultPtr()->GetClearance(); + return m_NetSettings->m_DefaultNetClass->GetClearance(); } else { @@ -1185,8 +1162,8 @@ int BOARD_DESIGN_SETTINGS::GetCurrentDiffPairViaGap() const } else if( m_diffPairIndex == 0 ) { - if( GetNetClasses().GetDefaultPtr()->HasDiffPairViaGap() ) - return GetNetClasses().GetDefaultPtr()->GetDiffPairViaGap(); + if( m_NetSettings->m_DefaultNetClass->HasDiffPairViaGap() ) + return m_NetSettings->m_DefaultNetClass->GetDiffPairViaGap(); else return GetCurrentDiffPairGap(); } diff --git a/pcbnew/connectivity/connectivity_data.cpp b/pcbnew/connectivity/connectivity_data.cpp index 46d25ad31d..8d0911ca89 100644 --- a/pcbnew/connectivity/connectivity_data.cpp +++ b/pcbnew/connectivity/connectivity_data.cpp @@ -34,7 +34,8 @@ #include #include #include - +#include +#include #include #include #include @@ -103,6 +104,8 @@ void CONNECTIVITY_DATA::Build( BOARD* aBoard, PROGRESS_REPORTER* aReporter ) aReporter->KeepRefreshing( false ); } + std::shared_ptr& netSettings = aBoard->GetDesignSettings().m_NetSettings; + m_connAlgo.reset( new CN_CONNECTIVITY_ALGO ); m_connAlgo->Build( aBoard, aReporter ); @@ -110,6 +113,8 @@ void CONNECTIVITY_DATA::Build( BOARD* aBoard, PROGRESS_REPORTER* aReporter ) for( NETINFO_ITEM* net : aBoard->GetNetInfo() ) { + net->SetNetClass( netSettings->GetEffectiveNetClass( net->GetNetname() ) ); + if( net->GetNetClass()->GetName() != NETCLASS::Default ) m_netclassMap[ net->GetNetCode() ] = net->GetNetClass()->GetName(); } diff --git a/pcbnew/dialogs/dialog_board_setup.cpp b/pcbnew/dialogs/dialog_board_setup.cpp index 472be4b195..477a9ec345 100644 --- a/pcbnew/dialogs/dialog_board_setup.cpp +++ b/pcbnew/dialogs/dialog_board_setup.cpp @@ -1,7 +1,7 @@ /* * This program source code file is part of KiCad, a free EDA CAD application. * - * Copyright (C) 2017-2021 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2017-2022 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -53,6 +53,7 @@ DIALOG_BOARD_SETUP::DIALOG_BOARD_SETUP( PCB_EDIT_FRAME* aFrame ) : _( "Import Settings from Another Board..." ) ), m_frame( aFrame ) { + PROJECT_FILE& project = aFrame->Prj().GetProjectFile(); BOARD* board = aFrame->GetBoard(); BOARD_DESIGN_SETTINGS& bds = board->GetDesignSettings(); @@ -69,7 +70,7 @@ DIALOG_BOARD_SETUP::DIALOG_BOARD_SETUP( PCB_EDIT_FRAME* aFrame ) : m_severities = new PANEL_SETUP_SEVERITIES( this, DRC_ITEM::GetItemsWithSeverities(), bds.m_DRCSeverities ); - m_netclasses = new PANEL_SETUP_NETCLASSES( this, aFrame, &bds.GetNetClasses(), + m_netclasses = new PANEL_SETUP_NETCLASSES( this, aFrame, project.NetSettings(), board->GetNetClassAssignmentCandidates(), false ); m_textVars = new PANEL_TEXT_VARIABLES( m_treebook, &Prj() ); @@ -250,7 +251,7 @@ void DIALOG_BOARD_SETUP::OnAuxiliaryAction( wxCommandEvent& aEvent ) m_constraints->ImportSettingsFrom( otherBoard ); if( importDlg.m_NetclassesOpt->GetValue() ) - m_netclasses->ImportSettingsFrom( &otherBoard->GetDesignSettings().GetNetClasses() ); + m_netclasses->ImportSettingsFrom( otherPrj->GetProjectFile().m_NetSettings ); if( importDlg.m_TracksAndViasOpt->GetValue() ) m_tracksAndVias->ImportSettingsFrom( otherBoard ); diff --git a/pcbnew/dialogs/dialog_global_edit_tracks_and_vias.cpp b/pcbnew/dialogs/dialog_global_edit_tracks_and_vias.cpp index 7b9cfb3428..7ad6ca9b40 100644 --- a/pcbnew/dialogs/dialog_global_edit_tracks_and_vias.cpp +++ b/pcbnew/dialogs/dialog_global_edit_tracks_and_vias.cpp @@ -201,13 +201,13 @@ void DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS::buildFilterLists() m_netFilter->SetSelectedNetcode( *m_brd->GetHighLightNetCodes().begin() ); // Populate the netclass filter list with netclass names - wxArrayString netclassNames; - NETCLASSES& netclasses = m_brd->GetDesignSettings().GetNetClasses(); + wxArrayString netclassNames; + std::shared_ptr& settings = m_brd->GetDesignSettings().m_NetSettings; - netclassNames.push_back( netclasses.GetDefaultPtr()->GetName() ); + netclassNames.push_back( settings->m_DefaultNetClass->GetName() ); - for( NETCLASSES::const_iterator nc = netclasses.begin(); nc != netclasses.end(); ++nc ) - netclassNames.push_back( nc->second->GetName() ); + for( const auto& [ name, netclass ] : settings->m_NetClasses ) + netclassNames.push_back( name ); m_netclassFilter->Set( netclassNames ); m_netclassFilter->SetStringSelection( m_brd->GetDesignSettings().GetCurrentNetClassName() ); @@ -223,38 +223,42 @@ void DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS::buildFilterLists() void DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS::buildNetclassesGrid() { -#define SET_NETCLASS_VALUE( row, col, val ) \ - m_netclassGrid->SetCellValue( row, col, StringFromValue( m_parent->GetUserUnits(), val, true ) ) + EDA_UNITS units = m_parent->GetUserUnits(); + int row = 0; - m_netclassGrid->SetCellValue( 0, GRID_TRACKSIZE, _( "Track Width" ) ); - m_netclassGrid->SetCellValue( 0, GRID_VIASIZE, _( "Via Diameter" ) ); - m_netclassGrid->SetCellValue( 0, GRID_VIADRILL, _( "Via Hole" ) ); - m_netclassGrid->SetCellValue( 0, GRID_uVIASIZE, _( "uVia Diameter" ) ); - m_netclassGrid->SetCellValue( 0, GRID_uVIADRILL, _( "uVia Hole" ) ); + m_netclassGrid->SetCellValue( row, GRID_TRACKSIZE, _( "Track Width" ) ); + m_netclassGrid->SetCellValue( row, GRID_VIASIZE, _( "Via Diameter" ) ); + m_netclassGrid->SetCellValue( row, GRID_VIADRILL, _( "Via Hole" ) ); + m_netclassGrid->SetCellValue( row, GRID_uVIASIZE, _( "uVia Diameter" ) ); + m_netclassGrid->SetCellValue( row, GRID_uVIADRILL, _( "uVia Hole" ) ); + row++; - NETCLASSES& netclasses = m_brd->GetDesignSettings().GetNetClasses(); - NETCLASS* defaultNetclass = m_brd->GetDesignSettings().GetDefault(); - m_netclassGrid->AppendRows( netclasses.GetCount() + 1 ); + auto setNetclassValue = + [&]( int row, int col, int value ) + { + m_netclassGrid->SetCellValue( row, col, StringFromValue( units, value, true ) ); + }; - m_netclassGrid->SetCellValue( 1, GRID_NAME, defaultNetclass->GetName() ); - SET_NETCLASS_VALUE( 1, GRID_TRACKSIZE, defaultNetclass->GetTrackWidth() ); - SET_NETCLASS_VALUE( 1, GRID_VIASIZE, defaultNetclass->GetViaDiameter() ); - SET_NETCLASS_VALUE( 1, GRID_VIADRILL, defaultNetclass->GetViaDrill() ); - SET_NETCLASS_VALUE( 1, GRID_uVIASIZE, defaultNetclass->GetuViaDiameter() ); - SET_NETCLASS_VALUE( 1, GRID_uVIADRILL, defaultNetclass->GetuViaDrill() ); + auto buildRow = + [&]( int row, const std::shared_ptr& nc ) + { + m_netclassGrid->SetCellValue( row, GRID_NAME, nc->GetName() ); + setNetclassValue( row, GRID_TRACKSIZE, nc->GetTrackWidth() ); + setNetclassValue( row, GRID_VIASIZE, nc->GetViaDiameter() ); + setNetclassValue( row, GRID_VIADRILL, nc->GetViaDrill() ); + setNetclassValue( row, GRID_uVIASIZE, nc->GetuViaDiameter() ); + setNetclassValue( row, GRID_uVIADRILL, nc->GetuViaDrill() ); + }; - int row = 2; + const std::shared_ptr& settings = m_brd->GetDesignSettings().m_NetSettings; - for( const std::pair>& netclass : netclasses ) - { - m_netclassGrid->SetCellValue( row, GRID_NAME, netclass.first ); - SET_NETCLASS_VALUE( row, GRID_TRACKSIZE, netclass.second->GetTrackWidth() ); - SET_NETCLASS_VALUE( row, GRID_VIASIZE, netclass.second->GetViaDiameter() ); - SET_NETCLASS_VALUE( row, GRID_VIADRILL, netclass.second->GetViaDrill() ); - SET_NETCLASS_VALUE( row, GRID_uVIASIZE, netclass.second->GetuViaDiameter() ); - SET_NETCLASS_VALUE( row, GRID_uVIADRILL, netclass.second->GetuViaDrill() ); - row++; - } + m_netclassGrid->AppendRows( 1 ); + buildRow( row++, settings->m_DefaultNetClass ); + + m_netclassGrid->AppendRows( settings->m_NetClasses.size() ); + + for( const auto& [ name, netclass ] : settings->m_NetClasses ) + buildRow( row++, netclass ); } @@ -270,7 +274,7 @@ bool DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS::TransferDataToWindow() if( g_filterByNetclass && m_netclassFilter->SetStringSelection( g_netclassFilter ) ) m_netclassFilterOpt->SetValue( true ); else if( item ) - m_netclassFilter->SetStringSelection( item->GetNet()->GetNetClassName() ); + m_netclassFilter->SetStringSelection( item->GetNet()->GetNetClass()->GetName() ); if( g_filterByNet && m_brd->FindNet( g_netFilter ) != nullptr ) { @@ -283,7 +287,9 @@ bool DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS::TransferDataToWindow() } if( g_filterByLayer && m_layerFilter->SetLayerSelection( g_layerFilter ) != wxNOT_FOUND ) + { m_layerFilterOpt->SetValue( true ); + } else if( item ) { if( item->Type() == PCB_ZONE_T ) // a zone can be on more than one layer @@ -391,7 +397,7 @@ void DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS::visitItem( PICKED_ITEMS_LIST* aUndoList if( m_netclassFilterOpt->GetValue() && !m_netclassFilter->GetStringSelection().IsEmpty() ) { - if( aItem->GetNetClassName() != m_netclassFilter->GetStringSelection() ) + if( aItem->GetEffectiveNetClass()->GetName() != m_netclassFilter->GetStringSelection() ) return; } diff --git a/pcbnew/dialogs/dialog_track_via_properties.cpp b/pcbnew/dialogs/dialog_track_via_properties.cpp index 14ca49a348..f1cf3f841b 100644 --- a/pcbnew/dialogs/dialog_track_via_properties.cpp +++ b/pcbnew/dialogs/dialog_track_via_properties.cpp @@ -542,7 +542,7 @@ bool DIALOG_TRACK_VIA_PROPERTIES::TransferDataFromWindow() t->SetEnd( wxPoint( t->GetEnd().x, m_trackEndY.GetValue() ) ); if( m_trackNetclass->IsChecked() ) - t->SetWidth( t->GetNetClass()->GetTrackWidth() ); + t->SetWidth( t->GetEffectiveNetClass()->GetTrackWidth() ); else if( !m_trackWidth.IsIndeterminate() ) t->SetWidth( m_trackWidth.GetValue() ); @@ -617,6 +617,8 @@ bool DIALOG_TRACK_VIA_PROPERTIES::TransferDataFromWindow() if( m_viaNetclass->IsChecked() ) { + NETCLASS* netclass = v->GetEffectiveNetClass(); + switch( v->GetViaType() ) { default: @@ -625,13 +627,13 @@ bool DIALOG_TRACK_VIA_PROPERTIES::TransferDataFromWindow() case VIATYPE::THROUGH: case VIATYPE::BLIND_BURIED: - v->SetWidth( v->GetNetClass()->GetViaDiameter() ); - v->SetDrill( v->GetNetClass()->GetViaDrill() ); + v->SetWidth( netclass->GetViaDiameter() ); + v->SetDrill( netclass->GetViaDrill() ); break; case VIATYPE::MICROVIA: - v->SetWidth( v->GetNetClass()->GetuViaDiameter() ); - v->SetDrill( v->GetNetClass()->GetuViaDrill() ); + v->SetWidth( netclass->GetuViaDiameter() ); + v->SetDrill( netclass->GetuViaDrill() ); break; } } diff --git a/pcbnew/dialogs/panel_setup_rules.cpp b/pcbnew/dialogs/panel_setup_rules.cpp index a3c8871955..32a3e0343a 100644 --- a/pcbnew/dialogs/panel_setup_rules.cpp +++ b/pcbnew/dialogs/panel_setup_rules.cpp @@ -458,11 +458,11 @@ void PANEL_SETUP_RULES::onScintillaCharAdded( wxStyledTextEvent &aEvent ) { if( m_netClassRegex.Matches( last ) ) { - BOARD* board = m_frame->GetBoard(); - BOARD_DESIGN_SETTINGS& bds = board->GetDesignSettings(); + BOARD_DESIGN_SETTINGS& bds = m_frame->GetBoard()->GetDesignSettings(); + std::shared_ptr& netSettings = bds.m_NetSettings; - for( const std::pair& entry : bds.GetNetClasses() ) - tokens += wxT( "|" ) + entry.first; + for( const auto& [ name, netclass ] : netSettings->m_NetClasses ) + tokens += wxT( "|" ) + name; } else if( m_netNameRegex.Matches( last ) ) { diff --git a/pcbnew/drc/drc_engine.cpp b/pcbnew/drc/drc_engine.cpp index 3bc1459e90..f64f38a86f 100644 --- a/pcbnew/drc/drc_engine.cpp +++ b/pcbnew/drc/drc_engine.cpp @@ -230,7 +230,7 @@ void DRC_ENGINE::loadImplicitRules() std::vector> netclassItemSpecificRules; auto makeNetclassRules = - [&]( const NETCLASSPTR& nc, bool isDefault ) + [&]( const std::shared_ptr& nc, bool isDefault ) { wxString ncName = nc->GetName(); wxString expr; @@ -372,10 +372,10 @@ void DRC_ENGINE::loadImplicitRules() }; m_board->SynchronizeNetsAndNetClasses(); - makeNetclassRules( bds.GetNetClasses().GetDefault(), true ); + makeNetclassRules( bds.m_NetSettings->m_DefaultNetClass, true ); - for( const std::pair& netclass : bds.GetNetClasses() ) - makeNetclassRules( netclass.second, false ); + for( const auto& [ name, netclass ] : bds.m_NetSettings->m_NetClasses ) + makeNetclassRules( netclass, false ); // The netclass clearance rules have to be sorted by min clearance so the right one fires // if 'A' and 'B' belong to two different netclasses. diff --git a/pcbnew/edit_track_width.cpp b/pcbnew/edit_track_width.cpp index 7503e0f50b..4b00c6c87c 100644 --- a/pcbnew/edit_track_width.cpp +++ b/pcbnew/edit_track_width.cpp @@ -42,7 +42,7 @@ void PCB_EDIT_FRAME::SetTrackSegmentWidth( PCB_TRACK* aTrackItem, initial_width = aTrackItem->GetWidth(); if( aUseNetclassValue ) - new_width = aTrackItem->GetNetClass()->GetTrackWidth(); + new_width = aTrackItem->GetEffectiveNetClass()->GetTrackWidth(); else new_width = GetDesignSettings().GetCurrentTrackWidth(); @@ -55,8 +55,8 @@ void PCB_EDIT_FRAME::SetTrackSegmentWidth( PCB_TRACK* aTrackItem, if( aUseNetclassValue || via->GetViaType() == VIATYPE::MICROVIA ) { - new_width = aTrackItem->GetNetClass()->GetViaDiameter(); - new_drill = aTrackItem->GetNetClass()->GetViaDrill(); + new_width = aTrackItem->GetEffectiveNetClass()->GetViaDiameter(); + new_drill = aTrackItem->GetEffectiveNetClass()->GetViaDrill(); } else { diff --git a/pcbnew/exporters/gerber_jobfile_writer.cpp b/pcbnew/exporters/gerber_jobfile_writer.cpp index 1825267c47..c5da125e9f 100644 --- a/pcbnew/exporters/gerber_jobfile_writer.cpp +++ b/pcbnew/exporters/gerber_jobfile_writer.cpp @@ -464,14 +464,14 @@ void GERBER_JOBFILE_WRITER::addJSONDesignRules() { // Add the Design Rules section in JSON format to m_JSONbuffer // Job file support a few design rules: - const BOARD_DESIGN_SETTINGS& dsnSettings = m_pcb->GetDesignSettings(); - NETCLASS defaultNC = *dsnSettings.GetDefault(); - int minclearanceOuter = defaultNC.GetClearance(); - bool hasInnerLayers = m_pcb->GetCopperLayerCount() > 2; + std::shared_ptr& netSettings = m_pcb->GetDesignSettings().m_NetSettings; + + int minclearanceOuter = netSettings->m_DefaultNetClass->GetClearance(); + bool hasInnerLayers = m_pcb->GetCopperLayerCount() > 2; // Search a smaller clearance in other net classes, if any. - for( const std::pair& entry : dsnSettings.GetNetClasses() ) - minclearanceOuter = std::min( minclearanceOuter, entry.second->GetClearance() ); + for( const auto& [ name, netclass ] : netSettings->m_NetClasses ) + minclearanceOuter = std::min( minclearanceOuter, netclass->GetClearance() ); // job file knows different clearance types. // Kicad knows only one clearance for pads and tracks @@ -480,8 +480,8 @@ void GERBER_JOBFILE_WRITER::addJSONDesignRules() // However, pads can have a specific clearance defined for a pad or a footprint, // and min clearance can be dependent on layers. // Search for a minimal pad clearance: - int minPadClearanceOuter = defaultNC.GetClearance(); - int minPadClearanceInner = defaultNC.GetClearance(); + int minPadClearanceOuter = netSettings->m_DefaultNetClass->GetClearance(); + int minPadClearanceInner = netSettings->m_DefaultNetClass->GetClearance(); for( FOOTPRINT* footprint : m_pcb->Footprints() ) { diff --git a/pcbnew/files.cpp b/pcbnew/files.cpp index 541aa02070..96e36b5cf8 100644 --- a/pcbnew/files.cpp +++ b/pcbnew/files.cpp @@ -775,8 +775,6 @@ bool PCB_EDIT_FRAME::OpenProjectFiles( const std::vector& aFileSet, in { Prj().SetReadOnly( false ); - Prj().GetProjectFile().NetSettings().RebuildNetClassAssignments(); - // Before we had a copper edge clearance setting, the edge line widths could be used // as a kludge to control them. So if there's no setting then infer it from the // edge widths. diff --git a/pcbnew/footprint_edit_frame.cpp b/pcbnew/footprint_edit_frame.cpp index 4cc306f74a..71d65d24d6 100644 --- a/pcbnew/footprint_edit_frame.cpp +++ b/pcbnew/footprint_edit_frame.cpp @@ -138,7 +138,7 @@ FOOTPRINT_EDIT_FRAME::FOOTPRINT_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) : // In Footprint Editor, the default net clearance is not known (it depends on the actual // board). So we do not show the default clearance, by setting it to 0. The footprint or // pad specific clearance will be shown. - GetBoard()->GetDesignSettings().GetDefault()->SetClearance( 0 ); + GetBoard()->GetDesignSettings().m_NetSettings->m_DefaultNetClass->SetClearance( 0 ); // Don't show the default board solder mask expansion in the footprint editor. Only the // footprint or pad mask expansions settings should be shown. diff --git a/pcbnew/footprint_wizard_frame.cpp b/pcbnew/footprint_wizard_frame.cpp index 3696da59b7..3ebda1bd4d 100644 --- a/pcbnew/footprint_wizard_frame.cpp +++ b/pcbnew/footprint_wizard_frame.cpp @@ -129,7 +129,7 @@ FOOTPRINT_WIZARD_FRAME::FOOTPRINT_WIZARD_FRAME( KIWAY* aKiway, wxWindow* aParent // In viewer, the default net clearance is not known (it depends on the actual board). // So we do not show the default clearance, by setting it to 0 // The footprint or pad specific clearance will be shown - GetBoard()->GetDesignSettings().GetDefault()->SetClearance( 0 ); + GetBoard()->GetDesignSettings().m_NetSettings->m_DefaultNetClass->SetClearance( 0 ); GetBoard()->SetElementVisibility( LAYER_NO_CONNECTS, false ); // Create the manager and dispatcher & route draw panel events to the dispatcher diff --git a/pcbnew/netinfo.h b/pcbnew/netinfo.h index 14d346924a..6fcb1f11e1 100644 --- a/pcbnew/netinfo.h +++ b/pcbnew/netinfo.h @@ -2,7 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2009 Jean-Pierre Charras, jp.charras at wanadoo.fr - * Copyright (C) 1992-2021 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -102,21 +102,13 @@ public: return new NETINFO_ITEM( *this ); } - void SetNetClass( const NETCLASSPTR& aNetClass ); + void SetNetClass( const std::shared_ptr& aNetClass ); /** * @note Do **not** return a std::shared_ptr from this. It is used heavily in DRC, and the * std::shared_ptr stuff shows up large in performance profiling. */ - NETCLASS* GetNetClass() - { - return m_netClass.get(); - } - - wxString GetNetClassName() const - { - return m_netClass ? m_netClass->GetName() : NETCLASS::Default; - } + NETCLASS* GetNetClass() { return m_netClass.get(); } int GetNetCode() const { return m_netCode; } void SetNetCode( int aNetCode ) { m_netCode = aNetCode; } @@ -159,10 +151,7 @@ public: /** * Set all fields to their default values. */ - void Clear() - { - SetNetClass( NETCLASSPTR()); - } + void Clear(); BOARD* GetParent() const { @@ -178,7 +167,7 @@ private: wxString m_netname; ///< Full net name like /sheet/subsheet/vout used by Eeschema. wxString m_shortNetname; ///< short net name, like vout from /sheet/subsheet/vout. - NETCLASSPTR m_netClass; + std::shared_ptr m_netClass; bool m_isCurrent; ///< Indicates the net is currently in use. We still store ///< those that are not during a session for undo/redo and to diff --git a/pcbnew/netinfo_item.cpp b/pcbnew/netinfo_item.cpp index 733cadc111..73bd18b579 100644 --- a/pcbnew/netinfo_item.cpp +++ b/pcbnew/netinfo_item.cpp @@ -49,7 +49,7 @@ NETINFO_ITEM::NETINFO_ITEM( BOARD* aParent, const wxString& aNetName, int aNetCo m_parent = aParent; if( aParent ) - m_netClass = aParent->GetDesignSettings().GetNetClasses().GetDefault(); + m_netClass = aParent->GetDesignSettings().m_NetSettings->m_DefaultNetClass; else m_netClass = std::make_shared( wxT( "" ) ); } @@ -61,10 +61,20 @@ NETINFO_ITEM::~NETINFO_ITEM() } -void NETINFO_ITEM::SetNetClass( const NETCLASSPTR& aNetClass ) +void NETINFO_ITEM::Clear() +{ + m_netClass = m_parent->GetDesignSettings().m_NetSettings->m_DefaultNetClass; +} + + +void NETINFO_ITEM::SetNetClass( const std::shared_ptr& aNetClass ) { wxCHECK( m_parent, /* void */ ); - m_netClass = aNetClass ? aNetClass : m_parent->GetDesignSettings().GetNetClasses().GetDefault(); + + if( aNetClass ) + m_netClass = aNetClass; + else + m_netClass = m_parent->GetDesignSettings().m_NetSettings->m_DefaultNetClass; } diff --git a/pcbnew/netlist_reader/netlist.cpp b/pcbnew/netlist_reader/netlist.cpp index 89f8630c80..f7831b08c1 100644 --- a/pcbnew/netlist_reader/netlist.cpp +++ b/pcbnew/netlist_reader/netlist.cpp @@ -88,9 +88,6 @@ bool PCB_EDIT_FRAME::ReadNetlistFromFile( const wxString &aFilename, NETLIST& aN 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 ); diff --git a/pcbnew/pad.cpp b/pcbnew/pad.cpp index 305421178e..ae74cc7020 100644 --- a/pcbnew/pad.cpp +++ b/pcbnew/pad.cpp @@ -917,7 +917,8 @@ void PAD::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector& { aList.emplace_back( _( "Net" ), UnescapeString( GetNetname() ) ); - aList.emplace_back( _( "Net Class" ), UnescapeString( GetNetClass()->GetName() ) ); + aList.emplace_back( _( "Resolved Netclass" ), + UnescapeString( GetEffectiveNetClass()->GetName() ) ); if( IsLocked() ) aList.emplace_back( _( "Status" ), _( "Locked" ) ); diff --git a/pcbnew/pcb_edit_frame.cpp b/pcbnew/pcb_edit_frame.cpp index eb5b536701..b840e92aa2 100644 --- a/pcbnew/pcb_edit_frame.cpp +++ b/pcbnew/pcb_edit_frame.cpp @@ -1036,8 +1036,6 @@ void PCB_EDIT_FRAME::ShowBoardSetupDialog( const wxString& aInitialPage ) if( dlg.ShowQuasiModal() == wxID_OK ) { - Prj().GetProjectFile().NetSettings().RebuildNetClassAssignments(); - GetBoard()->SynchronizeNetsAndNetClasses(); SaveProjectSettings(); diff --git a/pcbnew/pcb_expr_evaluator.cpp b/pcbnew/pcb_expr_evaluator.cpp index 06d44fa138..cd128a1cff 100644 --- a/pcbnew/pcb_expr_evaluator.cpp +++ b/pcbnew/pcb_expr_evaluator.cpp @@ -1035,29 +1035,23 @@ LIBEVAL::VALUE PCB_EXPR_VAR_REF::GetValue( LIBEVAL::CONTEXT* aCtx ) LIBEVAL::VALUE PCB_EXPR_NETCLASS_REF::GetValue( LIBEVAL::CONTEXT* aCtx ) { - BOARD_ITEM* item = GetObject( aCtx ); + BOARD_CONNECTED_ITEM* item = dynamic_cast( GetObject( aCtx ) ); if( !item ) return LIBEVAL::VALUE(); - if( item->IsConnected() ) - return LIBEVAL::VALUE( static_cast( item )->GetNetClassName() ); - else - return LIBEVAL::VALUE(); + return LIBEVAL::VALUE( item->GetEffectiveNetClass()->GetName() ); } LIBEVAL::VALUE PCB_EXPR_NETNAME_REF::GetValue( LIBEVAL::CONTEXT* aCtx ) { - BOARD_ITEM* item = GetObject( aCtx ); + BOARD_CONNECTED_ITEM* item = dynamic_cast( GetObject( aCtx ) ); if( !item ) return LIBEVAL::VALUE(); - if( item->IsConnected() ) - return LIBEVAL::VALUE( static_cast( item )->GetNetname() ); - else - return LIBEVAL::VALUE(); + return LIBEVAL::VALUE( item->GetNetname() ); } diff --git a/pcbnew/pcb_track.cpp b/pcbnew/pcb_track.cpp index e12e4a9389..a625b31a25 100644 --- a/pcbnew/pcb_track.cpp +++ b/pcbnew/pcb_track.cpp @@ -187,7 +187,7 @@ int PCB_VIA::GetDrillValue() const return m_drill; // Use the default value from the Netclass - NETCLASS* netclass = GetNetClass(); + NETCLASS* netclass = GetEffectiveNetClass(); if( GetViaType() == VIATYPE::MICROVIA ) return netclass->GetuViaDrill(); @@ -888,7 +888,8 @@ void PCB_TRACK::GetMsgPanelInfoBase_Common( EDA_DRAW_FRAME* aFrame, { aList.emplace_back( _( "Net" ), UnescapeString( GetNetname() ) ); - aList.emplace_back( _( "Net Class" ), UnescapeString( GetNetClass()->GetName() ) ); + aList.emplace_back( _( "Resolved Netclass" ), + UnescapeString( GetEffectiveNetClass()->GetName() ) ); #if 0 // Enable for debugging if( GetBoard() ) diff --git a/pcbnew/pcbnew_config.cpp b/pcbnew/pcbnew_config.cpp index 641b660d97..2667dcdca1 100644 --- a/pcbnew/pcbnew_config.cpp +++ b/pcbnew/pcbnew_config.cpp @@ -56,38 +56,36 @@ bool PCB_EDIT_FRAME::LoadProjectSettings() // Load render settings that aren't stored in PCB_DISPLAY_OPTIONS - NET_SETTINGS& netSettings = project.NetSettings(); - NETINFO_LIST& nets = GetBoard()->GetNetInfo(); + std::shared_ptr& netSettings = project.NetSettings(); + KIGFX::RENDER_SETTINGS* rs = GetCanvas()->GetView()->GetPainter()->GetSettings(); + KIGFX::PCB_RENDER_SETTINGS* renderSettings = static_cast( rs ); - KIGFX::PCB_RENDER_SETTINGS* rs = static_cast( - GetCanvas()->GetView()->GetPainter()->GetSettings() ); - - std::set& hiddenNets = rs->GetHiddenNets(); + std::set& hiddenNets = renderSettings->GetHiddenNets(); hiddenNets.clear(); for( const wxString& hidden : localSettings.m_HiddenNets ) { - if( NETINFO_ITEM* net = nets.GetNetItem( hidden ) ) + if( NETINFO_ITEM* net = GetBoard()->GetNetInfo().GetNetItem( hidden ) ) hiddenNets.insert( net->GetNetCode() ); } - std::map& netColors = rs->GetNetColorMap(); + std::map& netColors = renderSettings->GetNetColorMap(); netColors.clear(); - for( const auto& pair : netSettings.m_PcbNetColors ) + for( const auto& [ netname, color ] : netSettings->m_NetColorAssignments ) { - if( pair.second == COLOR4D::UNSPECIFIED ) - continue; - - if( NETINFO_ITEM* net = nets.GetNetItem( pair.first ) ) - netColors[ net->GetNetCode() ] = pair.second; + if( color != COLOR4D::UNSPECIFIED ) + { + if( NETINFO_ITEM* net = GetBoard()->GetNetInfo().GetNetItem( netname ) ) + netColors[ net->GetNetCode() ] = color; + } } - std::map& netclassColors = rs->GetNetclassColorMap(); + std::map& netclassColors = renderSettings->GetNetclassColorMap(); netclassColors.clear(); - for( const auto& pair : netSettings.m_NetClasses ) - netclassColors[pair.first] = pair.second->GetPcbColor(); + for( const auto& [ name, netclass ] : netSettings->m_NetClasses ) + netclassColors[ name ] = netclass->GetPcbColor(); m_appearancePanel->SetUserLayerPresets( project.m_LayerPresets ); m_appearancePanel->SetUserViewports( project.m_Viewports ); @@ -168,36 +166,34 @@ void PCB_EDIT_FRAME::SaveProjectSettings() // Save render settings that aren't stored in PCB_DISPLAY_OPTIONS - KIGFX::PCB_RENDER_SETTINGS* rs = static_cast( - GetCanvas()->GetView()->GetPainter()->GetSettings() ); - - NETINFO_LIST& nets = GetBoard()->GetNetInfo(); + std::shared_ptr& netSettings = project.NetSettings(); + KIGFX::RENDER_SETTINGS* rs = GetCanvas()->GetView()->GetPainter()->GetSettings(); + KIGFX::PCB_RENDER_SETTINGS* renderSettings = static_cast( rs ); + NETINFO_LIST& nets = GetBoard()->GetNetInfo(); localSettings.m_HiddenNets.clear(); - for( int netcode : rs->GetHiddenNets() ) + for( int netcode : renderSettings->GetHiddenNets() ) { if( NETINFO_ITEM* net = nets.GetNetItem( netcode ) ) localSettings.m_HiddenNets.emplace_back( net->GetNetname() ); } - NET_SETTINGS& netSettings = project.NetSettings(); + netSettings->m_NetColorAssignments.clear(); - netSettings.m_PcbNetColors.clear(); - - for( const std::pair& pair : rs->GetNetColorMap() ) + for( const auto& [ netcode, color ] : renderSettings->GetNetColorMap() ) { - if( NETINFO_ITEM* net = nets.GetNetItem( pair.first ) ) - netSettings.m_PcbNetColors[net->GetNetname()] = pair.second; + if( NETINFO_ITEM* net = nets.GetNetItem( netcode ) ) + netSettings->m_NetColorAssignments[ net->GetNetname() ] = color; } - std::map& netclassColors = rs->GetNetclassColorMap(); + std::map& netclassColors = renderSettings->GetNetclassColorMap(); // NOTE: this assumes netclasses will have already been updated, which I think is the case - for( const std::pair& pair : netSettings.m_NetClasses ) + for( const auto& [ name, netclass ] : netSettings->m_NetClasses ) { - if( netclassColors.count( pair.first ) ) - pair.second->SetPcbColor( netclassColors.at( pair.first ) ); + if( netclassColors.count( name ) ) + netclass->SetPcbColor( netclassColors.at( name ) ); } PCB_SELECTION_TOOL* selTool = GetToolManager()->GetTool(); diff --git a/pcbnew/plugins/altium/altium_pcb.cpp b/pcbnew/plugins/altium/altium_pcb.cpp index 23cb906311..d7e8a4acf6 100644 --- a/pcbnew/plugins/altium/altium_pcb.cpp +++ b/pcbnew/plugins/altium/altium_pcb.cpp @@ -1084,20 +1084,27 @@ void ALTIUM_PCB::ParseClasses6Data( const ALTIUM_COMPOUND_FILE& aAltiumPcbFi if( elem.kind == ALTIUM_CLASS_KIND::NET_CLASS ) { - NETCLASSPTR nc = std::make_shared( elem.name ); + std::shared_ptr nc = std::make_shared( elem.name ); - for( const auto& name : elem.names ) + for( const wxString& name : elem.names ) { - // TODO: it seems it can happen that we have names not attached to any net. - nc->Add( name ); + m_board->GetDesignSettings().m_NetSettings->m_NetClassPatternAssignments.push_back( + { + std::make_unique( name, CTX_NETCLASS ), + nc->GetName() + } ); } - if( !m_board->GetDesignSettings().GetNetClasses().Add( nc ) ) + if( m_board->GetDesignSettings().m_NetSettings->m_NetClasses.count( nc->GetName() ) ) { // Name conflict, this is likely a bad board file. // unique_ptr will delete nc on this code path THROW_IO_ERROR( wxString::Format( _( "Duplicate netclass name '%s'." ), elem.name ) ); } + else + { + m_board->GetDesignSettings().m_NetSettings->m_NetClasses[ nc->GetName() ] = nc; + } } } diff --git a/pcbnew/plugins/cadstar/cadstar_pcb_archive_loader.cpp b/pcbnew/plugins/cadstar/cadstar_pcb_archive_loader.cpp index 8a0f856652..7d7c96f99b 100644 --- a/pcbnew/plugins/cadstar/cadstar_pcb_archive_loader.cpp +++ b/pcbnew/plugins/cadstar/cadstar_pcb_archive_loader.cpp @@ -663,7 +663,7 @@ void CADSTAR_PCB_ARCHIVE_LOADER::remapUnsureLayers() void CADSTAR_PCB_ARCHIVE_LOADER::loadDesignRules() { - BOARD_DESIGN_SETTINGS& ds = m_board->GetDesignSettings(); + BOARD_DESIGN_SETTINGS& bds = m_board->GetDesignSettings(); std::map& spacingCodes = Assignments.Codedefs.SpacingCodes; auto applyRule = @@ -677,27 +677,28 @@ void CADSTAR_PCB_ARCHIVE_LOADER::loadDesignRules() //Note: for details on the different spacing codes see SPACINGCODE::ID - applyRule( "T_T", &ds.m_MinClearance ); - applyRule( "C_B", &ds.m_CopperEdgeClearance ); - applyRule( "H_H", &ds.m_HoleToHoleMin ); + applyRule( "T_T", &bds.m_MinClearance ); + applyRule( "C_B", &bds.m_CopperEdgeClearance ); + applyRule( "H_H", &bds.m_HoleToHoleMin ); - ds.m_TrackMinWidth = getKiCadLength( Assignments.Technology.MinRouteWidth ); - ds.m_ViasMinSize = ds.m_TrackMinWidth; // Not specified, assumed same as track width - ds.m_ViasMinAnnularWidth = ds.m_TrackMinWidth / 2; // Not specified, assumed half track width - ds.m_MinThroughDrill = PCB_IU_PER_MM * 0.0508; // CADSTAR does not specify a minimum hole size + bds.m_TrackMinWidth = getKiCadLength( Assignments.Technology.MinRouteWidth ); + bds.m_ViasMinSize = bds.m_TrackMinWidth; // Not specified, assumed same as track width + bds.m_ViasMinAnnularWidth = bds.m_TrackMinWidth / 2; // Not specified, assumed half track width + bds.m_MinThroughDrill = PCB_IU_PER_MM * 0.0508; // CADSTAR does not specify a minimum hole size // so set to minimum permitted in KiCad (2 mils) - ds.m_HoleClearance = 0; // Testing suggests cadstar might not have a copper-to-hole clearance + bds.m_HoleClearance = 0; // Testing suggests cadstar might not have a copper-to-hole clearance - auto applyNetClassRule = [&]( wxString aID, NETCLASS* aNetClassPtr, - void ( NETCLASS::*aFunc )( int ) ) { - int value = -1; - applyRule( aID, &value ); + auto applyNetClassRule = + [&]( wxString aID, std::shared_ptr& aNetClassPtr ) + { + int value = -1; + applyRule( aID, &value ); - if( value != -1 ) - ( aNetClassPtr->*aFunc )( value ); - }; + if( value != -1 ) + aNetClassPtr->SetClearance( value ); + }; - applyNetClassRule( "T_T", ds.GetDefault(), &::NETCLASS::SetClearance ); + applyNetClassRule( "T_T", bds.m_NetSettings->m_DefaultNetClass ); wxLogWarning( _( "KiCad design rules are different from CADSTAR ones. Only the compatible " "design rules were imported. It is recommended that you review the design " @@ -3953,10 +3954,11 @@ NETINFO_ITEM* CADSTAR_PCB_ARCHIVE_LOADER::getKiCadNet( const NET_ID& aCadstarNet m_doneSpacingClassWarning = true; } - NETINFO_ITEM* netInfo = new NETINFO_ITEM( m_board, newName, ++m_numNets ); - NETCLASSPTR netclass; + std::shared_ptr& netSettings = m_board->GetDesignSettings().m_NetSettings; + NETINFO_ITEM* netInfo = new NETINFO_ITEM( m_board, newName, ++m_numNets ); + std::shared_ptr netclass; - std::tuple key = { csNet.RouteCodeID, + std::tuple key = { csNet.RouteCodeID, csNet.NetClassID, csNet.SpacingClassID }; @@ -3968,7 +3970,6 @@ NETINFO_ITEM* CADSTAR_PCB_ARCHIVE_LOADER::getKiCadNet( const NET_ID& aCadstarNet { wxString netClassName; - ROUTECODE rc = getRouteCode( csNet.RouteCodeID ); netClassName += wxT( "Route code: " ) + rc.Name; @@ -3984,14 +3985,19 @@ NETINFO_ITEM* CADSTAR_PCB_ARCHIVE_LOADER::getKiCadNet( const NET_ID& aCadstarNet netClassName += wxT( " | Spacing class: " ) + sp.Name; } - netclass.reset( new NETCLASS( *m_board->GetDesignSettings().GetDefault() ) ); + netclass.reset( new NETCLASS( *netSettings->m_DefaultNetClass ) ); netclass->SetName( netClassName ); - m_board->GetDesignSettings().GetNetClasses().Add( netclass ); + netSettings->m_NetClasses[ netClassName ] = netclass; netclass->SetTrackWidth( getKiCadLength( rc.OptimalWidth ) ); m_netClassMap.insert( { key, netclass } ); } - netclass->Add( newName ); + m_board->GetDesignSettings().m_NetSettings->m_NetClassPatternAssignments.push_back( + { + std::make_unique( newName, CTX_NETCLASS ), + netclass->GetName() + } ); + netInfo->SetNetClass( netclass ); m_board->Add( netInfo, ADD_MODE::APPEND ); m_netMap.insert( { aCadstarNetID, netInfo } ); diff --git a/pcbnew/plugins/cadstar/cadstar_pcb_archive_loader.h b/pcbnew/plugins/cadstar/cadstar_pcb_archive_loader.h index 26d970d0d2..71ba359af8 100644 --- a/pcbnew/plugins/cadstar/cadstar_pcb_archive_loader.h +++ b/pcbnew/plugins/cadstar/cadstar_pcb_archive_loader.h @@ -115,7 +115,7 @@ private: std::map m_librarycopperpads; std::map m_netMap; ///< Map between Cadstar and KiCad Nets - std::map, NETCLASSPTR> + std::map, std::shared_ptr> m_netClassMap; ///< Map between Cadstar and KiCad classes std::map m_zonesMap; ///< Map between Cadstar and KiCad zones std::vector m_powerPlaneLayers; ///< List of layers that are marked as diff --git a/pcbnew/plugins/eagle/eagle_plugin.cpp b/pcbnew/plugins/eagle/eagle_plugin.cpp index 60c4e55caf..410aa4962b 100644 --- a/pcbnew/plugins/eagle/eagle_plugin.cpp +++ b/pcbnew/plugins/eagle/eagle_plugin.cpp @@ -58,12 +58,12 @@ Load() TODO's #include #include +#include #include #include #include #include #include -#include #include #include #include // for KiROUND @@ -407,31 +407,31 @@ BOARD* EAGLE_PLUGIN::Load( const wxString& aFileName, BOARD* aAppendToMe, loadAllSections( doc ); - BOARD_DESIGN_SETTINGS& designSettings = m_board->GetDesignSettings(); + BOARD_DESIGN_SETTINGS& bds = m_board->GetDesignSettings(); - if( m_min_trace < designSettings.m_TrackMinWidth ) - designSettings.m_TrackMinWidth = m_min_trace; + if( m_min_trace < bds.m_TrackMinWidth ) + bds.m_TrackMinWidth = m_min_trace; - if( m_min_via < designSettings.m_ViasMinSize ) - designSettings.m_ViasMinSize = m_min_via; + if( m_min_via < bds.m_ViasMinSize ) + bds.m_ViasMinSize = m_min_via; - if( m_min_hole < designSettings.m_MinThroughDrill ) - designSettings.m_MinThroughDrill = m_min_hole; + if( m_min_hole < bds.m_MinThroughDrill ) + bds.m_MinThroughDrill = m_min_hole; - if( m_min_annulus < designSettings.m_ViasMinAnnularWidth ) - designSettings.m_ViasMinAnnularWidth = m_min_annulus; + if( m_min_annulus < bds.m_ViasMinAnnularWidth ) + bds.m_ViasMinAnnularWidth = m_min_annulus; if( m_rules->mdWireWire ) - designSettings.m_MinClearance = KiROUND( m_rules->mdWireWire ); + bds.m_MinClearance = KiROUND( m_rules->mdWireWire ); NETCLASS defaults( wxT( "dummy" ) ); auto finishNetclass = - [&]( NETCLASSPTR netclass ) + [&]( std::shared_ptr netclass ) { // If Eagle has a clearance matrix then we'll build custom rules from that. // Netclasses should just be the board minimum clearance. - netclass->SetClearance( KiROUND( designSettings.m_MinClearance ) ); + netclass->SetClearance( KiROUND( bds.m_MinClearance ) ); if( netclass->GetTrackWidth() == INT_MAX ) netclass->SetTrackWidth( defaults.GetTrackWidth() ); @@ -443,10 +443,12 @@ BOARD* EAGLE_PLUGIN::Load( const wxString& aFileName, BOARD* aAppendToMe, netclass->SetViaDrill( defaults.GetViaDrill() ); }; - finishNetclass( designSettings.GetNetClasses().GetDefault() ); + std::shared_ptr& netSettings = bds.m_NetSettings; - for( const std::pair& entry : designSettings.GetNetClasses() ) - finishNetclass( entry.second ); + finishNetclass( netSettings->m_DefaultNetClass ); + + for( const auto& [ name, netclass ] : netSettings->m_NetClasses ) + finishNetclass( netclass ); m_board->m_LegacyNetclassesLoaded = true; m_board->m_LegacyDesignSettingsLoaded = true; @@ -2582,17 +2584,17 @@ void EAGLE_PLUGIN::loadClasses( wxXmlNode* aClasses ) { checkpoint(); - ECLASS eClass( classNode ); - NETCLASSPTR netclass; + ECLASS eClass( classNode ); + std::shared_ptr netclass; if( eClass.name.CmpNoCase( wxT( "default" ) ) == 0 ) { - netclass = bds.GetNetClasses().GetDefault(); + netclass = bds.m_NetSettings->m_DefaultNetClass; } else { netclass.reset( new NETCLASS( eClass.name ) ); - m_board->GetDesignSettings().GetNetClasses().Add( netclass ); + bds.m_NetSettings->m_NetClasses[ eClass.name ] = netclass; } netclass->SetTrackWidth( INT_MAX ); @@ -2651,15 +2653,20 @@ void EAGLE_PLUGIN::loadSignals( wxXmlNode* aSignals ) zones.clear(); - const wxString& netName = escapeName( net->GetAttribute( "name" ) ); - NETINFO_ITEM* netInfo = new NETINFO_ITEM( m_board, netName, netCode ); - NETCLASSPTR netclass; + const wxString& netName = escapeName( net->GetAttribute( "name" ) ); + NETINFO_ITEM* netInfo = new NETINFO_ITEM( m_board, netName, netCode ); + std::shared_ptr netclass; if( net->HasAttribute( "class" ) ) { netclass = m_classMap[ net->GetAttribute( "class" ) ]; - netclass->Add( netName ); + m_board->GetDesignSettings().m_NetSettings->m_NetClassPatternAssignments.push_back( + { + std::make_unique( netName, CTX_NETCLASS ), + netclass->GetName() + } ); + netInfo->SetNetClass( netclass ); } diff --git a/pcbnew/plugins/eagle/eagle_plugin.h b/pcbnew/plugins/eagle/eagle_plugin.h index 6f03f3cc05..5e310e4320 100644 --- a/pcbnew/plugins/eagle/eagle_plugin.h +++ b/pcbnew/plugins/eagle/eagle_plugin.h @@ -2,7 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck - * Copyright (C) 2012-2021 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2012-2022 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -288,7 +288,9 @@ private: std::map m_eagleLayersIds; ///< Eagle layer ids stored by layer name std::map m_layer_map; ///< Map of Eagle layers to KiCad layers - std::map m_classMap; ///< Eagle class number to KiCad netclass + ///< Eagle class number to KiCad netclass + std::map> m_classMap; + wxString m_customRules; ERULES* m_rules; ///< Eagle design rules. diff --git a/pcbnew/plugins/kicad/pcb_parser.cpp b/pcbnew/plugins/kicad/pcb_parser.cpp index 94e38f9d0b..3905086b26 100644 --- a/pcbnew/plugins/kicad/pcb_parser.cpp +++ b/pcbnew/plugins/kicad/pcb_parser.cpp @@ -1858,9 +1858,9 @@ void PCB_PARSER::parseSetup() wxCHECK_RET( CurTok() == T_setup, wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as setup." ) ); - BOARD_DESIGN_SETTINGS& bds = m_board->GetDesignSettings(); - NETCLASS* defaultNetClass = bds.GetDefault(); - ZONE_SETTINGS& zoneSettings = bds.GetDefaultZoneSettings(); + BOARD_DESIGN_SETTINGS& bds = m_board->GetDesignSettings(); + std::shared_ptr& defaultNetClass = bds.m_NetSettings->m_DefaultNetClass; + ZONE_SETTINGS& zoneSettings = bds.GetDefaultZoneSettings(); // Missing soldermask min width value means that the user has set the value to 0 and // not the default value (0.25mm) @@ -2379,7 +2379,7 @@ void PCB_PARSER::parseNETCLASS() T token; - NETCLASSPTR nc = std::make_shared( wxEmptyString ); + std::shared_ptr nc = std::make_shared( wxEmptyString ); // Read netclass name (can be a name or just a number like track width) NeedSYMBOLorNUMBER(); @@ -2429,16 +2429,24 @@ void PCB_PARSER::parseNETCLASS() break; case T_add_net: + { NeedSYMBOLorNUMBER(); + wxString netName = FromUTF8(); + // Convert overbar syntax from `~...~` to `~{...}`. These were left out of the // first merge so the version is a bit later. if( m_requiredVersion < 20210606 ) - nc->Add( ConvertToNewOverbarNotation( FromUTF8() ) ); - else - nc->Add( FromUTF8() ); + netName = ConvertToNewOverbarNotation( FromUTF8() ); + + m_board->GetDesignSettings().m_NetSettings->m_NetClassPatternAssignments.push_back( + { + std::make_unique( netName, CTX_NETCLASS ), + nc->GetName() + } ); break; + } default: Expecting( "clearance, trace_width, via_dia, via_drill, uvia_dia, uvia_drill, " @@ -2448,19 +2456,20 @@ void PCB_PARSER::parseNETCLASS() NeedRIGHT(); } - if( !m_board->GetDesignSettings().GetNetClasses().Add( nc ) ) + if( m_board->GetDesignSettings().m_NetSettings->m_NetClasses.count( nc->GetName() ) ) { // Must have been a name conflict, this is a bad board file. // User may have done a hand edit to the file. - - // unique_ptr will delete nc on this code path - wxString error; error.Printf( _( "Duplicate NETCLASS name '%s' in file '%s' at line %d, offset %d." ), nc->GetName().GetData(), CurSource().GetData(), CurLineNumber(), CurOffset() ); THROW_IO_ERROR( error ); } + else + { + m_board->GetDesignSettings().m_NetSettings->m_NetClasses[ nc->GetName() ] = nc; + } } diff --git a/pcbnew/plugins/legacy/legacy_plugin.cpp b/pcbnew/plugins/legacy/legacy_plugin.cpp index 2d9df869f4..6c37bf7fad 100644 --- a/pcbnew/plugins/legacy/legacy_plugin.cpp +++ b/pcbnew/plugins/legacy/legacy_plugin.cpp @@ -841,11 +841,11 @@ void LEGACY_PLUGIN::loadSHEET() void LEGACY_PLUGIN::loadSETUP() { - BOARD_DESIGN_SETTINGS& bds = m_board->GetDesignSettings(); - ZONE_SETTINGS zs = m_board->GetZoneSettings(); - NETCLASS* netclass_default = bds.GetDefault(); - char* line; - char* saveptr; + BOARD_DESIGN_SETTINGS& bds = m_board->GetDesignSettings(); + ZONE_SETTINGS zoneSettings = m_board->GetZoneSettings(); + std::shared_ptr defaultNetclass = bds.m_NetSettings->m_DefaultNetClass; + char* line; + char* saveptr; m_board->m_LegacyDesignSettingsLoaded = true; @@ -897,7 +897,7 @@ void LEGACY_PLUGIN::loadSETUP() else if( TESTLINE( "TrackWidth" ) ) { BIU tmp = biuParse( line + SZ( "TrackWidth" ) ); - netclass_default->SetTrackWidth( tmp ); + defaultNetclass->SetTrackWidth( tmp ); } else if( TESTLINE( "TrackWidthList" ) ) { @@ -907,7 +907,7 @@ void LEGACY_PLUGIN::loadSETUP() else if( TESTLINE( "TrackClearence" ) ) { BIU tmp = biuParse( line + SZ( "TrackClearence" ) ); - netclass_default->SetClearance( tmp ); + defaultNetclass->SetClearance( tmp ); } else if( TESTLINE( "TrackMinWidth" ) ) { @@ -917,7 +917,7 @@ void LEGACY_PLUGIN::loadSETUP() else if( TESTLINE( "ZoneClearence" ) ) { BIU tmp = biuParse( line + SZ( "ZoneClearence" ) ); - zs.m_ZoneClearance = tmp; + zoneSettings.m_ZoneClearance = tmp; } else if( TESTLINE( "Zone_45_Only" ) ) // No longer used { @@ -959,12 +959,12 @@ void LEGACY_PLUGIN::loadSETUP() else if( TESTLINE( "ViaSize" ) ) { BIU tmp = biuParse( line + SZ( "ViaSize" ) ); - netclass_default->SetViaDiameter( tmp ); + defaultNetclass->SetViaDiameter( tmp ); } else if( TESTLINE( "ViaDrill" ) ) { BIU tmp = biuParse( line + SZ( "ViaDrill" ) ); - netclass_default->SetViaDrill( tmp ); + defaultNetclass->SetViaDrill( tmp ); } else if( TESTLINE( "ViaMinDrill" ) ) { @@ -974,12 +974,12 @@ void LEGACY_PLUGIN::loadSETUP() else if( TESTLINE( "MicroViaSize" ) ) { BIU tmp = biuParse( line + SZ( "MicroViaSize" ) ); - netclass_default->SetuViaDiameter( tmp ); + defaultNetclass->SetuViaDiameter( tmp ); } else if( TESTLINE( "MicroViaDrill" ) ) { BIU tmp = biuParse( line + SZ( "MicroViaDrill" ) ); - netclass_default->SetuViaDrill( tmp ); + defaultNetclass->SetuViaDrill( tmp ); } else if( TESTLINE( "MicroViaMinDrill" ) ) { @@ -1082,7 +1082,7 @@ void LEGACY_PLUGIN::loadSETUP() } else if( TESTLINE( "$EndSETUP" ) ) { - m_board->SetZoneSettings( zs ); + m_board->SetZoneSettings( zoneSettings ); // Very old *.brd file does not have NETCLASSes // "TrackWidth", "ViaSize", "ViaDrill", "ViaMinSize", and "TrackClearence" were @@ -2253,7 +2253,7 @@ void LEGACY_PLUGIN::loadNETCLASS() // yet since that would bypass duplicate netclass name checking within the BOARD. // store it temporarily in an unique_ptr until successfully inserted into the BOARD // just before returning. - NETCLASSPTR nc = std::make_shared( wxEmptyString ); + std::shared_ptr nc = std::make_shared( wxEmptyString ); while( ( line = READLINE( m_reader ) ) != nullptr ) { @@ -2262,7 +2262,12 @@ void LEGACY_PLUGIN::loadNETCLASS() // e.g. "AddNet "V3.3D"\n" ReadDelimitedText( buf, line + SZ( "AddNet" ), sizeof(buf) ); netname = ConvertToNewOverbarNotation( FROM_UTF8( buf ) ); - nc->Add( netname ); + + m_board->GetDesignSettings().m_NetSettings->m_NetClassPatternAssignments.push_back( + { + std::make_unique( netname, CTX_NETCLASS ), + nc->GetName() + } ); } else if( TESTLINE( "Clearance" ) ) { @@ -2306,16 +2311,20 @@ void LEGACY_PLUGIN::loadNETCLASS() } else if( TESTLINE( "$EndNCLASS" ) ) { - if( !m_board->GetDesignSettings().GetNetClasses().Add( nc ) ) + if( m_board->GetDesignSettings().m_NetSettings->m_NetClasses.count( nc->GetName() ) ) { // Must have been a name conflict, this is a bad board file. // User may have done a hand edit to the file. // unique_ptr will delete nc on this code path - m_error.Printf( _( "Duplicate NETCLASS name '%s'." ), nc->GetName().GetData() ); + m_error.Printf( _( "Duplicate NETCLASS name '%s'." ), nc->GetName() ); THROW_IO_ERROR( m_error ); } + else + { + m_board->GetDesignSettings().m_NetSettings->m_NetClasses[ nc->GetName() ] = nc; + } return; // preferred exit } diff --git a/pcbnew/python/scripting/pcbnew_scripting_helpers.cpp b/pcbnew/python/scripting/pcbnew_scripting_helpers.cpp index a3fcbe9148..34de547e7a 100644 --- a/pcbnew/python/scripting/pcbnew_scripting_helpers.cpp +++ b/pcbnew/python/scripting/pcbnew_scripting_helpers.cpp @@ -163,9 +163,6 @@ BOARD* LoadBoard( wxString& aFileName, IO_MGR::PCB_FILE_T aFormat ) { brd->SetProject( project ); - if( brd->m_LegacyDesignSettingsLoaded ) - project->GetProjectFile().NetSettings().RebuildNetClassAssignments(); - // Move legacy view settings to local project settings if( !brd->m_LegacyVisibleLayers.test( Rescue ) ) project->GetLocalSettings().m_VisibleLayers = brd->m_LegacyVisibleLayers; diff --git a/pcbnew/router/router_tool.cpp b/pcbnew/router/router_tool.cpp index 8e77f7d094..f70ef29169 100644 --- a/pcbnew/router/router_tool.cpp +++ b/pcbnew/router/router_tool.cpp @@ -43,6 +43,7 @@ using namespace std::placeholders; #include #include #include +#include #include #include #include @@ -2066,8 +2067,10 @@ void ROUTER_TOOL::UpdateMessagePanel() NETINFO_ITEM* netInfo = board()->FindNet( m_startItem->Net() ); wxASSERT( netInfo ); - items.emplace_back( wxString::Format( description, netInfo->GetNetname() ), - wxString::Format( _( "Net Class: %s" ), netInfo->GetNetClassName() ) ); + items.emplace_back( wxString::Format( description, + UnescapeString( netInfo->GetNetname() ) ), + wxString::Format( _( "Resolved Netclass: %s" ), + UnescapeString( netInfo->GetNetClass()->GetName() ) ) ); } else { diff --git a/pcbnew/specctra_import_export/specctra_export.cpp b/pcbnew/specctra_import_export/specctra_export.cpp index a372500713..c859a20811 100644 --- a/pcbnew/specctra_import_export/specctra_export.cpp +++ b/pcbnew/specctra_import_export/specctra_export.cpp @@ -1099,7 +1099,9 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) { PCB_TYPE_COLLECTOR items; - static const KICAD_T scanMODULEs[] = { PCB_FOOTPRINT_T, EOT }; + static const KICAD_T scanMODULEs[] = { PCB_FOOTPRINT_T, EOT }; + + std::shared_ptr& netSettings = aBoard->GetDesignSettings().m_NetSettings; // Not all boards are exportable. Check that all reference Ids are unique. // Unless they are unique, we cannot import the session file which comes @@ -1206,12 +1208,9 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) //------------------------------------------------------------- { char rule[80]; - NETCLASS* defaultClass = aBoard->GetDesignSettings().GetDefault(); - - int defaultTrackWidth = defaultClass->GetTrackWidth(); - int defaultClearance = defaultClass->GetClearance(); - - double clearance = scale( defaultClearance ); + int defaultTrackWidth = netSettings->m_DefaultNetClass->GetTrackWidth(); + int defaultClearance = netSettings->m_DefaultNetClass->GetClearance(); + double clearance = scale( defaultClearance ); STRINGS& rules = m_pcb->structure->rules->rules; @@ -1608,8 +1607,6 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) //-----< output vias used in netclasses >----------------------------------- { - NETCLASSES& nclasses = aBoard->GetDesignSettings().GetNetClasses(); - // Assume the netclass vias are all the same kind of thru, blind, or buried vias. // This is in lieu of either having each netclass via have its own layer pair in // the netclass dialog, or such control in the specctra export dialog. @@ -1621,9 +1618,8 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) // Add the via from the Default netclass first. The via container // in pcb->library preserves the sequence of addition. - NETCLASSPTR netclass = nclasses.GetDefault(); - - PADSTACK* via = makeVia( netclass->GetViaDiameter(), netclass->GetViaDrill(), + PADSTACK* via = makeVia( netSettings->m_DefaultNetClass->GetViaDiameter(), + netSettings->m_DefaultNetClass->GetViaDrill(), m_top_via_layer, m_bot_via_layer ); // we AppendVia() this first one, there is no way it can be a duplicate, @@ -1636,10 +1632,8 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) // pcb->library->spareViaIndex = pcb->library->vias.size(); // output the non-Default netclass vias - for( NETCLASSES::iterator nc = nclasses.begin(); nc != nclasses.end(); ++nc ) + for( const auto& [ name, netclass ] : netSettings->m_NetClasses ) { - netclass = nc->second; - via = makeVia( netclass->GetViaDiameter(), netclass->GetViaDrill(), m_top_via_layer, m_bot_via_layer ); @@ -1781,19 +1775,15 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) } //--------------------------------------------------------- - NETCLASSES& nclasses = aBoard->GetDesignSettings().GetNetClasses(); - exportNETCLASS( nclasses.GetDefault(), aBoard ); + exportNETCLASS( netSettings->m_DefaultNetClass, aBoard ); - for( NETCLASSES::iterator nc = nclasses.begin(); nc != nclasses.end(); ++nc ) - { - NETCLASSPTR netclass = nc->second; + for( const auto& [ name, netclass ] : netSettings->m_NetClasses ) exportNETCLASS( netclass, aBoard ); - } } -void SPECCTRA_DB::exportNETCLASS( const NETCLASSPTR& aNetClass, BOARD* aBoard ) +void SPECCTRA_DB::exportNETCLASS( const std::shared_ptr& aNetClass, BOARD* aBoard ) { /* From page 11 of specctra spec: * @@ -1829,13 +1819,15 @@ void SPECCTRA_DB::exportNETCLASS( const NETCLASSPTR& aNetClass, BOARD* aBoard ) m_pcb->network->classes.push_back( clazz ); - // freerouter creates a class named 'default' anyway, and if we - // try and use that, we end up with two 'default' via rules so use - // something else as the name of our default class. + // Freerouter creates a class named 'default' anyway, and if we try to use that we end up + // with two 'default' via rules so use something else as the name of our default class. clazz->class_id = TO_UTF8( aNetClass->GetName() ); - for( NETCLASS::iterator net = aNetClass->begin(); net != aNetClass->end(); ++net ) - clazz->net_ids.push_back( TO_UTF8( *net ) ); + for( NETINFO_ITEM* net : aBoard->GetNetInfo() ) + { + if( net->GetNetClass()->GetName() == clazz->class_id ) + clazz->net_ids.push_back( TO_UTF8( net->GetNetname() ) ); + } clazz->rules = new RULE( clazz, T_rule ); @@ -1850,14 +1842,11 @@ void SPECCTRA_DB::exportNETCLASS( const NETCLASSPTR& aNetClass, BOARD* aBoard ) clazz->rules->rules.push_back( text ); if( aNetClass->GetName() == NETCLASS::Default ) - { clazz->class_id = "kicad_default"; - } - // the easiest way to get the via name is to create a via (which generates - // the name internal to the PADSTACK), and then grab the name and then - // delete the via. There are not that many netclasses so - // this should never become a performance issue. + // The easiest way to get the via name is to create a temporary via (which generates the + // name internal to the PADSTACK), and then grab the name and delete the via. There are not + // that many netclasses so this should never become a performance issue. PADSTACK* via = makeVia( aNetClass->GetViaDiameter(), aNetClass->GetViaDrill(), m_top_via_layer, m_bot_via_layer ); @@ -1871,10 +1860,9 @@ void SPECCTRA_DB::exportNETCLASS( const NETCLASSPTR& aNetClass, BOARD* aBoard ) void SPECCTRA_DB::FlipFOOTPRINTs( BOARD* aBoard ) { - // DSN Images (=KiCad FOOTPRINTs and PADs) must be presented from the - // top view. - // Note: to export footprints, the footprints must be flipped around the X axis, - // otherwise the rotation angle is not good + // DSN Images (=KiCad FOOTPRINTs and PADs) must be presented from the top view. + // Note: to export footprints, the footprints must be flipped around the X axis, otherwise + // the rotation angle is not good. for( FOOTPRINT* footprint : aBoard->Footprints() ) { footprint->SetFlag( 0 ); diff --git a/pcbnew/specctra_import_export/specctra_import.cpp b/pcbnew/specctra_import_export/specctra_import.cpp index 7ecc6fbd43..891c77f802 100644 --- a/pcbnew/specctra_import_export/specctra_import.cpp +++ b/pcbnew/specctra_import_export/specctra_import.cpp @@ -546,9 +546,9 @@ void SPECCTRA_DB::FromSESSION( BOARD* aBoard ) psid ) ); } - NETCLASSPTR netclass = aBoard->GetDesignSettings().GetNetClasses().GetDefault(); + std::shared_ptr& netSettings = aBoard->GetDesignSettings().m_NetSettings; - int via_drill_default = netclass->GetViaDrill(); + int via_drill_default = netSettings->m_DefaultNetClass->GetViaDrill(); for( unsigned v = 0; v < wire_via->vertexes.size(); ++v ) { diff --git a/pcbnew/tools/board_inspection_tool.cpp b/pcbnew/tools/board_inspection_tool.cpp index 9d753e9c3d..a3c25ac3b8 100644 --- a/pcbnew/tools/board_inspection_tool.cpp +++ b/pcbnew/tools/board_inspection_tool.cpp @@ -151,7 +151,7 @@ wxString BOARD_INSPECTION_TOOL::getItemDescription( BOARD_ITEM* aItem ) { BOARD_CONNECTED_ITEM* cItem = static_cast( aItem ); s += wxS( " " ) + wxString::Format( _( "[netclass %s]" ), - cItem->GetNetClass()->GetName() ); + cItem->GetEffectiveNetClass()->GetName() ); } return s; diff --git a/pcbnew/tools/drawing_tool.cpp b/pcbnew/tools/drawing_tool.cpp index 2370e2c11b..d65a646a72 100644 --- a/pcbnew/tools/drawing_tool.cpp +++ b/pcbnew/tools/drawing_tool.cpp @@ -3167,7 +3167,7 @@ int DRAWING_TOOL::DrawVia( const TOOL_EVENT& aEvent ) via->SetLayerPair( first_layer, last_layer ); // Update diameter and hole size, which where set previously for normal vias - NETCLASS* netClass = via->GetNetClass(); + NETCLASS* netClass = via->GetEffectiveNetClass(); via->SetWidth( netClass->GetuViaDiameter() ); via->SetDrill( netClass->GetuViaDrill() ); diff --git a/pcbnew/tools/edit_tool.cpp b/pcbnew/tools/edit_tool.cpp index 338713995a..bf518de2a3 100644 --- a/pcbnew/tools/edit_tool.cpp +++ b/pcbnew/tools/edit_tool.cpp @@ -704,7 +704,7 @@ int EDIT_TOOL::ChangeTrackWidth( const TOOL_EVENT& aEvent ) if( via->GetViaType() == VIATYPE::MICROVIA ) { - NETCLASS* netClass = via->GetNetClass(); + NETCLASS* netClass = via->GetEffectiveNetClass(); new_width = netClass->GetuViaDiameter(); new_drill = netClass->GetuViaDrill(); diff --git a/pcbnew/tools/pcb_control.cpp b/pcbnew/tools/pcb_control.cpp index e2b1b6f22e..e7d38e3ad1 100644 --- a/pcbnew/tools/pcb_control.cpp +++ b/pcbnew/tools/pcb_control.cpp @@ -1118,7 +1118,7 @@ int PCB_CONTROL::AppendBoard( PLUGIN& pi, wxString& fileName ) WX_PROGRESS_REPORTER progressReporter( editFrame, _( "Loading PCB" ), 1 ); - editFrame->GetDesignSettings().GetNetClasses().Clear(); + editFrame->GetDesignSettings().m_NetSettings->m_NetClasses.clear(); pi.Load( fileName, brd, &props, nullptr, &progressReporter ); } catch( const IO_ERROR& ioe ) diff --git a/pcbnew/widgets/appearance_controls.cpp b/pcbnew/widgets/appearance_controls.cpp index 4bdadccb18..f27d84df8d 100644 --- a/pcbnew/widgets/appearance_controls.cpp +++ b/pcbnew/widgets/appearance_controls.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -882,7 +883,8 @@ void APPEARANCE_CONTROLS::OnNetGridRightClick( wxGridEvent& event ) { m_netsGrid->SelectRow( event.GetRow() ); - wxString netName = m_netsGrid->GetCellValue( event.GetRow(), NET_GRID_TABLE::COL_LABEL ); + wxString netName = UnescapeString( m_netsGrid->GetCellValue( event.GetRow(), + NET_GRID_TABLE::COL_LABEL ) ); wxMenu menu; menu.Append( new wxMenuItem( &menu, ID_SET_NET_COLOR, _( "Set Net Color" ), wxEmptyString, @@ -2240,7 +2242,7 @@ void APPEARANCE_CONTROLS::rebuildNets() m_netclassOuterSizer->Clear( true ); auto appendNetclass = - [&]( int aId, const NETCLASSPTR& aClass, bool isDefaultClass = false ) + [&]( int aId, const std::shared_ptr& aClass, bool isDefaultClass = false ) { wxString name = aClass->GetName(); @@ -2297,6 +2299,7 @@ void APPEARANCE_CONTROLS::rebuildNets() [&, name, isDefaultClass]( wxMouseEvent& aEvent ) { m_contextMenuNetclass = name; + wxString escapedName = UnescapeString( name ); wxMenu menu; @@ -2308,15 +2311,16 @@ void APPEARANCE_CONTROLS::rebuildNets() } menu.Append( new wxMenuItem( &menu, ID_HIGHLIGHT_NET, - wxString::Format( _( "Highlight Nets in %s" ), name ), - wxEmptyString, wxITEM_NORMAL ) ); + wxString::Format( _( "Highlight Nets in %s" ), + escapedName ), + wxEmptyString, wxITEM_NORMAL ) ); menu.Append( new wxMenuItem( &menu, ID_SELECT_NET, wxString::Format( _( "Select Tracks and Vias in %s" ), - name ), + escapedName ), wxEmptyString, wxITEM_NORMAL ) ); menu.Append( new wxMenuItem( &menu, ID_DESELECT_NET, wxString::Format( _( "Unselect Tracks and Vias in %s" ), - name ), + escapedName ), wxEmptyString, wxITEM_NORMAL ) ); menu.AppendSeparator(); @@ -2340,12 +2344,12 @@ void APPEARANCE_CONTROLS::rebuildNets() setting->ctl_text->Bind( wxEVT_RIGHT_DOWN, menuHandler ); }; - const NETCLASS_MAP& classes = board->GetDesignSettings().GetNetClasses().NetClasses(); + std::shared_ptr& netSettings = board->GetDesignSettings().m_NetSettings; std::vector names; - for( const auto& pair : classes ) - names.emplace_back( pair.first ); + for( const auto& [ name, netclass ] : netSettings->m_NetClasses ) + names.emplace_back( name ); std::sort( names.begin(), names.end() ); @@ -2353,15 +2357,13 @@ void APPEARANCE_CONTROLS::rebuildNets() int idx = wxID_HIGHEST; - NETCLASSPTR defaultClass = board->GetDesignSettings().GetNetClasses().GetDefault(); - - m_netclassIdMap[idx] = defaultClass->GetName(); - appendNetclass( idx++, defaultClass, true ); + m_netclassIdMap[idx] = netSettings->m_DefaultNetClass->GetName(); + appendNetclass( idx++, netSettings->m_DefaultNetClass, true ); for( const wxString& name : names ) { m_netclassIdMap[idx] = name; - appendNetclass( idx++, classes.at( name ) ); + appendNetclass( idx++, netSettings->m_NetClasses.at( name ) ); } int hotkey; @@ -2926,50 +2928,19 @@ void APPEARANCE_CONTROLS::onNetclassVisibilityChanged( wxCommandEvent& aEvent ) void APPEARANCE_CONTROLS::showNetclass( const wxString& aClassName, bool aShow ) { - BOARD* board = m_frame->GetBoard(); - NETINFO_LIST& nets = board->GetNetInfo(); - NETCLASSES& classes = board->GetDesignSettings().GetNetClasses(); - NETCLASSPTR netclass = classes.Find( aClassName ); - TOOL_MANAGER* manager = m_frame->GetToolManager(); - - if( !netclass ) - return; - - NETCLASS* defaultClass = classes.GetDefaultPtr(); - - if( netclass == classes.GetDefault() ) + for( NETINFO_ITEM* net : m_frame->GetBoard()->GetNetInfo() ) { - const TOOL_ACTION& action = aShow ? PCB_ACTIONS::showNet : PCB_ACTIONS::hideNet; - - for( NETINFO_ITEM* net : nets ) + if( net->GetNetClass()->GetName() == aClassName ) { - if( net->GetNetClass() == defaultClass ) - { - manager->RunAction( action, true, static_cast( net->GetNetCode() ) ); + m_frame->GetToolManager()->RunAction( aShow ? PCB_ACTIONS::showNet + : PCB_ACTIONS::hideNet, + true, + static_cast( net->GetNetCode() ) ); - int row = m_netsTable->GetRowByNetcode( net->GetNetCode() ); + int row = m_netsTable->GetRowByNetcode( net->GetNetCode() ); - if( row >= 0 ) - m_netsTable->SetValueAsBool( row, NET_GRID_TABLE::COL_VISIBILITY, aShow ); - } - } - } - else - { - const TOOL_ACTION& action = aShow ? PCB_ACTIONS::showNet : PCB_ACTIONS::hideNet; - - for( const wxString& member : *netclass ) - { - if( NETINFO_ITEM* net = nets.GetNetItem( member ) ) - { - int code = net->GetNetCode(); - manager->RunAction( action, true, static_cast( code ) ); - - int row = m_netsTable->GetRowByNetcode( code ); - - if( row >= 0 ) - m_netsTable->SetValueAsBool( row, NET_GRID_TABLE::COL_VISIBILITY, aShow ); - } + if( row >= 0 ) + m_netsTable->SetValueAsBool( row, NET_GRID_TABLE::COL_VISIBILITY, aShow ); } } @@ -3052,30 +3023,20 @@ void APPEARANCE_CONTROLS::onNetclassContextMenu( wxCommandEvent& aEvent ) KIGFX::PCB_RENDER_SETTINGS* rs = static_cast( view->GetPainter()->GetSettings() ); - BOARD* board = m_frame->GetBoard(); - NETINFO_LIST& nets = board->GetNetInfo(); - NETCLASSES& classes = board->GetDesignSettings().GetNetClasses(); - NETCLASSPTR netclass = classes.Find( m_contextMenuNetclass ); + BOARD* board = m_frame->GetBoard(); + std::shared_ptr& netSettings = board->GetDesignSettings().m_NetSettings; + APPEARANCE_SETTING* setting = m_netclassSettingsMap.count( m_contextMenuNetclass ) ? m_netclassSettingsMap.at( m_contextMenuNetclass ) : nullptr; - NETCLASSPTR defaultClass = classes.GetDefault(); - wxString defaultClassName = defaultClass->GetName(); - auto runOnNetsOfClass = - [&]( NETCLASSPTR aClass, std::function aFunction ) + [&]( const wxString& netClassName, std::function aFunction ) { - if( aClass == defaultClass ) + for( NETINFO_ITEM* net : board->GetNetInfo() ) { - for( NETINFO_ITEM* net : nets ) - if( net->GetNetClass() == defaultClass.get() ) - aFunction( net ); - } - else - { - for( const wxString& netName : *aClass ) - aFunction( nets.GetNetItem( netName ) ); + if( net->GetNetClass()->GetName() == netClassName ) + aFunction( net ); } }; @@ -3104,14 +3065,11 @@ void APPEARANCE_CONTROLS::onNetclassContextMenu( wxCommandEvent& aEvent ) case ID_HIGHLIGHT_NET: { - if( netclass ) + if( !m_contextMenuNetclass.IsEmpty() ) { - runOnNetsOfClass( netclass, + runOnNetsOfClass( m_contextMenuNetclass, [&]( NETINFO_ITEM* aItem ) { - if( !aItem ) - return; - static bool first = true; int code = aItem->GetNetCode(); @@ -3137,18 +3095,17 @@ void APPEARANCE_CONTROLS::onNetclassContextMenu( wxCommandEvent& aEvent ) case ID_SELECT_NET: case ID_DESELECT_NET: { - if( netclass ) + if( !m_contextMenuNetclass.IsEmpty() ) { - TOOL_ACTION& action = aEvent.GetId() == ID_SELECT_NET ? PCB_ACTIONS::selectNet : - PCB_ACTIONS::deselectNet; - runOnNetsOfClass( netclass, + TOOL_MANAGER* toolMgr = m_frame->GetToolManager(); + TOOL_ACTION& action = aEvent.GetId() == ID_SELECT_NET ? PCB_ACTIONS::selectNet + : PCB_ACTIONS::deselectNet; + + runOnNetsOfClass( m_contextMenuNetclass, [&]( NETINFO_ITEM* aItem ) { - if( !aItem ) - return; - - intptr_t code = static_cast( aItem->GetNetCode() ); - m_frame->GetToolManager()->RunAction( action, true, code ); + toolMgr->RunAction( action, true, + static_cast( aItem->GetNetCode() ) ); } ); } break; @@ -3156,16 +3113,16 @@ void APPEARANCE_CONTROLS::onNetclassContextMenu( wxCommandEvent& aEvent ) case ID_SHOW_ALL_NETS: { - showNetclass( defaultClassName ); - wxASSERT( m_netclassSettingsMap.count( defaultClassName ) ); - m_netclassSettingsMap.at( defaultClassName )->ctl_visibility->SetValue( true ); + showNetclass( NETCLASS::Default ); + wxASSERT( m_netclassSettingsMap.count( NETCLASS::Default ) ); + m_netclassSettingsMap.at( NETCLASS::Default )->ctl_visibility->SetValue( true ); - for( const auto& pair : classes.NetClasses() ) + for( const auto& [ name, netclass ] : netSettings->m_NetClasses ) { - showNetclass( pair.first ); + showNetclass( name ); - if( m_netclassSettingsMap.count( pair.first ) ) - m_netclassSettingsMap.at( pair.first )->ctl_visibility->SetValue( true ); + if( m_netclassSettingsMap.count( name ) ) + m_netclassSettingsMap.at( name )->ctl_visibility->SetValue( true ); } break; @@ -3173,19 +3130,19 @@ void APPEARANCE_CONTROLS::onNetclassContextMenu( wxCommandEvent& aEvent ) case ID_HIDE_OTHER_NETS: { - bool showDefault = m_contextMenuNetclass == defaultClassName; - showNetclass( defaultClassName, showDefault ); - wxASSERT( m_netclassSettingsMap.count( defaultClassName ) ); - m_netclassSettingsMap.at( defaultClassName )->ctl_visibility->SetValue( showDefault ); + bool showDefault = m_contextMenuNetclass == NETCLASS::Default; + showNetclass( NETCLASS::Default, showDefault ); + wxASSERT( m_netclassSettingsMap.count( NETCLASS::Default ) ); + m_netclassSettingsMap.at( NETCLASS::Default )->ctl_visibility->SetValue( showDefault ); - for( const auto& pair : classes.NetClasses() ) + for( const auto& [ name, netclass ] : netSettings->m_NetClasses ) { - bool show = pair.first == m_contextMenuNetclass; + bool show = ( name == m_contextMenuNetclass ); - showNetclass( pair.first, show ); + showNetclass( name, show ); - if( m_netclassSettingsMap.count( pair.first ) ) - m_netclassSettingsMap.at( pair.first )->ctl_visibility->SetValue( show ); + if( m_netclassSettingsMap.count( name ) ) + m_netclassSettingsMap.at( name )->ctl_visibility->SetValue( show ); } break; diff --git a/pcbnew/zone.cpp b/pcbnew/zone.cpp index 67f0993b84..1eb510c838 100644 --- a/pcbnew/zone.cpp +++ b/pcbnew/zone.cpp @@ -530,7 +530,8 @@ void ZONE::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector& { aList.emplace_back( _( "Net" ), UnescapeString( GetNetname() ) ); - aList.emplace_back( _( "Net Class" ), UnescapeString( GetNetClass()->GetName() ) ); + aList.emplace_back( _( "Resolved Netclass" ), + UnescapeString( GetEffectiveNetClass()->GetName() ) ); } // Display priority level diff --git a/pcbnew/zone.h b/pcbnew/zone.h index 24b80c32f7..7bda8fce60 100644 --- a/pcbnew/zone.h +++ b/pcbnew/zone.h @@ -85,22 +85,6 @@ public: return !GetIsRuleArea(); } - NETCLASS* GetNetClass() const override - { - if( GetIsRuleArea() ) - return nullptr; - - return BOARD_CONNECTED_ITEM::GetNetClass(); - } - - wxString GetNetClassName() const override - { - if( GetIsRuleArea() ) - return "UNDEFINED"; - - return BOARD_CONNECTED_ITEM::GetNetClassName(); - } - /** * Copy aZone data to me */ diff --git a/qa/unittests/pcbnew/test_libeval_compiler.cpp b/qa/unittests/pcbnew/test_libeval_compiler.cpp index 007a8fcd80..b6f0279ce4 100644 --- a/qa/unittests/pcbnew/test_libeval_compiler.cpp +++ b/qa/unittests/pcbnew/test_libeval_compiler.cpp @@ -154,8 +154,8 @@ BOOST_AUTO_TEST_CASE( IntrospectedProperties ) NETINFO_LIST& netInfo = brd.GetNetInfo(); - NETCLASSPTR netclass1( new NETCLASS( "HV" ) ); - NETCLASSPTR netclass2( new NETCLASS( "otherClass" ) ); + std::shared_ptr netclass1( new NETCLASS( "HV" ) ); + std::shared_ptr netclass2( new NETCLASS( "otherClass" ) ); auto net1info = new NETINFO_ITEM( &brd, "net1", 1 ); auto net2info = new NETINFO_ITEM( &brd, "net2", 2 );