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();
389 wxString output =
m_pzOutput->GetStringSelection();
391 wxString transferFunction = wxS(
"vol" );
392 wxString analyses = wxS(
"pz" );
395 transferFunction = wxS(
"cur" );
398 analyses = wxS(
"pol" );
400 analyses = wxS(
"zer" );
412 wxString output =
m_noiseMeas->GetStringSelection();
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;
737 m_circuitModel->ParsePZCommand( aCommand, &transferFunction, &input, &inputRef, &output,
738 &outputRef, &analyses );
745 m_pzFunctionType->SetSelection( transferFunction.Lower() ==
"cur" ? 1 : 0 );
768 bool saveAll =
false;
771 &fStart, &fStop, &saveAll );
802 token = tokenizer.GetNextToken();
804 if( token.IsSameAs( wxS(
"uic" ),
false ) )
806 else if( !token.IsEmpty() )
809 token = tokenizer.GetNextToken();
811 if( token.IsSameAs( wxS(
"uic" ),
false ) )
813 else if( !token.IsEmpty() )
816 token = tokenizer.GetNextToken();
818 if( token.IsSameAs( wxS(
"uic" ),
false ) )
830 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 handle Spice way of expressing values (e.g. 10.5 Meg)
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.