30#include <wx/tokenzr.h>
37static bool empty(
const wxTextEntryBase* aCtrl )
39 return aCtrl->GetValue().IsEmpty();
45 aCtrl->SetSelection( aCtrl->FindString( aStr ) );
51 if( aCtrl->GetSelection() >= 0 )
52 return aCtrl->GetString( aCtrl->GetSelection() );
59 std::shared_ptr<SPICE_CIRCUIT_MODEL> aCircuitModel,
60 std::shared_ptr<SPICE_SETTINGS>& aSettings ) :
120 if( item.model->GetDeviceType() == SIM_MODEL::DEVICE_T::V )
127 int minWidth = GetTextExtent( wxS(
"XXX.XXXXXXX" ) ).x;
128 m_y1Min->SetMinSize( wxSize( minWidth, -1 ) );
129 m_y1Max->SetMinSize( wxSize( minWidth, -1 ) );
130 m_y2Min->SetMinSize( wxSize( minWidth, -1 ) );
131 m_y2Max->SetMinSize( wxSize( minWidth, -1 ) );
132 m_y3Min->SetMinSize( wxSize( minWidth, -1 ) );
133 m_y3Max->SetMinSize( wxSize( minWidth, -1 ) );
153 switch( settings->GetCompatibilityMode() )
161 default: wxFAIL_MSG( wxString::Format(
"Unknown NGSPICE_COMPATIBILITY_MODE %d.",
162 settings->GetCompatibilityMode() ) );
break;
172 event.Enable(
m_lockY1->GetValue() );
178 event.Enable(
m_lockY2->GetValue() );
184 event.Enable(
m_lockY3->GetValue() );
192 if( !plotTab->GetLabelY1().IsEmpty() )
195 m_lockY1->SetLabel( wxString::Format(
m_lockY1->GetLabel(), plotTab->GetLabelY1() ) );
196 m_y1Units->SetLabel( plotTab->GetUnitsY1() );
198 double min = 0.0, max = 0.0;
199 bool locked = plotTab->GetY1Scale( &min, &max );
202 if( !std::isnan( min ) )
205 if( !std::isnan( max ) )
209 if( !plotTab->GetLabelY2().IsEmpty() )
212 m_lockY2->SetLabel( wxString::Format(
m_lockY2->GetLabel(), plotTab->GetLabelY2() ) );
213 m_y2Units->SetLabel( plotTab->GetUnitsY2() );
215 double min = 0.0, max = 0.0;
216 bool locked = plotTab->GetY2Scale( &min, &max );
219 if( !std::isnan( min ) )
222 if( !std::isnan( max ) )
226 if( !plotTab->GetLabelY3().IsEmpty() )
229 m_lockY3->SetLabel( wxString::Format(
m_lockY3->GetLabel(), plotTab->GetLabelY3() ) );
230 m_y3Units->SetLabel( plotTab->GetUnitsY3() );
232 double min = 0.0, max = 0.0;
233 bool locked = plotTab->GetY3Scale( &min, &max );
236 if( !std::isnan( min ) )
239 if( !std::isnan( max ) )
243 m_grid->SetValue( plotTab->IsGridShown() );
244 m_legend->SetValue( plotTab->IsLegendShown() );
247#define GET_STR( val ) EDA_UNIT_UTILS::UI::MessageTextFromValue( unityScale, EDA_UNITS::UNSCALED, \
259 wxTextCtrl* aDcStop, wxTextCtrl* aDcIncr )
262 wxWindow* ctrlWithError =
nullptr;
264 if( aDcSource->GetSelection() >= 0 )
265 dcSource = aDcSource->GetString( aDcSource->GetSelection() );
267 if( dcSource.IsEmpty() )
270 ctrlWithError = aDcSource;
272 else if( !aDcStart->Validate() )
273 ctrlWithError = aDcStart;
274 else if( !aDcStop->Validate() )
275 ctrlWithError = aDcStop;
276 else if( !aDcIncr->Validate() )
277 ctrlWithError = aDcIncr;
281 ctrlWithError->SetFocus();
282 return wxEmptyString;
286 if( dcSource.Cmp(
"TEMP" ) )
289 return wxString::Format(
"%s %s %s %s", dcSource,
298 if( !wxDialog::TransferDataFromWindow() )
316 wxWindow* page =
m_simPages->GetCurrentPage();
342 wxString simCmd = wxString(
".dc " );
358 simCmd +=
" " + src2;
362 DisplayError(
this,
_(
"Source 1 and Source 2 must be different." ) );
381 m_simCommand = wxT(
"linearize" ) + vectors + wxS(
"\n" );
387 wxString input =
m_pzInput->GetStringSelection();
391 wxString transferFunction = wxS(
"vol" );
392 wxString analyses = wxS(
"pz" );
395 transferFunction = wxS(
"cur" );
398 analyses = wxS(
"pol" );
400 analyses = wxS(
"zer" );
413 wxString ref =
m_noiseRef->GetStringSelection();
414 wxString noiseSource =
m_noiseSrc->GetStringSelection();
418 DisplayError(
this,
_(
"A frequency range must be specified." ) );
425 m_simCommand.Printf(
".noise v(%s%s) %s %s %s %s %s %s",
444 const wxString spc = wxS(
" " );
456 optionals = wxS(
"uic" );
462 else if( !optionals.IsEmpty() )
464 SPICE_VALUE maxStep = ( finalTime - startTime ) / 50.0;
466 if( maxStep > timeStep )
474 else if( !optionals.IsEmpty() )
475 optionals = wxS(
"0 " ) + optionals;
520#define TO_INT( ctrl ) (int) EDA_UNIT_UTILS::UI::ValueFromString( unityScale, EDA_UNITS::UNSCALED, \
525 if( !plotTab->GetLabelY1().IsEmpty() )
527 plotTab->SetY1Scale(
m_lockY1->GetValue(),
532 if( !plotTab->GetLabelY2().IsEmpty() )
534 plotTab->SetY2Scale(
m_lockY2->GetValue(),
539 if( !plotTab->GetLabelY3().IsEmpty() )
541 plotTab->SetY3Scale(
m_lockY3->GetValue(),
546 plotTab->GetPlotWin()->LockY(
m_lockY1->GetValue()
550 plotTab->ShowGrid(
m_grid->GetValue() );
551 plotTab->ShowLegend(
m_legend->GetValue() );
559 plotTab->GetPlotWin()->AdjustLimitedView();
560 plotTab->GetPlotWin()->UpdateAll();
567 wxString prevSelection;
569 if( !aSource->IsEmpty() && aSource->GetSelection() >= 0 )
570 prevSelection = aSource->GetString( aSource->GetSelection() );
572 std::set<wxString> sourcesList;
573 bool enableSrcSelection =
true;
579 if( ( aType ==
'R' && item.model->GetDeviceType() == SIM_MODEL::DEVICE_T::R )
580 || ( aType ==
'V' && item.model->GetDeviceType() == SIM_MODEL::DEVICE_T::V )
581 || ( aType ==
'I' && item.model->GetDeviceType() == SIM_MODEL::DEVICE_T::I ) )
583 sourcesList.insert( item.refName );
588 enableSrcSelection =
false;
592 prevSelection = wxT(
"TEMP" );
593 sourcesList.insert( prevSelection );
594 enableSrcSelection =
false;
597 aSource->Enable( enableSrcSelection );
601 for(
const wxString& src : sourcesList )
602 aSource->Append( src );
605 aSource->SetStringSelection( prevSelection );
611 if( aCommand.IsEmpty() )
614 if( aCommand == wxT(
"*" ) )
616 SetTitle(
_(
"New Simulation Tab" ) );
642 wxStringTokenizer tokenizer( aCommand,
" \t\r\n", wxTOKEN_STRTOK );
643 wxString token = tokenizer.GetNextToken().Lower();
650 token = tokenizer.GetNextToken().Lower();
669 token = tokenizer.GetNextToken().Lower();
684 if( tokenizer.HasMoreTokens() )
698 if( src1.
m_source.IsSameAs( wxT(
"TEMP" ),
false ) )
711 if( src2.
m_source.IsSameAs( wxT(
"TEMP" ),
false ) )
732 wxString transferFunction;
733 wxString input, inputRef;
734 wxString
output, outputRef;
738 &outputRef, &analyses );
745 m_pzFunctionType->SetSelection( transferFunction.Lower() ==
"cur" ? 1 : 0 );
771 &fStart, &fStop, &saveAll );
802 token = tokenizer.GetNextToken();
804 if( !token.IsEmpty() )
808 token = tokenizer.GetNextToken();
810 if( !token.IsEmpty() )
814 token = tokenizer.GetNextToken();
816 if( token.IsSameAs( wxS(
"uic" ) ) )
829 while( tokenizer.HasMoreTokens() )
847 wxString str =
m_commandType->GetString( event.GetSelection() );
876 for(
auto& couple : textCtrl )
878 wxString tmp = couple.first->GetValue();
879 couple.first->SetValue( couple.second->GetValue() );
880 couple.second->SetValue( tmp );
924 if( is2ndSrcEnabled )
928 if( fullType.Length() > 0 )
929 type = fullType.GetChar( 0 );
933 m_dcSource2->Enable( is2ndSrcEnabled && type !=
'T' );
941 wxStaticText* aEndValUnit, wxStaticText* aStepUnit )
947 case 'V': unit = wxS(
"V" );
break;
948 case 'I': unit = wxS(
"A" );
break;
949 case 'R': unit = wxS(
"Ω" );
break;
950 case 'T': unit = wxS(
"°C" );
break;
953 aStartValUnit->SetLabel( unit );
954 aEndValUnit->SetLabel( unit );
955 aStepUnit->SetLabel( unit );
982 if( aFilter.IsEmpty() )
983 aFilter = wxS(
"*" );
989 if( matcher.
Find( signal.Upper() ) )
1002#if defined( __WXOSX__ )
1003 wxPoint pos = aEvent.GetPosition();
1005 int buttonWidth = ctrlRect.GetHeight();
1008 SetCursor( wxCURSOR_ARROW );
1010 && pos.x > ctrlRect.GetWidth() - buttonWidth )
1011 SetCursor( wxCURSOR_ARROW );
1013 SetCursor( wxCURSOR_IBEAM );
void SetupStandardButtons(std::map< int, wxString > aLabels={})
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
DIALOG_SIM_COMMAND_BASE(wxWindow *parent, wxWindowID id=wxID_ANY, const wxString &title=_("Simulation Analysis"), const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxSize(-1,-1), long style=wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER)
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
wxCheckBox * m_saveAllEvents
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)
Look in all existing matchers, return the earliest match of any of the existing.
Container for Ngspice simulator settings.
The SIMULATOR_FRAME holds the main user-interface for running simulations.
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)
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)
Abstract pattern-matching tool and implementations.
SIM_TYPE
< Possible simulation types