42#include <wx/filedlg.h>
43#include <fmt/format.h>
51#define FORCE_UPDATE_PINS true
54bool equivalent( SIM_MODEL::DEVICE_T a, SIM_MODEL::DEVICE_T b )
65 std::vector<SCH_FIELD>& aFields ) :
70 m_libraryModelsMgr( &
Prj() ),
71 m_builtinModelsMgr( &
Prj() ),
72 m_prevModel( nullptr ),
74 m_scintillaTricksCode( nullptr ),
75 m_scintillaTricksSubckt( nullptr ),
76 m_firstCategory( nullptr ),
77 m_prevParamGridSelection( nullptr ),
78 m_lastParamGridWidth( 0 )
86 if( !
pin->GetParentSymbol()->HasAlternateBodyStyle() ||
pin->GetBodyStyle() < 2 )
94 return StrNumCmp( lhs->GetNumber(), rhs->GetNumber(), true ) < 0;
109 grid->SetCellDisabledTextColour( wxSystemSettings::GetColour( wxSYS_COLOUR_GRAYTEXT ) );
114 grid->DedicateKey( WXK_RETURN );
115 grid->DedicateKey( WXK_NUMPAD_ENTER );
116 grid->DedicateKey( WXK_UP );
117 grid->DedicateKey( WXK_DOWN );
119#if wxCHECK_VERSION( 3, 3, 0 )
120 grid->AddActionTrigger( wxPGKeyboardAction::Edit, WXK_RETURN );
121 grid->AddActionTrigger( wxPGKeyboardAction::NextProperty, WXK_RETURN );
122 grid->AddActionTrigger( wxPGKeyboardAction::Edit, WXK_NUMPAD_ENTER );
123 grid->AddActionTrigger( wxPGKeyboardAction::NextProperty, WXK_NUMPAD_ENTER );
125 grid->AddActionTrigger( wxPG_ACTION_EDIT, WXK_RETURN );
126 grid->AddActionTrigger( wxPG_ACTION_NEXT_PROPERTY, WXK_RETURN );
127 grid->AddActionTrigger( wxPG_ACTION_EDIT, WXK_NUMPAD_ENTER );
128 grid->AddActionTrigger( wxPG_ACTION_NEXT_PROPERTY, WXK_NUMPAD_ENTER );
146 for( wxPropertyGridIterator it = m_paramGrid->GetIterator(); !it.AtEnd(); ++it )
157 m_pinAssignmentsGrid->PopEventHandler(
true );
159 delete m_scintillaTricksCode;
160 delete m_scintillaTricksSubckt;
167 wxCommandEvent dummyEvent;
170 wxString modelParams;
172 bool storeInValue =
false;
177 [&](
const wxString& aFieldName,
const wxString& aValue )
181 if( field.GetName() == aFieldName )
183 field.SetText( aValue );
188 m_fields.emplace_back( &m_symbol, -1, aFieldName );
189 m_fields.back().SetText( aValue );
194 &deviceType, &modelType, &modelParams, &pinMap ) )
198 if( !modelType.IsEmpty() )
209 m_fields[
VALUE_FIELD ].SetText( wxT(
"${SIM.PARAMS}" ) );
214 if( libraryFilename !=
"" )
217 m_rbLibraryModel->SetValue(
true );
219 if( !loadLibrary( libraryFilename, reporter ) )
224 m_libraryPathText->ChangeValue( libraryFilename );
227 m_libraryModelsMgr.CreateModel(
nullptr, m_sortedPartPins, m_fields, reporter );
229 m_modelListBox->Append(
_(
"<unknown>" ) );
230 m_modelListBox->SetSelection( 0 );
235 int modelIdx = m_modelListBox->FindString( modelName );
237 if( modelIdx == wxNOT_FOUND )
239 m_infoBar->ShowMessage( wxString::Format(
_(
"No model named '%s' in library." ),
243 m_modelListBox->SetSelection( 0 );
248 m_modelListBox->SetSelection( modelIdx );
251 m_curModelType = curModel().GetType();
254 if( isIbisLoaded() && ( m_modelListBox->GetSelection() >= 0 ) )
257 wxString sel = m_modelListBox->GetStringSelection();
259 if( m_modelListBoxEntryToLibraryIdx.contains( sel ) )
260 idx = m_modelListBoxEntryToLibraryIdx.at( sel );
262 auto ibismodel =
dynamic_cast<SIM_MODEL_IBIS*
>( &m_libraryModelsMgr.GetModels()[idx].get() );
266 onModelNameChoice( dummyEvent );
270 for(
const std::pair<std::string, std::string>& strs : ibismodel->GetIbisPins() )
276 ibismodel->ChangePin( *ibisLibrary, strs.first );
277 m_pinCombobox->SetSelection(
static_cast<int>( i ) );
283 if( i <
static_cast<int>( ibismodel->GetIbisPins().size() ) )
285 onPinCombobox( dummyEvent );
287 m_pinModelCombobox->SetStringSelection(
293 ibismodel->SwitchSingleEndedDiff(
true );
294 m_differentialCheckbox->SetValue(
true );
298 ibismodel->SwitchSingleEndedDiff(
false );
299 m_differentialCheckbox->SetValue(
false );
308 m_rbBuiltinModel->SetValue(
true );
317 for( SIM_MODEL::TYPE type : SIM_MODEL::TYPE_ITERATOR() )
319 if( m_rbBuiltinModel->GetValue() && type == m_curModelType )
322 m_builtinModelsMgr.CreateModel( m_fields, m_sortedPartPins,
false, reporter );
332 m_builtinModelsMgr.CreateModel( type, m_sortedPartPins, reporter );
337 if( !m_curModelTypeOfDeviceType.count( deviceTypeT ) )
338 m_curModelTypeOfDeviceType[deviceTypeT] = type;
342 curModel().SetIsStoredInValue(
true );
344 m_saveInValueCheckbox->SetValue( curModel().IsStoredInValue() );
346 onRadioButton( dummyEvent );
347 return DIALOG_SIM_MODEL_BASE::TransferDataToWindow();
354 m_pinAssignmentsGrid->CommitPendingChanges();
355 m_paramGrid->GetGrid()->CommitChangesFromEditor();
357 if( !DIALOG_SIM_MODEL_BASE::TransferDataFromWindow() )
364 if( m_rbLibraryModel->GetValue() )
366 path = m_libraryPathText->GetValue();
367 wxFileName fn(
path );
369 if( fn.MakeRelativeTo(
Prj().GetProjectPath() ) && !fn.GetFullPath().StartsWith(
".." ) )
370 path = fn.GetFullPath();
372 if( m_modelListBox->GetSelection() >= 0 )
373 name = m_modelListBox->GetStringSelection().ToStdString();
384 wxString sel = m_modelListBox->GetStringSelection();
386 if( m_modelListBoxEntryToLibraryIdx.contains( sel ) )
387 idx = m_modelListBoxEntryToLibraryIdx.at( sel );
389 auto* ibismodel =
static_cast<SIM_MODEL_IBIS*
>( &m_libraryModelsMgr.GetModels().at( idx ).get() );
394 std::string modelName = std::string( m_pinModelCombobox->GetValue().c_str() );
395 std::string differential;
397 if( m_pinCombobox->GetSelection() >= 0 )
398 pins = ibismodel->GetIbisPins().at( m_pinCombobox->GetSelection() ).first;
400 if( ibismodel->CanDifferential() && m_differentialCheckbox->GetValue() )
409 if( model.
GetType() == SIM_MODEL::TYPE::RAWSPICE )
411 if( m_modelNotebook->GetSelection() == 0 )
412 updateModelCodeTab( &model );
414 wxString code = m_codePreview->GetText().Trim(
true ).Trim(
false );
415 model.
SetParamValue(
"model", std::string( code.ToUTF8() ) );
420 for(
int row = 0; row < m_pinAssignmentsGrid->GetNumberRows(); ++row )
422 wxString modelPinName = m_pinAssignmentsGrid->GetCellValue( row, PIN_COLUMN::MODEL );
423 wxString symbolPinName = m_sortedPartPins.at( row )->GetShownNumber();
426 std::string( symbolPinName.ToUTF8() ) );
429 removeOrphanedPinAssignments( &model );
431 curModel().WriteFields( m_fields );
442 m_browseButton->Enable();
445 bool undetermined = !m_rbLibraryModel->GetValue() && !m_rbBuiltinModel->GetValue();
446 bool enableLibCtrls = m_rbLibraryModel->GetValue() || undetermined;
447 bool enableBuiltinCtrls = m_rbBuiltinModel->GetValue() || undetermined;
449 m_pathLabel->Enable( enableLibCtrls );
450 m_libraryPathText->Enable( enableLibCtrls );
451 m_modelNameLabel->Enable( enableLibCtrls );
452 m_modelFilter->Enable( enableLibCtrls && !isIbisLoaded() );
453 m_modelListBox->Enable( enableLibCtrls );
454 m_pinLabel->Enable( enableLibCtrls );
455 m_pinCombobox->Enable( enableLibCtrls );
456 m_differentialCheckbox->Enable( enableLibCtrls );
457 m_pinModelLabel->Enable( enableLibCtrls );
458 m_pinModelCombobox->Enable( enableLibCtrls );
459 m_waveformLabel->Enable( enableLibCtrls );
460 m_waveformChoice->Enable( enableLibCtrls );
462 m_deviceLabel->Enable( enableBuiltinCtrls );
463 m_deviceChoice->Enable( enableBuiltinCtrls );
464 m_deviceSubtypeLabel->Enable( enableBuiltinCtrls );
465 m_deviceSubtypeChoice->Enable( enableBuiltinCtrls );
469 updateIbisWidgets( model );
470 updateBuiltinModelWidgets( model );
471 updateModelParamsTab( model );
472 updateModelCodeTab( model );
473 updatePinAssignments( model,
false );
477 m_modelPanel->Layout();
478 m_pinAssignmentsPanel->Layout();
479 m_parametersPanel->Layout();
480 m_codePanel->Layout();
482 SendSizeEvent( wxSEND_EVENT_POST );
484 m_prevModel = &curModel();
494 m_pinLabel->Show( isIbisLoaded() );
495 m_pinCombobox->Show( isIbisLoaded() );
496 m_pinModelLabel->Show( isIbisLoaded() );
497 m_pinModelCombobox->Show( isIbisLoaded() );
498 m_waveformLabel->Show( isIbisLoaded() );
499 m_waveformChoice->Show( isIbisLoaded() );
501 if( aModel != m_prevModel )
503 m_waveformChoice->Clear();
507 for( SIM_MODEL::TYPE type : { SIM_MODEL::TYPE::KIBIS_DEVICE,
508 SIM_MODEL::TYPE::KIBIS_DRIVER_DC,
509 SIM_MODEL::TYPE::KIBIS_DRIVER_RECT,
510 SIM_MODEL::TYPE::KIBIS_DRIVER_PRBS } )
520 if( type == aModel->
GetType() )
521 m_waveformChoice->SetSelection( m_waveformChoice->GetCount() - 1 );
527 m_differentialCheckbox->Show( isIbisLoaded() && modelibis && modelibis->
CanDifferential() );
528 m_modelNameLabel->SetLabel( isIbisLoaded() ?
_(
"Component:" ) :
_(
"Model:" ) );
536 if( aModel != m_prevModel )
538 m_deviceChoice->Clear();
539 m_deviceSubtypeChoice->Clear();
541 if( !m_rbLibraryModel->GetValue() )
543 for( SIM_MODEL::DEVICE_T deviceType : SIM_MODEL::DEVICE_T_ITERATOR() )
551 m_deviceChoice->SetSelection( m_deviceChoice->GetCount() - 1 );
554 for( SIM_MODEL::TYPE type : SIM_MODEL::TYPE_ITERATOR() )
556 if( type == SIM_MODEL::TYPE::KIBIS_DEVICE
557 || type == SIM_MODEL::TYPE::KIBIS_DRIVER_DC
558 || type == SIM_MODEL::TYPE::KIBIS_DRIVER_RECT
559 || type == SIM_MODEL::TYPE::KIBIS_DRIVER_PRBS )
572 if( type == aModel->
GetType() )
573 m_deviceSubtypeChoice->SetSelection( m_deviceSubtypeChoice->GetCount() - 1 );
578 m_deviceSubtypeLabel->Show( m_deviceSubtypeChoice->GetCount() > 1 );
579 m_deviceSubtypeChoice->Show( m_deviceSubtypeChoice->GetCount() > 1 );
583 m_modelNotebook->SetSelection( 1 );
585 m_modelNotebook->SetSelection( 0 );
591 m_saveInValueCheckbox->SetLabel( wxString::Format(
_(
"Save parameter '%s (%s)' in Value "
595 m_saveInValueCheckbox->Enable(
true );
599 m_saveInValueCheckbox->SetLabel(
_(
"Save primary parameter in Value field" ) );
600 m_saveInValueCheckbox->SetValue(
false );
601 m_saveInValueCheckbox->Enable(
false );
609 if( aModel != m_prevModel )
614 m_paramGridMgr->SetColumnCount( PARAM_COLUMN::END_ );
616 m_paramGridMgr->SetColumnTitle( PARAM_COLUMN::DESCRIPTION,
_(
"Parameter" ) );
617 m_paramGridMgr->SetColumnTitle( PARAM_COLUMN::UNIT,
_(
"Unit" ) );
618 m_paramGridMgr->SetColumnTitle( PARAM_COLUMN::DEFAULT,
_(
"Default" ) );
619 m_paramGridMgr->SetColumnTitle( PARAM_COLUMN::TYPE,
_(
"Type" ) );
621 m_paramGridMgr->ShowHeader();
624 m_paramGrid->Clear();
626 m_firstCategory = m_paramGrid->Append(
new wxPropertyCategory(
"Geometry" ) );
627 m_paramGrid->HideProperty(
"Geometry" );
629 m_paramGrid->Append(
new wxPropertyCategory(
"AC" ) );
630 m_paramGrid->HideProperty(
"AC" );
632 m_paramGrid->Append(
new wxPropertyCategory(
"DC" ) );
633 m_paramGrid->HideProperty(
"DC" );
635 m_paramGrid->Append(
new wxPropertyCategory(
"S-Parameters" ) );
636 m_paramGrid->HideProperty(
"S-Parameters" );
638 m_paramGrid->Append(
new wxPropertyCategory(
"Capacitance" ) );
639 m_paramGrid->HideProperty(
"Capacitance" );
641 m_paramGrid->Append(
new wxPropertyCategory(
"Temperature" ) );
642 m_paramGrid->HideProperty(
"Temperature" );
644 m_paramGrid->Append(
new wxPropertyCategory(
"Noise" ) );
645 m_paramGrid->HideProperty(
"Noise" );
647 m_paramGrid->Append(
new wxPropertyCategory(
"Distributed Quantities" ) );
648 m_paramGrid->HideProperty(
"Distributed Quantities" );
650 m_paramGrid->Append(
new wxPropertyCategory(
"Waveform" ) );
651 m_paramGrid->HideProperty(
"Waveform" );
653 m_paramGrid->Append(
new wxPropertyCategory(
"Limiting Values" ) );
654 m_paramGrid->HideProperty(
"Limiting Values" );
656 m_paramGrid->Append(
new wxPropertyCategory(
"Advanced" ) );
657 m_paramGrid->HideProperty(
"Advanced" );
659 m_paramGrid->Append(
new wxPropertyCategory(
"Flags" ) );
660 m_paramGrid->HideProperty(
"Flags" );
662 m_paramGrid->CollapseAll();
665 addParamPropertyIfRelevant( aModel, i );
667 m_paramGrid->CollapseAll();
668 m_paramGrid->Expand(
"AC" );
669 m_paramGrid->Expand(
"Waveform" );
672 adjustParamGridColumns( m_paramGrid->GetGrid()->GetSize().GetX(),
true );
676 for( wxPropertyGridIterator it = m_paramGrid->GetIterator(); !it.AtEnd(); ++it )
678 wxColour bgCol = m_paramGrid->GetGrid()->GetPropertyDefaultCell().GetBgCol();
679 wxColour fgCol = m_paramGrid->GetGrid()->GetPropertyDefaultCell().GetFgCol();
681 for(
int col = 0; col < m_paramGridMgr->GetColumnCount(); ++col )
683 ( *it )->GetCell( col ).SetBgCol( bgCol );
684 ( *it )->GetCell( col ).SetFgCol( fgCol );
698 ( *it )->SetValueFromString( param.
value );
712 item.
modelName = m_modelListBox->GetStringSelection();
714 if( m_rbBuiltinModel->GetValue() || item.
modelName ==
"" )
719 m_codePreview->SetText(
text );
720 m_codePreview->SelectNone();
727 if( m_pinAssignmentsGrid->GetNumberRows() == 0 )
729 m_pinAssignmentsGrid->AppendRows(
static_cast<int>( m_sortedPartPins.size() ) );
731 for(
int ii = 0; ii < m_pinAssignmentsGrid->GetNumberRows(); ++ii )
733 wxString symbolPinString = getSymbolPinString( ii );
735 m_pinAssignmentsGrid->SetReadOnly( ii, PIN_COLUMN::SYMBOL );
736 m_pinAssignmentsGrid->SetCellValue( ii, PIN_COLUMN::SYMBOL, symbolPinString );
739 aForceUpdatePins =
true;
742 if( aForceUpdatePins )
745 for(
int row = 0; row < m_pinAssignmentsGrid->GetNumberRows(); ++row )
746 m_pinAssignmentsGrid->SetCellValue( row, PIN_COLUMN::MODEL,
_(
"Not Connected" ) );
749 for(
int modelPinIndex = 0; modelPinIndex < aModel->
GetPinCount(); ++modelPinIndex )
753 if( symbolPinNumber ==
"" )
756 int symbolPinRow = findSymbolPinRow( symbolPinNumber );
758 if( symbolPinRow == -1 )
761 wxString modelPinString = getModelPinString( aModel, modelPinIndex );
762 m_pinAssignmentsGrid->SetCellValue( symbolPinRow, PIN_COLUMN::MODEL, modelPinString );
766 for(
int ii = 0; ii < m_pinAssignmentsGrid->GetNumberRows(); ++ii )
769 std::vector<BITMAPS> modelPinIcons;
770 wxArrayString modelPinChoices;
772 for(
int jj = 0; jj < aModel->
GetPinCount(); ++jj )
779 modelPinChoices.Add( getModelPinString( aModel, jj ) );
783 modelPinChoices.Add(
_(
"Not Connected" ) );
787 m_pinAssignmentsGrid->SetCellEditor( ii, PIN_COLUMN::MODEL,
794 if( aModel->
GetType() == SIM_MODEL::TYPE::SUBCKT )
798 m_subckt->SetEditable(
false );
802 m_subcktLabel->Show(
false );
803 m_subckt->Show(
false );
823 if( m_prevLibrary == aLibraryPath && !aForceReload )
826 m_libraryModelsMgr.SetForceFullParse();
827 m_libraryModelsMgr.SetLibrary( aLibraryPath, aReporter );
834 for(
const auto& [baseModelName, baseModel] :
library()->GetModels() )
836 if( baseModelName == modelName )
837 m_libraryModelsMgr.CreateModel( &baseModel, m_sortedPartPins, m_fields, aReporter );
839 m_libraryModelsMgr.CreateModel( &baseModel, m_sortedPartPins, aReporter );
842 m_rbLibraryModel->SetValue(
true );
843 m_libraryPathText->ChangeValue( aLibraryPath );
845 m_modelListBoxEntryToLibraryIdx.clear();
846 wxArrayString modelNames;
848 for(
const auto& [
name, model] :
library()->GetModels() )
850 modelNames.Add(
name );
851 m_modelListBoxEntryToLibraryIdx[
name] = m_modelListBoxEntryToLibraryIdx.size();
856 m_modelListBox->Clear();
857 m_modelListBox->Append( modelNames );
861 wxArrayString emptyArray;
862 m_pinModelCombobox->Set( emptyArray );
863 m_pinCombobox->Set( emptyArray );
864 m_pinModelCombobox->SetSelection( -1 );
865 m_pinCombobox->SetSelection( -1 );
868 m_modelListBox->SetStringSelection( modelName );
870 if( m_modelListBox->GetSelection() < 0 && m_modelListBox->GetCount() > 0 )
871 m_modelListBox->SetSelection( 0 );
873 m_curModelType = curModel().GetType();
875 m_prevLibrary = aLibraryPath;
889 m_paramGrid->HideProperty(
"AC",
false );
890 m_paramGrid->AppendIn(
"AC", newParamProperty( aModel, aParamIndex ) );
894 m_paramGrid->HideProperty(
"DC",
false );
895 m_paramGrid->AppendIn(
"DC", newParamProperty( aModel, aParamIndex ) );
898 case CATEGORY::S_PARAM:
899 m_paramGrid->HideProperty(
"S-Parameters",
false );
900 m_paramGrid->AppendIn(
"S-Parameters", newParamProperty( aModel, aParamIndex ) );
903 case CATEGORY::CAPACITANCE:
904 m_paramGrid->HideProperty(
"Capacitance",
false );
905 m_paramGrid->AppendIn(
"Capacitance", newParamProperty( aModel, aParamIndex ) );
908 case CATEGORY::TEMPERATURE:
909 m_paramGrid->HideProperty(
"Temperature",
false );
910 m_paramGrid->AppendIn(
"Temperature", newParamProperty( aModel, aParamIndex ) );
913 case CATEGORY::NOISE:
914 m_paramGrid->HideProperty(
"Noise",
false );
915 m_paramGrid->AppendIn(
"Noise", newParamProperty( aModel, aParamIndex ) );
918 case CATEGORY::DISTRIBUTED_QUANTITIES:
919 m_paramGrid->HideProperty(
"Distributed Quantities",
false );
920 m_paramGrid->AppendIn(
"Distributed Quantities", newParamProperty( aModel, aParamIndex ) );
923 case CATEGORY::WAVEFORM:
924 m_paramGrid->HideProperty(
"Waveform",
false );
925 m_paramGrid->AppendIn(
"Waveform", newParamProperty( aModel, aParamIndex ) );
928 case CATEGORY::GEOMETRY:
929 m_paramGrid->HideProperty(
"Geometry",
false );
930 m_paramGrid->AppendIn(
"Geometry", newParamProperty( aModel, aParamIndex ) );
933 case CATEGORY::LIMITING_VALUES:
934 m_paramGrid->HideProperty(
"Limiting Values",
false );
935 m_paramGrid->AppendIn(
"Limiting Values", newParamProperty( aModel, aParamIndex ) );
938 case CATEGORY::ADVANCED:
939 m_paramGrid->HideProperty(
"Advanced",
false );
940 m_paramGrid->AppendIn(
"Advanced", newParamProperty( aModel, aParamIndex ) );
943 case CATEGORY::FLAGS:
944 m_paramGrid->HideProperty(
"Flags",
false );
945 m_paramGrid->AppendIn(
"Flags", newParamProperty( aModel, aParamIndex ) );
949 m_paramGrid->Insert( m_firstCategory, newParamProperty( aModel, aParamIndex ) );
952 case CATEGORY::INITIAL_CONDITIONS:
953 case CATEGORY::SUPERFLUOUS:
963 wxString paramDescription;
966 paramDescription = wxString::Format(
"%s", param.
info.
name );
970 wxPGProperty* prop =
nullptr;
977 prop->SetAttribute( wxPG_BOOL_USE_CHECKBOX,
true );
999 wxArrayString inductors;
1011 if( item.model->GetDeviceType() == SIM_MODEL::DEVICE_T::L )
1012 inductors.push_back( item.refName );
1016 [](
const wxString& a,
const wxString& b ) ->
int
1022 if( inductors.empty() )
1030 aParamIndex, inductors );
1040 wxArrayString values;
1043 values.Add(
string );
1051 prop =
new wxStringProperty( paramDescription, param.
info.
name );
1055 prop->SetAttribute( wxPG_ATTR_UNITS, wxString::FromUTF8( param.
info.
unit.c_str() ) );
1075 prop->SetCell( PARAM_COLUMN::TYPE, typeStr );
1081template <
typename T>
1084 for(
int row = 0; row < static_cast<int>( m_sortedPartPins.size() ); ++row )
1088 if(
pin->GetNumber() == aSymbolPinNumber )
1096template <
typename T>
1099 if( m_rbLibraryModel->GetValue() )
1101 wxString sel = m_modelListBox->GetStringSelection();
1103 if( m_modelListBoxEntryToLibraryIdx.contains( sel ) )
1104 return m_libraryModelsMgr.GetModels().at( m_modelListBoxEntryToLibraryIdx.at( sel ) ).get();
1108 if(
static_cast<int>( m_curModelType ) <
static_cast<int>( m_builtinModelsMgr.GetModels().size() ) )
1109 return m_builtinModelsMgr.GetModels().at(
static_cast<int>( m_curModelType ) );
1112 return m_builtinModelsMgr.GetModels().at(
static_cast<int>( SIM_MODEL::TYPE::NONE ) );
1116template <
typename T>
1119 if( m_libraryModelsMgr.GetLibraries().size() == 1 )
1120 return &m_libraryModelsMgr.GetLibraries().begin()->second.get();
1126template <
typename T>
1129 SCH_PIN*
pin = m_sortedPartPins.at( symbolPinIndex );
1135 pinNumber =
pin->GetShownNumber();
1136 pinName =
pin->GetShownName();
1139 if( !pinName.IsEmpty() && pinName != pinNumber )
1140 pinNumber += wxString::Format( wxT(
" (%s)" ), pinName );
1146template <
typename T>
1153 wxString modelPinNumber = wxString::Format(
"%d", aModelPinIndex + 1 );
1155 if( !modelPinName.IsEmpty() && modelPinName != modelPinNumber )
1156 modelPinNumber += wxString::Format( wxT(
" (%s)" ), modelPinName );
1158 return modelPinNumber;
1162template <
typename T>
1165 if( aModelPinString ==
"Not Connected" )
1168 int length = aModelPinString.Find(
" " );
1170 if( length == wxNOT_FOUND )
1171 length =
static_cast<int>( aModelPinString.Length() );
1174 aModelPinString.Mid( 0, length ).ToCLong( &result );
1176 return static_cast<int>( result - 1 );
1180template <
typename T>
1183 m_prevModel =
nullptr;
1188template <
typename T>
1191 m_rbLibraryModel->SetValue(
true );
1195template <
typename T>
1198 m_rbLibraryModel->SetValue(
true );
1201 wxString
path = m_libraryPathText->GetValue();
1203 if( loadLibrary(
path, reporter,
true ) ||
path.IsEmpty() )
1212template <
typename T>
1222 wxCommandEvent
dummy;
1223 onLibraryPathTextEnter(
dummy );
1230template <
typename T>
1233 static wxString s_mruPath;
1236 wxFileDialog dlg(
this,
_(
"Browse Models" ),
path );
1238 if( dlg.ShowModal() == wxID_CANCEL )
1241 m_rbLibraryModel->SetValue(
true );
1243 path = dlg.GetPath();
1244 wxFileName fn(
path );
1246 s_mruPath = fn.GetPath();
1248 if( fn.MakeRelativeTo(
Prj().GetProjectPath() ) && !fn.GetFullPath().StartsWith( wxS(
".." ) ) )
1249 path = fn.GetFullPath();
1253 if( loadLibrary(
path, reporter,
true ) )
1262template <
typename T>
1265 int sel = m_modelListBox->GetSelection();
1267 switch( aKeyStroke.GetKeyCode() )
1270 if( sel == wxNOT_FOUND )
1271 sel = m_modelListBox->GetCount() - 1;
1278 if( sel == wxNOT_FOUND )
1286 wxPostEvent(
this, wxCommandEvent( wxEVT_COMMAND_BUTTON_CLICKED, wxID_OK ) );
1294 if( sel >= 0 && sel < (
int) m_modelListBox->GetCount() )
1295 m_modelListBox->SetSelection( sel );
1299template <
typename T>
1302 wxArrayString modelNames;
1303 wxString current = m_modelListBox->GetStringSelection();
1304 wxString
filter = wxT(
"*" ) + m_modelFilter->GetValue() + wxT(
"*" );
1306 for(
const auto& [
name, model] :
library()->GetModels() )
1308 wxString wx_name(
name );
1310 if( wx_name.Matches(
filter ) )
1311 modelNames.Add( wx_name );
1316 m_modelListBox->Clear();
1317 m_modelListBox->Append( modelNames );
1319 if( !m_modelListBox->SetStringSelection( current ) )
1320 m_modelListBox->SetSelection( 0 );
1324template <
typename T>
1327 if( isIbisLoaded() )
1329 wxArrayString pinLabels;
1332 wxCHECK2( modelkibis,
return );
1334 for( std::pair<wxString, wxString> strs : modelkibis->
GetIbisPins() )
1335 pinLabels.Add( strs.first + wxT(
" - " ) + strs.second );
1337 m_pinCombobox->Set( pinLabels );
1339 wxArrayString emptyArray;
1340 m_pinModelCombobox->Set( emptyArray );
1343 m_rbLibraryModel->SetValue(
true );
1347 wxArrayString lines = wxSplit( fallback->GetSpiceCode(),
'\n' );
1350 for(
const wxString& line : lines )
1352 if( !line.StartsWith(
'*' ) )
1354 if( !code.IsEmpty() )
1361 m_infoBar->ShowMessage( wxString::Format(
_(
"Failed to parse:\n\n"
1363 "Using generic SPICE model." ),
1375template <
typename T>
1378 wxArrayString modelLabels;
1382 std::vector<std::pair<std::string, std::string>> strs = ibisModel.
GetIbisPins();
1383 std::string pinNumber = strs.at( m_pinCombobox->GetSelection() ).first;
1387 ibisModel.
ChangePin( *ibisLibrary, pinNumber );
1392 modelLabels.Add( modelName );
1394 m_pinModelCombobox->Set( modelLabels );
1396 if( m_pinModelCombobox->GetCount() == 1 )
1397 m_pinModelCombobox->SetSelection( 0 );
1399 m_pinModelCombobox->SetSelection( -1 );
1405template <
typename T>
1408 m_pinCombobox->SetSelection( m_pinCombobox->FindString( m_pinCombobox->GetValue() ) );
1410 onPinModelCombobox( aEvent );
1414template <
typename T>
1421template <
typename T>
1424 m_pinModelCombobox->SetSelection( m_pinModelCombobox->FindString( m_pinModelCombobox->GetValue() ) );
1427template <
typename T>
1432 bool diff = m_differentialCheckbox->GetValue() && modelibis->CanDifferential();
1433 modelibis->SwitchSingleEndedDiff( diff );
1440template <
typename T>
1443 m_rbBuiltinModel->SetValue(
true );
1445 for( SIM_MODEL::DEVICE_T deviceType : SIM_MODEL::DEVICE_T_ITERATOR() )
1449 m_curModelType = m_curModelTypeOfDeviceType.at( deviceType );
1458template <
typename T>
1461 SIM_MODEL::DEVICE_T deviceType = curModel().GetDeviceType();
1462 wxString typeDescription = m_waveformChoice->GetStringSelection();
1464 for( SIM_MODEL::TYPE type : { SIM_MODEL::TYPE::KIBIS_DEVICE,
1465 SIM_MODEL::TYPE::KIBIS_DRIVER_DC,
1466 SIM_MODEL::TYPE::KIBIS_DRIVER_RECT,
1467 SIM_MODEL::TYPE::KIBIS_DRIVER_PRBS } )
1473 wxString sel = m_modelListBox->GetStringSelection();
1475 if( m_modelListBoxEntryToLibraryIdx.contains( sel ) )
1476 idx = m_modelListBoxEntryToLibraryIdx.at( sel );
1478 auto& baseModel =
static_cast<SIM_MODEL_IBIS&
>( m_libraryModelsMgr.GetModels()[idx].get() );
1480 m_libraryModelsMgr.SetModel( idx, std::make_unique<SIM_MODEL_IBIS>( type, baseModel ) );
1484 m_libraryModelsMgr.GetModels()[idx].get().
ReadDataFields( &m_fields, m_sortedPartPins );
1491 m_curModelType = type;
1496 m_curModelTypeOfDeviceType.at( deviceType ) = m_curModelType;
1501template <
typename T>
1504 SIM_MODEL::DEVICE_T deviceType = curModel().GetDeviceType();
1505 wxString typeDescription = m_deviceSubtypeChoice->GetStringSelection();
1507 for( SIM_MODEL::TYPE type : SIM_MODEL::TYPE_ITERATOR() )
1512 m_curModelType = type;
1517 m_curModelTypeOfDeviceType.at( deviceType ) = m_curModelType;
1522template <
typename T>
1525 updateModelCodeTab( &curModel() );
1529template <
typename T>
1532 int symbolPinIndex = aEvent.GetRow();
1533 wxString oldModelPinName = aEvent.GetString();
1534 wxString modelPinName = m_pinAssignmentsGrid->GetCellValue( aEvent.GetRow(), aEvent.GetCol() );
1536 int oldModelPinIndex = getModelPinIndex( oldModelPinName );
1537 int modelPinIndex = getModelPinIndex( modelPinName );
1540 curModel().AssignSymbolPinNumberToModelPin( oldModelPinIndex,
"" );
1544 SCH_PIN* symbolPin = m_sortedPartPins.at( symbolPinIndex );
1546 curModel().AssignSymbolPinNumberToModelPin( modelPinIndex, symbolPin->
GetShownNumber() );
1555template <
typename T>
1558 wxGridUpdateLocker deferRepaintsTillLeavingScope( m_pinAssignmentsGrid );
1561 m_pinAssignmentsGrid->SetColSize( PIN_COLUMN::MODEL, gridWidth / 2 );
1562 m_pinAssignmentsGrid->SetColSize( PIN_COLUMN::SYMBOL, gridWidth / 2 );
1568template <
typename T>
1574 wxPropertyGrid*
grid = m_paramGrid->GetGrid();
1575 wxPGProperty* selected =
grid->GetSelection();
1578 selected =
grid->wxPropertyGridInterface::GetFirst();
1580#if wxCHECK_VERSION( 3, 3, 0 )
1582 grid->DoSelectProperty( selected, wxPGSelectPropertyFlags::Focus );
1585 grid->DoSelectProperty( selected, wxPG_SEL_FOCUS );
1592template <
typename T>
1595 wxPropertyGrid*
grid = m_paramGrid->GetGrid();
1598 if(
grid->GetSelection() &&
grid->GetSelection()->IsCategory() )
1600 wxPGProperty* selection =
grid->GetSelection();
1605 wxPropertyGridIterator it =
grid->GetIterator( wxPG_ITERATE_VISIBLE, selection );
1608 wxKeyEvent* keyEvent =
new wxKeyEvent( wxEVT_KEY_DOWN );
1610 if( *it == m_prevParamGridSelection )
1612 if( !selection->IsExpanded() )
1614 grid->Expand( selection );
1615 keyEvent->m_keyCode = WXK_DOWN;
1616 wxQueueEvent(
grid, keyEvent );
1624 keyEvent->m_keyCode = WXK_UP;
1625 wxQueueEvent(
grid, keyEvent );
1630 if( !selection->IsExpanded() )
1631 grid->Expand( selection );
1633 keyEvent->m_keyCode = WXK_DOWN;
1634 wxQueueEvent(
grid, keyEvent );
1637 m_prevParamGridSelection =
grid->GetSelection();
1641 wxWindow* editorControl =
grid->GetEditorControl();
1643 if( !editorControl )
1645 m_prevParamGridSelection =
grid->GetSelection();
1650 editorControl->SetFocus();
1651 m_prevParamGridSelection =
grid->GetSelection();
1655template <
typename T>
1666 wxPropertyGrid*
grid = m_paramGrid->GetGrid();
1667 wxTextCtrl* ctrl =
grid->GetEditorTextCtrl();
1671 wxRect ctrlRect = ctrl->GetScreenRect();
1672 wxRect gridRect =
grid->GetScreenRect();
1674 if( ctrlRect.GetTop() < gridRect.GetTop() || ctrlRect.GetBottom() > gridRect.GetBottom() )
1675 grid->ClearSelection();
1681template <
typename T>
1684 wxPropertyGrid*
grid = m_paramGridMgr->GetGrid();
1688 if( aWidth != m_lastParamGridWidth || aForce )
1690 m_lastParamGridWidth = aWidth;
1694 std::vector<int> colWidths;
1696 for(
size_t ii = 0; ii <
grid->GetColumnCount(); ii++ )
1698 if( ii == PARAM_COLUMN::DESCRIPTION )
1699 colWidths.push_back(
grid->GetState()->GetColumnWidth( ii ) + margin + indent );
1700 else if( ii == PARAM_COLUMN::VALUE )
1701 colWidths.push_back( std::max( 72,
grid->GetState()->GetColumnWidth( ii ) ) + margin );
1703 colWidths.push_back( 60 + margin );
1705 aWidth -= colWidths[ ii ];
1708 for(
size_t ii = 0; ii <
grid->GetColumnCount(); ii++ )
1709 grid->SetColumnProportion( ii, colWidths[ ii ] );
1711 grid->ResetColumnSizes();
1712 grid->RefreshEditor();
1717template <
typename T>
1720 adjustParamGridColumns( event.GetSize().GetX(),
false );
wxBitmapBundle KiBitmapBundle(BITMAPS aBitmap)
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)
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
wxPGProperty * newParamProperty(SIM_MODEL *aModel, int aParamIndex) const
void onPinModelCombobox(wxCommandEvent &event) override
const SIM_LIBRARY * library() const
SIM_MODEL & curModel() const
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.
Instances are attached to a symbol or sheet and provide a place for the symbol's value,...
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
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)
static void SetFieldValue(std::vector< SCH_FIELD > &aFields, const wxString &aFieldName, const std::string &aValue)
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)
static std::string GetFieldValue(const std::vector< SCH_FIELD > *aFields, const wxString &aFieldName, bool aResolve=true)
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
KICOMMON_API wxFont GetInfoFont(wxWindow *aWindow)
BITMAPS PinShapeGetBitmap(GRAPHIC_PINSHAPE aShape)
@ NONE
No connection to this item.
#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
@ VALUE_FIELD
Field Value of part, i.e. "3.3K".
@ REFERENCE_FIELD
Field Reference of part, i.e. "IC21".