From 4fe05bfe47ae1fa9dad555ed0f7046dbdca45d89 Mon Sep 17 00:00:00 2001
From: Jeff Young <jeff@rokeby.ie>
Date: Tue, 21 Jan 2025 23:38:55 +0000
Subject: [PATCH] Remove some more usages of MANDATORY_FIELDS.

---
 eeschema/dialogs/dialog_change_symbols.cpp    |  7 +----
 .../dialogs/dialog_lib_symbol_properties.cpp  |  8 ++---
 eeschema/dialogs/dialog_sheet_properties.cpp  | 16 ++++++----
 eeschema/dialogs/dialog_symbol_properties.cpp | 16 ++++++----
 eeschema/fields_grid_table.cpp                | 29 ++++++++++++++-----
 eeschema/fields_grid_table.h                  |  3 +-
 .../netlist_exporter_xml.cpp                  | 20 +++++++------
 eeschema/sch_sheet.cpp                        | 12 ++++----
 .../dialogs/dialog_footprint_properties.cpp   |  6 ++--
 .../dialog_footprint_properties_fp_editor.cpp |  6 ++--
 pcbnew/pcb_fields_grid_table.cpp              |  2 +-
 pcbnew/pcb_fields_grid_table.h                |  4 +--
 12 files changed, 75 insertions(+), 54 deletions(-)

diff --git a/eeschema/dialogs/dialog_change_symbols.cpp b/eeschema/dialogs/dialog_change_symbols.cpp
index 159347352a..3ce209c629 100644
--- a/eeschema/dialogs/dialog_change_symbols.cpp
+++ b/eeschema/dialogs/dialog_change_symbols.cpp
@@ -425,14 +425,9 @@ void DIALOG_CHANGE_SYMBOLS::onOkButtonClicked( wxCommandEvent& aEvent )
         if( m_fieldsBox->IsChecked( i ) )
         {
             if( i < MANDATORY_FIELDS )
-            {
-                SCH_FIELD dummy_field( nullptr, i );
-                m_updateFields.insert( dummy_field.GetCanonicalName() );
-            }
+                m_updateFields.insert( GetCanonicalFieldName( i ) );
             else
-            {
                 m_updateFields.insert( m_fieldsBox->GetString( i ) );
-            }
         }
     }
 
diff --git a/eeschema/dialogs/dialog_lib_symbol_properties.cpp b/eeschema/dialogs/dialog_lib_symbol_properties.cpp
index 4529c2edc6..0797afe1ec 100644
--- a/eeschema/dialogs/dialog_lib_symbol_properties.cpp
+++ b/eeschema/dialogs/dialog_lib_symbol_properties.cpp
@@ -628,10 +628,10 @@ void DIALOG_LIB_SYMBOL_PROPERTIES::OnDeleteField( wxCommandEvent& event )
 
     for( int row : selectedRows )
     {
-        if( row < MANDATORY_FIELDS )
+        if( row < m_fields->GetMandatoryRowCount() )
         {
             DisplayError( this, wxString::Format( _( "The first %d fields are mandatory." ),
-                                                  MANDATORY_FIELDS ) );
+                                                  m_fields->GetMandatoryRowCount() ) );
             return;
         }
     }
@@ -668,7 +668,7 @@ void DIALOG_LIB_SYMBOL_PROPERTIES::OnMoveUp( wxCommandEvent& event )
 
     int i = m_grid->GetGridCursorRow();
 
