Remove ugly hack of passing SCH_SYMBOL as parent of LIB_FIELD array.

Also adds simulation model inference to Symbol Editor's Simulation Model
Editor, and adds write-back from both Simulation Model Editors to their
parent Symbol Fields Editor dialogs.

Fixes https://gitlab.com/kicad/code/kicad/issues/12505
This commit is contained in:
Jeff Young 2022-12-09 20:02:47 +00:00
parent 3ae404f764
commit 05b9836f60
14 changed files with 183 additions and 197 deletions

View File

@ -607,9 +607,8 @@ void DIALOG_LIB_SYMBOL_PROPERTIES::OnEditSpiceModel( wxCommandEvent& event )
{
#ifdef KICAD_SPICE
int diff = m_fields->size();
auto symbol = SCH_SYMBOL( *m_libEntry, m_libEntry->GetLibId(), nullptr, 0 );
DIALOG_SIM_MODEL dialog( this, symbol, *m_fields );
DIALOG_SIM_MODEL dialog( this, *m_libEntry, *m_fields );
if( dialog.ShowModal() != wxID_OK )
return;

View File

@ -2,6 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2022 Mikolaj Wielgus
* Copyright (C) 2022 CERN
* Copyright (C) 2022 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
@ -27,6 +28,7 @@
#include <sim/sim_property.h>
#include <sim/sim_library_kibis.h>
#include <sim/sim_library_spice.h>
#include <sim/sim_model.h>
#include <sim/sim_model_kibis.h>
#include <sim/sim_model_raw_spice.h>
#include <sim/sim_serde.h>
@ -42,18 +44,18 @@
using CATEGORY = SIM_MODEL::PARAM::CATEGORY;
template <typename T>
DIALOG_SIM_MODEL<T>::DIALOG_SIM_MODEL( wxWindow* aParent, SCH_SYMBOL& aSymbol,
std::vector<T>& aFields )
template <typename T_symbol, typename T_field>
DIALOG_SIM_MODEL<T_symbol, T_field>::DIALOG_SIM_MODEL( wxWindow* aParent, T_symbol& aSymbol,
std::vector<T_field>& aFields )
: DIALOG_SIM_MODEL_BASE( aParent ),
m_symbol( aSymbol ),
m_fields( aFields ),
m_fieldsOrigin( aFields ),
m_libraryModelsMgr( Prj() ),
m_builtinModelsMgr( Prj() ),
m_prevModel( nullptr ),
m_curModelType( SIM_MODEL::TYPE::NONE ),
m_scintillaTricks( nullptr ),
m_wasCodePreviewUpdated( true ),
m_firstCategory( nullptr ),
m_prevParamGridSelection( nullptr ),
m_lastParamGridWidth( 0 ),
@ -108,8 +110,8 @@ DIALOG_SIM_MODEL<T>::DIALOG_SIM_MODEL( wxWindow* aParent, SCH_SYMBOL& aSymbol,
}
template <typename T>
DIALOG_SIM_MODEL<T>::~DIALOG_SIM_MODEL()
template <typename T_symbol, typename T_field>
DIALOG_SIM_MODEL<T_symbol, T_field>::~DIALOG_SIM_MODEL()
{
// Disable all properties. This is necessary because some of their methods are called after
// destruction of DIALOG_SIM_MODEL, oddly. When disabled, they never access their models.
@ -130,11 +132,41 @@ DIALOG_SIM_MODEL<T>::~DIALOG_SIM_MODEL()
}
template <typename T>
bool DIALOG_SIM_MODEL<T>::TransferDataToWindow()
template <typename T_symbol, typename T_field>
bool DIALOG_SIM_MODEL<T_symbol, T_field>::TransferDataToWindow()
{
wxCommandEvent dummyEvent;
wxString value;
// Yes, the Value field is always present, but Coverity doesn't know that...
if( T_field* valueField = m_symbol.FindField( wxT( "Value" ) ) )
value = valueField->GetText();
// Infer RLC models if they aren't specified
if( !m_symbol.FindField( SIM_MODEL::DEVICE_TYPE_FIELD )
&& !m_symbol.FindField( SIM_MODEL::PARAMS_FIELD ) )
{
// pair.first: wxString sim model type
// pair.second: wxString sim model parameters
auto model = SIM_MODEL::InferSimModel( m_symbol.GetPrefix(), value );
if( !model.second.IsEmpty() )
{
m_fields.emplace_back( &m_symbol, -1, SIM_MODEL::DEVICE_TYPE_FIELD );
m_fields.back().SetText( m_symbol.GetPrefix() );
if( !model.first.IsEmpty() )
{
m_fields.emplace_back( &m_symbol, -1, SIM_MODEL::TYPE_FIELD );
m_fields.back().SetText( model.first );
}
m_fields.emplace_back( &m_symbol, -1, SIM_MODEL::PARAMS_FIELD );
m_fields.back().SetText( model.second );
}
}
std::string libraryFilename = SIM_MODEL::GetFieldValue( &m_fields, SIM_LIBRARY::LIBRARY_FIELD );
if( libraryFilename != "" )
@ -197,7 +229,7 @@ bool DIALOG_SIM_MODEL<T>::TransferDataToWindow()
{
// The model is sourced from the instance.
m_useInstanceModelRadioButton->SetValue( true );
m_curModelType = SIM_MODEL::ReadTypeFromFields( m_fields, m_symbol.GetRawPins().size() );
m_curModelType = SIM_MODEL::ReadTypeFromFields( m_fields, m_symbol.GetPinCount() );
}
for( SIM_MODEL::TYPE type : SIM_MODEL::TYPE_ITERATOR() )
@ -205,9 +237,9 @@ bool DIALOG_SIM_MODEL<T>::TransferDataToWindow()
try
{
if( m_useInstanceModelRadioButton->GetValue() && type == m_curModelType )
m_builtinModelsMgr.CreateModel( m_fields, m_symbol.GetRawPins().size() );
m_builtinModelsMgr.CreateModel( m_fields, m_symbol.GetPinCount() );
else
m_builtinModelsMgr.CreateModel( type, m_symbol.GetRawPins().size() );
m_builtinModelsMgr.CreateModel( type, m_symbol.GetPinCount() );
}
catch( const IO_ERROR& e )
{
@ -230,8 +262,8 @@ bool DIALOG_SIM_MODEL<T>::TransferDataToWindow()
}
template <typename T>
bool DIALOG_SIM_MODEL<T>::TransferDataFromWindow()
template <typename T_symbol, typename T_field>
bool DIALOG_SIM_MODEL<T_symbol, T_field>::TransferDataFromWindow()
{
m_pinAssignmentsGrid->CommitPendingChanges();
@ -285,12 +317,14 @@ bool DIALOG_SIM_MODEL<T>::TransferDataFromWindow()
curModel().WriteFields( m_fields );
m_fieldsOrigin = m_fields;
return true;
}
template <typename T>
void DIALOG_SIM_MODEL<T>::updateWidgets()
template <typename T_symbol, typename T_field>
void DIALOG_SIM_MODEL<T_symbol, T_field>::updateWidgets()
{
updateIbisWidgets();
updateInstanceWidgets();
@ -313,8 +347,8 @@ void DIALOG_SIM_MODEL<T>::updateWidgets()
}
template <typename T>
void DIALOG_SIM_MODEL<T>::updateIbisWidgets()
template <typename T_symbol, typename T_field>
void DIALOG_SIM_MODEL<T_symbol, T_field>::updateIbisWidgets()
{
SIM_MODEL_KIBIS* modelkibis = isIbisLoaded() ? dynamic_cast<SIM_MODEL_KIBIS*>( &curModel() )
: nullptr;
@ -329,11 +363,11 @@ void DIALOG_SIM_MODEL<T>::updateIbisWidgets()
}
template <typename T>
void DIALOG_SIM_MODEL<T>::updateInstanceWidgets()
template <typename T_symbol, typename T_field>
void DIALOG_SIM_MODEL<T_symbol, T_field>::updateInstanceWidgets()
{
// Change the Type choice to match the current device type.
if( !m_prevModel || m_prevModel != &curModel() )
if( &curModel() != m_prevModel )
{
m_deviceTypeChoice->Clear();
@ -396,8 +430,8 @@ void DIALOG_SIM_MODEL<T>::updateInstanceWidgets()
}
template <typename T>
void DIALOG_SIM_MODEL<T>::updateModelParamsTab()
template <typename T_symbol, typename T_field>
void DIALOG_SIM_MODEL<T_symbol, T_field>::updateModelParamsTab()
{
if( &curModel() != m_prevModel )
{
@ -490,8 +524,8 @@ void DIALOG_SIM_MODEL<T>::updateModelParamsTab()
}
template <typename T>
void DIALOG_SIM_MODEL<T>::updateModelCodeTab()
template <typename T_symbol, typename T_field>
void DIALOG_SIM_MODEL<T_symbol, T_field>::updateModelCodeTab()
{
wxString text;
SPICE_ITEM item;
@ -508,12 +542,12 @@ void DIALOG_SIM_MODEL<T>::updateModelCodeTab()
text << rawSpice->GetSource();
m_codePreview->SetText( text );
m_wasCodePreviewUpdated = true;
m_codePreview->SelectNone();
}
template <typename T>
void DIALOG_SIM_MODEL<T>::updatePinAssignments()
template <typename T_symbol, typename T_field>
void DIALOG_SIM_MODEL<T_symbol, T_field>::updatePinAssignments()
{
removeOrphanedPinAssignments();
@ -580,29 +614,19 @@ void DIALOG_SIM_MODEL<T>::updatePinAssignments()
}
template <typename T>
void DIALOG_SIM_MODEL<T>::removeOrphanedPinAssignments()
template <typename T_symbol, typename T_field>
void DIALOG_SIM_MODEL<T_symbol, T_field>::removeOrphanedPinAssignments()
{
for( int i = 0; i < curModel().GetPinCount(); ++i )
{
const SIM_MODEL::PIN& modelPin = curModel().GetPin( i );
const std::vector<std::unique_ptr<SCH_PIN>>& allPins = m_symbol.GetRawPins();
if( std::none_of( allPins.begin(), allPins.end(),
[modelPin]( const std::unique_ptr<SCH_PIN>& symbolPin )
{
return modelPin.symbolPinNumber == symbolPin->GetNumber();
} ) )
{
// Is orphaned.
if( !m_symbol.GetPin( curModel().GetPin( i ).symbolPinNumber ) )
curModel().SetPinSymbolPinNumber( i, "" );
}
}
}
template <typename T>
void DIALOG_SIM_MODEL<T>::loadLibrary( const wxString& aLibraryPath, bool aForceReload )
template <typename T_symbol, typename T_field>
void DIALOG_SIM_MODEL<T_symbol, T_field>::loadLibrary( const wxString& aLibraryPath, bool aForceReload )
{
auto libraries = m_libraryModelsMgr.GetLibraries();
@ -631,14 +655,13 @@ void DIALOG_SIM_MODEL<T>::loadLibrary( const wxString& aLibraryPath, bool aForce
try
{
std::string modelName = SIM_MODEL::GetFieldValue( &m_fields, SIM_LIBRARY::NAME_FIELD );
int pinCount = m_symbol.GetRawPins().size();
for( auto& [baseModelName, baseModel] : library()->GetModels() )
{
if( baseModelName == modelName )
m_libraryModelsMgr.CreateModel( baseModel, pinCount, m_fields );
m_libraryModelsMgr.CreateModel( baseModel, m_symbol.GetPinCount(), m_fields );
else
m_libraryModelsMgr.CreateModel( baseModel, pinCount );
m_libraryModelsMgr.CreateModel( baseModel, m_symbol.GetPinCount() );
}
}
catch( const IO_ERROR& e )
@ -671,8 +694,8 @@ void DIALOG_SIM_MODEL<T>::loadLibrary( const wxString& aLibraryPath, bool aForce
}
template <typename T>
void DIALOG_SIM_MODEL<T>::addParamPropertyIfRelevant( int aParamIndex )
template <typename T_symbol, typename T_field>
void DIALOG_SIM_MODEL<T_symbol, T_field>::addParamPropertyIfRelevant( int aParamIndex )
{
if( curModel().GetParam( aParamIndex ).info.dir == SIM_MODEL::PARAM::DIR_OUT )
return;
@ -745,8 +768,8 @@ void DIALOG_SIM_MODEL<T>::addParamPropertyIfRelevant( int aParamIndex )
}
template <typename T>
wxPGProperty* DIALOG_SIM_MODEL<T>::newParamProperty( int aParamIndex ) const
template <typename T_symbol, typename T_field>
wxPGProperty* DIALOG_SIM_MODEL<T_symbol, T_field>::newParamProperty( int aParamIndex ) const
{
const SIM_MODEL::PARAM& param = curModel().GetParam( aParamIndex );
wxString paramDescription;
@ -833,8 +856,8 @@ wxPGProperty* DIALOG_SIM_MODEL<T>::newParamProperty( int aParamIndex ) const
}
template <typename T>
int DIALOG_SIM_MODEL<T>::findSymbolPinRow( const wxString& aSymbolPinNumber ) const
template <typename T_symbol, typename T_field>
int DIALOG_SIM_MODEL<T_symbol, T_field>::findSymbolPinRow( const wxString& aSymbolPinNumber ) const
{
for( int row = 0; row < static_cast<int>( m_sortedPartPins.size() ); ++row )
{
@ -848,8 +871,8 @@ int DIALOG_SIM_MODEL<T>::findSymbolPinRow( const wxString& aSymbolPinNumber ) co
}
template <typename T>
SIM_MODEL& DIALOG_SIM_MODEL<T>::curModel() const
template <typename T_symbol, typename T_field>
SIM_MODEL& DIALOG_SIM_MODEL<T_symbol, T_field>::curModel() const
{
if( m_useLibraryModelRadioButton->GetValue()
&& m_modelNameCombobox->GetSelection() != wxNOT_FOUND )
@ -863,8 +886,8 @@ SIM_MODEL& DIALOG_SIM_MODEL<T>::curModel() const
}
template <typename T>
const SIM_LIBRARY* DIALOG_SIM_MODEL<T>::library() const
template <typename T_symbol, typename T_field>
const SIM_LIBRARY* DIALOG_SIM_MODEL<T_symbol, T_field>::library() const
{
if( m_libraryModelsMgr.GetLibraries().size() == 1 )
return &m_libraryModelsMgr.GetLibraries().begin()->second.get();
@ -873,8 +896,8 @@ const SIM_LIBRARY* DIALOG_SIM_MODEL<T>::library() const
}
template <typename T>
wxString DIALOG_SIM_MODEL<T>::getSymbolPinString( int symbolPinIndex ) const
template <typename T_symbol, typename T_field>
wxString DIALOG_SIM_MODEL<T_symbol, T_field>::getSymbolPinString( int symbolPinIndex ) const
{
LIB_PIN* pin = m_sortedPartPins.at( symbolPinIndex );
wxString pinNumber;
@ -893,8 +916,8 @@ wxString DIALOG_SIM_MODEL<T>::getSymbolPinString( int symbolPinIndex ) const
}
template <typename T>
wxString DIALOG_SIM_MODEL<T>::getModelPinString( int aModelPinIndex ) const
template <typename T_symbol, typename T_field>
wxString DIALOG_SIM_MODEL<T_symbol, T_field>::getModelPinString( int aModelPinIndex ) const
{
const wxString& pinName = curModel().GetPin( aModelPinIndex ).name;
@ -909,8 +932,8 @@ wxString DIALOG_SIM_MODEL<T>::getModelPinString( int aModelPinIndex ) const
}
template <typename T>
int DIALOG_SIM_MODEL<T>::getModelPinIndex( const wxString& aModelPinString ) const
template <typename T_symbol, typename T_field>
int DIALOG_SIM_MODEL<T_symbol, T_field>::getModelPinIndex( const wxString& aModelPinString ) const
{
if( aModelPinString == "Not Connected" )
return SIM_MODEL::PIN::NOT_CONNECTED;
@ -927,8 +950,8 @@ int DIALOG_SIM_MODEL<T>::getModelPinIndex( const wxString& aModelPinString ) con
}
template <typename T>
void DIALOG_SIM_MODEL<T>::onRadioButton( wxCommandEvent& aEvent )
template <typename T_symbol, typename T_field>
void DIALOG_SIM_MODEL<T_symbol, T_field>::onRadioButton( wxCommandEvent& aEvent )
{
bool fromLibrary = m_useLibraryModelRadioButton->GetValue();
@ -951,8 +974,8 @@ void DIALOG_SIM_MODEL<T>::onRadioButton( wxCommandEvent& aEvent )
}
template <typename T>
void DIALOG_SIM_MODEL<T>::onLibraryPathTextEnter( wxCommandEvent& aEvent )
template <typename T_symbol, typename T_field>
void DIALOG_SIM_MODEL<T_symbol, T_field>::onLibraryPathTextEnter( wxCommandEvent& aEvent )
{
if( m_useLibraryModelRadioButton->GetValue() )
{
@ -974,20 +997,8 @@ void DIALOG_SIM_MODEL<T>::onLibraryPathTextEnter( wxCommandEvent& aEvent )
}
template <typename T>
void DIALOG_SIM_MODEL<T>::onLibraryPathText( wxCommandEvent& aEvent )
{
}
template <typename T>
void DIALOG_SIM_MODEL<T>::onLibraryPathTextSetFocus( wxFocusEvent& aEvent )
{
}
template <typename T>
void DIALOG_SIM_MODEL<T>::onLibraryPathTextKillFocus( wxFocusEvent& aEvent )
template <typename T_symbol, typename T_field>
void DIALOG_SIM_MODEL<T_symbol, T_field>::onLibraryPathTextKillFocus( wxFocusEvent& aEvent )
{
if( !m_inKillFocus )
{
@ -1001,8 +1012,8 @@ void DIALOG_SIM_MODEL<T>::onLibraryPathTextKillFocus( wxFocusEvent& aEvent )
}
template <typename T>
void DIALOG_SIM_MODEL<T>::onBrowseButtonClick( wxCommandEvent& aEvent )
template <typename T_symbol, typename T_field>
void DIALOG_SIM_MODEL<T_symbol, T_field>::onBrowseButtonClick( wxCommandEvent& aEvent )
{
wxFileDialog dlg( this, _( "Browse Models" ), Prj().GetProjectPath() );
@ -1020,8 +1031,8 @@ void DIALOG_SIM_MODEL<T>::onBrowseButtonClick( wxCommandEvent& aEvent )
}
template <typename T>
void DIALOG_SIM_MODEL<T>::onModelNameCombobox( wxCommandEvent& aEvent )
template <typename T_symbol, typename T_field>
void DIALOG_SIM_MODEL<T_symbol, T_field>::onModelNameCombobox( wxCommandEvent& aEvent )
{
if( isIbisLoaded() )
{
@ -1043,8 +1054,8 @@ void DIALOG_SIM_MODEL<T>::onModelNameCombobox( wxCommandEvent& aEvent )
}
template <typename T>
void DIALOG_SIM_MODEL<T>::onModelNameComboboxKillFocus( wxFocusEvent& aEvent )
template <typename T_symbol, typename T_field>
void DIALOG_SIM_MODEL<T_symbol, T_field>::onModelNameComboboxKillFocus( wxFocusEvent& aEvent )
{
m_modelNameCombobox->SetSelection(
m_modelNameCombobox->FindString( m_modelNameCombobox->GetValue() ) );
@ -1052,8 +1063,8 @@ void DIALOG_SIM_MODEL<T>::onModelNameComboboxKillFocus( wxFocusEvent& aEvent )
}
template <typename T>
void DIALOG_SIM_MODEL<T>::onModelNameComboboxTextEnter( wxCommandEvent& aEvent )
template <typename T_symbol, typename T_field>
void DIALOG_SIM_MODEL<T_symbol, T_field>::onModelNameComboboxTextEnter( wxCommandEvent& aEvent )
{
m_modelNameCombobox->SetSelection(
m_modelNameCombobox->FindString( m_modelNameCombobox->GetValue() ) );
@ -1061,8 +1072,8 @@ void DIALOG_SIM_MODEL<T>::onModelNameComboboxTextEnter( wxCommandEvent& aEvent )
}
template <typename T>
void DIALOG_SIM_MODEL<T>::onIbisPinCombobox( wxCommandEvent& aEvent )
template <typename T_symbol, typename T_field>
void DIALOG_SIM_MODEL<T_symbol, T_field>::onIbisPinCombobox( wxCommandEvent& aEvent )
{
if( isIbisLoaded() )
{
@ -1090,8 +1101,8 @@ void DIALOG_SIM_MODEL<T>::onIbisPinCombobox( wxCommandEvent& aEvent )
}
template <typename T>
void DIALOG_SIM_MODEL<T>::onIbisPinComboboxTextEnter( wxCommandEvent& aEvent )
template <typename T_symbol, typename T_field>
void DIALOG_SIM_MODEL<T_symbol, T_field>::onIbisPinComboboxTextEnter( wxCommandEvent& aEvent )
{
m_ibisPinCombobox->SetSelection(
m_ibisPinCombobox->FindString( m_ibisPinCombobox->GetValue() ) );
@ -1100,15 +1111,15 @@ void DIALOG_SIM_MODEL<T>::onIbisPinComboboxTextEnter( wxCommandEvent& aEvent )
}
template <typename T>
void DIALOG_SIM_MODEL<T>::onIbisModelCombobox( wxCommandEvent& aEvent )
template <typename T_symbol, typename T_field>
void DIALOG_SIM_MODEL<T_symbol, T_field>::onIbisModelCombobox( wxCommandEvent& aEvent )
{
updateWidgets();
}
template <typename T>
void DIALOG_SIM_MODEL<T>::onIbisModelComboboxTextEnter( wxCommandEvent& aEvent )
template <typename T_symbol, typename T_field>
void DIALOG_SIM_MODEL<T_symbol, T_field>::onIbisModelComboboxTextEnter( wxCommandEvent& aEvent )
{
m_ibisModelCombobox->SetSelection(
m_ibisModelCombobox->FindString( m_ibisModelCombobox->GetValue() ) );
@ -1116,8 +1127,8 @@ void DIALOG_SIM_MODEL<T>::onIbisModelComboboxTextEnter( wxCommandEvent& aEvent )
onIbisPinCombobox( aEvent );
}
template <typename T>
void DIALOG_SIM_MODEL<T>::onDifferentialCheckbox( wxCommandEvent& aEvent )
template <typename T_symbol, typename T_field>
void DIALOG_SIM_MODEL<T_symbol, T_field>::onDifferentialCheckbox( wxCommandEvent& aEvent )
{
if( isIbisLoaded() )
{
@ -1130,8 +1141,8 @@ void DIALOG_SIM_MODEL<T>::onDifferentialCheckbox( wxCommandEvent& aEvent )
}
template <typename T>
void DIALOG_SIM_MODEL<T>::onDeviceTypeChoice( wxCommandEvent& aEvent )
template <typename T_symbol, typename T_field>
void DIALOG_SIM_MODEL<T_symbol, T_field>::onDeviceTypeChoice( wxCommandEvent& aEvent )
{
for( SIM_MODEL::DEVICE_T deviceType : SIM_MODEL::DEVICE_T_ITERATOR() )
{
@ -1146,8 +1157,8 @@ void DIALOG_SIM_MODEL<T>::onDeviceTypeChoice( wxCommandEvent& aEvent )
}
template <typename T>
void DIALOG_SIM_MODEL<T>::onTypeChoice( wxCommandEvent& aEvent )
template <typename T_symbol, typename T_field>
void DIALOG_SIM_MODEL<T_symbol, T_field>::onTypeChoice( wxCommandEvent& aEvent )
{
SIM_MODEL::DEVICE_T deviceType = curModel().GetDeviceType();
wxString typeDescription = m_typeChoice->GetString( m_typeChoice->GetSelection() );
@ -1181,26 +1192,15 @@ void DIALOG_SIM_MODEL<T>::onTypeChoice( wxCommandEvent& aEvent )
}
template <typename T>
void DIALOG_SIM_MODEL<T>::onParamGridChanged( wxPropertyGridEvent& aEvent )
template <typename T_symbol, typename T_field>
void DIALOG_SIM_MODEL<T_symbol, T_field>::onParamGridChanged( wxPropertyGridEvent& aEvent )
{
updateWidgets();
}
template <typename T>
void DIALOG_SIM_MODEL<T>::onCodePreviewSetFocus( wxFocusEvent& aEvent )
{
// For some reason all text gets selected for me -Mikolaj
if( m_wasCodePreviewUpdated )
m_codePreview->SelectNone();
m_wasCodePreviewUpdated = false;
}
template <typename T>
void DIALOG_SIM_MODEL<T>::onPinAssignmentsGridCellChange( wxGridEvent& aEvent )
template <typename T_symbol, typename T_field>
void DIALOG_SIM_MODEL<T_symbol, T_field>::onPinAssignmentsGridCellChange( wxGridEvent& aEvent )
{
int symbolPinIndex = aEvent.GetRow();
wxString oldModelPinName = aEvent.GetString();
@ -1224,8 +1224,8 @@ void DIALOG_SIM_MODEL<T>::onPinAssignmentsGridCellChange( wxGridEvent& aEvent )
}
template <typename T>
void DIALOG_SIM_MODEL<T>::onPinAssignmentsGridSize( wxSizeEvent& aEvent )
template <typename T_symbol, typename T_field>
void DIALOG_SIM_MODEL<T_symbol, T_field>::onPinAssignmentsGridSize( wxSizeEvent& aEvent )
{
wxGridUpdateLocker deferRepaintsTillLeavingScope( m_pinAssignmentsGrid );
@ -1237,22 +1237,22 @@ void DIALOG_SIM_MODEL<T>::onPinAssignmentsGridSize( wxSizeEvent& aEvent )
}
template <typename T>
void DIALOG_SIM_MODEL<T>::onSaveInValueCheckbox( wxCommandEvent& aEvent )
template <typename T_symbol, typename T_field>
void DIALOG_SIM_MODEL<T_symbol, T_field>::onSaveInValueCheckbox( wxCommandEvent& aEvent )
{
curModel().SetIsStoredInValue( m_saveInValueCheckbox->GetValue() );
}
template <typename T>
void DIALOG_SIM_MODEL<T>::onExcludeCheckbox( wxCommandEvent& aEvent )
template <typename T_symbol, typename T_field>
void DIALOG_SIM_MODEL<T_symbol, T_field>::onExcludeCheckbox( wxCommandEvent& aEvent )
{
curModel().SetIsEnabled( !m_excludeCheckbox->GetValue() );
}
template <typename T>
void DIALOG_SIM_MODEL<T>::onParamGridSetFocus( wxFocusEvent& aEvent )
template <typename T_symbol, typename T_field>
void DIALOG_SIM_MODEL<T_symbol, T_field>::onParamGridSetFocus( wxFocusEvent& aEvent )
{
// By default, when a property grid is focused, the textbox is not immediately focused until
// Tab key is pressed. This is inconvenient, so we fix that here.
@ -1273,8 +1273,8 @@ void DIALOG_SIM_MODEL<T>::onParamGridSetFocus( wxFocusEvent& aEvent )
}
template <typename T>
void DIALOG_SIM_MODEL<T>::onParamGridSelectionChange( wxPropertyGridEvent& aEvent )
template <typename T_symbol, typename T_field>
void DIALOG_SIM_MODEL<T_symbol, T_field>::onParamGridSelectionChange( wxPropertyGridEvent& aEvent )
{
wxPropertyGrid* grid = m_paramGrid->GetGrid();
@ -1337,8 +1337,8 @@ void DIALOG_SIM_MODEL<T>::onParamGridSelectionChange( wxPropertyGridEvent& aEven
}
template <typename T>
void DIALOG_SIM_MODEL<T>::adjustParamGridColumns( int aWidth, bool aForce )
template <typename T_symbol, typename T_field>
void DIALOG_SIM_MODEL<T_symbol, T_field>::adjustParamGridColumns( int aWidth, bool aForce )
{
wxPropertyGrid* grid = m_paramGridMgr->GetGrid();
int margin = 15;
@ -1379,8 +1379,8 @@ void DIALOG_SIM_MODEL<T>::adjustParamGridColumns( int aWidth, bool aForce )
}
template <typename T>
void DIALOG_SIM_MODEL<T>::onSizeParamGrid( wxSizeEvent& event )
template <typename T_symbol, typename T_field>
void DIALOG_SIM_MODEL<T_symbol, T_field>::onSizeParamGrid( wxSizeEvent& event )
{
adjustParamGridColumns( event.GetSize().GetX(), false );
@ -1389,6 +1389,5 @@ void DIALOG_SIM_MODEL<T>::onSizeParamGrid( wxSizeEvent& event )
template class DIALOG_SIM_MODEL<SCH_FIELD>;
template class DIALOG_SIM_MODEL<LIB_FIELD>;
template class DIALOG_SIM_MODEL<SCH_SYMBOL, SCH_FIELD>;
template class DIALOG_SIM_MODEL<LIB_SYMBOL, LIB_FIELD>;

View File

@ -41,7 +41,7 @@
// wxPG_NATIVE_DOUBLE_BUFFERING flag is not set.
// 2. wxPropertyGridManager->ShowHeader() segfaults when called from this dialog's constructor.
template <typename T>
template <typename T_symbol, typename T_field>
class DIALOG_SIM_MODEL : public DIALOG_SIM_MODEL_BASE
{
public:
@ -82,7 +82,7 @@ public:
MODEL
};
DIALOG_SIM_MODEL( wxWindow* aParent, SCH_SYMBOL& aSymbol, std::vector<T>& aSchFields );
DIALOG_SIM_MODEL( wxWindow* aParent, T_symbol& aSymbol, std::vector<T_field>& aSchFields );
~DIALOG_SIM_MODEL();
@ -114,10 +114,8 @@ private:
int getModelPinIndex( const wxString& aModelPinString ) const;
void onRadioButton( wxCommandEvent& aEvent ) override;
void onLibraryPathText( wxCommandEvent& aEvent ) override;
void onLibraryPathTextEnter( wxCommandEvent& aEvent ) override;
void onLibraryPathTextKillFocus( wxFocusEvent& aEvent ) override;
void onLibraryPathTextSetFocus( wxFocusEvent& aEvent ) override;
void onBrowseButtonClick( wxCommandEvent& aEvent ) override;
void onModelNameCombobox( wxCommandEvent& aEvent ) override;
void onModelNameComboboxKillFocus( wxFocusEvent& event ) override;
@ -129,7 +127,6 @@ private:
void onDeviceTypeChoice( wxCommandEvent& aEvent ) override;
void onTypeChoice( wxCommandEvent& aEvent ) override;
void onParamGridChanged( wxPropertyGridEvent& aEvent ) override;
void onCodePreviewSetFocus( wxFocusEvent& aEvent ) override;
void onPinAssignmentsGridCellChange( wxGridEvent& aEvent ) override;
void onPinAssignmentsGridSize( wxSizeEvent& aEvent ) override;
void onSaveInValueCheckbox( wxCommandEvent& aEvent ) override;
@ -145,12 +142,13 @@ private:
bool isIbisLoaded() { return dynamic_cast<const SIM_LIBRARY_KIBIS*>( library() ); }
private:
SCH_SYMBOL& m_symbol;
std::vector<T>& m_fields;
T_symbol& m_symbol;
std::vector<T_field> m_fields; // Local copy of the fields
std::vector<T_field>& m_fieldsOrigin; // Pointer back to the source copy of the fields
SIM_LIB_MGR m_libraryModelsMgr;
SIM_LIB_MGR m_builtinModelsMgr;
const SIM_MODEL* m_prevModel;
SIM_LIB_MGR m_libraryModelsMgr;
SIM_LIB_MGR m_builtinModelsMgr;
const SIM_MODEL* m_prevModel;
std::vector<LIB_PIN*> m_sortedPartPins; //< Pins of the current part.
std::map<SIM_MODEL::DEVICE_T, SIM_MODEL::TYPE> m_curModelTypeOfDeviceType;
@ -158,7 +156,6 @@ private:
MODEL_NAME_VALIDATOR m_modelNameValidator;
SCINTILLA_TRICKS* m_scintillaTricks;
bool m_wasCodePreviewUpdated;
wxPGProperty* m_firstCategory; // Used to add principal parameters to root.
wxPGProperty* m_prevParamGridSelection;

View File

@ -283,8 +283,6 @@ DIALOG_SIM_MODEL_BASE::DIALOG_SIM_MODEL_BASE( wxWindow* parent, wxWindowID id, c
m_useLibraryModelRadioButton->Connect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( DIALOG_SIM_MODEL_BASE::onRadioButton ), NULL, this );
m_pathLabel->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SIM_MODEL_BASE::onLibraryPathLabelUpdate ), NULL, this );
m_libraryPathText->Connect( wxEVT_KILL_FOCUS, wxFocusEventHandler( DIALOG_SIM_MODEL_BASE::onLibraryPathTextKillFocus ), NULL, this );
m_libraryPathText->Connect( wxEVT_SET_FOCUS, wxFocusEventHandler( DIALOG_SIM_MODEL_BASE::onLibraryPathTextSetFocus ), NULL, this );
m_libraryPathText->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_SIM_MODEL_BASE::onLibraryPathText ), NULL, this );
m_libraryPathText->Connect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( DIALOG_SIM_MODEL_BASE::onLibraryPathTextEnter ), NULL, this );
m_browseButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SIM_MODEL_BASE::onBrowseButtonClick ), NULL, this );
m_browseButton->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SIM_MODEL_BASE::onBrowseButtonUpdate ), NULL, this );
@ -313,7 +311,6 @@ DIALOG_SIM_MODEL_BASE::DIALOG_SIM_MODEL_BASE( wxWindow* parent, wxWindowID id, c
m_typeChoice->Connect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_SIM_MODEL_BASE::onTypeChoice ), NULL, this );
m_paramGridMgr->Connect( wxEVT_PG_CHANGED, wxPropertyGridEventHandler( DIALOG_SIM_MODEL_BASE::onParamGridChanged ), NULL, this );
m_paramGridMgr->Connect( wxEVT_SIZE, wxSizeEventHandler( DIALOG_SIM_MODEL_BASE::onSizeParamGrid ), NULL, this );
m_codePreview->Connect( wxEVT_SET_FOCUS, wxFocusEventHandler( DIALOG_SIM_MODEL_BASE::onCodePreviewSetFocus ), NULL, this );
m_saveInValueCheckbox->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_SIM_MODEL_BASE::onSaveInValueCheckbox ), NULL, this );
m_pinAssignmentsGrid->Connect( wxEVT_GRID_CELL_CHANGED, wxGridEventHandler( DIALOG_SIM_MODEL_BASE::onPinAssignmentsGridCellChange ), NULL, this );
m_pinAssignmentsGrid->Connect( wxEVT_SIZE, wxSizeEventHandler( DIALOG_SIM_MODEL_BASE::onPinAssignmentsGridSize ), NULL, this );
@ -326,8 +323,6 @@ DIALOG_SIM_MODEL_BASE::~DIALOG_SIM_MODEL_BASE()
m_useLibraryModelRadioButton->Disconnect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( DIALOG_SIM_MODEL_BASE::onRadioButton ), NULL, this );
m_pathLabel->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SIM_MODEL_BASE::onLibraryPathLabelUpdate ), NULL, this );
m_libraryPathText->Disconnect( wxEVT_KILL_FOCUS, wxFocusEventHandler( DIALOG_SIM_MODEL_BASE::onLibraryPathTextKillFocus ), NULL, this );
m_libraryPathText->Disconnect( wxEVT_SET_FOCUS, wxFocusEventHandler( DIALOG_SIM_MODEL_BASE::onLibraryPathTextSetFocus ), NULL, this );
m_libraryPathText->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_SIM_MODEL_BASE::onLibraryPathText ), NULL, this );
m_libraryPathText->Disconnect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( DIALOG_SIM_MODEL_BASE::onLibraryPathTextEnter ), NULL, this );
m_browseButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SIM_MODEL_BASE::onBrowseButtonClick ), NULL, this );
m_browseButton->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SIM_MODEL_BASE::onBrowseButtonUpdate ), NULL, this );
@ -356,7 +351,6 @@ DIALOG_SIM_MODEL_BASE::~DIALOG_SIM_MODEL_BASE()
m_typeChoice->Disconnect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_SIM_MODEL_BASE::onTypeChoice ), NULL, this );
m_paramGridMgr->Disconnect( wxEVT_PG_CHANGED, wxPropertyGridEventHandler( DIALOG_SIM_MODEL_BASE::onParamGridChanged ), NULL, this );
m_paramGridMgr->Disconnect( wxEVT_SIZE, wxSizeEventHandler( DIALOG_SIM_MODEL_BASE::onSizeParamGrid ), NULL, this );
m_codePreview->Disconnect( wxEVT_SET_FOCUS, wxFocusEventHandler( DIALOG_SIM_MODEL_BASE::onCodePreviewSetFocus ), NULL, this );
m_saveInValueCheckbox->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_SIM_MODEL_BASE::onSaveInValueCheckbox ), NULL, this );
m_pinAssignmentsGrid->Disconnect( wxEVT_GRID_CELL_CHANGED, wxGridEventHandler( DIALOG_SIM_MODEL_BASE::onPinAssignmentsGridCellChange ), NULL, this );
m_pinAssignmentsGrid->Disconnect( wxEVT_SIZE, wxSizeEventHandler( DIALOG_SIM_MODEL_BASE::onPinAssignmentsGridSize ), NULL, this );

