From bc29c145afb940620eb6c64122d99c2e0a4e00c9 Mon Sep 17 00:00:00 2001
From: Jeff Young <jeff@rokeby.ie>
Date: Sat, 21 Dec 2024 14:27:23 +0000
Subject: [PATCH] Simulation model lib is not sorted, but listbox is.

Don't attempt to use an index from one in the other.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/19306
---
 eeschema/dialogs/dialog_sim_model.cpp | 32 ++++++++++++++++++++++-----
 eeschema/dialogs/dialog_sim_model.h   |  2 ++
 2 files changed, 28 insertions(+), 6 deletions(-)

diff --git a/eeschema/dialogs/dialog_sim_model.cpp b/eeschema/dialogs/dialog_sim_model.cpp
index e8074a7983..932e7c9c4e 100644
--- a/eeschema/dialogs/dialog_sim_model.cpp
+++ b/eeschema/dialogs/dialog_sim_model.cpp
@@ -253,7 +253,12 @@ bool DIALOG_SIM_MODEL<T>::TransferDataToWindow()
 
         if( isIbisLoaded() && ( m_modelListBox->GetSelection() >= 0 ) )
         {
-            int  idx = m_modelListBox->GetSelection();
+            int      idx = 0;
+            wxString sel = m_modelListBox->GetStringSelection();
+
+            if( m_modelListBoxEntryToLibraryIdx.contains( sel ) )
+                idx = m_modelListBoxEntryToLibraryIdx.at( sel );
+
             auto ibismodel = dynamic_cast<SIM_MODEL_IBIS*>( &m_libraryModelsMgr.GetModels()[idx].get() );
 
             if( ibismodel )
@@ -375,8 +380,13 @@ bool DIALOG_SIM_MODEL<T>::TransferDataFromWindow()
 
     if( isIbisLoaded() )
     {
-        SIM_MODEL_IBIS* ibismodel = static_cast<SIM_MODEL_IBIS*>(
-                &m_libraryModelsMgr.GetModels().at( m_modelListBox->GetSelection() ).get() );
+        int      idx = 0;
+        wxString sel = m_modelListBox->GetStringSelection();
+
+        if( m_modelListBoxEntryToLibraryIdx.contains( sel ) )
+            idx = m_modelListBoxEntryToLibraryIdx.at( sel );
+
+        auto* ibismodel = static_cast<SIM_MODEL_IBIS*>( &m_libraryModelsMgr.GetModels().at( idx ).get() );
 
         if( ibismodel )
         {
@@ -832,10 +842,14 @@ bool DIALOG_SIM_MODEL<T>::loadLibrary( const wxString& aLibraryPath, REPORTER& a
     m_rbLibraryModel->SetValue( true );
     m_libraryPathText->ChangeValue( aLibraryPath );
 
+    m_modelListBoxEntryToLibraryIdx.clear();
     wxArrayString modelNames;
 
     for( const auto& [name, model] : library()->GetModels() )
+    {
         modelNames.Add( name );
+        m_modelListBoxEntryToLibraryIdx[name] = m_modelListBoxEntryToLibraryIdx.size();
+    }
 
     modelNames.Sort();
 
@@ -1084,8 +1098,10 @@ SIM_MODEL& DIALOG_SIM_MODEL<T>::curModel() const
 {
     if( m_rbLibraryModel->GetValue() )
     {
-        if( library() && m_modelListBox->GetSelection() >= 0 )
-            return *library()->FindModel( m_modelListBox->GetStringSelection().ToStdString() );
+        wxString sel = m_modelListBox->GetStringSelection();
+
+        if( m_modelListBoxEntryToLibraryIdx.contains( sel ) )
+            return m_libraryModelsMgr.GetModels().at( m_modelListBoxEntryToLibraryIdx.at( sel ) ).get();
     }
     else
     {
@@ -1453,7 +1469,11 @@ void DIALOG_SIM_MODEL<T>::onWaveformChoice( wxCommandEvent& aEvent )
         if( equivalent( deviceType, SIM_MODEL::TypeInfo( type ).deviceType )
             && typeDescription == SIM_MODEL::TypeInfo( type ).description )
         {
-            int idx = m_modelListBox->GetSelection();
+            int      idx = 0;
+            wxString sel = m_modelListBox->GetStringSelection();
+
+            if( m_modelListBoxEntryToLibraryIdx.contains( sel ) )
+                idx = m_modelListBoxEntryToLibraryIdx.at( sel );
 
             auto& baseModel = static_cast<SIM_MODEL_IBIS&>( m_libraryModelsMgr.GetModels()[idx].get() );
 
diff --git a/eeschema/dialogs/dialog_sim_model.h b/eeschema/dialogs/dialog_sim_model.h
index 756c22c5da..ec5efcb6d5 100644
--- a/eeschema/dialogs/dialog_sim_model.h
+++ b/eeschema/dialogs/dialog_sim_model.h
@@ -133,6 +133,8 @@ private:
     wxString                m_prevLibrary;
     const SIM_MODEL*        m_prevModel;
 
+    std::map<wxString, int> m_modelListBoxEntryToLibraryIdx;
+
     std::vector<SCH_PIN*>                          m_sortedPartPins; //< Pins of the current part.
     std::map<SIM_MODEL::DEVICE_T, SIM_MODEL::TYPE> m_curModelTypeOfDeviceType;
     SIM_MODEL::TYPE                                m_curModelType;