Gracefully handle spice models not recognized by KiCad.
Fixes https://gitlab.com/kicad/code/kicad/issues/12689
This commit is contained in:
parent
f29f0c5c0a
commit
1855885d1e
|
@ -375,6 +375,11 @@ void DIALOG_SIM_MODEL<T>::updateInstanceWidgets()
|
||||||
|
|
||||||
m_typeChoice->Enable( !m_useLibraryModelRadioButton->GetValue() || isIbisLoaded() );
|
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() )
|
if( curModel().HasPrimaryValue() )
|
||||||
{
|
{
|
||||||
const SIM_MODEL::PARAM& primary = curModel().GetParam( 0 );
|
const SIM_MODEL::PARAM& primary = curModel().GetParam( 0 );
|
||||||
|
@ -489,46 +494,21 @@ void DIALOG_SIM_MODEL<T>::updateModelParamsTab()
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void DIALOG_SIM_MODEL<T>::updateModelCodeTab()
|
void DIALOG_SIM_MODEL<T>::updateModelCodeTab()
|
||||||
{
|
{
|
||||||
|
wxString text;
|
||||||
SPICE_ITEM item;
|
SPICE_ITEM item;
|
||||||
item.modelName = m_modelNameCombobox->GetStringSelection();
|
item.modelName = m_modelNameCombobox->GetStringSelection();
|
||||||
|
|
||||||
if( m_useInstanceModelRadioButton->GetValue() || item.modelName == "" )
|
if( m_useInstanceModelRadioButton->GetValue() || item.modelName == "" )
|
||||||
item.modelName = m_fields.at( REFERENCE_FIELD ).GetText();
|
item.modelName = m_fields.at( REFERENCE_FIELD ).GetText();
|
||||||
|
|
||||||
m_codePreview->SetEditable( true ); // ???
|
SIM_MODEL& model = curModel();
|
||||||
|
|
||||||
if( dynamic_cast<SIM_MODEL_RAW_SPICE*>( &curModel() ) )
|
text << model.SpiceGenerator().Preview( item );
|
||||||
{
|
|
||||||
// For raw Spice models display the whole file instead.
|
|
||||||
|
|
||||||
wxString path = curModel().FindParam( "lib" )->value->ToString();
|
if( SIM_MODEL_RAW_SPICE* rawSpice = dynamic_cast<SIM_MODEL_RAW_SPICE*>( &model ) )
|
||||||
wxString absolutePath = Prj().AbsolutePath( path );
|
text << rawSpice->GetSource();
|
||||||
wxTextFile file;
|
|
||||||
wxString text;
|
|
||||||
|
|
||||||
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 );
|
m_codePreview->SetText( text );
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_codePreview->SetText( curModel().SpiceGenerator().Preview( item ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
m_codePreview->SetEditable( false ); // ???
|
|
||||||
m_wasCodePreviewUpdated = true;
|
m_wasCodePreviewUpdated = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -644,7 +624,7 @@ void DIALOG_SIM_MODEL<T>::loadLibrary( const wxString& aLibraryPath, bool aForce
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
m_libraryModelsMgr.SetLibrary( std::string( aLibraryPath.ToUTF8() ),
|
m_libraryModelsMgr.SetLibrary( std::string( aLibraryPath.ToUTF8() ),
|
||||||
&( dlg.m_messagePanel->Reporter() ) );
|
&dlg.m_messagePanel->Reporter() );
|
||||||
}
|
}
|
||||||
catch( const IO_ERROR& e )
|
catch( const IO_ERROR& e )
|
||||||
{
|
{
|
||||||
|
@ -654,7 +634,9 @@ void DIALOG_SIM_MODEL<T>::loadLibrary( const wxString& aLibraryPath, bool aForce
|
||||||
dlg.ShowQuasiModal();
|
dlg.ShowQuasiModal();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
DisplayErrorMessage( this, e.What() );
|
DisplayErrorMessage( this, e.What() );
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -887,7 +869,9 @@ SIM_MODEL& DIALOG_SIM_MODEL<T>::curModel() const
|
||||||
return m_libraryModelsMgr.GetModels().at( m_modelNameCombobox->GetSelection() ).get();
|
return m_libraryModelsMgr.GetModels().at( m_modelNameCombobox->GetSelection() ).get();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
return m_builtinModelsMgr.GetModels().at( static_cast<int>( m_curModelType ) );
|
return m_builtinModelsMgr.GetModels().at( static_cast<int>( m_curModelType ) );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1064,11 +1048,7 @@ void DIALOG_SIM_MODEL<T>::onModelNameCombobox( wxCommandEvent& aEvent )
|
||||||
wxArrayString pinLabels;
|
wxArrayString pinLabels;
|
||||||
SIM_MODEL_KIBIS* modelkibis = dynamic_cast<SIM_MODEL_KIBIS*>( &curModel() );
|
SIM_MODEL_KIBIS* modelkibis = dynamic_cast<SIM_MODEL_KIBIS*>( &curModel() );
|
||||||
|
|
||||||
if( !modelkibis )
|
wxCHECK2( modelkibis, return );
|
||||||
{
|
|
||||||
wxFAIL;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for( std::pair<wxString, wxString> strs : modelkibis->GetIbisPins() )
|
for( std::pair<wxString, wxString> strs : modelkibis->GetIbisPins() )
|
||||||
pinLabels.Add( strs.first + wxT( " - " ) + strs.second );
|
pinLabels.Add( strs.first + wxT( " - " ) + strs.second );
|
||||||
|
|
|
@ -125,8 +125,8 @@ DIALOG_SIM_MODEL_BASE::DIALOG_SIM_MODEL_BASE( wxWindow* parent, wxWindowID id, c
|
||||||
|
|
||||||
bSizerMargins->Add( fgSizer16, 0, wxEXPAND|wxLEFT, 24 );
|
bSizerMargins->Add( fgSizer16, 0, wxEXPAND|wxLEFT, 24 );
|
||||||
|
|
||||||
m_notebook4 = new wxNotebook( m_modelPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
|
m_modelNotebook = new wxNotebook( m_modelPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
|
||||||
m_parametersPanel = new wxPanel( m_notebook4, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
|
m_parametersPanel = new wxPanel( m_modelNotebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
|
||||||
m_parametersPanel->SetMinSize( wxSize( 500,-1 ) );
|
m_parametersPanel->SetMinSize( wxSize( 500,-1 ) );
|
||||||
|
|
||||||
wxBoxSizer* bSizer12;
|
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->SetSizer( bSizer12 );
|
||||||
m_parametersPanel->Layout();
|
m_parametersPanel->Layout();
|
||||||
bSizer12->Fit( m_parametersPanel );
|
bSizer12->Fit( m_parametersPanel );
|
||||||
m_notebook4->AddPage( m_parametersPanel, _("Parameters"), true );
|
m_modelNotebook->AddPage( m_parametersPanel, _("Parameters"), true );
|
||||||
m_codePanel = new wxPanel( m_notebook4, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
|
m_codePanel = new wxPanel( m_modelNotebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
|
||||||
wxBoxSizer* bSizer5;
|
wxBoxSizer* bSizer5;
|
||||||
bSizer5 = new wxBoxSizer( wxVERTICAL );
|
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->SetSizer( bSizer5 );
|
||||||
m_codePanel->Layout();
|
m_codePanel->Layout();
|
||||||
bSizer5->Fit( m_codePanel );
|
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 );
|
m_saveInValueCheckbox = new wxCheckBox( m_modelPanel, wxID_ANY, _("Save {} in Value field as \"{}\""), wxDefaultPosition, wxDefaultSize, 0 );
|
||||||
bSizerMargins->Add( m_saveInValueCheckbox, 0, wxALL, 6 );
|
bSizerMargins->Add( m_saveInValueCheckbox, 0, wxALL, 6 );
|
||||||
|
|
|
@ -1372,7 +1372,7 @@
|
||||||
<property name="minimize_button">0</property>
|
<property name="minimize_button">0</property>
|
||||||
<property name="minimum_size"></property>
|
<property name="minimum_size"></property>
|
||||||
<property name="moveable">1</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_border">1</property>
|
||||||
<property name="pane_position"></property>
|
<property name="pane_position"></property>
|
||||||
<property name="pane_size"></property>
|
<property name="pane_size"></property>
|
||||||
|
|
|
@ -69,7 +69,7 @@ class DIALOG_SIM_MODEL_BASE : public DIALOG_SHIM
|
||||||
wxChoice* m_deviceTypeChoice;
|
wxChoice* m_deviceTypeChoice;
|
||||||
wxStaticText* m_staticTextSpiceType;
|
wxStaticText* m_staticTextSpiceType;
|
||||||
wxChoice* m_typeChoice;
|
wxChoice* m_typeChoice;
|
||||||
wxNotebook* m_notebook4;
|
wxNotebook* m_modelNotebook;
|
||||||
wxPanel* m_parametersPanel;
|
wxPanel* m_parametersPanel;
|
||||||
wxPropertyGridManager* m_paramGridMgr;
|
wxPropertyGridManager* m_paramGridMgr;
|
||||||
wxPropertyGridPage* m_paramGrid;
|
wxPropertyGridPage* m_paramGrid;
|
||||||
|
|
|
@ -64,6 +64,16 @@ public:
|
||||||
|
|
||||||
SIM_MODEL_RAW_SPICE();
|
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:
|
protected:
|
||||||
void CreatePins( unsigned aSymbolPinCount ) override;
|
void CreatePins( unsigned aSymbolPinCount ) override;
|
||||||
|
|
||||||
|
@ -71,7 +81,8 @@ private:
|
||||||
static std::vector<PARAM::INFO> makeParamInfos();
|
static std::vector<PARAM::INFO> makeParamInfos();
|
||||||
bool requiresSpiceModelLine() const override { return false; }
|
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
|
#endif // SIM_MODEL_RAW_SPICE_H
|
||||||
|
|
|
@ -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 )
|
const std::string& aSpiceCode )
|
||||||
{
|
{
|
||||||
auto model = dynamic_cast<SIM_MODEL_SPICE*>(
|
SIM_MODEL::TYPE modelType = SPICE_MODEL_PARSER::ReadType( aLibrary, aSpiceCode );
|
||||||
SIM_MODEL::Create( SPICE_MODEL_PARSER::ReadType( aLibrary, aSpiceCode ) ).release() );
|
SIM_MODEL* model = SIM_MODEL::Create( modelType ).release();
|
||||||
|
|
||||||
if( !model )
|
if( SIM_MODEL_SPICE* spiceModel = dynamic_cast<SIM_MODEL_SPICE*>( model ) )
|
||||||
THROW_IO_ERROR( "Could not determine Spice model type" );
|
{
|
||||||
|
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 );
|
delete model;
|
||||||
return std::unique_ptr<SIM_MODEL_SPICE>( model );
|
THROW_IO_ERROR( "Could not determine Spice model modelType" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SIM_MODEL_SPICE::SIM_MODEL_SPICE( TYPE aType,
|
SIM_MODEL_SPICE::SIM_MODEL_SPICE( TYPE aType, std::unique_ptr<SPICE_GENERATOR> aSpiceGenerator ) :
|
||||||
std::unique_ptr<SPICE_GENERATOR> aSpiceGenerator ) :
|
|
||||||
SIM_MODEL( aType, std::move( aSpiceGenerator ) ),
|
SIM_MODEL( aType, std::move( aSpiceGenerator ) ),
|
||||||
m_spiceModelParser( std::make_unique<SPICE_MODEL_PARSER>( *this ) )
|
m_spiceModelParser( std::make_unique<SPICE_MODEL_PARSER>( *this ) )
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SIM_MODEL_SPICE::SIM_MODEL_SPICE( TYPE aType,
|
SIM_MODEL_SPICE::SIM_MODEL_SPICE( TYPE aType, std::unique_ptr<SPICE_GENERATOR> aSpiceGenerator,
|
||||||
std::unique_ptr<SPICE_GENERATOR> aSpiceGenerator,
|
|
||||||
std::unique_ptr<SPICE_MODEL_PARSER> aSpiceModelParser ) :
|
std::unique_ptr<SPICE_MODEL_PARSER> aSpiceModelParser ) :
|
||||||
SIM_MODEL( aType, std::move( aSpiceGenerator ) ),
|
SIM_MODEL( aType, std::move( aSpiceGenerator ) ),
|
||||||
m_spiceModelParser( std::move( aSpiceModelParser ) )
|
m_spiceModelParser( std::move( aSpiceModelParser ) )
|
||||||
|
|
|
@ -47,7 +47,7 @@ public:
|
||||||
friend class SPICE_GENERATOR_SPICE;
|
friend class SPICE_GENERATOR_SPICE;
|
||||||
friend class SPICE_MODEL_PARSER;
|
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 );
|
const std::string& aSpiceCode );
|
||||||
|
|
||||||
SIM_MODEL_SPICE( TYPE aType,
|
SIM_MODEL_SPICE( TYPE aType,
|
||||||
|
|
Loading…
Reference in New Issue