-    if( i > MANDATORY_FIELDS )
+    if( i > m_fields->GetMandatoryRowCount() )
     {
         SCH_FIELD tmp = m_fields->at( (unsigned) i );
         m_fields->erase( m_fields->begin() + i, m_fields->begin() + i + 1 );
@@ -694,7 +694,7 @@ void DIALOG_LIB_SYMBOL_PROPERTIES::OnMoveDown( wxCommandEvent& event )
 
     int i = m_grid->GetGridCursorRow();
 
-    if( i >= MANDATORY_FIELDS && i + 1 < m_fields->GetNumberRows() )
+    if( i >= m_fields->GetMandatoryRowCount() && i + 1 < m_fields->GetNumberRows() )
     {
         SCH_FIELD tmp = m_fields->at( (unsigned) i );
         m_fields->erase( m_fields->begin() + i, m_fields->begin() + i + 1 );
diff --git a/eeschema/dialogs/dialog_sheet_properties.cpp b/eeschema/dialogs/dialog_sheet_properties.cpp
index ad038fffbb..224b1b4c48 100644
--- a/eeschema/dialogs/dialog_sheet_properties.cpp
+++ b/eeschema/dialogs/dialog_sheet_properties.cpp
@@ -380,9 +380,13 @@ bool DIALOG_SHEET_PROPERTIES::TransferDataFromWindow()
     if( positioningChanged( m_fields, m_sheet->GetFields() ) )
         m_sheet->SetFieldsAutoplaced( AUTOPLACE_NONE );
 
-    for( int ii = m_fields->GetNumberRows() - 1; ii >= SHEET_MANDATORY_FIELDS; ii-- )
+    for( int ii = m_fields->GetNumberRows() - 1; ii >= 0; ii-- )
     {
-        SCH_FIELD&      field = m_fields->at( ii );
+        SCH_FIELD& field = m_fields->at( ii );
+
+        if( field.IsMandatory() )
+            continue;
+
         const wxString& fieldName = field.GetCanonicalName();
 
         if( field.IsEmpty() )
@@ -776,10 +780,10 @@ void DIALOG_SHEET_PROPERTIES::OnDeleteField( wxCommandEvent& event )
 
     for( int row : selectedRows )
     {
-        if( row < SHEET_MANDATORY_FIELDS )
+        if( row < m_fields->GetMandatoryRowCount() )
         {
             DisplayError( this, wxString::Format( _( "The first %d fields are mandatory." ),
-                                                  SHEET_MANDATORY_FIELDS ) );
+                                                  m_fields->GetMandatoryRowCount() ) );
             return;
         }
     }
@@ -813,7 +817,7 @@ void DIALOG_SHEET_PROPERTIES::OnMoveUp( wxCommandEvent& event )
 
     int i = m_grid->GetGridCursorRow();
 
-    if( i > SHEET_MANDATORY_FIELDS )
+    if( i > m_fields->GetMandatoryRowCount() )
     {
         SCH_FIELD tmp = m_fields->at( (unsigned) i );
         m_fields->erase( m_fields->begin() + i, m_fields->begin() + i + 1 );
@@ -837,7 +841,7 @@ void DIALOG_SHEET_PROPERTIES::OnMoveDown( wxCommandEvent& event )
 
     int i = m_grid->GetGridCursorRow();
 
-    if( i >= SHEET_MANDATORY_FIELDS && i < m_grid->GetNumberRows() - 1 )
+    if( i >= m_fields->GetMandatoryRowCount() && i < m_grid->GetNumberRows() - 1 )
     {
         SCH_FIELD tmp = m_fields->at( (unsigned) i );
         m_fields->erase( m_fields->begin() + i, m_fields->begin() + i + 1 );
diff --git a/eeschema/dialogs/dialog_symbol_properties.cpp b/eeschema/dialogs/dialog_symbol_properties.cpp
index 25c602faca..61ccb55c1d 100644
--- a/eeschema/dialogs/dialog_symbol_properties.cpp
+++ b/eeschema/dialogs/dialog_symbol_properties.cpp
@@ -636,10 +636,14 @@ bool DIALOG_SYMBOL_PROPERTIES::Validate()
         return false;
 
     // Check for missing field names.
-    for( size_t i = MANDATORY_FIELDS;  i < m_fields->size(); ++i )
+    for( size_t i = 0; i < m_fields->size(); ++i )
     {
         SCH_FIELD& field = m_fields->at( i );
-        wxString   fieldName = field.GetName( false );
+
+        if( field.IsMandatory() )
+            continue;
+
+        wxString fieldName = field.GetName( false );
 
         if( fieldName.IsEmpty() )
         {
@@ -873,10 +877,10 @@ void DIALOG_SYMBOL_PROPERTIES::OnDeleteField( wxCommandEvent& event )
 
     for( int row : selectedRows )
     {
-        if( row < MANDATORY_FIELDS )
+        if( row < m_fields->GetMandatoryRowCount() )
         {
             DisplayError( this, wxString::Format( _( "The first %d fields are mandatory." ),
-                                                  MANDATORY_FIELDS ) );
+                                                  m_fields->GetMandatoryRowCount() ) );
             return;
         }
     }
@@ -913,7 +917,7 @@ void DIALOG_SYMBOL_PROPERTIES::OnMoveUp( wxCommandEvent& event )
 
     int i = m_fieldsGrid->GetGridCursorRow();
 
-    if( i > MANDATORY_FIELDS )
+    if( i > m_fields->GetMandatoryRowCount() )
     {
         SCH_FIELD tmp = m_fields->at( (unsigned) i );
         m_fields->erase( m_fields->begin() + i, m_fields->begin() + i + 1 );
@@ -940,7 +944,7 @@ void DIALOG_SYMBOL_PROPERTIES::OnMoveDown( wxCommandEvent& event )
 
     int i = m_fieldsGrid->GetGridCursorRow();
 
-    if( i >= MANDATORY_FIELDS && i < m_fieldsGrid->GetNumberRows() - 1 )
+    if( i >= m_fields->GetMandatoryRowCount() && i < m_fieldsGrid->GetNumberRows() - 1 )
     {
         SCH_FIELD tmp = m_fields->at( (unsigned) i );
         m_fields->erase( m_fields->begin() + i, m_fields->begin() + i + 1 );
diff --git a/eeschema/fields_grid_table.cpp b/eeschema/fields_grid_table.cpp
index fbbf923147..1a3eab5515 100644
--- a/eeschema/fields_grid_table.cpp
+++ b/eeschema/fields_grid_table.cpp
@@ -135,7 +135,6 @@ FIELDS_GRID_TABLE::FIELDS_GRID_TABLE( DIALOG_SHIM* aDialog, SCH_BASE_FRAME* aFra
         m_frame( aFrame ),
         m_dialog( aDialog ),
         m_parentType( SCH_SYMBOL_T ),
-        m_mandatoryFieldCount( MANDATORY_FIELDS ),
         m_part( aSymbol ),
         m_symbolNetlist( netList( aSymbol ) ),
         m_fieldNameValidator( FIELD_NAME ),
@@ -154,7 +153,6 @@ FIELDS_GRID_TABLE::FIELDS_GRID_TABLE( DIALOG_SHIM* aDialog, SCH_EDIT_FRAME* aFra
         m_frame( aFrame ),
         m_dialog( aDialog ),
         m_parentType( SCH_SYMBOL_T ),
-        m_mandatoryFieldCount( MANDATORY_FIELDS ),
         m_part( aSymbol->GetLibSymbolRef().get() ),
         m_symbolNetlist( netList( aSymbol, aFrame->GetCurrentSheet() ) ),
         m_fieldNameValidator( FIELD_NAME ),
@@ -173,7 +171,6 @@ SCH_SHEET* aSheet ) :
         m_frame( aFrame ),
         m_dialog( aDialog ),
         m_parentType( SCH_SHEET_T ),
-        m_mandatoryFieldCount( SHEET_MANDATORY_FIELDS ),
         m_part( nullptr ),
         m_fieldNameValidator( FIELD_NAME ),
         m_referenceValidator( SHEETNAME_V ),
@@ -191,7 +188,6 @@ FIELDS_GRID_TABLE::FIELDS_GRID_TABLE( DIALOG_SHIM* aDialog, SCH_EDIT_FRAME* aFra
         m_frame( aFrame ),
         m_dialog( aDialog ),
         m_parentType( SCH_LABEL_LOCATE_ANY_T ),
-        m_mandatoryFieldCount( aLabel->GetMandatoryFieldCount() ),
         m_part( nullptr ),
         m_fieldNameValidator( FIELD_NAME ),
         m_referenceValidator( 0 ),
@@ -204,6 +200,20 @@ FIELDS_GRID_TABLE::FIELDS_GRID_TABLE( DIALOG_SHIM* aDialog, SCH_EDIT_FRAME* aFra
 }
 
 
+int FIELDS_GRID_TABLE::GetMandatoryRowCount() const
+{
+    int mandatoryRows = 0;
+
+    for( const SCH_FIELD& field : *this )
+    {
+        if( field.IsMandatory() )
+            mandatoryRows++;
+    }
+
+    return mandatoryRows;
+}
+
+
 void FIELDS_GRID_TABLE::initGrid( WX_GRID* aGrid )
 {
     // Build the various grid cell attributes.
@@ -525,12 +535,15 @@ bool FIELDS_GRID_TABLE::CanSetValueAs( int aRow, int aCol, const wxString& aType
 
 wxGridCellAttr* FIELDS_GRID_TABLE::GetAttr( int aRow, int aCol, wxGridCellAttr::wxAttrKind aKind  )
 {
-    wxGridCellAttr* tmp;
+    wxCHECK( aRow < GetNumberRows(), nullptr );
+
+    const SCH_FIELD& field = getField( aRow );
+    wxGridCellAttr*  tmp;
 
     switch( aCol )
     {
     case FDC_NAME:
-        if( aRow < m_mandatoryFieldCount )
+        if( field.IsMandatory() )
         {
             tmp = m_fieldNameAttr->Clone();
             tmp->SetReadOnly( true );
@@ -675,14 +688,14 @@ wxString FIELDS_GRID_TABLE::GetValue( int aRow, int aCol )
         // according to the current locale
         if( m_parentType == SCH_SYMBOL_T || m_parentType == LIB_SYMBOL_T )
         {
-            if( aRow < m_mandatoryFieldCount )
+            if( field.IsMandatory() )
                 return GetDefaultFieldName( aRow, DO_TRANSLATE );
             else
                 return field.GetName( false );
         }
         else if( m_parentType == SCH_SHEET_T )
         {
-            if( aRow < m_mandatoryFieldCount )
+            if( field.IsMandatory() )
                 return SCH_SHEET::GetDefaultFieldName( aRow, DO_TRANSLATE );
             else
                 return field.GetName( false );
diff --git a/eeschema/fields_grid_table.h b/eeschema/fields_grid_table.h
index d55d8428cf..06e4c7aa59 100644
--- a/eeschema/fields_grid_table.h
+++ b/eeschema/fields_grid_table.h
@@ -97,6 +97,8 @@ public:
     int GetNumberRows() override { return getVisibleRowCount(); }
     int GetNumberCols() override { return getColumnCount(); }
 
+    int GetMandatoryRowCount() const;
+
     wxString GetColLabelValue( int aCol ) override;
 
     bool IsEmptyCell( int row, int col ) override
@@ -131,7 +133,6 @@ private:
     SCH_BASE_FRAME*   m_frame;
     DIALOG_SHIM*      m_dialog;
     KICAD_T           m_parentType;
-    int               m_mandatoryFieldCount;
     LIB_SYMBOL*       m_part;
     wxString          m_symbolNetlist;
     wxString          m_curdir;
diff --git a/eeschema/netlist_exporters/netlist_exporter_xml.cpp b/eeschema/netlist_exporters/netlist_exporter_xml.cpp
index 7b01537b24..5fd3c4c636 100644
--- a/eeschema/netlist_exporters/netlist_exporter_xml.cpp
+++ b/eeschema/netlist_exporters/netlist_exporter_xml.cpp
@@ -160,16 +160,17 @@ void NETLIST_EXPORTER_XML::addSymbolFields( XNODE* aNode, SCH_SYMBOL* aSymbol,
                     description = candidate;
 
                 // All non-mandatory fields
-                for( int ii = MANDATORY_FIELDS; ii < symbol2->GetFieldCount(); ++ii )
+                for( SCH_FIELD& field : symbol2->GetFields() )
                 {
-                    const SCH_FIELD& f = symbol2->GetFields()[ ii ];
+                    if( field.IsMandatory() )
+                        continue;
 
-                    if( unit < minUnit || fields.count( f.GetName() ) == 0 )
+                    if( unit < minUnit || fields.count( field.GetName() ) == 0 )
                     {
                         if( m_resolveTextVars )
-                            fields[f.GetName()] = f.GetShownText( &aSheet, false );
+                            fields[field.GetName()] = field.GetShownText( &aSheet, false );
                         else
-                            fields[f.GetName()] = f.GetText();
+                            fields[field.GetName()] = field.GetText();
                     }
                 }
 
@@ -197,14 +198,15 @@ void NETLIST_EXPORTER_XML::addSymbolFields( XNODE* aNode, SCH_SYMBOL* aSymbol,
         else
             description = descriptionField->GetText();
 
-        for( int ii = MANDATORY_FIELDS; ii < aSymbol->GetFieldCount(); ++ii )
+        for( SCH_FIELD& field : aSymbol->GetFields() )
         {
-            const SCH_FIELD& f = aSymbol->GetFields()[ ii ];
+            if( field.IsMandatory() )
+                continue;
 
             if( m_resolveTextVars )
-                fields[f.GetName()] = f.GetShownText( &aSheet, false );
+                fields[field.GetName()] = field.GetShownText( &aSheet, false );
             else
-                fields[f.GetName()] = f.GetText();
+                fields[field.GetName()] = field.GetText();
         }
     }
 
diff --git a/eeschema/sch_sheet.cpp b/eeschema/sch_sheet.cpp
index 71cd5bcdf6..9fd57243e0 100644
--- a/eeschema/sch_sheet.cpp
+++ b/eeschema/sch_sheet.cpp
@@ -216,11 +216,13 @@ void SCH_SHEET::GetContextualTextVars( wxArrayString* aVars ) const
                     aVars->push_back( aVar );
             };
 
-    for( int i = 0; i < SHEET_MANDATORY_FIELDS; ++i )
-        add( m_fields[i].GetCanonicalName().Upper() );
-
-    for( size_t i = SHEET_MANDATORY_FIELDS; i < m_fields.size(); ++i )
-        add( m_fields[i].GetName() );
+    for( const SCH_FIELD& field : m_fields )
+    {
+        if( field.IsMandatory() )
+            add( field.GetCanonicalName().Upper() );
+        else
+            add( field.GetName() );
+    }
 
     SCH_SHEET_PATH sheetPath = findSelf();
 
diff --git a/pcbnew/dialogs/dialog_footprint_properties.cpp b/pcbnew/dialogs/dialog_footprint_properties.cpp
index 8596fea64a..52f280d4ba 100644
--- a/pcbnew/dialogs/dialog_footprint_properties.cpp
+++ b/pcbnew/dialogs/dialog_footprint_properties.cpp
@@ -684,10 +684,10 @@ void DIALOG_FOOTPRINT_PROPERTIES::OnDeleteField( wxCommandEvent&  )
     for( int row : selectedRows )
     {
 
-        if( row < m_fields->GetMandatoryRows() )
+        if( row < m_fields->GetMandatoryRowCount() )
         {
             DisplayError( this, wxString::Format( _( "The first %d fields are mandatory." ),
-                                                  m_fields->GetMandatoryRows() ) );
+                                                  m_fields->GetMandatoryRowCount() ) );
             return;
         }
     }
@@ -778,7 +778,7 @@ void DIALOG_FOOTPRINT_PROPERTIES::OnUpdateUI( wxUpdateUIEvent&  )
         {
             grid->SetGridCursor( row, col );
 
-            if( !( col == 0 && row < m_fields->GetMandatoryRows() ) )
+            if( !( col == 0 && row < m_fields->GetMandatoryRowCount() ) )
                 grid->EnableCellEditControl( true );
 
             grid->ShowCellEditControl();
diff --git a/pcbnew/dialogs/dialog_footprint_properties_fp_editor.cpp b/pcbnew/dialogs/dialog_footprint_properties_fp_editor.cpp
index e5da71b897..c9061d7cbc 100644
--- a/pcbnew/dialogs/dialog_footprint_properties_fp_editor.cpp
+++ b/pcbnew/dialogs/dialog_footprint_properties_fp_editor.cpp
@@ -680,10 +680,10 @@ void DIALOG_FOOTPRINT_PROPERTIES_FP_EDITOR::OnDeleteField( wxCommandEvent& event
 
     for( int row : selectedRows )
     {
-        if( row < m_fields->GetMandatoryRows() )
+        if( row < m_fields->GetMandatoryRowCount() )
         {
             DisplayError( this, wxString::Format( _( "The first %d fields are mandatory." ),
-                                                  m_fields->GetMandatoryRows() ) );
+                                                  m_fields->GetMandatoryRowCount() ) );
             return;
         }
     }
@@ -884,7 +884,7 @@ void DIALOG_FOOTPRINT_PROPERTIES_FP_EDITOR::OnUpdateUI( wxUpdateUIEvent& event )
         m_delayedFocusGrid->MakeCellVisible( m_delayedFocusRow, m_delayedFocusColumn );
         m_delayedFocusGrid->SetGridCursor( m_delayedFocusRow, m_delayedFocusColumn );
 
-        if( !( m_delayedFocusColumn == 0 && m_delayedFocusRow < m_fields->GetMandatoryRows() ) )
+        if( !( m_delayedFocusColumn == 0 && m_delayedFocusRow < m_fields->GetMandatoryRowCount() ) )
             m_delayedFocusGrid->EnableCellEditControl( true );
 
         m_delayedFocusGrid->ShowCellEditControl();
diff --git a/pcbnew/pcb_fields_grid_table.cpp b/pcbnew/pcb_fields_grid_table.cpp
index 41e51cc522..1254dbe595 100644
--- a/pcbnew/pcb_fields_grid_table.cpp
+++ b/pcbnew/pcb_fields_grid_table.cpp
@@ -144,7 +144,7 @@ PCB_FIELDS_GRID_TABLE::~PCB_FIELDS_GRID_TABLE()
 }
 
 
-int PCB_FIELDS_GRID_TABLE::GetMandatoryRows()
+int PCB_FIELDS_GRID_TABLE::GetMandatoryRowCount() const
 {
     int mandatoryRows = 0;
 
diff --git a/pcbnew/pcb_fields_grid_table.h b/pcbnew/pcb_fields_grid_table.h
index fb8428aaf7..97d9df77a3 100644
--- a/pcbnew/pcb_fields_grid_table.h
+++ b/pcbnew/pcb_fields_grid_table.h
@@ -62,7 +62,8 @@ public:
 
     int GetNumberRows() override { return (int) size(); }
     int GetNumberCols() override { return PFC_COUNT; }
-    int GetMandatoryRows();
+
+    int GetMandatoryRowCount() const;
 
     wxString GetColLabelValue( int aCol ) override;
 
@@ -89,7 +90,6 @@ protected:
 private:
     PCB_BASE_FRAME* m_frame;
     DIALOG_SHIM*    m_dialog;
-    int             m_mandatoryRows;
 
     FIELD_VALIDATOR m_fieldNameValidator;
     FIELD_VALIDATOR m_referenceValidator;