View File

@ -407,8 +407,6 @@
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnKillFocus">onLibraryPathTextKillFocus</event>
<event name="OnSetFocus">onLibraryPathTextSetFocus</event>
<event name="OnText">onLibraryPathText</event>
<event name="OnTextEnter">onLibraryPathTextEnter</event>
</object>
</object>
@ -1645,7 +1643,6 @@
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnSetFocus">onCodePreviewSetFocus</event>
</object>
</object>
</object>

View File

@ -87,8 +87,6 @@ class DIALOG_SIM_MODEL_BASE : public DIALOG_SHIM
virtual void onRadioButton( wxCommandEvent& event ) { event.Skip(); }
virtual void onLibraryPathLabelUpdate( wxUpdateUIEvent& event ) { event.Skip(); }
virtual void onLibraryPathTextKillFocus( wxFocusEvent& event ) { event.Skip(); }
virtual void onLibraryPathTextSetFocus( wxFocusEvent& event ) { event.Skip(); }
virtual void onLibraryPathText( wxCommandEvent& event ) { event.Skip(); }
virtual void onLibraryPathTextEnter( wxCommandEvent& event ) { event.Skip(); }
virtual void onBrowseButtonClick( wxCommandEvent& event ) { event.Skip(); }
virtual void onBrowseButtonUpdate( wxUpdateUIEvent& event ) { event.Skip(); }
@ -112,7 +110,6 @@ class DIALOG_SIM_MODEL_BASE : public DIALOG_SHIM
virtual void onTypeChoice( wxCommandEvent& event ) { event.Skip(); }
virtual void onParamGridChanged( wxPropertyGridEvent& event ) { event.Skip(); }
virtual void onSizeParamGrid( wxSizeEvent& event ) { event.Skip(); }
virtual void onCodePreviewSetFocus( wxFocusEvent& event ) { event.Skip(); }
virtual void onSaveInValueCheckbox( wxCommandEvent& event ) { event.Skip(); }
virtual void onPinAssignmentsGridCellChange( wxGridEvent& event ) { event.Skip(); }
virtual void onPinAssignmentsGridSize( wxSizeEvent& event ) { event.Skip(); }

