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 #ifdef KICAD_SPICE
int diff = m_fields->size(); 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 ) if( dialog.ShowModal() != wxID_OK )
return; return;

View File

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

View File

@ -41,7 +41,7 @@
// wxPG_NATIVE_DOUBLE_BUFFERING flag is not set. // wxPG_NATIVE_DOUBLE_BUFFERING flag is not set.
// 2. wxPropertyGridManager->ShowHeader() segfaults when called from this dialog's constructor. // 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 class DIALOG_SIM_MODEL : public DIALOG_SIM_MODEL_BASE
{ {
public: public:
@ -82,7 +82,7 @@ public:
MODEL 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(); ~DIALOG_SIM_MODEL();
@ -114,10 +114,8 @@ private:
int getModelPinIndex( const wxString& aModelPinString ) const; int getModelPinIndex( const wxString& aModelPinString ) const;
void onRadioButton( wxCommandEvent& aEvent ) override; void onRadioButton( wxCommandEvent& aEvent ) override;
void onLibraryPathText( wxCommandEvent& aEvent ) override;
void onLibraryPathTextEnter( wxCommandEvent& aEvent ) override; void onLibraryPathTextEnter( wxCommandEvent& aEvent ) override;
void onLibraryPathTextKillFocus( wxFocusEvent& aEvent ) override; void onLibraryPathTextKillFocus( wxFocusEvent& aEvent ) override;
void onLibraryPathTextSetFocus( wxFocusEvent& aEvent ) override;
void onBrowseButtonClick( wxCommandEvent& aEvent ) override; void onBrowseButtonClick( wxCommandEvent& aEvent ) override;
void onModelNameCombobox( wxCommandEvent& aEvent ) override; void onModelNameCombobox( wxCommandEvent& aEvent ) override;
void onModelNameComboboxKillFocus( wxFocusEvent& event ) override; void onModelNameComboboxKillFocus( wxFocusEvent& event ) override;
@ -129,7 +127,6 @@ private:
void onDeviceTypeChoice( wxCommandEvent& aEvent ) override; void onDeviceTypeChoice( wxCommandEvent& aEvent ) override;
void onTypeChoice( wxCommandEvent& aEvent ) override; void onTypeChoice( wxCommandEvent& aEvent ) override;
void onParamGridChanged( wxPropertyGridEvent& aEvent ) override; void onParamGridChanged( wxPropertyGridEvent& aEvent ) override;
void onCodePreviewSetFocus( wxFocusEvent& aEvent ) override;
void onPinAssignmentsGridCellChange( wxGridEvent& aEvent ) override; void onPinAssignmentsGridCellChange( wxGridEvent& aEvent ) override;
void onPinAssignmentsGridSize( wxSizeEvent& aEvent ) override; void onPinAssignmentsGridSize( wxSizeEvent& aEvent ) override;
void onSaveInValueCheckbox( wxCommandEvent& aEvent ) override; void onSaveInValueCheckbox( wxCommandEvent& aEvent ) override;
@ -145,12 +142,13 @@ private:
bool isIbisLoaded() { return dynamic_cast<const SIM_LIBRARY_KIBIS*>( library() ); } bool isIbisLoaded() { return dynamic_cast<const SIM_LIBRARY_KIBIS*>( library() ); }
private: private:
SCH_SYMBOL& m_symbol; T_symbol& m_symbol;
std::vector<T>& m_fields; 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_libraryModelsMgr;
SIM_LIB_MGR m_builtinModelsMgr; SIM_LIB_MGR m_builtinModelsMgr;
const SIM_MODEL* m_prevModel; const SIM_MODEL* m_prevModel;
std::vector<LIB_PIN*> m_sortedPartPins; //< Pins of the current part. std::vector<LIB_PIN*> m_sortedPartPins; //< Pins of the current part.
std::map<SIM_MODEL::DEVICE_T, SIM_MODEL::TYPE> m_curModelTypeOfDeviceType; std::map<SIM_MODEL::DEVICE_T, SIM_MODEL::TYPE> m_curModelTypeOfDeviceType;
@ -158,7 +156,6 @@ private:
MODEL_NAME_VALIDATOR m_modelNameValidator; MODEL_NAME_VALIDATOR m_modelNameValidator;
SCINTILLA_TRICKS* m_scintillaTricks; SCINTILLA_TRICKS* m_scintillaTricks;
bool m_wasCodePreviewUpdated;
wxPGProperty* m_firstCategory; // Used to add principal parameters to root. wxPGProperty* m_firstCategory; // Used to add principal parameters to root.
wxPGProperty* m_prevParamGridSelection; 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_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_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_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_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_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 ); 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_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_PG_CHANGED, wxPropertyGridEventHandler( DIALOG_SIM_MODEL_BASE::onParamGridChanged ), NULL, this );
m_paramGridMgr->Connect( wxEVT_SIZE, wxSizeEventHandler( DIALOG_SIM_MODEL_BASE::onSizeParamGrid ), 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_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_GRID_CELL_CHANGED, wxGridEventHandler( DIALOG_SIM_MODEL_BASE::onPinAssignmentsGridCellChange ), NULL, this );
m_pinAssignmentsGrid->Connect( wxEVT_SIZE, wxSizeEventHandler( DIALOG_SIM_MODEL_BASE::onPinAssignmentsGridSize ), 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_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_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_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_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_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 ); 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_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_PG_CHANGED, wxPropertyGridEventHandler( DIALOG_SIM_MODEL_BASE::onParamGridChanged ), NULL, this );
m_paramGridMgr->Disconnect( wxEVT_SIZE, wxSizeEventHandler( DIALOG_SIM_MODEL_BASE::onSizeParamGrid ), 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_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_GRID_CELL_CHANGED, wxGridEventHandler( DIALOG_SIM_MODEL_BASE::onPinAssignmentsGridCellChange ), NULL, this );
m_pinAssignmentsGrid->Disconnect( wxEVT_SIZE, wxSizeEventHandler( DIALOG_SIM_MODEL_BASE::onPinAssignmentsGridSize ), 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_name"></property>
<property name="window_style"></property> <property name="window_style"></property>
<event name="OnKillFocus">onLibraryPathTextKillFocus</event> <event name="OnKillFocus">onLibraryPathTextKillFocus</event>
<event name="OnSetFocus">onLibraryPathTextSetFocus</event>
<event name="OnText">onLibraryPathText</event>
<event name="OnTextEnter">onLibraryPathTextEnter</event> <event name="OnTextEnter">onLibraryPathTextEnter</event>
</object> </object>
</object> </object>
@ -1645,7 +1643,6 @@
<property name="window_extra_style"></property> <property name="window_extra_style"></property>
<property name="window_name"></property> <property name="window_name"></property>
<property name="window_style"></property> <property name="window_style"></property>
<event name="OnSetFocus">onCodePreviewSetFocus</event>
</object> </object>
</object> </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 onRadioButton( wxCommandEvent& event ) { event.Skip(); }
virtual void onLibraryPathLabelUpdate( wxUpdateUIEvent& event ) { event.Skip(); } virtual void onLibraryPathLabelUpdate( wxUpdateUIEvent& event ) { event.Skip(); }
virtual void onLibraryPathTextKillFocus( wxFocusEvent& 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 onLibraryPathTextEnter( wxCommandEvent& event ) { event.Skip(); }
virtual void onBrowseButtonClick( wxCommandEvent& event ) { event.Skip(); } virtual void onBrowseButtonClick( wxCommandEvent& event ) { event.Skip(); }
virtual void onBrowseButtonUpdate( wxUpdateUIEvent& 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 onTypeChoice( wxCommandEvent& event ) { event.Skip(); }
virtual void onParamGridChanged( wxPropertyGridEvent& event ) { event.Skip(); } virtual void onParamGridChanged( wxPropertyGridEvent& event ) { event.Skip(); }
virtual void onSizeParamGrid( wxSizeEvent& 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 onSaveInValueCheckbox( wxCommandEvent& event ) { event.Skip(); }
virtual void onPinAssignmentsGridCellChange( wxGridEvent& event ) { event.Skip(); } virtual void onPinAssignmentsGridCellChange( wxGridEvent& event ) { event.Skip(); }
virtual void onPinAssignmentsGridSize( wxSizeEvent& 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 ) LIB_FIELD& LIB_FIELD::operator=( const LIB_FIELD& field )
{ {
m_id = field.m_id; m_id = field.m_id;
@ -90,8 +85,6 @@ LIB_FIELD& LIB_FIELD::operator=( const LIB_FIELD& field )
void LIB_FIELD::Init( int aId ) void LIB_FIELD::Init( int aId )
{ {
wxCHECK2( aId >= 0, aId = MANDATORY_FIELDS );
m_id = aId; m_id = aId;
SetTextAngle( ANGLE_HORIZONTAL ); // constructor already did this. SetTextAngle( ANGLE_HORIZONTAL ); // constructor already did this.
@ -114,7 +107,6 @@ void LIB_FIELD::Init( int aId )
void LIB_FIELD::SetId( int aId ) void LIB_FIELD::SetId( int aId )
{ {
wxCHECK2( aId >= 0, aId = MANDATORY_FIELDS );
m_id = aId; m_id = aId;
} }

View File

@ -68,8 +68,6 @@ public:
// Do not create a copy constructor. The one generated by the compiler is adequate. // Do not create a copy constructor. The one generated by the compiler is adequate.
~LIB_FIELD();
wxString GetClass() const override wxString GetClass() const override
{ {
return wxT( "LIB_FIELD" ); 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 ) const LIB_SYMBOL& LIB_SYMBOL::operator=( const LIB_SYMBOL& aSymbol )
{ {
if( &aSymbol == this ) 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_PIN* LIB_SYMBOL::GetPin( const wxString& aNumber, int aUnit, int aConvert ) const
{ {
LIB_PINS pinList; 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(); 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. // 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 ); field->SetParent( this );
m_drawings.push_back( field ); m_drawings.push_back( field );

View File

@ -103,7 +103,8 @@ public:
LIB_SYMBOL( const LIB_SYMBOL& aSymbol, SYMBOL_LIB* aLibrary = nullptr ); 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 ///< 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; } LIB_SYMBOL_SPTR SharedPtr() const { return m_me; }
@ -254,15 +255,11 @@ public:
bool UnitsLocked() const { return m_unitsLocked; } bool UnitsLocked() const { return m_unitsLocked; }
/** /**
* Overwrite all the existing fields in this symbol with fields supplied * Overwrite all the existing fields in this symbol with fields supplied in \a aFieldsList.
* in \a aFieldsList.
*
* The only known caller of this function is the library symbol field editor, and it
* establishes needed behavior.
* *
* @param aFieldsList is a set of fields to import, removing all previous fields. * @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. * 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; 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. * 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.first: wxString sim model type
// pair.second: wxString sim model parameters // pair.second: wxString sim model parameters
auto model = SIM_MODEL_IDEAL::InferSimModel( symbol->GetPrefix(), auto model = SIM_MODEL::InferSimModel( symbol->GetPrefix(),
symbol->GetValueFieldText( true ) ); symbol->GetValueFieldText( true ) );
if( !model.second.IsEmpty() ) 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() ); spiceItem.fields.back().SetText( symbol->GetPrefix() );
if( !model.first.IsEmpty() ) 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.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 ); spiceItem.fields.back().SetText( model.second );
} }
} }

View File

@ -456,7 +456,7 @@ public:
* *
* @param aFields are the fields to set in this symbol. * @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 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 ) 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; std::vector<SCH_FIELD> fields;
for( int i = 0; i < aSymbol.GetFieldCount(); ++i ) 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.first: wxString sim model type
// pair.second: wxString sim model parameters // pair.second: wxString sim model parameters
auto model = SIM_MODEL_IDEAL::InferSimModel( aSymbol.GetPrefix(), auto model = SIM_MODEL::InferSimModel( aSymbol.GetPrefix(),
aSymbol.GetValueFieldText( true ) ); aSymbol.GetValueFieldText( true ) );
if( !model.second.IsEmpty() ) 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() ); fields.back().SetText( aSymbol.GetPrefix() );
if( !model.first.IsEmpty() ) 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.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 ); 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 ); std::string baseModelName = SIM_MODEL::GetFieldValue( &aFields, SIM_LIBRARY::NAME_FIELD );
if( libraryPath != "" ) if( libraryPath != "" )
{
return CreateModel( libraryPath, baseModelName, aFields, aSymbolPinCount ); return CreateModel( libraryPath, baseModelName, aFields, aSymbolPinCount );
}
else else
{ {
m_models.push_back( SIM_MODEL::Create( aSymbolPinCount, aFields ) ); 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. // 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 ); deviceTypeField.SetText( SIM_MODEL::DeviceInfo( SIM_MODEL::DEVICE_T::SPICE ).fieldValue );
aSymbol.AddField( deviceTypeField ); 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\"", paramsField.SetText( wxString::Format( "type=\"%s\" model=\"%s\" lib=\"%s\"",
spiceType, spiceModel, spiceLib ) ); spiceType, spiceModel, spiceLib ) );
aSymbol.AddField( paramsField ); aSymbol.AddField( paramsField );
@ -1210,7 +1210,7 @@ void SIM_MODEL::MigrateSimModel( T_symbol& aSymbol )
// Legacy models by default get linear pin mapping. // Legacy models by default get linear pin mapping.
if( pinMap != "" ) if( pinMap != "" )
{ {
T_field pinsField( &aSymbol, aSymbol.GetFieldCount(), SIM_MODEL::PINS_FIELD ); T_field pinsField( &aSymbol, -1, SIM_MODEL::PINS_FIELD );
pinsField.SetText( pinMap ); pinsField.SetText( pinMap );
aSymbol.AddField( pinsField ); aSymbol.AddField( pinsField );