Gracefully handle spice models not recognized by KiCad.

Fixes https://gitlab.com/kicad/code/kicad/issues/12689
This commit is contained in:
Jeff Young 2022-12-04 19:43:57 +00:00
parent f29f0c5c0a
commit 1855885d1e
7 changed files with 57 additions and 60 deletions

View File

@ -375,6 +375,11 @@ void DIALOG_SIM_MODEL<T>::updateInstanceWidgets()
m_typeChoice->Enable( !m_useLibraryModelRadioButton->GetValue() || isIbisLoaded() );
if( dynamic_cast<SIM_MODEL_RAW_SPICE*>( &curModel() ) )
m_modelNotebook->SetSelection( 1 );
else
m_modelNotebook->SetSelection( 0 );
if( curModel().HasPrimaryValue() )
{
const SIM_MODEL::PARAM& primary = curModel().GetParam( 0 );
@ -489,46 +494,21 @@ void DIALOG_SIM_MODEL<T>::updateModelParamsTab()
template <typename T>
void DIALOG_SIM_MODEL<T>::updateModelCodeTab()
{
wxString text;
SPICE_ITEM item;
item.modelName = m_modelNameCombobox->GetStringSelection();
if( m_useInstanceModelRadioButton->GetValue() || item.modelName == "" )
item.modelName = m_fields.at( REFERENCE_FIELD ).GetText();
m_codePreview->SetEditable( true ); // ???
SIM_MODEL& model = curModel();
if( dynamic_cast<SIM_MODEL_RAW_SPICE*>( &curModel() ) )
{
// For raw Spice models display the whole file instead.
text << model.SpiceGenerator().Preview( item );
wxString path = curModel().FindParam( "lib" )->value->ToString();
wxString absolutePath = Prj().AbsolutePath( path );
wxTextFile file;
wxString text;
if( SIM_MODEL_RAW_SPICE* rawSpice = dynamic_cast<SIM_MODEL_RAW_SPICE*>( &model ) )
text << rawSpice->GetSource();
text << curModel().SpiceGenerator().Preview( item );
text << "\n";
text << "--- FILE SOURCE (" << path << ") ---\n";
text << "\n";
if( wxFileExists( absolutePath ) && file.Open( absolutePath ) )
{
for( text << file.GetFirstLine() << "\n";
!file.Eof();
text << file.GetNextLine() << "\n" )
{
}
file.Close();
m_codePreview->SetText( text );
}
}
else
{
m_codePreview->SetText( curModel().SpiceGenerator().Preview( item ) );
}
m_codePreview->SetEditable( false ); // ???
m_wasCodePreviewUpdated = true;
}
@ -644,7 +624,7 @@ void DIALOG_SIM_MODEL<T>::loadLibrary( const wxString& aLibraryPath, bool aForce
try
{
m_libraryModelsMgr.SetLibrary( std::string( aLibraryPath.ToUTF8() ),
&( dlg.m_messagePanel->Reporter() ) );
&dlg.m_messagePanel->Reporter() );
}
catch( const IO_ERROR& e )
{
@ -654,7 +634,9 @@ void DIALOG_SIM_MODEL<T>::loadLibrary( const wxString& aLibraryPath, bool aForce
dlg.ShowQuasiModal();
}
else
{
DisplayErrorMessage( this, e.What() );
}
return;
}
@ -887,7 +869,9 @@ SIM_MODEL& DIALOG_SIM_MODEL<T>::curModel() const
return m_libraryModelsMgr.GetModels().at( m_modelNameCombobox->GetSelection() ).get();
}
else
{
return m_builtinModelsMgr.GetModels().at( static_cast<int>( m_curModelType ) );
}
}
@ -1064,11 +1048,7 @@ void DIALOG_SIM_MODEL<T>::onModelNameCombobox( wxCommandEvent& aEvent )
wxArrayString pinLabels;
SIM_MODEL_KIBIS* modelkibis = dynamic_cast<SIM_MODEL_KIBIS*>( &curModel() );
if( !modelkibis )
{
wxFAIL;
return;
}
wxCHECK2( modelkibis, return );
for( std::pair<wxString, wxString> strs : modelkibis->GetIbisPins() )
pinLabels.Add( strs.first + wxT( " - " ) + strs.second );

View File

