42#include <wx/filedlg.h>
43#include <fmt/format.h>
48#include <wx/filedlg.h>
53#define FORCE_UPDATE_PINS true
56bool equivalent( SIM_MODEL::DEVICE_T a, SIM_MODEL::DEVICE_T b )
67 std::vector<SCH_FIELD>& aFields ) :
72 m_libraryModelsMgr( &
Prj(), nullptr ),
73 m_builtinModelsMgr( &
Prj(), nullptr ),
74 m_prevModel( nullptr ),
76 m_scintillaTricksCode( nullptr ),
77 m_scintillaTricksSubckt( nullptr ),
78 m_firstCategory( nullptr ),
79 m_prevParamGridSelection( nullptr ),
80 m_lastParamGridWidth( 0 )
85 if constexpr (std::is_same_v<T, SCH_SYMBOL>)
96 if( !
pin->GetParentSymbol()->HasAlternateBodyStyle() ||
pin->GetBodyStyle() < 2 )
104 return StrNumCmp( lhs->GetNumber(), rhs->GetNumber(), true ) < 0;
117 grid->SetCellDisabledTextColour( wxSystemSettings::GetColour( wxSYS_COLOUR_GRAYTEXT ) );
121 grid->DedicateKey( WXK_RETURN );
122 grid->DedicateKey( WXK_NUMPAD_ENTER );
123 grid->DedicateKey( WXK_UP );
124 grid->DedicateKey( WXK_DOWN );
126#if wxCHECK_VERSION( 3, 3, 0 )
127 grid->AddActionTrigger( wxPGKeyboardAction::Edit, WXK_RETURN );
128 grid->AddActionTrigger( wxPGKeyboardAction::NextProperty, WXK_RETURN );
129 grid->AddActionTrigger( wxPGKeyboardAction::Edit, WXK_NUMPAD_ENTER );
130 grid->AddActionTrigger( wxPGKeyboardAction::NextProperty, WXK_NUMPAD_ENTER );
132 grid->AddActionTrigger( wxPG_ACTION_EDIT, WXK_RETURN );
133 grid->AddActionTrigger( wxPG_ACTION_NEXT_PROPERTY, WXK_RETURN );
134 grid->AddActionTrigger( wxPG_ACTION_EDIT, WXK_NUMPAD_ENTER );
135 grid->AddActionTrigger( wxPG_ACTION_NEXT_PROPERTY, WXK_NUMPAD_ENTER );
151 for( wxPropertyGridIterator it = m_paramGrid->GetIterator(); !it.AtEnd(); ++it )
162 m_pinAssignmentsGrid->PopEventHandler(
true );
164 delete m_scintillaTricksCode;
165 delete m_scintillaTricksSubckt;
172 wxCommandEvent dummyEvent;
175 wxString modelParams;
177 bool storeInValue =
false;
183 &deviceType, &modelType, &modelParams, &pinMap ) )
187 if( !modelType.IsEmpty() )
203 if( libraryFilename !=
"" )
206 m_rbLibraryModel->SetValue(
true );
208 if( !loadLibrary( libraryFilename, reporter ) )
213 m_libraryPathText->ChangeValue( libraryFilename );
216 m_libraryModelsMgr.CreateModel(
nullptr, m_sortedPartPins, m_fields, reporter );
218 m_modelListBox->Append(
_(
"<unknown>" ) );
219 m_modelListBox->SetSelection( 0 );
224 int modelIdx = m_modelListBox->FindString( modelName );
226 if( modelIdx == wxNOT_FOUND )
228 m_infoBar->ShowMessage( wxString::Format(
_(
"No model named '%s' in library." ),
232 m_modelListBox->SetSelection( 0 );
237 m_modelListBox->SetSelection( modelIdx );
240 m_curModelType = curModel().GetType();
243 if( isIbisLoaded() && ( m_modelListBox->GetSelection() >= 0 ) )
246 wxString sel = m_modelListBox->GetStringSelection();
248 if( m_modelListBoxEntryToLibraryIdx.contains( sel ) )
249 idx = m_modelListBoxEntryToLibraryIdx.at( sel );
252 dynamic_cast<SIM_MODEL_IBIS*
>( &m_libraryModelsMgr.GetModels()[idx].get() );
256 onModelNameChoice( dummyEvent );
260 for(
const std::pair<std::string, std::string>& strs : ibismodel->GetIbisPins() )
266 ibismodel->ChangePin( *ibisLibrary, strs.first );
267 m_pinCombobox->SetSelection(
static_cast<int>( i ) );
273 if( i <
static_cast<int>( ibismodel->GetIbisPins().size() ) )
275 onPinCombobox( dummyEvent );
282 ibismodel->SwitchSingleEndedDiff(
true );
283 m_differentialCheckbox->SetValue(
true );
287 ibismodel->SwitchSingleEndedDiff(
false );
288 m_differentialCheckbox->SetValue(
false );
297 m_rbBuiltinModel->SetValue(
true );
306 for( SIM_MODEL::TYPE type : SIM_MODEL::TYPE_ITERATOR() )
308 if( m_rbBuiltinModel->GetValue() && type == m_curModelType )
311 m_builtinModelsMgr.CreateModel( m_fields, m_sortedPartPins,
false, reporter );
321 m_builtinModelsMgr.CreateModel( type, m_sortedPartPins, reporter );
326 if( !m_curModelTypeOfDeviceType.count( deviceTypeT ) )
327 m_curModelTypeOfDeviceType[deviceTypeT] = type;
331 curModel().SetIsStoredInValue(
true );
333 m_saveInValueCheckbox->SetValue( curModel().IsStoredInValue() );
335 onRadioButton( dummyEvent );
336 return DIALOG_SIM_MODEL_BASE::TransferDataToWindow();
343 m_pinAssignmentsGrid->CommitPendingChanges();
344 m_paramGrid->GetGrid()->CommitChangesFromEditor();
346 if( !DIALOG_SIM_MODEL_BASE::TransferDataFromWindow() )
353 if( m_rbLibraryModel->GetValue() )
355 path = m_libraryPathText->GetValue();
356 wxFileName fn(
path );
359 && !fn.GetFullPath().StartsWith(
".." ) )
361 path = fn.GetFullPath();
364 if( m_modelListBox->GetSelection() >= 0 )
365 name = m_modelListBox->GetStringSelection().ToStdString();
376 wxString sel = m_modelListBox->GetStringSelection();
378 if( m_modelListBoxEntryToLibraryIdx.contains( sel ) )
379 idx = m_modelListBoxEntryToLibraryIdx.at( sel );
382 static_cast<SIM_MODEL_IBIS*
>( &m_libraryModelsMgr.GetModels().at( idx ).get() );
387 std::string modelName = std::string( m_pinModelCombobox->GetValue().c_str() );
388 std::string differential;
390 if( m_pinCombobox->GetSelection() >= 0 )
391 pins = ibismodel->GetIbisPins().at( m_pinCombobox->GetSelection() ).first;
393 if( ibismodel->CanDifferential() && m_differentialCheckbox->GetValue() )
402 if( model.
GetType() == SIM_MODEL::TYPE::RAWSPICE )
404 if( m_modelNotebook->GetSelection() == 0 )
405 updateModelCodeTab( &model );
407 wxString code = m_codePreview->GetText().Trim(
true ).Trim(
false );
408 model.
SetParamValue(
"model", std::string( code.ToUTF8() ) );
413 for(
int row = 0; row < m_pinAssignmentsGrid->GetNumberRows(); ++row )
415 wxString modelPinName = m_pinAssignmentsGrid->GetCellValue( row, PIN_COLUMN::MODEL );
416 wxString symbolPinName = m_sortedPartPins.at( row )->GetShownNumber();
419 std::string( symbolPinName.ToUTF8() ) );
422 removeOrphanedPinAssignments( &model );
424 curModel().WriteFields( m_fields );
435 m_browseButton->Enable();
438 bool undetermined = !m_rbLibraryModel->GetValue() && !m_rbBuiltinModel->GetValue();
439 bool enableLibCtrls = m_rbLibraryModel->GetValue() || undetermined;
440 bool enableBuiltinCtrls = m_rbBuiltinModel->GetValue() || undetermined;
442 m_pathLabel->Enable( enableLibCtrls );
443 m_libraryPathText->Enable( enableLibCtrls );
444 m_modelNameLabel->Enable( enableLibCtrls );
445 m_modelFilter->Enable( enableLibCtrls && !isIbisLoaded() );
446 m_modelListBox->Enable( enableLibCtrls );
447 m_pinLabel->Enable( enableLibCtrls );
448 m_pinCombobox->Enable( enableLibCtrls );
449 m_differentialCheckbox->Enable( enableLibCtrls );
450 m_pinModelLabel->Enable( enableLibCtrls );
451 m_pinModelCombobox->Enable( enableLibCtrls );
452 m_waveformLabel->Enable( enableLibCtrls );
453 m_waveformChoice->Enable( enableLibCtrls );
455 m_deviceLabel->Enable( enableBuiltinCtrls );
456 m_deviceChoice->Enable( enableBuiltinCtrls );
457 m_deviceSubtypeLabel->Enable( enableBuiltinCtrls );
458 m_deviceSubtypeChoice->Enable( enableBuiltinCtrls );
462 updateIbisWidgets( model );
463 updateBuiltinModelWidgets( model );
464 updateModelParamsTab( model );
465 updateModelCodeTab( model );
466 updatePinAssignments( model, model != m_prevModel );
470 m_modelPanel->Layout();
471 m_pinAssignmentsPanel->Layout();
472 m_parametersPanel->Layout();
473 m_codePanel->Layout();
475 SendSizeEvent( wxSEND_EVENT_POST );
477 m_prevModel = &curModel();
487 m_pinLabel->Show( isIbisLoaded() );
488 m_pinCombobox->Show( isIbisLoaded() );
489 m_pinModelLabel->Show( isIbisLoaded() );
490 m_pinModelCombobox->Show( isIbisLoaded() );
491 m_waveformLabel->Show( isIbisLoaded() );
492 m_waveformChoice->Show( isIbisLoaded() );
494 if( aModel != m_prevModel )
496 m_waveformChoice->Clear();
500 for( SIM_MODEL::TYPE type : { SIM_MODEL::TYPE::KIBIS_DEVICE,
501 SIM_MODEL::TYPE::KIBIS_DRIVER_DC,
502 SIM_MODEL::TYPE::KIBIS_DRIVER_RECT,
503 SIM_MODEL::TYPE::KIBIS_DRIVER_PRBS } )
513 if( type == aModel->
GetType() )
514 m_waveformChoice->SetSelection( m_waveformChoice->GetCount() - 1 );
520 m_differentialCheckbox->Show( isIbisLoaded() && modelibis && modelibis->
CanDifferential() );
521 m_modelNameLabel->SetLabel( isIbisLoaded() ?
_(
"Component:" ) :
_(
"Model:" ) );
529 if( aModel != m_prevModel )
531 m_deviceChoice->Clear();
532 m_deviceSubtypeChoice->Clear();
534 if( !m_rbLibraryModel->GetValue() )
536 for( SIM_MODEL::DEVICE_T deviceType : SIM_MODEL::DEVICE_T_ITERATOR() )
544 m_deviceChoice->SetSelection( m_deviceChoice->GetCount() - 1 );
547 for( SIM_MODEL::TYPE type : SIM_MODEL::TYPE_ITERATOR() )
549 if( type == SIM_MODEL::TYPE::KIBIS_DEVICE
550 || type == SIM_MODEL::TYPE::KIBIS_DRIVER_DC
551 || type == SIM_MODEL::TYPE::KIBIS_DRIVER_RECT
552 || type == SIM_MODEL::TYPE::KIBIS_DRIVER_PRBS )
565 if( type == aModel->
GetType() )
566 m_deviceSubtypeChoice->SetSelection( m_deviceSubtypeChoice->GetCount()
572 m_deviceSubtypeLabel->Show( m_deviceSubtypeChoice->GetCount() > 1 );
573 m_deviceSubtypeChoice->Show( m_deviceSubtypeChoice->GetCount() > 1 );
577 m_modelNotebook->SetSelection( 1 );
579 m_modelNotebook->SetSelection( 0 );
585 m_saveInValueCheckbox->SetLabel( wxString::Format(
_(
"Save parameter '%s (%s)' in Value "
589 m_saveInValueCheckbox->Enable(
true );
593 m_saveInValueCheckbox->SetLabel(
_(
"Save primary parameter in Value field" ) );
594 m_saveInValueCheckbox->SetValue(
false );
595 m_saveInValueCheckbox->Enable(
false );
603 if( aModel != m_prevModel )
608 m_paramGridMgr->SetColumnCount( PARAM_COLUMN::END_ );
610 m_paramGridMgr->SetColumnTitle( PARAM_COLUMN::DESCRIPTION,
_(
"Parameter" ) );
611 m_paramGridMgr->SetColumnTitle( PARAM_COLUMN::UNIT,
_(
"Unit" ) );
612 m_paramGridMgr->SetColumnTitle( PARAM_COLUMN::DEFAULT,
_(
"Default" ) );
613 m_paramGridMgr->SetColumnTitle( PARAM_COLUMN::TYPE,
_(
"Type" ) );
615 m_paramGridMgr->ShowHeader();
618 m_paramGrid->Clear();
620 m_firstCategory = m_paramGrid->Append(
new wxPropertyCategory(
"Geometry" ) );
621 m_paramGrid->HideProperty(
"Geometry" );
623 m_paramGrid->Append(
new wxPropertyCategory(
"AC" ) );
624 m_paramGrid->HideProperty(
"AC" );
626 m_paramGrid->Append(
new wxPropertyCategory(
"DC" ) );
627 m_paramGrid->HideProperty(
"DC" );
629 m_paramGrid->Append(
new wxPropertyCategory(
"S-Parameters" ) );
630 m_paramGrid->HideProperty(
"S-Parameters" );
632 m_paramGrid->Append(
new wxPropertyCategory(
"Capacitance" ) );
633 m_paramGrid->HideProperty(
"Capacitance" );
635 m_paramGrid->Append(
new wxPropertyCategory(
"Temperature" ) );
636 m_paramGrid->HideProperty(
"Temperature" );
638 m_paramGrid->Append(
new wxPropertyCategory(
"Noise" ) );
639 m_paramGrid->HideProperty(
"Noise" );
641 m_paramGrid->Append(
new wxPropertyCategory(
"Distributed Quantities" ) );
642 m_paramGrid->HideProperty(
"Distributed Quantities" );
644 m_paramGrid->Append(
new wxPropertyCategory(
"Waveform" ) );
645 m_paramGrid->HideProperty(
"Waveform" );
647 m_paramGrid->Append(
new wxPropertyCategory(
"Limiting Values" ) );
648 m_paramGrid->HideProperty(
"Limiting Values" );
650 m_paramGrid->Append(
new wxPropertyCategory(
"Advanced" ) );
651 m_paramGrid->HideProperty(
"Advanced" );
653 m_paramGrid->Append(
new wxPropertyCategory(
"Flags" ) );
654 m_paramGrid->HideProperty(
"Flags" );
656 m_paramGrid->CollapseAll();
659 addParamPropertyIfRelevant( aModel, i );
661 m_paramGrid->CollapseAll();
662 m_paramGrid->Expand(
"AC" );
663 m_paramGrid->Expand(
"Waveform" );
666 adjustParamGridColumns( m_paramGrid->GetGrid()->GetSize().GetX(),
true );
670 for( wxPropertyGridIterator it = m_paramGrid->GetIterator(); !it.AtEnd(); ++it )
672 wxColour bgCol = m_paramGrid->GetGrid()->GetPropertyDefaultCell().GetBgCol();
673 wxColour fgCol = m_paramGrid->GetGrid()->GetPropertyDefaultCell().GetFgCol();
675 for(
int col = 0; col < m_paramGridMgr->GetColumnCount(); ++col )
677 ( *it )->GetCell( col ).SetBgCol( bgCol );
678 ( *it )->GetCell( col ).SetFgCol( fgCol );
692 ( *it )->SetValueFromString( param.
value );
706 item.
modelName = m_modelListBox->GetStringSelection();
708 if( m_rbBuiltinModel->GetValue() || item.
modelName ==
"" )
713 m_codePreview->SetText(
text );
714 m_codePreview->SelectNone();
721 if( m_pinAssignmentsGrid->GetNumberRows() == 0 )
723 m_pinAssignmentsGrid->AppendRows(
static_cast<int>( m_sortedPartPins.size() ) );
725 for(
int ii = 0; ii < m_pinAssignmentsGrid->GetNumberRows(); ++ii )
727 wxString symbolPinString = getSymbolPinString( ii );
729 m_pinAssignmentsGrid->SetReadOnly( ii, PIN_COLUMN::SYMBOL );
730 m_pinAssignmentsGrid->SetCellValue( ii, PIN_COLUMN::SYMBOL, symbolPinString );
733 aForceUpdatePins =
true;
736 if( aForceUpdatePins )
739 for(
int row = 0; row < m_pinAssignmentsGrid->GetNumberRows(); ++row )
740 m_pinAssignmentsGrid->SetCellValue( row, PIN_COLUMN::MODEL,
_(
"Not Connected" ) );
743 for(
int modelPinIndex = 0; modelPinIndex < aModel->
GetPinCount(); ++modelPinIndex )
747 if( symbolPinNumber ==
"" )
750 int symbolPinRow = findSymbolPinRow( symbolPinNumber );
752 if( symbolPinRow == -1 )
755 wxString modelPinString = getModelPinString( aModel, modelPinIndex );
756 m_pinAssignmentsGrid->SetCellValue( symbolPinRow, PIN_COLUMN::MODEL, modelPinString );
760 for(
int ii = 0; ii < m_pinAssignmentsGrid->GetNumberRows(); ++ii )
763 std::vector<BITMAPS> modelPinIcons;
764 wxArrayString modelPinChoices;
766 for(
int jj = 0; jj < aModel->
GetPinCount(); ++jj )
773 modelPinChoices.Add( getModelPinString( aModel, jj ) );
777 modelPinChoices.Add(
_(
"Not Connected" ) );
781 m_pinAssignmentsGrid->SetCellEditor( ii, PIN_COLUMN::MODEL,
788 if( aModel->
GetType() == SIM_MODEL::TYPE::SUBCKT )
792 m_subckt->SetEditable(
false );
796 m_subcktLabel->Show(
false );
797 m_subckt->Show(
false );
817 if( m_prevLibrary == aLibraryPath && !aForceReload )
820 m_libraryModelsMgr.SetForceFullParse();
821 m_libraryModelsMgr.SetLibrary( aLibraryPath, aReporter );
828 for(
const auto& [baseModelName, baseModel] :
library()->GetModels() )
830 if( baseModelName == modelName )
831 m_libraryModelsMgr.CreateModel( &baseModel, m_sortedPartPins, m_fields, aReporter );
833 m_libraryModelsMgr.CreateModel( &baseModel, m_sortedPartPins, aReporter );
836 m_rbLibraryModel->SetValue(
true );
837 m_libraryPathText->ChangeValue( aLibraryPath );
839 m_modelListBoxEntryToLibraryIdx.clear();
840 wxArrayString modelNames;
842 bool modelNameExists =
false;
843 for(
const auto& [
name, model] :
library()->GetModels() )
845 modelNames.Add(
name );
846 m_modelListBoxEntryToLibraryIdx[
name] = m_modelListBoxEntryToLibraryIdx.size();
847 if(
name == modelName )
848 modelNameExists =
true;
853 m_modelListBox->Clear();
854 m_modelListBox->Append( modelNames );
856 if( !modelNameExists )
858 m_infoBar->ShowMessage(
859 wxString::Format(
_(
"No model named '%s' in '%s'." ), modelName, aLibraryPath ) );
865 wxArrayString emptyArray;
866 m_pinModelCombobox->Set( emptyArray );
867 m_pinCombobox->Set( emptyArray );
868 m_pinModelCombobox->SetSelection( -1 );
869 m_pinCombobox->SetSelection( -1 );
872 m_modelListBox->SetStringSelection( modelName );
874 if( m_modelListBox->GetSelection() < 0 && m_modelListBox->GetCount() > 0 )
875 m_modelListBox->SetSelection( 0 );
877 m_curModelType = curModel().GetType();
879 m_prevLibrary = aLibraryPath;
893 m_paramGrid->HideProperty(
"AC",
false );
894 m_paramGrid->AppendIn(
"AC", newParamProperty( aModel, aParamIndex ) );
898 m_paramGrid->HideProperty(
"DC",
false );
899 m_paramGrid->AppendIn(
"DC", newParamProperty( aModel, aParamIndex ) );
902 case CATEGORY::S_PARAM:
903 m_paramGrid->HideProperty(
"S-Parameters",
false );
904 m_paramGrid->AppendIn(
"S-Parameters", newParamProperty( aModel, aParamIndex ) );
907 case CATEGORY::CAPACITANCE:
908 m_paramGrid->HideProperty(
"Capacitance",
false );
909 m_paramGrid->AppendIn(
"Capacitance", newParamProperty( aModel, aParamIndex ) );
912 case CATEGORY::TEMPERATURE:
913 m_paramGrid->HideProperty(
"Temperature",
false );
914 m_paramGrid->AppendIn(
"Temperature", newParamProperty( aModel, aParamIndex ) );
917 case CATEGORY::NOISE:
918 m_paramGrid->HideProperty(
"Noise",
false );
919 m_paramGrid->AppendIn(
"Noise", newParamProperty( aModel, aParamIndex ) );
922 case CATEGORY::DISTRIBUTED_QUANTITIES:
923 m_paramGrid->HideProperty(
"Distributed Quantities",
false );
924 m_paramGrid->AppendIn(
"Distributed Quantities", newParamProperty( aModel, aParamIndex ) );
927 case CATEGORY::WAVEFORM:
928 m_paramGrid->HideProperty(
"Waveform",
false );
929 m_paramGrid->AppendIn(
"Waveform", newParamProperty( aModel, aParamIndex ) );
932 case CATEGORY::GEOMETRY:
933 m_paramGrid->HideProperty(
"Geometry",
false );
934 m_paramGrid->AppendIn(
"Geometry", newParamProperty( aModel, aParamIndex ) );
937 case CATEGORY::LIMITING_VALUES:
938 m_paramGrid->HideProperty(
"Limiting Values",
false );
939 m_paramGrid->AppendIn(
"Limiting Values", newParamProperty( aModel, aParamIndex ) );
942 case CATEGORY::ADVANCED:
943 m_paramGrid->HideProperty(
"Advanced",
false );
944 m_paramGrid->AppendIn(
"Advanced", newParamProperty( aModel, aParamIndex ) );
947 case CATEGORY::FLAGS:
948 m_paramGrid->HideProperty(
"Flags",
false );
949 m_paramGrid->AppendIn(
"Flags", newParamProperty( aModel, aParamIndex ) );
953 m_paramGrid->Insert( m_firstCategory, newParamProperty( aModel, aParamIndex ) );
956 case CATEGORY::INITIAL_CONDITIONS:
957 case CATEGORY::SUPERFLUOUS:
967 wxString paramDescription;
970 paramDescription = wxString::Format(
"%s", param.
info.
name );
974 wxPGProperty* prop =
nullptr;
981 prop->SetAttribute( wxPG_BOOL_USE_CHECKBOX,
true );
1003 wxArrayString inductors;
1015 if( item.model->GetDeviceType() == SIM_MODEL::DEVICE_T::L )
1016 inductors.push_back( item.refName );
1020 [](
const wxString& a,
const wxString& b ) ->
int
1026 if( inductors.empty() )
1034 aParamIndex, inductors );
1044 wxArrayString values;
1047 values.Add(
string );
1055 prop =
new wxStringProperty( paramDescription, param.
info.
name );
1059 prop->SetAttribute( wxPG_ATTR_UNITS, wxString::FromUTF8( param.
info.
unit.c_str() ) );
1079 prop->SetCell( PARAM_COLUMN::TYPE, typeStr );
1085template <
typename T>
1088 for(
int row = 0; row < static_cast<int>( m_sortedPartPins.size() ); ++row )
1092 if(
pin->GetNumber() == aSymbolPinNumber )
1100template <
typename T>
1103 if( m_rbLibraryModel->GetValue() )
1105 wxString sel = m_modelListBox->GetStringSelection();
1107 if( m_modelListBoxEntryToLibraryIdx.contains( sel ) )
1108 return m_libraryModelsMgr.GetModels()
1109 .at( m_modelListBoxEntryToLibraryIdx.at( sel ) )
1114 if(
static_cast<int>( m_curModelType )
1115 <
static_cast<int>( m_builtinModelsMgr.GetModels().size() ) )
1116 return m_builtinModelsMgr.GetModels().at(
static_cast<int>( m_curModelType ) );
1119 return m_builtinModelsMgr.GetModels().at(
static_cast<int>( SIM_MODEL::TYPE::NONE ) );
1123template <
typename T>
1126 if( m_libraryModelsMgr.GetLibraries().size() == 1 )
1127 return &m_libraryModelsMgr.GetLibraries().begin()->second.get();
1133template <
typename T>
1136 SCH_PIN*
pin = m_sortedPartPins.at( symbolPinIndex );
1142 pinNumber =
pin->GetShownNumber();
1143 pinName =
pin->GetShownName();
1146 if( !pinName.IsEmpty() && pinName != pinNumber )
1147 pinNumber += wxString::Format( wxT(
" (\"%s\")" ), pinName );
1153template <
typename T>
1160 wxString modelPinNumber = wxString::Format(
"%d", aModelPinIndex + 1 );
1162 if( !modelPinName.IsEmpty() && modelPinName != modelPinNumber )
1163 modelPinNumber += wxString::Format( wxT(
" (\"%s\")" ), modelPinName );
1165 return modelPinNumber;
1169template <
typename T>
1172 if( aModelPinString ==
"Not Connected" )
1175 int length = aModelPinString.Find(
" " );
1177 if( length == wxNOT_FOUND )
1178 length =
static_cast<int>( aModelPinString.Length() );
1181 aModelPinString.Mid( 0, length ).ToCLong( &result );
1183 return static_cast<int>( result - 1 );
1187template <
typename T>
1190 m_prevModel =
nullptr;
1195template <
typename T>
1198 m_rbLibraryModel->SetValue(
true );
1202template <
typename T>
1205 m_rbLibraryModel->SetValue(
true );
1208 wxString
path = m_libraryPathText->GetValue();
1210 if( loadLibrary(
path, reporter,
true ) ||
path.IsEmpty() )
1219template <
typename T>
1229 wxCommandEvent
dummy;
1230 onLibraryPathTextEnter(
dummy );
1237template <
typename T>
1240 static wxString s_mruPath;
1243 wxFileDialog dlg(
this,
_(
"Browse Models" ),
path );
1246 dlg.SetCustomizeHook( customize );
1248 if( dlg.ShowModal() == wxID_CANCEL )
1251 m_rbLibraryModel->SetValue(
true );
1253 path = dlg.GetPath();
1254 wxFileName fn(
path );
1255 s_mruPath = fn.GetPath();
1262 else if( fn.MakeRelativeTo(
Prj().GetProjectPath() ) && !fn.GetFullPath().StartsWith( wxS(
".." ) ) )
1263 path = fn.GetFullPath();
1267 if( loadLibrary(
path, reporter,
true ) )
1276template <
typename T>
1279 int sel = m_modelListBox->GetSelection();
1281 switch( aKeyStroke.GetKeyCode() )
1284 if( sel == wxNOT_FOUND )
1285 sel = m_modelListBox->GetCount() - 1;
1292 if( sel == wxNOT_FOUND )
1300 wxPostEvent(
this, wxCommandEvent( wxEVT_COMMAND_BUTTON_CLICKED, wxID_OK ) );
1308 if( sel >= 0 && sel < (
int) m_modelListBox->GetCount() )
1309 m_modelListBox->SetSelection( sel );
1313template <
typename T>
1319 wxArrayString modelNames;
1320 wxString current = m_modelListBox->GetStringSelection();
1321 wxString
filter = wxT(
"*" ) + m_modelFilter->GetValue() + wxT(
"*" );
1323 for(
const auto& [
name, model] :
library()->GetModels() )
1325 wxString wx_name(
name );
1327 if( wx_name.Matches(
filter ) )
1328 modelNames.Add( wx_name );
1333 m_modelListBox->Clear();
1334 m_modelListBox->Append( modelNames );
1336 if( !m_modelListBox->SetStringSelection( current ) )
1337 m_modelListBox->SetSelection( 0 );
1341template <
typename T>
1344 if( isIbisLoaded() )
1346 wxArrayString pinLabels;
1349 wxCHECK2( modelkibis,
return );
1351 for( std::pair<wxString, wxString> strs : modelkibis->
GetIbisPins() )
1352 pinLabels.Add( strs.first + wxT(
" - " ) + strs.second );
1354 m_pinCombobox->Set( pinLabels );
1356 wxArrayString emptyArray;
1357 m_pinModelCombobox->Set( emptyArray );
1360 m_rbLibraryModel->SetValue(
true );
1365 wxArrayString lines = wxSplit( fallback->GetSpiceCode(),
'\n' );
1368 for(
const wxString& line : lines )
1370 if( !line.StartsWith(
'*' ) )
1372 if( !code.IsEmpty() )
1379 m_infoBar->ShowMessage( wxString::Format(
_(
"Failed to parse:\n\n"
1381 "Using generic SPICE model." ),
1393template <
typename T>
1396 wxArrayString modelLabels;
1400 std::vector<std::pair<std::string, std::string>> strs = ibisModel.
GetIbisPins();
1401 std::string pinNumber = strs.at( m_pinCombobox->GetSelection() ).first;
1405 ibisModel.
ChangePin( *ibisLibrary, pinNumber );
1410 modelLabels.Add( modelName );
1412 m_pinModelCombobox->Set( modelLabels );
1414 if( m_pinModelCombobox->GetCount() == 1 )
1415 m_pinModelCombobox->SetSelection( 0 );
1417 m_pinModelCombobox->SetSelection( -1 );
1423template <
typename T>
1426 m_pinCombobox->SetSelection( m_pinCombobox->FindString( m_pinCombobox->GetValue() ) );
1428 onPinModelCombobox( aEvent );
1432template <
typename T>
1439template <
typename T>
1442 m_pinModelCombobox->SetSelection(
1443 m_pinModelCombobox->FindString( m_pinModelCombobox->GetValue() ) );
1447template <
typename T>
1452 bool diff = m_differentialCheckbox->GetValue() && modelibis->CanDifferential();
1453 modelibis->SwitchSingleEndedDiff( diff );
1460template <
typename T>
1463 m_rbBuiltinModel->SetValue(
true );
1465 for( SIM_MODEL::DEVICE_T deviceType : SIM_MODEL::DEVICE_T_ITERATOR() )
1468 == m_deviceChoice->GetStringSelection() )
1470 m_curModelType = m_curModelTypeOfDeviceType.at( deviceType );
1479template <
typename T>
1482 SIM_MODEL::DEVICE_T deviceType = curModel().GetDeviceType();
1483 wxString typeDescription = m_waveformChoice->GetStringSelection();
1485 for( SIM_MODEL::TYPE type : { SIM_MODEL::TYPE::KIBIS_DEVICE,
1486 SIM_MODEL::TYPE::KIBIS_DRIVER_DC,
1487 SIM_MODEL::TYPE::KIBIS_DRIVER_RECT,
1488 SIM_MODEL::TYPE::KIBIS_DRIVER_PRBS } )
1494 wxString sel = m_modelListBox->GetStringSelection();
1496 if( m_modelListBoxEntryToLibraryIdx.contains( sel ) )
1497 idx = m_modelListBoxEntryToLibraryIdx.at( sel );
1500 static_cast<SIM_MODEL_IBIS&
>( m_libraryModelsMgr.GetModels()[idx].get() );
1502 m_libraryModelsMgr.SetModel( idx, std::make_unique<SIM_MODEL_IBIS>( type, baseModel ) );
1506 m_libraryModelsMgr.GetModels()[idx].get().
ReadDataFields( &m_fields,
1514 m_curModelType = type;
1519 m_curModelTypeOfDeviceType.at( deviceType ) = m_curModelType;
1524template <
typename T>
1527 SIM_MODEL::DEVICE_T deviceType = curModel().GetDeviceType();
1528 wxString typeDescription = m_deviceSubtypeChoice->GetStringSelection();
1530 for( SIM_MODEL::TYPE type : SIM_MODEL::TYPE_ITERATOR() )
1535 m_curModelType = type;
1540 m_curModelTypeOfDeviceType.at( deviceType ) = m_curModelType;
1545template <
typename T>
1548 updateModelCodeTab( &curModel() );
1552template <
typename T>
1555 int symbolPinIndex = aEvent.GetRow();
1556 wxString oldModelPinName = aEvent.GetString();
1557 wxString modelPinName = m_pinAssignmentsGrid->GetCellValue( aEvent.GetRow(), aEvent.GetCol() );
1559 int oldModelPinIndex = getModelPinIndex( oldModelPinName );
1560 int modelPinIndex = getModelPinIndex( modelPinName );
1563 curModel().AssignSymbolPinNumberToModelPin( oldModelPinIndex,
"" );
1567 SCH_PIN* symbolPin = m_sortedPartPins.at( symbolPinIndex );
1569 curModel().AssignSymbolPinNumberToModelPin( modelPinIndex, symbolPin->
GetShownNumber() );
1578template <
typename T>
1581 wxGridUpdateLocker deferRepaintsTillLeavingScope( m_pinAssignmentsGrid );
1584 m_pinAssignmentsGrid->SetColSize( PIN_COLUMN::MODEL, gridWidth / 2 );
1585 m_pinAssignmentsGrid->SetColSize( PIN_COLUMN::SYMBOL, gridWidth / 2 );
1591template <
typename T>
1597 wxPropertyGrid*
grid = m_paramGrid->GetGrid();
1598 wxPGProperty* selected =
grid->GetSelection();
1601 selected =
grid->wxPropertyGridInterface::GetFirst();
1603#if wxCHECK_VERSION( 3, 3, 0 )
1605 grid->DoSelectProperty( selected, wxPGSelectPropertyFlags::Focus );
1608 grid->DoSelectProperty( selected, wxPG_SEL_FOCUS );
1615template <
typename T>
1618 wxPropertyGrid*
grid = m_paramGrid->GetGrid();
1621 if(
grid->GetSelection() &&
grid->GetSelection()->IsCategory() )
1623 wxPGProperty* selection =
grid->GetSelection();
1628 wxPropertyGridIterator it =
grid->GetIterator( wxPG_ITERATE_VISIBLE, selection );
1631 wxKeyEvent* keyEvent =
new wxKeyEvent( wxEVT_KEY_DOWN );
1633 if( *it == m_prevParamGridSelection )
1635 if( !selection->IsExpanded() )
1637 grid->Expand( selection );
1638 keyEvent->m_keyCode = WXK_DOWN;
1639 wxQueueEvent(
grid, keyEvent );
1647 keyEvent->m_keyCode = WXK_UP;
1648 wxQueueEvent(
grid, keyEvent );
1653 if( !selection->IsExpanded() )
1654 grid->Expand( selection );
1656 keyEvent->m_keyCode = WXK_DOWN;
1657 wxQueueEvent(
grid, keyEvent );
1660 m_prevParamGridSelection =
grid->GetSelection();
1664 wxWindow* editorControl =
grid->GetEditorControl();
1666 if( !editorControl )
1668 m_prevParamGridSelection =
grid->GetSelection();
1673 editorControl->SetFocus();
1674 m_prevParamGridSelection =
grid->GetSelection();
1678template <
typename T>
1689 wxPropertyGrid*
grid = m_paramGrid->GetGrid();
1690 wxTextCtrl* ctrl =
grid->GetEditorTextCtrl();
1694 wxRect ctrlRect = ctrl->GetScreenRect();
1695 wxRect gridRect =
grid->GetScreenRect();
1697 if( ctrlRect.GetTop() < gridRect.GetTop() || ctrlRect.GetBottom() > gridRect.GetBottom() )
1698 grid->ClearSelection();
1704template <
typename T>
1707 wxPropertyGrid*
grid = m_paramGridMgr->GetGrid();
1711 if( aWidth != m_lastParamGridWidth || aForce )
1713 m_lastParamGridWidth = aWidth;
1717 std::vector<int> colWidths;
1719 for(
size_t ii = 0; ii <
grid->GetColumnCount(); ii++ )
1721 if( ii == PARAM_COLUMN::DESCRIPTION )
1722 colWidths.push_back(
grid->GetState()->GetColumnWidth( ii ) + margin + indent );
1723 else if( ii == PARAM_COLUMN::VALUE )
1724 colWidths.push_back( std::max( 72,
1725 grid->GetState()->GetColumnWidth( ii ) ) + margin );
1727 colWidths.push_back( 60 + margin );
1729 aWidth -= colWidths[ ii ];
1732 for(
size_t ii = 0; ii <
grid->GetColumnCount(); ii++ )
1733 grid->SetColumnProportion( ii, colWidths[ ii ] );
1735 grid->ResetColumnSizes();
1736 grid->RefreshEditor();
1741template <
typename T>
1744 adjustParamGridColumns( event.GetSize().GetX(),
false );
wxBitmapBundle KiBitmapBundle(BITMAPS aBitmap, int aMinHeight)
void finishDialogSettings()
In all dialogs, we must call the same functions to fix minimal dlg size, the default position and per...
Class DIALOG_SIM_MODEL_BASE.
wxStaticText * m_subcktLabel
wxPropertyGridManager * m_paramGridMgr
wxChoice * m_deviceSubtypeChoice
wxChoice * m_deviceChoice
wxChoice * m_waveformChoice
WX_GRID * m_pinAssignmentsGrid
STD_BITMAP_BUTTON * m_browseButton
wxStyledTextCtrl * m_subckt
wxPropertyGridPage * m_paramGrid
wxStyledTextCtrl * m_codePreview
void onTypeChoice(wxCommandEvent &aEvent) override
void onLibraryPathTextKillFocus(wxFocusEvent &aEvent) override
wxString getSymbolPinString(int aSymbolPinNumber) const
void updateBuiltinModelWidgets(SIM_MODEL *aModel)
void onPinAssignmentsGridCellChange(wxGridEvent &aEvent) override
void onFilterCharHook(wxKeyEvent &aKeyStroke) override
int findSymbolPinRow(const wxString &aSymbolPinNumber) const
void onModelNameChoice(wxCommandEvent &aEvent) override
void onRadioButton(wxCommandEvent &aEvent) override
SCINTILLA_TRICKS * m_scintillaTricksSubckt
bool loadLibrary(const wxString &aLibraryPath, REPORTER &aReporter, bool aForceReload=false)
SIM_LIB_MGR m_builtinModelsMgr
int getModelPinIndex(const wxString &aModelPinString) const
void onModelFilter(wxCommandEvent &aEvent) override
void onLibraryPathText(wxCommandEvent &aEvent) override
void onDifferentialCheckbox(wxCommandEvent &event) override
void onParamGridSelectionChange(wxPropertyGridEvent &aEvent)
void removeOrphanedPinAssignments(SIM_MODEL *aModel)
void adjustParamGridColumns(int aWidth, bool aForce)
std::vector< SCH_PIN * > m_sortedPartPins
Pins of the current part.
wxPGProperty * newParamProperty(SIM_MODEL *aModel, int aParamIndex) const
void onPinModelCombobox(wxCommandEvent &event) override
const SIM_LIBRARY * library() const
SIM_MODEL & curModel() const
SIM_LIB_MGR m_libraryModelsMgr
void onBrowseButtonClick(wxCommandEvent &aEvent) override
void onPinComboboxTextEnter(wxCommandEvent &event) override
void onPinCombobox(wxCommandEvent &event) override
SCINTILLA_TRICKS * m_scintillaTricksCode
void updatePinAssignments(SIM_MODEL *aModel, bool aForceUpdatePins)
void onUpdateUI(wxUpdateUIEvent &aEvent)
DIALOG_SIM_MODEL(wxWindow *aParent, EDA_BASE_FRAME *aFrame, T &aSymbol, std::vector< SCH_FIELD > &aFields)
wxString getModelPinString(SIM_MODEL *aModel, int aModelPinIndex) const
void onPinAssignmentsGridSize(wxSizeEvent &aEvent) override
void updateIbisWidgets(SIM_MODEL *aModel)
void onParamGridSetFocus(wxFocusEvent &aEvent)
void updateModelParamsTab(SIM_MODEL *aModel)
bool TransferDataFromWindow() override
void updateModelCodeTab(SIM_MODEL *aModel)
void onSizeParamGrid(wxSizeEvent &event) override
void onPageChanging(wxNotebookEvent &event) override
void onWaveformChoice(wxCommandEvent &aEvent) override
void onPinModelComboboxTextEnter(wxCommandEvent &event) override
void onLibraryPathTextEnter(wxCommandEvent &aEvent) override
void onDeviceTypeChoice(wxCommandEvent &aEvent) override
bool TransferDataToWindow() override
void addParamPropertyIfRelevant(SIM_MODEL *aModel, int aParamIndex)
The base frame for deriving all KiCad main window classes.
Add mouse and command handling (such as cut, copy, and paste) to a WX_GRID instance.
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
virtual const wxString What() const
A composite of Problem() and Where()
Instantiate the current locale within a scope in which you are expecting exceptions to be thrown.
virtual bool ReadSchematicAndLibraries(unsigned aNetlistOptions, REPORTER &aReporter)
Process the schematic and Spice libraries to create net mapping and a list of SPICE_ITEMs.
const std::list< SPICE_ITEM > & GetItems() const
Return the list of items representing schematic symbols in the Spice world.
A singleton reporter that reports to nowhere.
virtual const wxString GetProjectPath() const
Return the full path of the project.
A pure virtual class used to derive REPORTER objects from.
virtual bool HasMessageOfSeverity(int aSeverityMask) const
Returns true if the reporter has one or more messages matching the specified severity mask.
Schematic editor (Eeschema) main window.
void SetText(const wxString &aText) override
wxString GetShownNumber() const
Add cut/copy/paste, dark theme, autocomplete and brace highlighting to a wxStyleTextCtrl instance.
static constexpr auto MODEL_FIELD
static constexpr auto PIN_FIELD
static constexpr auto DIFF_FIELD
bool isPinDiff(const std::string &aComp, const std::string &aPinNumber) const
static constexpr auto LIBRARY_FIELD
static constexpr auto NAME_FIELD
void SetFiles(EMBEDDED_FILES *aFiles)
std::vector< std::pair< std::string, std::string > > GetIbisPins() const
bool CanDifferential() const
std::vector< std::string > GetIbisModels() const
bool ChangePin(const SIM_LIBRARY_IBIS &aLib, const std::string &aPinNumber)
update the list of available models based on the pin number.
std::string GetComponentName() const
std::string GetSpiceCode() const
static TYPE ReadTypeFromFields(const std::vector< SCH_FIELD > &aFields, REPORTER &aReporter)
static INFO TypeInfo(TYPE aType)
void ReadDataFields(const std::vector< SCH_FIELD > *aFields, const std::vector< SCH_PIN * > &aPins)
const SPICE_GENERATOR & SpiceGenerator() const
virtual const PARAM & GetParam(unsigned aParamIndex) const
static bool InferSimModel(T &aSymbol, std::vector< SCH_FIELD > *aFields, bool aResolve, SIM_VALUE_GRAMMAR::NOTATION aNotation, wxString *aDeviceType, wxString *aModelType, wxString *aModelParams, wxString *aPinMap)
int GetParamCount() const
void AssignSymbolPinNumberToModelPin(int aPinIndex, const wxString &aSymbolPinNumber)
DEVICE_INFO GetDeviceInfo() const
DEVICE_T GetDeviceType() const
static DEVICE_INFO DeviceInfo(DEVICE_T aDeviceType)
virtual bool HasAutofill() const
void SetParamValue(int aParamIndex, const std::string &aValue, SIM_VALUE::NOTATION aNotation=SIM_VALUE::NOTATION::SI)
const SIM_MODEL_PIN & GetPin(unsigned aIndex) const
void SetIsStoredInValue(bool aIsStoredInValue)
virtual bool HasPrimaryValue() const
const SIM_MODEL::PARAM & GetParam() const
Special netlist exporter flavor that allows one to override simulation commands.
virtual std::string Preview(const SPICE_ITEM &aItem) const
void ClearRows()
wxWidgets recently added an ASSERT which fires if the position is greater than or equal to the number...
void AddCloseButton(const wxString &aTooltip=_("Hide this message."))
Add the default close button to the infobar on the right side.
A wrapper for reporting to a wxString object.
bool HasMessage() const override
Returns true if the reporter client is non-empty.
const wxString & GetMessages() const
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
This file is part of the common library.
static bool empty(const wxTextEntryBase *aCtrl)
bool equivalent(SIM_MODEL::DEVICE_T a, SIM_MODEL::DEVICE_T b)
#define FORCE_UPDATE_PINS
static const std::string KiCadUriPrefix
KICOMMON_API wxFont GetInfoFont(wxWindow *aWindow)
BITMAPS PinShapeGetBitmap(GRAPHIC_PINSHAPE aShape)
wxString GetFieldValue(const std::vector< SCH_FIELD > *aFields, FIELD_T aFieldType)
const SCH_FIELD * FindField(const std::vector< SCH_FIELD > &aFields, FIELD_T aFieldId)
void SetFieldValue(std::vector< SCH_FIELD > &aFields, const wxString &aFieldName, const std::string &aValue, bool aIsVisible=true)
#define SIM_REFERENCE_FIELD
#define SIM_DEVICE_SUBTYPE_FIELD
std::vector< FAB_LAYER_COLOR > dummy
int StrNumCmp(const wxString &aString1, const wxString &aString2, bool aIgnoreCase)
Compare two strings with alphanumerical content.
std::vector< std::string > enumValues
static constexpr auto NOT_CONNECTED
const std::string modelPinName
@ REFERENCE
Field Reference of part, i.e. "IC21".
@ VALUE
Field Value of part, i.e. "3.3K".