43#include <wx/filedlg.h>
44#include <wx/textfile.h>
45#include <fmt/format.h>
50bool equivalent( SIM_MODEL::DEVICE_T a, SIM_MODEL::DEVICE_T b )
59template <
typename T_symbol,
typename T_field>
61 std::vector<T_field>& aFields ) :\
65 m_libraryModelsMgr( &
Prj() ),
66 m_builtinModelsMgr( &
Prj() ),
67 m_prevModel( nullptr ),
69 m_scintillaTricksCode( nullptr ),
70 m_scintillaTricksSubckt( nullptr ),
71 m_firstCategory( nullptr ),
72 m_prevParamGridSelection( nullptr ),
73 m_lastParamGridWidth( 0 ),
74 m_inKillFocus( false )
81 if( !
pin->GetParent()->HasConversion() ||
pin->GetConvert() < 2 )
89 return StrNumCmp( lhs->GetNumber(), rhs->GetNumber(), true ) < 0;
104 grid->SetCellDisabledTextColour( wxSystemSettings::GetColour( wxSYS_COLOUR_GRAYTEXT ) );
109 grid->DedicateKey( WXK_RETURN );
110 grid->DedicateKey( WXK_NUMPAD_ENTER );
111 grid->DedicateKey( WXK_UP );
112 grid->DedicateKey( WXK_DOWN );
114#if wxCHECK_VERSION( 3, 3, 0 )
115 grid->AddActionTrigger( wxPGKeyboardActions::Edit, WXK_RETURN );
116 grid->AddActionTrigger( wxPGKeyboardActions::NextProperty, WXK_RETURN );
117 grid->AddActionTrigger( wxPGKeyboardActions::Edit, WXK_NUMPAD_ENTER );
118 grid->AddActionTrigger( wxPGKeyboardActions::NextProperty, WXK_NUMPAD_ENTER );
120 grid->AddActionTrigger( wxPG_ACTION_EDIT, WXK_RETURN );
121 grid->AddActionTrigger( wxPG_ACTION_NEXT_PROPERTY, WXK_RETURN );
122 grid->AddActionTrigger( wxPG_ACTION_EDIT, WXK_NUMPAD_ENTER );
123 grid->AddActionTrigger( wxPG_ACTION_NEXT_PROPERTY, WXK_NUMPAD_ENTER );
135template <
typename T_symbol,
typename T_field>
140 for( wxPropertyGridIterator it = m_paramGrid->GetIterator(); !it.AtEnd(); ++it )
151 m_pinAssignmentsGrid->PopEventHandler(
true );
153 delete m_scintillaTricksCode;
154 delete m_scintillaTricksSubckt;
158template <
typename T_symbol,
typename T_field>
161 wxCommandEvent dummyEvent;
164 wxString modelParams;
166 bool storeInValue =
false;
172 [&](
const wxString& aFieldName,
const wxString& aValue )
174 for( T_field& field : m_fields )
176 if( field.GetName() == aFieldName )
178 field.SetText( aValue );
183 m_fields.emplace_back( &m_symbol, -1, aFieldName );
184 m_fields.back().SetText( aValue );
189 &deviceType, &modelType, &modelParams, &pinMap ) )
193 if( !modelType.IsEmpty() )
204 m_fields[
VALUE_FIELD ].SetText( wxT(
"${SIM.PARAMS}" ) );
209 if( libraryFilename !=
"" )
212 m_rbLibraryModel->SetValue(
true );
214 if( !loadLibrary( libraryFilename ) )
216 m_libraryPathText->ChangeValue( libraryFilename );
220 m_libraryModelsMgr.CreateModel(
nullptr, m_sortedPartPins, m_fields, reporter );
222 m_modelNameChoice->Append(
_(
"<unknown>" ) );
223 m_modelNameChoice->SetSelection( 0 );
228 int modelIdx = m_modelNameChoice->FindString( modelName );
230 if( modelIdx == wxNOT_FOUND )
236 m_modelNameChoice->SetSelection( 0 );
240 m_modelNameChoice->SetSelection( modelIdx );
243 m_curModelType = curModel().GetType();
246 if( isIbisLoaded() && ( m_modelNameChoice->GetSelection() >= 0 ) )
248 int idx = m_modelNameChoice->GetSelection();
249 auto kibismodel =
dynamic_cast<SIM_MODEL_KIBIS*
>( &m_libraryModelsMgr.GetModels()[idx].get() );
253 onModelNameChoice( dummyEvent );
257 for(
const std::pair<std::string, std::string>& strs : kibismodel->GetIbisPins() )
263 kibismodel->ChangePin( *kibisLibrary, strs.first );
264 m_pinCombobox->SetSelection(
static_cast<int>( i ) );
270 if( i <
static_cast<int>( kibismodel->GetIbisPins().size() ) )
272 onPinCombobox( dummyEvent );
274 m_pinModelCombobox->SetStringSelection(
280 kibismodel->SwitchSingleEndedDiff(
true );
281 m_differentialCheckbox->SetValue(
true );
285 kibismodel->SwitchSingleEndedDiff(
false );
286 m_differentialCheckbox->SetValue(
false );
295 m_rbBuiltinModel->SetValue(
true );
304 for( SIM_MODEL::TYPE type : SIM_MODEL::TYPE_ITERATOR() )
306 if( m_rbBuiltinModel->GetValue() && type == m_curModelType )
309 m_builtinModelsMgr.CreateModel( m_fields, m_sortedPartPins,
false, reporter );
314 + wxT(
"\n\n" ) + msg );
319 m_builtinModelsMgr.CreateModel( type, m_sortedPartPins, reporter );
324 if( !m_curModelTypeOfDeviceType.count( deviceTypeT ) )
325 m_curModelTypeOfDeviceType[deviceTypeT] = type;
329 curModel().SetIsStoredInValue(
true );
331 m_saveInValueCheckbox->SetValue( curModel().IsStoredInValue() );
333 onRadioButton( dummyEvent );
334 return DIALOG_SIM_MODEL_BASE::TransferDataToWindow();
338template <
typename T_symbol,
typename T_field>
341 m_pinAssignmentsGrid->CommitPendingChanges();
342 m_paramGrid->GetGrid()->CommitChangesFromEditor();
344 if( !DIALOG_SIM_MODEL_BASE::TransferDataFromWindow() )
350 if( m_rbLibraryModel->GetValue() )
352 path = m_libraryPathText->GetValue();
353 wxFileName fn(
path );
355 if( fn.MakeRelativeTo(
Prj().GetProjectPath() ) && !fn.GetFullPath().StartsWith(
".." ) )
356 path = fn.GetFullPath();
358 if( !m_modelNameChoice->IsEmpty() )
359 name = m_modelNameChoice->GetStringSelection().ToStdString();
370 &m_libraryModelsMgr.GetModels().at( m_modelNameChoice->GetSelection() ).get() );
375 std::string modelName = std::string( m_pinModelCombobox->GetValue().c_str() );
376 std::string differential;
378 if( m_pinCombobox->GetSelection() >= 0 )
379 pins = ibismodel->
GetIbisPins().at( m_pinCombobox->GetSelection() ).first;
381 if( ibismodel->
CanDifferential() && m_differentialCheckbox->GetValue() )
390 if( curModel().GetType() == SIM_MODEL::TYPE::RAWSPICE )
392 if( m_modelNotebook->GetSelection() == 0 )
393 updateModelCodeTab( &curModel() );
395 wxString code = m_codePreview->GetText().Trim(
true ).Trim(
false );
396 curModel().SetParamValue(
"model", std::string( code.ToUTF8() ) );
399 curModel().SetIsStoredInValue( m_saveInValueCheckbox->GetValue() );
401 curModel().WriteFields( m_fields );
407template <
typename T_symbol,
typename T_field>
412 updateIbisWidgets( model );
413 updateBuiltinModelWidgets( model );
414 updateModelParamsTab( model );
415 updateModelCodeTab( model );
416 updatePinAssignments( model );
420 m_modelPanel->Layout();
421 m_pinAssignmentsPanel->Layout();
422 m_parametersPanel->Layout();
423 m_codePanel->Layout();
425 SendSizeEvent( wxSEND_EVENT_POST );
427 m_prevModel = &curModel();
431template <
typename T_symbol,
typename T_field>
437 m_pinLabel->Show( isIbisLoaded() );
438 m_pinCombobox->Show( isIbisLoaded() );
439 m_pinModelLabel->Show( isIbisLoaded() );
440 m_pinModelCombobox->Show( isIbisLoaded() );
441 m_waveformLabel->Show( isIbisLoaded() );
442 m_waveformChoice->Show( isIbisLoaded() );
444 if( aModel != m_prevModel )
446 m_waveformChoice->Clear();
450 for( SIM_MODEL::TYPE type : { SIM_MODEL::TYPE::KIBIS_DEVICE,
451 SIM_MODEL::TYPE::KIBIS_DRIVER_DC,
452 SIM_MODEL::TYPE::KIBIS_DRIVER_RECT,
453 SIM_MODEL::TYPE::KIBIS_DRIVER_PRBS } )
463 if( type == aModel->
GetType() )
464 m_waveformChoice->SetSelection( m_waveformChoice->GetCount() - 1 );
470 m_differentialCheckbox->Show( isIbisLoaded() && modelkibis && modelkibis->
CanDifferential() );
471 m_modelNameLabel->SetLabel( isIbisLoaded() ?
_(
"Component:" ) :
_(
"Model:" ) );
475template <
typename T_symbol,
typename T_field>
479 if( aModel != m_prevModel )
481 m_deviceChoice->Clear();
482 m_deviceTypeChoice->Clear();
484 if( m_rbBuiltinModel->GetValue() )
486 for( SIM_MODEL::DEVICE_T deviceType : SIM_MODEL::DEVICE_T_ITERATOR() )
494 m_deviceChoice->SetSelection( m_deviceChoice->GetCount() - 1 );
497 for( SIM_MODEL::TYPE type : SIM_MODEL::TYPE_ITERATOR() )
499 if( type == SIM_MODEL::TYPE::KIBIS_DEVICE
500 || type == SIM_MODEL::TYPE::KIBIS_DRIVER_DC
501 || type == SIM_MODEL::TYPE::KIBIS_DRIVER_RECT
502 || type == SIM_MODEL::TYPE::KIBIS_DRIVER_PRBS )
515 if( type == aModel->
GetType() )
516 m_deviceTypeChoice->SetSelection( m_deviceTypeChoice->GetCount() - 1 );
522 m_deviceTypeChoice->Enable( !m_rbLibraryModel->GetValue() );
525 m_modelNotebook->SetSelection( 1 );
527 m_modelNotebook->SetSelection( 0 );
533 m_saveInValueCheckbox->SetLabel( wxString::Format(
_(
"Save parameter '%s (%s)' in Value "
537 m_saveInValueCheckbox->Enable(
true );
541 m_saveInValueCheckbox->SetLabel(
_(
"Save primary parameter in Value field" ) );
542 m_saveInValueCheckbox->SetValue(
false );
543 m_saveInValueCheckbox->Enable(
false );
548template <
typename T_symbol,
typename T_field>
551 if( aModel != m_prevModel )
556 m_paramGridMgr->SetColumnCount( PARAM_COLUMN::END_ );
558 m_paramGridMgr->SetColumnTitle( PARAM_COLUMN::DESCRIPTION,
_(
"Parameter" ) );
559 m_paramGridMgr->SetColumnTitle( PARAM_COLUMN::UNIT,
_(
"Unit" ) );
560 m_paramGridMgr->SetColumnTitle( PARAM_COLUMN::DEFAULT,
_(
"Default" ) );
561 m_paramGridMgr->SetColumnTitle( PARAM_COLUMN::TYPE,
_(
"Type" ) );
563 m_paramGridMgr->ShowHeader();
566 m_paramGrid->Clear();
568 m_firstCategory = m_paramGrid->Append(
new wxPropertyCategory(
"Geometry" ) );
569 m_paramGrid->HideProperty(
"Geometry" );
571 m_paramGrid->Append(
new wxPropertyCategory(
"AC" ) );
572 m_paramGrid->HideProperty(
"AC" );
574 m_paramGrid->Append(
new wxPropertyCategory(
"DC" ) );
575 m_paramGrid->HideProperty(
"DC" );
577 m_paramGrid->Append(
new wxPropertyCategory(
"S-Parameters" ) );
578 m_paramGrid->HideProperty(
"S-Parameters" );
580 m_paramGrid->Append(
new wxPropertyCategory(
"Capacitance" ) );
581 m_paramGrid->HideProperty(
"Capacitance" );
583 m_paramGrid->Append(
new wxPropertyCategory(
"Temperature" ) );
584 m_paramGrid->HideProperty(
"Temperature" );
586 m_paramGrid->Append(
new wxPropertyCategory(
"Noise" ) );
587 m_paramGrid->HideProperty(
"Noise" );
589 m_paramGrid->Append(
new wxPropertyCategory(
"Distributed Quantities" ) );
590 m_paramGrid->HideProperty(
"Distributed Quantities" );
592 m_paramGrid->Append(
new wxPropertyCategory(
"Waveform" ) );
593 m_paramGrid->HideProperty(
"Waveform" );
595 m_paramGrid->Append(
new wxPropertyCategory(
"Limiting Values" ) );
596 m_paramGrid->HideProperty(
"Limiting Values" );
598 m_paramGrid->Append(
new wxPropertyCategory(
"Advanced" ) );
599 m_paramGrid->HideProperty(
"Advanced" );
601 m_paramGrid->Append(
new wxPropertyCategory(
"Flags" ) );
602 m_paramGrid->HideProperty(
"Flags" );
604 m_paramGrid->CollapseAll();
607 addParamPropertyIfRelevant( aModel, i );
609 m_paramGrid->CollapseAll();
610 m_paramGrid->Expand(
"AC" );
611 m_paramGrid->Expand(
"Waveform" );
614 adjustParamGridColumns( m_paramGrid->GetGrid()->GetSize().GetX(),
true );
618 for( wxPropertyGridIterator it = m_paramGrid->GetIterator(); !it.AtEnd(); ++it )
620 wxColour bgCol = m_paramGrid->GetGrid()->GetPropertyDefaultCell().GetBgCol();
621 wxColour fgCol = m_paramGrid->GetGrid()->GetPropertyDefaultCell().GetFgCol();
623 for(
int col = 0; col < m_paramGridMgr->GetColumnCount(); ++col )
625 ( *it )->GetCell( col ).SetBgCol( bgCol );
626 ( *it )->GetCell( col ).SetFgCol( fgCol );
640 ( *it )->SetValueFromString( param.
value );
645template <
typename T_symbol,
typename T_field>
654 item.
modelName = m_modelNameChoice->GetStringSelection();
656 if( m_rbBuiltinModel->GetValue() || item.
modelName ==
"" )
661 m_codePreview->SetText(
text );
662 m_codePreview->SelectNone();
666template <
typename T_symbol,
typename T_field>
669 removeOrphanedPinAssignments( aModel );
673 m_pinAssignmentsGrid->ClearRows();
674 m_pinAssignmentsGrid->AppendRows(
static_cast<int>( m_sortedPartPins.size() ) );
676 for(
int row = 0; row < m_pinAssignmentsGrid->GetNumberRows(); ++row )
677 m_pinAssignmentsGrid->SetCellValue( row, PIN_COLUMN::MODEL,
_(
"Not Connected" ) );
680 for(
int modelPinIndex = 0; modelPinIndex < aModel->
GetPinCount(); ++modelPinIndex )
684 if( symbolPinNumber ==
"" )
687 int symbolPinRow = findSymbolPinRow( symbolPinNumber );
689 if( symbolPinRow == -1 )
692 wxString modelPinString = getModelPinString( aModel, modelPinIndex );
693 m_pinAssignmentsGrid->SetCellValue( symbolPinRow, PIN_COLUMN::MODEL, modelPinString );
697 for(
int ii = 0; ii < m_pinAssignmentsGrid->GetNumberRows(); ++ii )
699 wxString symbolPinString = getSymbolPinString( ii );
701 m_pinAssignmentsGrid->SetReadOnly( ii, PIN_COLUMN::SYMBOL );
702 m_pinAssignmentsGrid->SetCellValue( ii, PIN_COLUMN::SYMBOL, symbolPinString );
704 wxString curModelPinString = m_pinAssignmentsGrid->GetCellValue( ii, PIN_COLUMN::MODEL );
706 std::vector<BITMAPS> modelPinIcons;
707 wxArrayString modelPinChoices;
709 for(
int jj = 0; jj < aModel->
GetPinCount(); ++jj )
716 modelPinChoices.Add( getModelPinString( aModel, jj ) );
720 modelPinChoices.Add(
_(
"Not Connected" ) );
724 m_pinAssignmentsGrid->SetCellEditor( ii, PIN_COLUMN::MODEL,
731 if( aModel->
GetType() == SIM_MODEL::TYPE::SUBCKT )
735 m_subckt->SetEditable(
false );
739 m_subcktLabel->Show(
false );
740 m_subckt->Show(
false );
745template <
typename T_symbol,
typename T_field>
756template <
typename T_symbol,
typename T_field>
760 if( m_prevLibrary == aLibraryPath && !aForceReload )
766 m_libraryModelsMgr.SetForceFullParse();
767 m_libraryModelsMgr.SetLibrary( aLibraryPath, reporter );
777 for(
const auto& [baseModelName, baseModel] :
library()->GetModels() )
779 if( baseModelName == modelName )
780 m_libraryModelsMgr.CreateModel( &baseModel, m_sortedPartPins, m_fields, reporter );
782 m_libraryModelsMgr.CreateModel( &baseModel, m_sortedPartPins, reporter );
788 m_rbLibraryModel->SetValue(
true );
789 m_libraryPathText->ChangeValue( aLibraryPath );
791 wxArrayString modelNames;
793 for(
const auto& [
name, model] :
library()->GetModels() )
794 modelNames.Add(
name );
796 m_modelNameChoice->Clear();
797 m_modelNameChoice->Append( modelNames );
801 wxArrayString emptyArray;
802 m_pinModelCombobox->Set( emptyArray );
803 m_pinCombobox->Set( emptyArray );
804 m_pinModelCombobox->SetSelection( -1 );
805 m_pinCombobox->SetSelection( -1 );
808 m_prevLibrary = aLibraryPath;
813template <
typename T_symbol,
typename T_field>
823 m_paramGrid->HideProperty(
"AC",
false );
824 m_paramGrid->AppendIn(
"AC", newParamProperty( aModel, aParamIndex ) );
828 m_paramGrid->HideProperty(
"DC",
false );
829 m_paramGrid->AppendIn(
"DC", newParamProperty( aModel, aParamIndex ) );
832 case CATEGORY::S_PARAM:
833 m_paramGrid->HideProperty(
"S-Parameters",
false );
834 m_paramGrid->AppendIn(
"S-Parameters", newParamProperty( aModel, aParamIndex ) );
837 case CATEGORY::CAPACITANCE:
838 m_paramGrid->HideProperty(
"Capacitance",
false );
839 m_paramGrid->AppendIn(
"Capacitance", newParamProperty( aModel, aParamIndex ) );
842 case CATEGORY::TEMPERATURE:
843 m_paramGrid->HideProperty(
"Temperature",
false );
844 m_paramGrid->AppendIn(
"Temperature", newParamProperty( aModel, aParamIndex ) );
847 case CATEGORY::NOISE:
848 m_paramGrid->HideProperty(
"Noise",
false );
849 m_paramGrid->AppendIn(
"Noise", newParamProperty( aModel, aParamIndex ) );
852 case CATEGORY::DISTRIBUTED_QUANTITIES:
853 m_paramGrid->HideProperty(
"Distributed Quantities",
false );
854 m_paramGrid->AppendIn(
"Distributed Quantities", newParamProperty( aModel, aParamIndex ) );
857 case CATEGORY::WAVEFORM:
858 m_paramGrid->HideProperty(
"Waveform",
false );
859 m_paramGrid->AppendIn(
"Waveform", newParamProperty( aModel, aParamIndex ) );
862 case CATEGORY::GEOMETRY:
863 m_paramGrid->HideProperty(
"Geometry",
false );
864 m_paramGrid->AppendIn(
"Geometry", newParamProperty( aModel, aParamIndex ) );
867 case CATEGORY::LIMITING_VALUES:
868 m_paramGrid->HideProperty(
"Limiting Values",
false );
869 m_paramGrid->AppendIn(
"Limiting Values", newParamProperty( aModel, aParamIndex ) );
872 case CATEGORY::ADVANCED:
873 m_paramGrid->HideProperty(
"Advanced",
false );
874 m_paramGrid->AppendIn(
"Advanced", newParamProperty( aModel, aParamIndex ) );
877 case CATEGORY::FLAGS:
878 m_paramGrid->HideProperty(
"Flags",
false );
879 m_paramGrid->AppendIn(
"Flags", newParamProperty( aModel, aParamIndex ) );
883 m_paramGrid->Insert( m_firstCategory, newParamProperty( aModel, aParamIndex ) );
886 case CATEGORY::INITIAL_CONDITIONS:
887 case CATEGORY::SUPERFLUOUS:
893template <
typename T_symbol,
typename T_field>
895 int aParamIndex )
const
898 wxString paramDescription;
901 paramDescription = wxString::Format(
"%s", param.
info.
name );
905 wxPGProperty* prop =
nullptr;
912 prop->SetAttribute( wxPG_BOOL_USE_CHECKBOX,
true );
941 prop =
new wxStringProperty( paramDescription, param.
info.
name );
945 prop->SetAttribute( wxPG_ATTR_UNITS, wxString::FromUTF8( param.
info.
unit.c_str() ) );
965 prop->SetCell( PARAM_COLUMN::TYPE, typeStr );
971template <
typename T_symbol,
typename T_field>
974 for(
int row = 0; row < static_cast<int>( m_sortedPartPins.size() ); ++row )
978 if(
pin->GetNumber() == aSymbolPinNumber )
986template <
typename T_symbol,
typename T_field>
989 if( m_rbLibraryModel->GetValue() )
991 int sel = m_modelNameChoice->GetSelection();
993 if( sel >= 0 && sel < (
int) m_libraryModelsMgr.GetModels().size() )
994 return m_libraryModelsMgr.GetModels().at( sel ).get();
998 if( (
int) m_curModelType < (
int) m_builtinModelsMgr.GetModels().size() )
999 return m_builtinModelsMgr.GetModels().at( (
int) m_curModelType );
1002 return m_builtinModelsMgr.GetModels().at( (
int) SIM_MODEL::TYPE::NONE );
1006template <
typename T_symbol,
typename T_field>
1009 if( m_libraryModelsMgr.GetLibraries().size() == 1 )
1010 return &m_libraryModelsMgr.GetLibraries().begin()->second.get();
1016template <
typename T_symbol,
typename T_field>
1019 LIB_PIN*
pin = m_sortedPartPins.at( symbolPinIndex );
1025 pinNumber =
pin->GetShownNumber();
1026 pinName =
pin->GetShownName();
1029 if( !pinName.IsEmpty() && pinName != pinNumber )
1030 pinNumber += wxString::Format( wxT(
" (%s)" ), pinName );
1036template <
typename T_symbol,
typename T_field>
1038 int aModelPinIndex )
const
1040 const wxString& pinName = aModel->
GetPin( aModelPinIndex ).
name;
1044 wxString pinNumber = wxString::Format(
"%d", aModelPinIndex + 1 );
1046 if( !pinName.IsEmpty() && pinName != pinNumber )
1047 pinNumber += wxString::Format( wxT(
" (%s)" ), pinName );
1053template <
typename T_symbol,
typename T_field>
1056 if( aModelPinString ==
"Not Connected" )
1059 int length = aModelPinString.Find(
" " );
1061 if( length == wxNOT_FOUND )
1062 length =
static_cast<int>( aModelPinString.Length() );
1065 aModelPinString.Mid( 0, length ).ToCLong( &result );
1067 return static_cast<int>( result - 1 );
1071template <
typename T_symbol,
typename T_field>
1074 bool fromLibrary = m_rbLibraryModel->GetValue();
1076 m_pathLabel->Enable( fromLibrary );
1077 m_libraryPathText->Enable( fromLibrary );
1078 m_browseButton->Enable( fromLibrary );
1079 m_modelNameLabel->Enable( fromLibrary );
1080 m_modelNameChoice->Enable( fromLibrary );
1081 m_pinLabel->Enable( fromLibrary );
1082 m_pinCombobox->Enable( fromLibrary );
1083 m_differentialCheckbox->Enable( fromLibrary );
1084 m_pinModelLabel->Enable( fromLibrary );
1085 m_pinModelCombobox->Enable( fromLibrary );
1086 m_waveformLabel->Enable( fromLibrary );
1087 m_waveformChoice->Enable( fromLibrary );
1089 m_deviceLabel->Enable( !fromLibrary );
1090 m_deviceChoice->Enable( !fromLibrary );
1091 m_deviceTypeLabel->Enable( !fromLibrary );
1093 m_prevModel =
nullptr;
1098template <
typename T_symbol,
typename T_field>
1101 if( m_rbLibraryModel->GetValue() )
1103 wxString
path = m_libraryPathText->GetValue();
1105 if( !
path.IsEmpty() )
1109 loadLibrary(
path );
1121template <
typename T_symbol,
typename T_field>
1124 if( !m_inKillFocus )
1126 m_inKillFocus =
true;
1128 wxCommandEvent
dummy;
1129 onLibraryPathTextEnter(
dummy );
1131 m_inKillFocus =
false;
1136template <
typename T_symbol,
typename T_field>
1139 static wxString s_mruPath;
1142 wxFileDialog dlg(
this,
_(
"Browse Models" ),
path );
1144 if( dlg.ShowModal() == wxID_CANCEL )
1147 path = dlg.GetPath();
1148 wxFileName fn(
path );
1150 s_mruPath = fn.GetPath();
1152 if( fn.MakeRelativeTo(
Prj().GetProjectPath() ) && !fn.GetFullPath().StartsWith( wxS(
".." ) ) )
1153 path = fn.GetFullPath();
1155 loadLibrary(
path,
true );
1160template <
typename T_symbol,
typename T_field>
1163 if( isIbisLoaded() )
1165 wxArrayString pinLabels;
1168 wxCHECK2( modelkibis,
return );
1170 for( std::pair<wxString, wxString> strs : modelkibis->
GetIbisPins() )
1171 pinLabels.Add( strs.first + wxT(
" - " ) + strs.second );
1173 m_pinCombobox->Set( pinLabels );
1175 wxArrayString emptyArray;
1176 m_pinModelCombobox->Set( emptyArray );
1183template <
typename T_symbol,
typename T_field>
1186 wxArrayString modelLabels;
1190 std::vector<std::pair<std::string, std::string>> strs = ibisModel.
GetIbisPins();
1191 std::string pinNumber = strs.at( m_pinCombobox->GetSelection() ).first;
1195 ibisModel.
ChangePin( *ibisLibrary, pinNumber );
1200 modelLabels.Add( modelName );
1202 m_pinModelCombobox->Set( modelLabels );
1204 if( m_pinModelCombobox->GetCount() == 1 )
1205 m_pinModelCombobox->SetSelection( 0 );
1207 m_pinModelCombobox->SetSelection( -1 );
1213template <
typename T_symbol,
typename T_field>
1216 m_pinCombobox->SetSelection( m_pinCombobox->FindString( m_pinCombobox->GetValue() ) );
1218 onPinModelCombobox( aEvent );
1222template <
typename T_symbol,
typename T_field>
1229template <
typename T_symbol,
typename T_field>
1232 m_pinModelCombobox->SetSelection( m_pinModelCombobox->FindString( m_pinModelCombobox->GetValue() ) );
1235template <
typename T_symbol,
typename T_field>
1240 wxCHECK( modelkibis, );
1242 bool diff = m_differentialCheckbox->GetValue() && modelkibis->
CanDifferential();
1249template <
typename T_symbol,
typename T_field>
1252 for( SIM_MODEL::DEVICE_T deviceType : SIM_MODEL::DEVICE_T_ITERATOR() )
1256 m_curModelType = m_curModelTypeOfDeviceType.at( deviceType );
1265template <
typename T_symbol,
typename T_field>
1268 SIM_MODEL::DEVICE_T deviceType = curModel().GetDeviceType();
1269 wxString typeDescription = m_waveformChoice->GetStringSelection();
1271 for( SIM_MODEL::TYPE type : { SIM_MODEL::TYPE::KIBIS_DEVICE,
1272 SIM_MODEL::TYPE::KIBIS_DRIVER_DC,
1273 SIM_MODEL::TYPE::KIBIS_DRIVER_RECT,
1274 SIM_MODEL::TYPE::KIBIS_DRIVER_PRBS } )
1279 int idx = m_modelNameChoice->GetSelection();
1281 auto& baseModel =
static_cast<SIM_MODEL_KIBIS&
>( m_libraryModelsMgr.GetModels()[idx].get() );
1283 m_libraryModelsMgr.SetModel( idx, std::make_unique<SIM_MODEL_KIBIS>( type, baseModel ) );
1287 m_libraryModelsMgr.GetModels()[idx].get().
ReadDataFields( &m_fields, m_sortedPartPins );
1294 m_curModelType = type;
1299 m_curModelTypeOfDeviceType.at( deviceType ) = m_curModelType;
1304template <
typename T_symbol,
typename T_field>
1307 SIM_MODEL::DEVICE_T deviceType = curModel().GetDeviceType();
1308 wxString typeDescription = m_deviceTypeChoice->GetStringSelection();
1310 for( SIM_MODEL::TYPE type : SIM_MODEL::TYPE_ITERATOR() )
1315 m_curModelType = type;
1320 m_curModelTypeOfDeviceType.at( deviceType ) = m_curModelType;
1325template <
typename T_symbol,
typename T_field>
1328 updateModelCodeTab( &curModel() );
1332template <
typename T_symbol,
typename T_field>
1335 int symbolPinIndex = aEvent.GetRow();
1336 wxString oldModelPinName = aEvent.GetString();
1337 wxString modelPinName = m_pinAssignmentsGrid->GetCellValue( aEvent.GetRow(), aEvent.GetCol() );
1339 int oldModelPinIndex = getModelPinIndex( oldModelPinName );
1340 int modelPinIndex = getModelPinIndex( modelPinName );
1343 curModel().SetPinSymbolPinNumber( oldModelPinIndex,
"" );
1347 curModel().SetPinSymbolPinNumber( modelPinIndex,
1348 std::string( m_sortedPartPins.at( symbolPinIndex )->GetShownNumber().ToUTF8() ) );
1351 updatePinAssignments( &curModel() );
1357template <
typename T_symbol,
typename T_field>
1360 wxGridUpdateLocker deferRepaintsTillLeavingScope( m_pinAssignmentsGrid );
1363 m_pinAssignmentsGrid->SetColSize( PIN_COLUMN::MODEL, gridWidth / 2 );
1364 m_pinAssignmentsGrid->SetColSize( PIN_COLUMN::SYMBOL, gridWidth / 2 );
1370template <
typename T_symbol,
typename T_field>
1376 wxPropertyGrid*
grid = m_paramGrid->GetGrid();
1377 wxPGProperty* selected =
grid->GetSelection();
1380 selected =
grid->wxPropertyGridInterface::GetFirst();
1382#if wxCHECK_VERSION( 3, 3, 0 )
1384 grid->DoSelectProperty( selected, wxPGSelectPropertyFlags::Focus );
1387 grid->DoSelectProperty( selected, wxPG_SEL_FOCUS );
1394template <
typename T_symbol,
typename T_field>
1397 wxPropertyGrid*
grid = m_paramGrid->GetGrid();
1400 if(
grid->GetSelection() &&
grid->GetSelection()->IsCategory() )
1402 wxPGProperty* selection =
grid->GetSelection();
1407 wxPropertyGridIterator it =
grid->GetIterator( wxPG_ITERATE_VISIBLE, selection );
1410 wxKeyEvent* keyEvent =
new wxKeyEvent( wxEVT_KEY_DOWN );
1412 if( *it == m_prevParamGridSelection )
1414 if( !selection->IsExpanded() )
1416 grid->Expand( selection );
1417 keyEvent->m_keyCode = WXK_DOWN;
1418 wxQueueEvent(
grid, keyEvent );
1426 keyEvent->m_keyCode = WXK_UP;
1427 wxQueueEvent(
grid, keyEvent );
1432 if( !selection->IsExpanded() )
1433 grid->Expand( selection );
1435 keyEvent->m_keyCode = WXK_DOWN;
1436 wxQueueEvent(
grid, keyEvent );
1439 m_prevParamGridSelection =
grid->GetSelection();
1443 wxWindow* editorControl =
grid->GetEditorControl();
1445 if( !editorControl )
1447 m_prevParamGridSelection =
grid->GetSelection();
1452 editorControl->SetFocus();
1453 m_prevParamGridSelection =
grid->GetSelection();
1457template <
typename T_symbol,
typename T_field>
1468 wxPropertyGrid*
grid = m_paramGrid->GetGrid();
1469 wxTextCtrl* ctrl =
grid->GetEditorTextCtrl();
1473 wxRect ctrlRect = ctrl->GetScreenRect();
1474 wxRect gridRect =
grid->GetScreenRect();
1476 if( ctrlRect.GetTop() < gridRect.GetTop() || ctrlRect.GetBottom() > gridRect.GetBottom() )
1477 grid->ClearSelection();
1483template <
typename T_symbol,
typename T_field>
1486 wxPropertyGrid*
grid = m_paramGridMgr->GetGrid();
1490 if( aWidth != m_lastParamGridWidth || aForce )
1492 m_lastParamGridWidth = aWidth;
1496 std::vector<int> colWidths;
1498 for(
size_t ii = 0; ii <
grid->GetColumnCount(); ii++ )
1500 if( ii == PARAM_COLUMN::DESCRIPTION )
1501 colWidths.push_back(
grid->GetState()->GetColumnWidth( ii ) + margin + indent );
1502 else if( ii == PARAM_COLUMN::VALUE )
1503 colWidths.push_back( std::max( 72,
grid->GetState()->GetColumnWidth( ii ) ) + margin );
1505 colWidths.push_back( 60 + margin );
1507 aWidth -= colWidths[ ii ];
1510 for(
size_t ii = 0; ii <
grid->GetColumnCount(); ii++ )
1511 grid->SetColumnProportion( ii, colWidths[ ii ] );
1513 grid->ResetColumnSizes();
1514 grid->RefreshEditor();
1519template <
typename T_symbol,
typename T_field>
1522 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_deviceChoice
wxChoice * m_waveformChoice
WX_GRID * m_pinAssignmentsGrid
STD_BITMAP_BUTTON * m_browseButton
wxStyledTextCtrl * m_subckt
wxPropertyGridPage * m_paramGrid
wxChoice * m_deviceTypeChoice
wxStyledTextCtrl * m_codePreview
void onTypeChoice(wxCommandEvent &aEvent) override
void onRadioButton(wxCommandEvent &aEvent) override
void updateBuiltinModelWidgets(SIM_MODEL *aModel)
std::vector< LIB_PIN * > m_sortedPartPins
DIALOG_SIM_MODEL(wxWindow *aParent, T_symbol &aSymbol, std::vector< T_field > &aFields)
bool loadLibrary(const wxString &aLibraryPath, bool aForceReload=false)
wxString getModelPinString(SIM_MODEL *aModel, int aModelPinIndex) const
void removeOrphanedPinAssignments(SIM_MODEL *aModel)
void onWaveformChoice(wxCommandEvent &aEvent) override
void onPinAssignmentsGridCellChange(wxGridEvent &aEvent) override
void onPageChanging(wxNotebookEvent &event) override
void onParamGridSelectionChange(wxPropertyGridEvent &aEvent)
void onUpdateUI(wxUpdateUIEvent &aEvent)
int findSymbolPinRow(const wxString &aSymbolPinNumber) const
void adjustParamGridColumns(int aWidth, bool aForce)
void updateIbisWidgets(SIM_MODEL *aModel)
void onDeviceTypeChoice(wxCommandEvent &aEvent) override
SCINTILLA_TRICKS * m_scintillaTricksSubckt
const SIM_LIBRARY * library() const
SIM_MODEL & curModel() const
int getModelPinIndex(const wxString &aModelPinString) const
void onSizeParamGrid(wxSizeEvent &event) override
void updateModelCodeTab(SIM_MODEL *aModel)
bool TransferDataToWindow() override
void onLibraryPathTextEnter(wxCommandEvent &aEvent) override
void onBrowseButtonClick(wxCommandEvent &aEvent) override
void addParamPropertyIfRelevant(SIM_MODEL *aModel, int aParamIndex)
wxString getSymbolPinString(int aSymbolPinNumber) const
void onPinCombobox(wxCommandEvent &event) override
wxPGProperty * newParamProperty(SIM_MODEL *aModel, int aParamIndex) const
void onPinComboboxTextEnter(wxCommandEvent &event) override
bool TransferDataFromWindow() override
void onDifferentialCheckbox(wxCommandEvent &event) override
void onPinModelComboboxTextEnter(wxCommandEvent &event) override
void onLibraryPathTextKillFocus(wxFocusEvent &aEvent) override
void onModelNameChoice(wxCommandEvent &aEvent) override
void updateModelParamsTab(SIM_MODEL *aModel)
SCINTILLA_TRICKS * m_scintillaTricksCode
void onParamGridSetFocus(wxFocusEvent &aEvent)
void onPinAssignmentsGridSize(wxSizeEvent &aEvent) override
void onPinModelCombobox(wxCommandEvent &event) override
void updatePinAssignments(SIM_MODEL *aModel)
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 const wxString GetProjectPath() const
Return the full path of the project.
Add cut/copy/paste, dark theme, autocomplete and brace highlighting to a wxStyleTextCtrl instance.
bool isPinDiff(const std::string &aComp, const std::string &aPinNumber) const
static constexpr auto DIFF_FIELD
static constexpr auto MODEL_FIELD
static constexpr auto PIN_FIELD
static constexpr auto LIBRARY_FIELD
static constexpr auto NAME_FIELD
bool ChangePin(const SIM_LIBRARY_KIBIS &aLib, std::string aPinNumber)
update the list of available models based on the pin number.
std::vector< std::string > GetIbisModels() const
std::string GetComponentName() const
bool CanDifferential() const
void SwitchSingleEndedDiff(bool aDiff) override
std::vector< std::pair< std::string, std::string > > GetIbisPins() const
std::string GetSpiceCode() const
static bool InferSimModel(T_symbol &aSymbol, std::vector< T_field > *aFields, bool aResolve, SIM_VALUE_GRAMMAR::NOTATION aNotation, wxString *aDeviceType, wxString *aModelType, wxString *aModelParams, wxString *aPinMap)
static INFO TypeInfo(TYPE aType)
void ReadDataFields(const std::vector< T > *aFields, const std::vector< LIB_PIN * > &aPins)
static void SetFieldValue(std::vector< T > &aFields, const wxString &aFieldName, const std::string &aValue)
const SPICE_GENERATOR & SpiceGenerator() const
static std::string GetFieldValue(const std::vector< T > *aFields, const wxString &aFieldName, bool aResolve=true)
virtual const PARAM & GetParam(unsigned aParamIndex) const
static TYPE ReadTypeFromFields(const std::vector< T > &aFields, REPORTER &aReporter)
int GetParamCount() const
void SetPinSymbolPinNumber(int aPinIndex, const std::string &aSymbolPinNumber)
DEVICE_INFO GetDeviceInfo() const
DEVICE_T GetDeviceType() const
static DEVICE_INFO DeviceInfo(DEVICE_T aDeviceType)
const PIN & GetPin(unsigned aIndex) const
virtual bool HasAutofill() const
virtual bool HasPrimaryValue() const
const SIM_MODEL::PARAM & GetParam() const
virtual std::string Preview(const SPICE_ITEM &aItem) const
A wrapper for reporting to a wxString object.
bool HasMessage() const override
Returns true if the reporter client is non-empty.
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)
wxFont GetInfoFont(wxWindow *aWindow)
BITMAPS PinShapeGetBitmap(GRAPHIC_PINSHAPE aShape)
#define SIM_DEVICE_TYPE_FIELD
#define SIM_REFERENCE_FIELD
std::vector< FAB_LAYER_COLOR > dummy
std::vector< std::string > enumValues
std::string symbolPinNumber
static constexpr auto NOT_CONNECTED
@ VALUE_FIELD
Field Value of part, i.e. "3.3K".
@ REFERENCE_FIELD
Field Reference of part, i.e. "IC21".