33#include <wx/tokenzr.h>
40static bool empty(
const wxTextEntryBase* aCtrl )
42 return aCtrl->GetValue().IsEmpty();
48 aCtrl->SetSelection( aCtrl->FindString( aStr ) );
54 return aCtrl->GetString( aCtrl->GetSelection() );
59 std::shared_ptr<SPICE_CIRCUIT_MODEL> aCircuitModel,
60 std::shared_ptr<SPICE_SETTINGS>& aSettings ) :
62 m_simulatorFrame( aParent ),
63 m_circuitModel( aCircuitModel ),
64 m_settings( aSettings ),
65 m_spiceEmptyValidator( true )
118 if( item.model->GetDeviceType() == SIM_MODEL::DEVICE_T::V )
125 int minWidth = GetTextExtent( wxS(
"XXX.XXXXXXX" ) ).x;
126 m_y1Min->SetMinSize( wxSize( minWidth, -1 ) );
127 m_y1Max->SetMinSize( wxSize( minWidth, -1 ) );
128 m_y2Min->SetMinSize( wxSize( minWidth, -1 ) );
129 m_y2Max->SetMinSize( wxSize( minWidth, -1 ) );
130 m_y3Min->SetMinSize( wxSize( minWidth, -1 ) );
131 m_y3Max->SetMinSize( wxSize( minWidth, -1 ) );
150 switch( settings->GetCompatibilityMode() )
152 case NGSPICE_COMPATIBILITY_MODE::USER_CONFIG:
m_compatibilityMode->SetSelection( 0 );
break;
158 default: wxFAIL_MSG( wxString::Format(
"Unknown NGSPICE_COMPATIBILITY_MODE %d.",
159 settings->GetCompatibilityMode() ) );
break;
169 event.Enable(
m_lockY1->GetValue() );
175 event.Enable(
m_lockY2->GetValue() );
181 event.Enable(
m_lockY3->GetValue() );
189 if( !plotTab->GetLabelY1().IsEmpty() )
192 m_lockY1->SetLabel( wxString::Format(
m_lockY1->GetLabel(), plotTab->GetLabelY1() ) );
193 m_y1Units->SetLabel( plotTab->GetUnitsY1() );
196 bool locked = plotTab->GetY1Scale( &min, &max );
199 if( !std::isnan( min ) )
202 if( !std::isnan( max ) )
206 if( !plotTab->GetLabelY2().IsEmpty() )
209 m_lockY2->SetLabel( wxString::Format(
m_lockY2->GetLabel(), plotTab->GetLabelY2() ) );
210 m_y2Units->SetLabel( plotTab->GetUnitsY2() );
213 bool locked = plotTab->GetY2Scale( &min, &max );
216 if( !std::isnan( min ) )
219 if( !std::isnan( max ) )
223 if( !plotTab->GetLabelY3().IsEmpty() )
226 m_lockY3->SetLabel( wxString::Format(
m_lockY3->GetLabel(), plotTab->GetLabelY3() ) );
227 m_y3Units->SetLabel( plotTab->GetUnitsY3() );
230 bool locked = plotTab->GetY3Scale( &min, &max );
233 if( !std::isnan( min ) )
236 if( !std::isnan( max ) )
240 m_grid->SetValue( plotTab->IsGridShown() );
241 m_legend->SetValue( plotTab->IsLegendShown() );
244#define GET_STR( val ) EDA_UNIT_UTILS::UI::MessageTextFromValue( unityScale, EDA_UNITS::UNSCALED, \
256 wxTextCtrl* aDcStop, wxTextCtrl* aDcIncr )
259 wxWindow* ctrlWithError =
nullptr;
261 if( aDcSource->GetSelection() >= 0 )
262 dcSource = aDcSource->GetString( aDcSource->GetSelection() );
264 if( dcSource.IsEmpty() )
267 ctrlWithError = aDcSource;
269 else if( !aDcStart->Validate() )
270 ctrlWithError = aDcStart;
271 else if( !aDcStop->Validate() )
272 ctrlWithError = aDcStop;
273 else if( !aDcIncr->Validate() )
274 ctrlWithError = aDcIncr;
278 ctrlWithError->SetFocus();
279 return wxEmptyString;
283 if( dcSource.Cmp(
"TEMP" ) )
284 dcSource =
m_circuitModel->GetItemName( std::string( dcSource.ToUTF8() ) );
286 return wxString::Format(
"%s %s %s %s", dcSource,
295 if( !wxDialog::TransferDataFromWindow() )
303 case 0: settings->SetCompatibilityMode( NGSPICE_COMPATIBILITY_MODE::USER_CONFIG );
break;
304 case 1: settings->SetCompatibilityMode( NGSPICE_COMPATIBILITY_MODE::NGSPICE );
break;
305 case 2: settings->SetCompatibilityMode( NGSPICE_COMPATIBILITY_MODE::PSPICE );
break;
306 case 3: settings->SetCompatibilityMode( NGSPICE_COMPATIBILITY_MODE::LTSPICE );
break;
307 case 4: settings->SetCompatibilityMode( NGSPICE_COMPATIBILITY_MODE::LT_PSPICE );
break;
308 case 5: settings->SetCompatibilityMode( NGSPICE_COMPATIBILITY_MODE::HSPICE );
break;
313 wxWindow* page =
m_simPages->GetCurrentPage();
339 wxString simCmd = wxString(
".dc " );
355 simCmd +=
" " + src2;
359 DisplayError(
this,
_(
"Source 1 and Source 2 must be different." ) );
377 m_simCommand = wxT(
"linearize" ) + vectors + wxS(
"\n" );
383 wxString input =
m_pzInput->GetStringSelection();
385 wxString output =
m_pzOutput->GetStringSelection();
387 wxString transferFunction = wxS(
"vol" );
388 wxString analyses = wxS(
"pz" );
391 transferFunction = wxS(
"cur" );
394 analyses = wxS(
"pol" );
396 analyses = wxS(
"zer" );
408 wxString output =
m_noiseMeas->GetStringSelection();
409 wxString ref =
m_noiseRef->GetStringSelection();
410 wxString noiseSource =
m_noiseSrc->GetStringSelection();
414 DisplayError(
this,
_(
"A frequency range must be specified." ) );
419 ref = wxS(
"," ) +
m_circuitModel->GetItemName( std::string( ref.ToUTF8() ) );
421 m_simCommand.Printf(
".noise v(%s%s) %s %s %s %s %s %s",
440 const wxString spc = wxS(
" " );
452 optionals = wxS(
"uic" );
458 else if( !optionals.IsEmpty() )
460 SPICE_VALUE maxStep = ( finalTime - startTime ) / 50.0;
462 if( maxStep > timeStep )
470 else if( !optionals.IsEmpty() )
471 optionals = wxS(
"0 " ) + optionals;
512#define TO_INT( ctrl ) (int) EDA_UNIT_UTILS::UI::ValueFromString( unityScale, EDA_UNITS::UNSCALED, \
517 if( !plotTab->GetLabelY1().IsEmpty() )
519 plotTab->SetY1Scale(
m_lockY1->GetValue(),
524 if( !plotTab->GetLabelY2().IsEmpty() )
526 plotTab->SetY2Scale(
m_lockY2->GetValue(),
531 if( !plotTab->GetLabelY3().IsEmpty() )
533 plotTab->SetY3Scale(
m_lockY3->GetValue(),
538 plotTab->GetPlotWin()->LockY(
m_lockY1->GetValue()
542 plotTab->ShowGrid(
m_grid->GetValue() );
543 plotTab->ShowLegend(
m_legend->GetValue() );
551 plotTab->GetPlotWin()->AdjustLimitedView();
552 plotTab->GetPlotWin()->UpdateAll();
559 wxString prevSelection;
561 if( !aSource->IsEmpty() )
562 prevSelection = aSource->GetString( aSource->GetSelection() );
564 std::set<wxString> sourcesList;
565 bool enableSrcSelection =
true;
571 if( ( aType ==
'R' && item.model->GetDeviceType() == SIM_MODEL::DEVICE_T::R )
572 || ( aType ==
'V' && item.model->GetDeviceType() == SIM_MODEL::DEVICE_T::V )
573 || ( aType ==
'I' && item.model->GetDeviceType() == SIM_MODEL::DEVICE_T::I ) )
575 sourcesList.insert( item.refName );
580 enableSrcSelection =
false;
584 prevSelection = wxT(
"TEMP" );
585 sourcesList.insert( prevSelection );
586 enableSrcSelection =
false;
589 aSource->Enable( enableSrcSelection );
593 for(
const wxString& src : sourcesList )
594 aSource->Append( src );
597 aSource->SetStringSelection( prevSelection );
603 if( aCommand.IsEmpty() )
606 if( aCommand == wxT(
"*" ) )
608 SetTitle(
_(
"New Simulation Tab" ) );
633 wxStringTokenizer tokenizer( aCommand, wxS(
" \t\n\r" ), wxTOKEN_STRTOK );
634 wxString token = tokenizer.GetNextToken().Lower();
641 token = tokenizer.GetNextToken().Lower();
660 token = tokenizer.GetNextToken().Lower();
675 if( tokenizer.HasMoreTokens() )
689 if( src1.
m_source.IsSameAs( wxT(
"TEMP" ),
false ) )
702 if( src2.
m_source.IsSameAs( wxT(
"TEMP" ),
false ) )
723 wxString transferFunction;
724 wxString input, inputRef;
725 wxString output, outputRef;
728 m_circuitModel->ParsePZCommand( aCommand, &transferFunction, &input, &inputRef, &output,
729 &outputRef, &analyses );
736 m_pzFunctionType->SetSelection( transferFunction.Lower() ==
"cur" ? 1 : 0 );
762 &fStart, &fStop, &saveAll );
793 token = tokenizer.GetNextToken();
795 if( !token.IsEmpty() )
799 token = tokenizer.GetNextToken();
801 if( !token.IsEmpty() )
805 token = tokenizer.GetNextToken();
807 if( token.IsSameAs( wxS(
"uic" ) ) )
820 while( tokenizer.HasMoreTokens() )
836 wxString str =
m_commandType->GetString( event.GetSelection() );
865 for(
auto& couple : textCtrl )
867 wxString tmp = couple.first->GetValue();
868 couple.first->SetValue( couple.second->GetValue() );
869 couple.second->SetValue( tmp );
914 m_dcSource2->Enable( is2ndSrcEnabled && type !=
'T' );
922 wxStaticText* aEndValUnit, wxStaticText* aStepUnit )
928 case 'V': unit = wxS(
"V" );
break;
929 case 'I': unit = wxS(
"A" );
break;
930 case 'R': unit = wxS(
"Ω" );
break;
931 case 'T': unit = wxS(
"°C" );
break;
934 aStartValUnit->SetLabel( unit );
935 aEndValUnit->SetLabel( unit );
936 aStepUnit->SetLabel( unit );
963 if( aFilter.IsEmpty() )
964 aFilter = wxS(
"*" );
970 if( matcher.
Find( signal.Upper() ) )
983 wxPoint pos = aEvent.GetPosition();
985 int buttonWidth = ctrlRect.GetHeight();
988 SetCursor( wxCURSOR_ARROW );
989 else if(
m_inputSignalsFilter->IsCancelButtonVisible() && pos.x > ctrlRect.GetWidth() - buttonWidth )
990 SetCursor( wxCURSOR_ARROW );
992 SetCursor( wxCURSOR_IBEAM );
void SetupStandardButtons(std::map< int, wxString > aLabels={})
Class DIALOG_SIM_COMMAND_BASE.
wxTextCtrl * m_transMaxStep
wxTextCtrl * m_marginLeft
wxBoxSizer * m_compatibilityModeSizer
wxCheckListBox * m_inputSignalsList
wxTextCtrl * m_noisePointsNumber
wxChoice * m_dcSourceType2
wxRadioBox * m_noiseScale
wxStaticText * m_src1DCStartValUnit
wxTextCtrl * m_transFinal
wxTextCtrl * m_spPointsNumber
wxTextCtrl * m_noiseFreqStart
wxStaticText * m_src1DCStepUnit
wxSimplebook * m_simPages
wxCheckBox * m_dottedSecondary
wxCheckBox * m_useInitialConditions
wxTextCtrl * m_spFreqStop
wxChoice * m_dcSourceType1
wxBoxSizer * m_commandTypeSizer
wxSearchCtrl * m_inputSignalsFilter
wxStaticText * m_src2DCStepUnit
wxStaticText * m_src2DCStartValUnit
wxTextCtrl * m_acFreqStart
wxChoice * m_compatibilityMode
wxTextCtrl * m_marginBottom
wxTextCtrl * m_marginRight
wxCheckBox * m_saveAllNoise
wxTextCtrl * m_spFreqStart
wxTextCtrl * m_noiseFreqStop
wxCheckBox * m_fixIncludePaths
wxStaticText * m_src2DCEndValUnit
wxCheckBox * m_saveAllCurrents
wxChoice * m_pzFunctionType
wxCheckBox * m_saveAllVoltages
wxTextCtrl * m_transInitial
wxCheckBox * m_saveAllDissipations
wxStaticText * m_src1DCEndValUnit
wxTextCtrl * m_acFreqStop
wxTextCtrl * m_acPointsNumber
wxString evaluateDCControls(wxChoice *aDcSource, wxTextCtrl *aDcStart, wxTextCtrl *aDcStop, wxTextCtrl *aDcIncr)
Read values from one DC sweep source to form a part of simulation command.
void onSwapDCSources(wxCommandEvent &event) override
static wxString scaleToString(int aOption)
void SetPlotSettings(const SIM_TAB *aSimTab)
void OnCommandType(wxCommandEvent &event) override
void OnFilterMouseMoved(wxMouseEvent &event) override
wxIntegerValidator< int > m_posIntValidator
void onDCSource2Selected(wxCommandEvent &event) override
void OnUpdateUILockY3(wxUpdateUIEvent &event) override
bool TransferDataFromWindow() override
void updateDCSources(wxChar aType, wxChoice *aSource)
Update DC sweep source with symbols from schematic.
void OnUpdateUILockY1(wxUpdateUIEvent &event) override
std::set< wxString > m_fftInputSignals
SPICE_VALIDATOR m_spiceValidator
void onDCEnableSecondSource(wxCommandEvent &event) override
void ApplySettings(SIM_TAB *aTab)
SIMULATOR_FRAME * m_simulatorFrame
void onDCSource1Selected(wxCommandEvent &event) override
void parseCommand(const wxString &aCommand)
Parse a Spice directive.
bool TransferDataToWindow() override
void updateDCUnits(wxChar aType, wxStaticText *aStartValUnit, wxStaticText *aEndValUnit, wxStaticText *aStepUnit)
Update units on labels depending on selected source.
void OnFilterText(wxCommandEvent &event) override
std::shared_ptr< SPICE_CIRCUIT_MODEL > m_circuitModel
DIALOG_SIM_COMMAND(SIMULATOR_FRAME *aParent, std::shared_ptr< SPICE_CIRCUIT_MODEL > aCircuitModel, std::shared_ptr< SPICE_SETTINGS > &aSettings)
std::shared_ptr< SPICE_SETTINGS > m_settings
void OnUpdateUILockY2(wxUpdateUIEvent &event) override
SPICE_VALIDATOR m_spiceEmptyValidator
bool Find(const wxString &aTerm, int &aMatchersTriggered, int &aPosition)
Container for Ngspice simulator settings.
The SIMULATOR_FRAME holds the main user-interface for running simulations.
const std::vector< wxString > Signals()
void SetSimOptions(int aOptions)
static std::string Normalize(double aValue)
static double ToDouble(const std::string &aString, double aDefault=NAN)
static SIM_TYPE CommandToSimType(const wxString &aCmd)
Return simulation type basing on a simulation command directive.
static wxString TypeToName(SIM_TYPE aType, bool aShortName)
Return a string with simulation name based on enum.
Helper class to recognize Spice formatted values.
wxString ToSpiceString() const
Return string value in Spice format (e.g.
void DisplayError(wxWindow *aParent, const wxString &aText, int aDisplayTime)
Display an error or warning message box with aMessage.
This file is part of the common library.
static void setStringSelection(wxChoice *aCtrl, const wxString &aStr)
static wxString getStringSelection(const wxChoice *aCtrl)
static bool empty(const wxTextEntryBase *aCtrl)
SIM_TYPE
< Possible simulation types