View File

@ -66,11 +66,6 @@ LIB_FIELD::LIB_FIELD( int aId, const wxString& aName ) :
}
LIB_FIELD::~LIB_FIELD()
{
}
LIB_FIELD& LIB_FIELD::operator=( const LIB_FIELD& field )
{
m_id = field.m_id;
@ -90,8 +85,6 @@ LIB_FIELD& LIB_FIELD::operator=( const LIB_FIELD& field )
void LIB_FIELD::Init( int aId )
{
wxCHECK2( aId >= 0, aId = MANDATORY_FIELDS );
m_id = aId;
SetTextAngle( ANGLE_HORIZONTAL ); // constructor already did this.
@ -114,7 +107,6 @@ void LIB_FIELD::Init( int aId )
void LIB_FIELD::SetId( int aId )
{
wxCHECK2( aId >= 0, aId = MANDATORY_FIELDS );
m_id = aId;
}

View File

@ -68,8 +68,6 @@ public:
// Do not create a copy constructor. The one generated by the compiler is adequate.
~LIB_FIELD();
wxString GetClass() const override
{
return wxT( "LIB_FIELD" );

View File

@ -181,11 +181,6 @@ LIB_SYMBOL::LIB_SYMBOL( const LIB_SYMBOL& aSymbol, SYMBOL_LIB* aLibrary ) :
}
LIB_SYMBOL::~LIB_SYMBOL()
{
}
const LIB_SYMBOL& LIB_SYMBOL::operator=( const LIB_SYMBOL& aSymbol )
{
if( &aSymbol == this )
@ -881,6 +876,16 @@ void LIB_SYMBOL::GetPins( LIB_PINS& aList, int aUnit, int aConvert ) const
}
std::vector<LIB_PIN*> LIB_SYMBOL::GetLibPins() const
{
std::vector<LIB_PIN*> pinList;
GetPins( pinList );
return pinList;
}
LIB_PIN* LIB_SYMBOL::GetPin( const wxString& aNumber, int aUnit, int aConvert ) const
{
LIB_PINS pinList;
@ -1061,14 +1066,14 @@ void LIB_SYMBOL::AddField( LIB_FIELD* aField )
}
void LIB_SYMBOL::SetFields( const std::vector <LIB_FIELD>& aFields )
void LIB_SYMBOL::SetFields( const std::vector<LIB_FIELD>& aFields )
{
deleteAllFields();
for( unsigned i=0; i<aFields.size(); ++i )
for( size_t ii = 0; ii < aFields.size(); ++ii )
{
// drawings is a ptr_vector, new and copy an object on the heap.
LIB_FIELD* field = new LIB_FIELD( aFields[i] );
LIB_FIELD* field = new LIB_FIELD( aFields[ ii ] );
field->SetParent( this );
m_drawings.push_back( field );

View File

@ -103,7 +103,8 @@ public:
LIB_SYMBOL( const LIB_SYMBOL& aSymbol, SYMBOL_LIB* aLibrary = nullptr );
virtual ~LIB_SYMBOL();
virtual ~LIB_SYMBOL()
{}
///< http://www.boost.org/doc/libs/1_55_0/libs/smart_ptr/sp_techniques.html#weak_without_shared
LIB_SYMBOL_SPTR SharedPtr() const { return m_me; }
@ -254,15 +255,11 @@ public:
bool UnitsLocked() const { return m_unitsLocked; }
/**
* Overwrite all the existing fields in this symbol with fields supplied
* in \a aFieldsList.
*
* The only known caller of this function is the library symbol field editor, and it
* establishes needed behavior.
* Overwrite all the existing fields in this symbol with fields supplied in \a aFieldsList.
*
* @param aFieldsList is a set of fields to import, removing all previous fields.
*/
void SetFields( const std::vector <LIB_FIELD>& aFieldsList );
void SetFields( const std::vector<LIB_FIELD>& aFieldsList );
/**
* Return a list of fields within this symbol.
@ -436,6 +433,8 @@ public:
*/
void GetPins( LIB_PINS& aList, int aUnit = 0, int aConvert = 0 ) const;
std::vector<LIB_PIN*> GetLibPins() const;
/**
* Return pin object with the requested pin \a aNumber.
*

View File

@ -236,21 +236,21 @@ bool NETLIST_EXPORTER_SPICE::ReadSchematicAndLibraries( unsigned aNetlistOptions
{
// pair.first: wxString sim model type
// pair.second: wxString sim model parameters
auto model = SIM_MODEL_IDEAL::InferSimModel( symbol->GetPrefix(),
symbol->GetValueFieldText( true ) );
auto model = SIM_MODEL::InferSimModel( symbol->GetPrefix(),
symbol->GetValueFieldText( true ) );
if( !model.second.IsEmpty() )
{
spiceItem.fields.emplace_back( VECTOR2I(), -1, symbol, SIM_MODEL::DEVICE_TYPE_FIELD );
spiceItem.fields.emplace_back( symbol, -1, SIM_MODEL::DEVICE_TYPE_FIELD );
spiceItem.fields.back().SetText( symbol->GetPrefix() );
if( !model.first.IsEmpty() )
{
spiceItem.fields.emplace_back( VECTOR2I(), -1, symbol, SIM_MODEL::TYPE_FIELD );
spiceItem.fields.emplace_back( symbol, -1, SIM_MODEL::TYPE_FIELD );
spiceItem.fields.back().SetText( model.first );
}
spiceItem.fields.emplace_back( VECTOR2I(), -1, symbol, SIM_MODEL::PARAMS_FIELD );
spiceItem.fields.emplace_back( symbol, -1, SIM_MODEL::PARAMS_FIELD );
spiceItem.fields.back().SetText( model.second );
}
}

View File

@ -456,7 +456,7 @@ public:
*
* @param aFields are the fields to set in this symbol.
*/
void SetFields( const SCH_FIELDS& aFields )
void SetFields( std::vector<SCH_FIELD>& aFields )
{
m_fields = aFields; // vector copying, length is changed possibly
}

View File

@ -128,6 +128,13 @@ template SIM_MODEL& SIM_LIB_MGR::CreateModel( const SIM_MODEL& aBaseModel, int a
SIM_LIBRARY::MODEL SIM_LIB_MGR::CreateModel( const SCH_SHEET_PATH* aSheetPath, SCH_SYMBOL& aSymbol )
{
// Note: currently this creates a resolved model (all Kicad variables references are resolved
// before building the model).
//
// That's not what we want if this is ever called from the Simulation Model Editor (or other
// editors, but it is what we want if called to generate a netlist or other exported items.
std::vector<SCH_FIELD> fields;
for( int i = 0; i < aSymbol.GetFieldCount(); ++i )
@ -146,21 +153,21 @@ SIM_LIBRARY::MODEL SIM_LIB_MGR::CreateModel( const SCH_SHEET_PATH* aSheetPath, S
{
// pair.first: wxString sim model type
// pair.second: wxString sim model parameters
auto model = SIM_MODEL_IDEAL::InferSimModel( aSymbol.GetPrefix(),
aSymbol.GetValueFieldText( true ) );
auto model = SIM_MODEL::InferSimModel( aSymbol.GetPrefix(),
aSymbol.GetValueFieldText( true ) );
if( !model.second.IsEmpty() )
{
fields.emplace_back( VECTOR2I(), -1, &aSymbol, SIM_MODEL::DEVICE_TYPE_FIELD );
fields.emplace_back( &aSymbol, -1, SIM_MODEL::DEVICE_TYPE_FIELD );
fields.back().SetText( aSymbol.GetPrefix() );
if( !model.first.IsEmpty() )
{
fields.emplace_back( VECTOR2I(), -1, &aSymbol, SIM_MODEL::TYPE_FIELD );
fields.emplace_back( &aSymbol, -1, SIM_MODEL::TYPE_FIELD );
fields.back().SetText( model.first );
}
fields.emplace_back( VECTOR2I(), -1, &aSymbol, SIM_MODEL::PARAMS_FIELD );
fields.emplace_back( &aSymbol, -1, SIM_MODEL::PARAMS_FIELD );
fields.back().SetText( model.second );
}
}
@ -175,7 +182,9 @@ SIM_LIBRARY::MODEL SIM_LIB_MGR::CreateModel( const std::vector<T>& aFields, int
std::string baseModelName = SIM_MODEL::GetFieldValue( &aFields, SIM_LIBRARY::NAME_FIELD );
if( libraryPath != "" )
{
return CreateModel( libraryPath, baseModelName, aFields, aSymbolPinCount );
}
else
{
m_models.push_back( SIM_MODEL::Create( aSymbolPinCount, aFields ) );

View File

@ -1198,11 +1198,11 @@ void SIM_MODEL::MigrateSimModel( T_symbol& aSymbol )
// Insert a plaintext model as a substitute.
T_field deviceTypeField( &aSymbol, aSymbol.GetFieldCount(), SIM_MODEL::DEVICE_TYPE_FIELD );
T_field deviceTypeField( &aSymbol, -1, SIM_MODEL::DEVICE_TYPE_FIELD );
deviceTypeField.SetText( SIM_MODEL::DeviceInfo( SIM_MODEL::DEVICE_T::SPICE ).fieldValue );
aSymbol.AddField( deviceTypeField );
T_field paramsField( &aSymbol, aSymbol.GetFieldCount(), SIM_MODEL::PARAMS_FIELD );
T_field paramsField( &aSymbol, -1, SIM_MODEL::PARAMS_FIELD );
paramsField.SetText( wxString::Format( "type=\"%s\" model=\"%s\" lib=\"%s\"",
spiceType, spiceModel, spiceLib ) );
aSymbol.AddField( paramsField );
@ -1210,7 +1210,7 @@ void SIM_MODEL::MigrateSimModel( T_symbol& aSymbol )
// Legacy models by default get linear pin mapping.
if( pinMap != "" )
{
T_field pinsField( &aSymbol, aSymbol.GetFieldCount(), SIM_MODEL::PINS_FIELD );
T_field pinsField( &aSymbol, -1, SIM_MODEL::PINS_FIELD );
pinsField.SetText( pinMap );
aSymbol.AddField( pinsField );