@ -125,8 +125,8 @@ DIALOG_SIM_MODEL_BASE::DIALOG_SIM_MODEL_BASE( wxWindow* parent, wxWindowID id, c
bSizerMargins->Add( fgSizer16, 0, wxEXPAND|wxLEFT, 24 );
m_notebook4 = new wxNotebook( m_modelPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
m_parametersPanel = new wxPanel( m_notebook4, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
m_modelNotebook = new wxNotebook( m_modelPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
m_parametersPanel = new wxPanel( m_modelNotebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
m_parametersPanel->SetMinSize( wxSize( 500,-1 ) );
wxBoxSizer* bSizer12;
@ -142,8 +142,8 @@ DIALOG_SIM_MODEL_BASE::DIALOG_SIM_MODEL_BASE( wxWindow* parent, wxWindowID id, c
m_parametersPanel->SetSizer( bSizer12 );
m_parametersPanel->Layout();
bSizer12->Fit( m_parametersPanel );
m_notebook4->AddPage( m_parametersPanel, _("Parameters"), true );
m_codePanel = new wxPanel( m_notebook4, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
m_modelNotebook->AddPage( m_parametersPanel, _("Parameters"), true );
m_codePanel = new wxPanel( m_modelNotebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
wxBoxSizer* bSizer5;
bSizer5 = new wxBoxSizer( wxVERTICAL );
@ -189,9 +189,9 @@ DIALOG_SIM_MODEL_BASE::DIALOG_SIM_MODEL_BASE( wxWindow* parent, wxWindowID id, c
m_codePanel->SetSizer( bSizer5 );
m_codePanel->Layout();
bSizer5->Fit( m_codePanel );
m_notebook4->AddPage( m_codePanel, _("Code"), false );
m_modelNotebook->AddPage( m_codePanel, _("Code"), false );
bSizerMargins->Add( m_notebook4, 1, wxEXPAND|wxTOP, 10 );
bSizerMargins->Add( m_modelNotebook, 1, wxEXPAND|wxTOP, 10 );
m_saveInValueCheckbox = new wxCheckBox( m_modelPanel, wxID_ANY, _("Save {} in Value field as \"{}\""), wxDefaultPosition, wxDefaultSize, 0 );
bSizerMargins->Add( m_saveInValueCheckbox, 0, wxALL, 6 );

View File

@ -1372,7 +1372,7 @@
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_notebook4</property>
<property name="name">m_modelNotebook</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>

View File

@ -69,7 +69,7 @@ class DIALOG_SIM_MODEL_BASE : public DIALOG_SHIM
wxChoice* m_deviceTypeChoice;
wxStaticText* m_staticTextSpiceType;
wxChoice* m_typeChoice;
wxNotebook* m_notebook4;
wxNotebook* m_modelNotebook;
wxPanel* m_parametersPanel;
wxPropertyGridManager* m_paramGridMgr;
wxPropertyGridPage* m_paramGrid;

View File

@ -64,6 +64,16 @@ public:
SIM_MODEL_RAW_SPICE();
void SetSource( const std::string& aSpiceSource ) { m_spiceCode = aSpiceSource; }
std::string GetSource() const
{
if( m_baseModel )
return static_cast<const SIM_MODEL_RAW_SPICE*>( m_baseModel )->GetSource();
return m_spiceCode;
}
protected:
void CreatePins( unsigned aSymbolPinCount ) override;
@ -71,7 +81,8 @@ private:
static std::vector<PARAM::INFO> makeParamInfos();
bool requiresSpiceModelLine() const override { return false; }
std::vector<std::unique_ptr<PARAM::INFO>> m_paramInfos;
private:
std::string m_spiceCode;
};
#endif // SIM_MODEL_RAW_SPICE_H

View File

@ -54,30 +54,36 @@ std::string SPICE_GENERATOR_SPICE::Preview( const SPICE_ITEM& aItem ) const
}
std::unique_ptr<SIM_MODEL_SPICE> SIM_MODEL_SPICE::Create( const SIM_LIBRARY_SPICE& aLibrary,
std::unique_ptr<SIM_MODEL> SIM_MODEL_SPICE::Create( const SIM_LIBRARY_SPICE& aLibrary,
const std::string& aSpiceCode )
{
auto model = dynamic_cast<SIM_MODEL_SPICE*>(
SIM_MODEL::Create( SPICE_MODEL_PARSER::ReadType( aLibrary, aSpiceCode ) ).release() );
SIM_MODEL::TYPE modelType = SPICE_MODEL_PARSER::ReadType( aLibrary, aSpiceCode );
SIM_MODEL* model = SIM_MODEL::Create( modelType ).release();
if( !model )
THROW_IO_ERROR( "Could not determine Spice model type" );
if( SIM_MODEL_SPICE* spiceModel = dynamic_cast<SIM_MODEL_SPICE*>( model ) )
{
spiceModel->m_spiceModelParser->ReadModel( aLibrary, aSpiceCode );
return std::unique_ptr<SIM_MODEL_SPICE>( spiceModel );
}
else if( SIM_MODEL_RAW_SPICE* rawSpice = dynamic_cast<SIM_MODEL_RAW_SPICE*>( model ) )
{
rawSpice->SetSource( aSpiceCode );
return std::unique_ptr<SIM_MODEL_RAW_SPICE>( rawSpice );
}
model->m_spiceModelParser->ReadModel( aLibrary, aSpiceCode );
return std::unique_ptr<SIM_MODEL_SPICE>( model );
delete model;
THROW_IO_ERROR( "Could not determine Spice model modelType" );
}
SIM_MODEL_SPICE::SIM_MODEL_SPICE( TYPE aType,
std::unique_ptr<SPICE_GENERATOR> aSpiceGenerator ) :
SIM_MODEL_SPICE::SIM_MODEL_SPICE( TYPE aType, std::unique_ptr<SPICE_GENERATOR> aSpiceGenerator ) :
SIM_MODEL( aType, std::move( aSpiceGenerator ) ),
m_spiceModelParser( std::make_unique<SPICE_MODEL_PARSER>( *this ) )
{
}
SIM_MODEL_SPICE::SIM_MODEL_SPICE( TYPE aType,
std::unique_ptr<SPICE_GENERATOR> aSpiceGenerator,
SIM_MODEL_SPICE::SIM_MODEL_SPICE( TYPE aType, std::unique_ptr<SPICE_GENERATOR> aSpiceGenerator,
std::unique_ptr<SPICE_MODEL_PARSER> aSpiceModelParser ) :
SIM_MODEL( aType, std::move( aSpiceGenerator ) ),
m_spiceModelParser( std::move( aSpiceModelParser ) )

View File

@ -47,7 +47,7 @@ public:
friend class SPICE_GENERATOR_SPICE;
friend class SPICE_MODEL_PARSER;
static std::unique_ptr<SIM_MODEL_SPICE> Create( const SIM_LIBRARY_SPICE& aLibrary,
static std::unique_ptr<SIM_MODEL> Create( const SIM_LIBRARY_SPICE& aLibrary,
const std::string& aSpiceCode );
SIM_MODEL_SPICE( TYPE aType,