29#include <fmt/format.h>
30#include <wx/wfstream.h>
31#include <wx/stdstream.h>
33#include <wx/clipbrd.h>
59 int res = (int) aFirst | (
int) aSecond;
120 void showPopupMenu( wxMenu& menu, wxGridEvent& aEvent )
override;
144 if( panel->GetSimType() ==
ST_TRAN || panel->GetSimType() ==
ST_AC
145 || panel->GetSimType() ==
ST_DC || panel->GetSimType() ==
ST_SP )
153 if( panel->GetSimType() ==
ST_AC || panel->GetSimType() ==
ST_SP )
166 if( panel->GetSimType() ==
ST_TRAN )
168 menu.AppendSeparator();
169 menu.Append(
MYID_FOURIER,
_(
"Perform Fourier Analysis..." ) );
172 menu.AppendSeparator();
175 m_grid->PopupMenu( &menu );
184 std::vector<wxString> signals;
186 wxGridCellCoordsArray cells1 =
m_grid->GetSelectionBlockTopLeft();
187 wxGridCellCoordsArray cells2 =
m_grid->GetSelectionBlockBottomRight();
189 for(
size_t i = 0; i < cells1.Count(); i++ )
193 for(
int j = cells1[i].GetRow(); j < cells2[i].GetRow() + 1; j++ )
195 signals.push_back(
m_grid->GetCellValue( j, cells1[i].GetCol() ) );
200 wxGridCellCoordsArray cells3 =
m_grid->GetSelectedCells();
202 for(
size_t i = 0; i < cells3.Count(); i++ )
205 signals.push_back(
m_grid->GetCellValue( cells3[i].GetRow(), cells3[i].GetCol() ) );
208 if( signals.size() < 1 )
211 auto addMeasurement =
212 [
this](
const wxString& cmd, wxString signal )
214 if( signal.EndsWith(
_(
" (phase)" ) ) )
217 if( signal.EndsWith(
_(
" (gain)" ) ) || signal.EndsWith(
_(
" (amplitude)" ) ) )
219 signal = signal.Left( signal.length() - 7 );
221 if( signal.Upper().StartsWith( wxS(
"V(" ) ) )
222 signal = wxS(
"vdb" ) + signal.Mid( 1 );
230 for(
const wxString& signal : signals )
231 addMeasurement( wxS(
"MIN" ), signal );
235 for(
const wxString& signal : signals )
236 addMeasurement( wxS(
"MAX" ), signal );
240 for(
const wxString& signal : signals )
241 addMeasurement( wxS(
"AVG" ), signal );
245 for(
const wxString& signal : signals )
246 addMeasurement( wxS(
"RMS" ), signal );
250 for(
const wxString& signal : signals )
251 addMeasurement( wxS(
"PP" ), signal );
255 for(
const wxString& signal : signals )
256 addMeasurement( wxS(
"MIN_AT" ), signal );
260 for(
const wxString& signal : signals )
261 addMeasurement( wxS(
"MAX_AT" ), signal );
265 for(
const wxString& signal : signals )
266 addMeasurement( wxS(
"INTEG" ), signal );
271 wxString fundamental = wxT(
"1K" );
273 if( signals.size() == 1 )
274 title.Printf(
_(
"Fourier Analysis of %s" ), signals[0] );
276 title =
_(
"Fourier Analyses of Multiple Signals" );
286 for(
const wxString& signal : signals )
294 for(
const wxString& signal : signals )
302 if( wxTheClipboard->Open() )
304 wxTheClipboard->SetData(
new wxTextDataObject( txt ) );
305 wxTheClipboard->Flush();
306 wxTheClipboard->Close();
323 void showPopupMenu( wxMenu& menu, wxGridEvent& aEvent )
override;
343 menu.AppendSeparator();
353 [
this](
int row ) -> wxString
357 if( signal.EndsWith(
"[2 - 1]" ) )
358 signal = signal.Left( signal.length() - 7 );
369 if( formatDialog.
ShowModal() == wxID_OK )
371 for(
int row = 0; row <
m_grid->GetNumberRows(); ++row )
373 if( getSignalName( row ) == getSignalName(
m_menuRow ) )
396 void showPopupMenu( wxMenu& menu, wxGridEvent& aEvent )
override;
422 menu.AppendSeparator();
435 if( formatDialog.
ShowModal() == wxID_OK )
444 std::vector<int> measurements;
446 wxGridCellCoordsArray cells1 =
m_grid->GetSelectionBlockTopLeft();
447 wxGridCellCoordsArray cells2 =
m_grid->GetSelectionBlockBottomRight();
449 for(
size_t i = 0; i < cells1.Count(); i++ )
453 for(
int j = cells1[i].GetRow(); j < cells2[i].GetRow() + 1; j++ )
454 measurements.push_back( j );
458 wxGridCellCoordsArray cells3 =
m_grid->GetSelectedCells();
460 for(
size_t i = 0; i < cells3.Count(); i++ )
463 measurements.push_back( cells3[i].GetRow() );
466 if( measurements.size() < 1 )
471 sort( measurements.begin(), measurements.end(), std::greater<>() );
473 for(
int row : measurements )
506#define ID_SIM_REFRESH 10207
507#define REFRESH_INTERVAL 50
513 m_SuppressGridEvents( 0 ),
514 m_simulatorFrame( aSimulatorFrame ),
515 m_schematicFrame( aSchematicFrame ),
533 wxGridCellAttr* attr =
new wxGridCellAttr;
537 attr =
new wxGridCellAttr;
541 attr =
new wxGridCellAttr;
545 attr =
new wxGridCellAttr;
549 for(
int cursorId = 0; cursorId < 3; ++cursorId )
555 attr =
new wxGridCellAttr;
565 [&]( wxTimerEvent& aEvent )
574#ifndef wxHAS_NATIVE_TABART
592 for(
int ii = 0; ii < (int)
m_plotNotebook->GetPageCount(); ++ii )
596 simTab->OnLanguageChanged();
598 wxString pageTitle(
simulator()->TypeToName( simTab->GetSimType(),
true ) );
599 pageTitle.Prepend( wxString::Format(
_(
"Analysis %u - " ), ii+1 ) );
620 tuner->ShowChangedLanguage();
658 for( std::size_t i = 0; i < pageCount; ++i )
661 auto simTab =
dynamic_cast<SIM_TAB*
>( page );
662 wxASSERT( simTab !=
nullptr );
663 simTab->ApplyPreferences( aPrefs );
670 if( !
simulator()->Settings()->GetWorkbookFilename().IsEmpty() )
672 wxFileName filename =
simulator()->Settings()->GetWorkbookFilename();
676 simulator()->Settings()->SetWorkbookFilename(
"" );
680 wxString schTextSimCommand =
circuitModel()->GetSchTextSimCommand();
682 if( !schTextSimCommand.IsEmpty() )
715 std::sort( signals.begin(), signals.end(),
716 [](
const wxString& lhs,
const wxString& rhs )
719 if( lhs.Upper().StartsWith(
'V' ) && !rhs.Upper().StartsWith(
'V' ) )
721 else if( !lhs.Upper().StartsWith(
'V' ) && rhs.Upper().StartsWith(
'V' ) )
724 return StrNumCmp( lhs, rhs, true ) < 0;
741 std::vector<wxString> signals;
745 wxStringTokenizer tokenizer( plotPanel->
GetSimCommand(), wxT(
" \t\r\n" ), wxTOKEN_STRTOK );
747 while( tokenizer.HasMoreTokens() && tokenizer.GetNextToken().Lower() != wxT(
"fft" ) )
750 while( tokenizer.HasMoreTokens() )
751 signals.emplace_back( tokenizer.GetNextToken() );
758 for(
const wxString& signal :
m_signals )
759 signals.push_back( signal );
763 if( simType ==
ST_AC )
765 signals.push_back( signal +
_(
" (gain)" ) );
766 signals.push_back( signal +
_(
" (phase)" ) );
768 else if( simType ==
ST_SP )
770 signals.push_back( signal +
_(
" (amplitude)" ) );
771 signals.push_back( signal +
_(
" (phase)" ) );
775 signals.push_back( signal );
782 if( aFilter.IsEmpty() )
783 aFilter = wxS(
"*" );
788 for(
const wxString& signal : signals )
790 if( matcher.
Find( signal.Upper() ) )
799 wxGridCellAttr* attr =
new wxGridCellAttr;
800 attr->SetRenderer(
new wxGridCellBoolRenderer() );
802 attr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
807 attr =
new wxGridCellAttr;
812 attr =
new wxGridCellAttr;
816 attr =
new wxGridCellAttr;
824 attr =
new wxGridCellAttr;
827 attr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
832 attr =
new wxGridCellAttr;
833 attr->SetRenderer(
new wxGridCellBoolRenderer() );
835 attr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
839 attr =
new wxGridCellAttr;
840 attr->SetRenderer(
new wxGridCellBoolRenderer() );
842 attr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
859 wxString unconnected = wxString( wxS(
"unconnected-(" ) );
864 unconnected.Replace(
'(',
'_' );
867 [&](
const wxString& aSignalName )
869 if( simType ==
ST_AC )
871 m_signals.push_back( aSignalName +
_(
" (gain)" ) );
872 m_signals.push_back( aSignalName +
_(
" (phase)" ) );
874 else if( simType ==
ST_SP )
876 m_signals.push_back( aSignalName +
_(
" (amplitude)" ) );
877 m_signals.push_back( aSignalName +
_(
" (phase)" ) );
894 if( netname ==
"GND" || netname ==
"0" || netname.StartsWith( unconnected ) )
898 addSignal( wxString::Format( wxS(
"V(%s)" ), netname ) );
908 for(
const std::string&
name : item.model->SpiceGenerator().CurrentNames( item ) )
918 if( item.model->GetPinCount() >= 2 )
920 wxString
name = item.model->SpiceGenerator().ItemName( item );
921 addSignal( wxString::Format( wxS(
"P(%s)" ),
name ) );
928 addSignal( wxS(
"inoise_spectrum" ) );
929 addSignal( wxS(
"onoise_spectrum" ) );
932 if( simType ==
ST_SP )
934 std::vector<std::string> portnums;
938 wxString
name = item.model->SpiceGenerator().ItemName( item );
941 if( !
name.StartsWith(
"V" ) )
944 std::string portnum =
"";
946 if(
const SIM_MODEL::PARAM* portnum_param = item.model->FindParam(
"portnum" ) )
950 portnums.push_back( portnum );
953 for(
const std::string& portnum1 : portnums )
955 for(
const std::string& portnum2 : portnums )
957 addSignal( wxString::Format( wxS(
"S_%s_%s" ), portnum1, portnum2 ) );
963 for(
const wxString& directive :
circuitModel()->GetDirectives() )
965 wxStringTokenizer directivesTokenizer( directive, wxT(
"\r\n" ), wxTOKEN_STRTOK );
967 while( directivesTokenizer.HasMoreTokens() )
969 wxString line = directivesTokenizer.GetNextToken().Upper();
970 wxString directiveParams;
972 if( line.StartsWith( wxS(
".SAVE" ), &directiveParams )
973 || line.StartsWith( wxS(
".PROBE" ), &directiveParams ) )
975 wxStringTokenizer paramsTokenizer( directiveParams, wxT(
" \t" ), wxTOKEN_STRTOK );
977 while( paramsTokenizer.HasMoreTokens() )
978 addSignal( paramsTokenizer.GetNextToken() );
1001 wxString pageTitle(
simulator()->TypeToName( simType,
true ) );
1002 pageTitle.Prepend( wxString::Format(
_(
"Analysis %u - " ), (
unsigned int) ++
m_plotNumber ) );
1018 wxPoint pos = aEvent.GetPosition();
1019 wxRect ctrlRect =
m_filter->GetScreenRect();
1020 int buttonWidth = ctrlRect.GetHeight();
1022 if(
m_filter->IsSearchButtonVisible() && pos.x < buttonWidth )
1023 SetCursor( wxCURSOR_ARROW );
1024 else if(
m_filter->IsCancelButtonVisible() && pos.x > ctrlRect.GetWidth() - buttonWidth )
1025 SetCursor( wxCURSOR_ARROW );
1027 SetCursor( wxCURSOR_IBEAM );
1033 return wxString::Format( wxS(
"user%d" ), aUserDefinedSignalId );
1042 const wxString& aSignalName,
1045 std::map<wxString, int> suffixes;
1061 wxUniChar firstChar = aSignalName.Upper()[0];
1063 if( firstChar ==
'V' )
1065 else if( firstChar ==
'I' )
1067 else if( firstChar ==
'P' )
1073 wxString
name = aSignalName;
1075 for(
const auto& [ candidate, type ] : suffixes )
1077 if(
name.EndsWith( candidate ) )
1079 name =
name.Left(
name.Length() - candidate.Length() );
1082 *aTraceType |= type;
1090 if(
name == signal )
1108 int row = aEvent.GetRow();
1109 int col = aEvent.GetCol();
1117 if(
text == wxS(
"1" ) )
1145 TRACE* activeTrace =
nullptr;
1147 if(
text == wxS(
"1" ) )
1151 activeTrace = plotTab->
GetTrace( vectorName, traceType );
1162 if( trace != activeTrace && trace->
HasCursor(
id ) )
1185 int row = aEvent.GetRow();
1186 int col = aEvent.GetCol();
1192 CURSOR* cursor1 =
nullptr;
1193 CURSOR* cursor2 =
nullptr;
1206 if( cursorName == wxS(
"1" ) && cursor1 )
1208 else if( cursorName == wxS(
"2" ) && cursor2 )
1210 else if( cursorName ==
_(
"Diff" ) && cursor1 && cursor2 )
1218 wxFAIL_MSG( wxT(
"All other columns are supposed to be read-only!" ) );
1251 int row = aEvent.GetRow();
1252 int col = aEvent.GetCol();
1263 wxFAIL_MSG( wxT(
"All other columns are supposed to be read-only!" ) );
1271 for( row = rowCount - 1; row >= 0; row-- )
1281 int killRows = emptyRows - 1;
1284 else if( emptyRows == 0 )
1295 if( plotTab->GetLegendPosition() != plotTab->m_LastLegendPosition )
1297 plotTab->m_LastLegendPosition = plotTab->GetLegendPosition();
1320 static wxRegEx measureParamsRegEx( wxT(
"^"
1324 "([a-zA-Z]*)\\(([^\\)]+)\\)" ) );
1333 if(
text.IsEmpty() )
1340 wxString resultName = wxString::Format( wxS(
"meas_result_%u" ), aRow );
1341 wxString result = wxS(
"?" );
1343 if( measureParamsRegEx.Matches(
text ) )
1345 wxString func = measureParamsRegEx.GetMatch(
text, 1 ).Upper();
1346 wxString signalType = measureParamsRegEx.GetMatch(
text, 2 ).Upper();
1347 wxString deviceName = measureParamsRegEx.GetMatch(
text, 3 );
1351 if( signalType.EndsWith( wxS(
"DB" ) ) )
1353 units = wxS(
"dB" );
1355 else if( signalType.StartsWith(
'I' ) )
1359 else if( signalType.StartsWith(
'P' ) )
1363 text = func +
" " + deviceName +
":power";
1370 if( func.EndsWith( wxS(
"_AT" ) ) )
1373 units = wxS(
"Hz" );
1377 else if( func.StartsWith( wxS(
"INTEG" ) ) )
1382 if ( signalType.StartsWith(
'P' ) )
1385 units += wxS(
".s" );
1395 units += wxS(
"·Hz" );
1403 units += wxS(
"·?" );
1416 wxString cmd = wxString::Format( wxS(
"meas %s %s %s" ), simType, resultName,
text );
1417 simulator()->Command(
"echo " + cmd.ToStdString() );
1418 simulator()->Command( cmd.ToStdString() );
1420 std::vector<double> resultVec =
simulator()->GetGainVector( resultName.ToStdString() );
1422 if( resultVec.size() > 0 )
1437 wxString ref = aSymbol->
GetRef( &aSheetPath );
1442 if( tuner->GetSymbolRef() == ref )
1468 const wxString& aRef,
const wxString& aValue )
1476 + wxString::Format(
_(
"%s not found" ), aRef ) );
1489 + wxString::Format(
_(
"%s is not tunable" ), aRef ) );
1555 wxString cmd = wxString::Format( wxS(
"fourier %s %s" ),
1559 simulator()->Command( cmd.ToStdString() );
1573 m_simConsole->AppendText(
_(
"Error: no current simulation.\n" ) );
1582 m_simConsole->AppendText(
_(
"Error: simulation type not defined.\n" ) );
1588 m_simConsole->AppendText(
_(
"Error: simulation type doesn't support plotting.\n" ) );
1595 if( simType ==
ST_AC )
1600 else if( simType ==
ST_SP )
1610 plotTab->GetPlotWin()->UpdateAll();
1632 if( aNewSignals.count(
id ) == 0 )
1637 plotTab->
DeleteTrace( vectorName, traceType | subType );
1642 plotTab->
DeleteTrace( vectorName, traceType | subType );
1655 if(
TRACE* trace = plotTab->
GetTrace( vectorName, traceType | subType ) )
1656 trace->SetName( aNewSignals.at(
id ) );
1663 if(
TRACE* trace = plotTab->
GetTrace( vectorName, traceType | subType ) )
1664 trace->SetName( aNewSignals.at(
id ) );
1669 if(
TRACE* trace = plotTab->
GetTrace( vectorName, traceType ) )
1670 trace->SetName( aNewSignals.at(
id ) );
1704 wxString simVectorName = aVectorName;
1707 simVectorName = simVectorName.AfterFirst(
'(' ).BeforeLast(
')' ) + wxS(
":power" );
1712 simulator()->Command( wxString::Format( wxT(
"print %s" ), aVectorName ).ToStdString() );
1717 std::vector<double> data_x;
1718 std::vector<double> data_y;
1720 if( !aDataX || aClearData )
1724 if( aDataX->empty() && !aClearData )
1726 wxString xAxisName(
simulator()->GetXAxis( simType ) );
1728 if( xAxisName.IsEmpty() )
1731 *aDataX =
simulator()->GetGainVector( (
const char*) xAxisName.c_str() );
1734 unsigned int size = aDataX->size();
1740 data_y =
simulator()->GetGainVector( (
const char*) simVectorName.c_str(), size );
1742 data_y =
simulator()->GetPhaseVector( (
const char*) simVectorName.c_str(), size );
1744 wxFAIL_MSG( wxT(
"Plot type missing AC_PHASE or AC_MAG bit" ) );
1749 data_y =
simulator()->GetGainVector( (
const char*) simVectorName.c_str(), size );
1751 data_y =
simulator()->GetPhaseVector( (
const char*) simVectorName.c_str(), size );
1753 wxFAIL_MSG( wxT(
"Plot type missing AC_PHASE or SPT_SP_AMP bit" ) );
1758 data_y =
simulator()->GetGainVector( (
const char*) simVectorName.c_str(), -1 );
1764 data_y =
simulator()->GetGainVector( (
const char*) simVectorName.c_str(), size );
1768 wxFAIL_MSG( wxT(
"Unhandled plot type" ) );
1773 size_t sweepSize = std::numeric_limits<size_t>::max();
1775 if( simType ==
ST_DC
1782 sweepSize = aDataX->size() / sweepCount;
1787 if( data_y.size() >= size )
1788 aPlotTab->
SetTraceData( trace, *aDataX, data_y, sweepCount, sweepSize );
1797 for(
int row = 0; row <
m_signalsGrid->GetNumberRows(); ++row )
1803 if(
TRACE* trace = plotTab ? plotTab->
GetTrace( vectorName, traceType ) :
nullptr )
1809 if( !attr->HasRenderer() )
1812 if( !attr->HasEditor() )
1815 attr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
1816 attr->SetReadOnly(
false );
1823 if( !attr->HasRenderer() )
1824 attr->SetRenderer(
new wxGridCellBoolRenderer() );
1826 attr->SetReadOnly();
1827 attr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
1831 if( !attr->HasRenderer() )
1832 attr->SetRenderer(
new wxGridCellBoolRenderer() );
1834 attr->SetReadOnly();
1835 attr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
1837 if( trace->HasCursor( 1 ) )
1842 if( trace->HasCursor( 2 ) )
1852 attr->SetEditor(
nullptr );
1853 attr->SetRenderer(
nullptr );
1854 attr->SetReadOnly();
1858 attr->SetEditor(
nullptr );
1859 attr->SetRenderer(
nullptr );
1860 attr->SetReadOnly();
1864 attr->SetEditor(
nullptr );
1865 attr->SetRenderer(
nullptr );
1866 attr->SetReadOnly();
1875 auto quoteNetNames =
1876 [&]( wxString aExpression ) -> wxString
1879 aExpression.Replace( netname, quotedNetname );
1886 constexpr const char* cmd =
"let user{} = {}";
1888 simulator()->Command(
"echo " + fmt::format( cmd,
id, signal.ToStdString() ) );
1889 simulator()->Command( fmt::format( cmd,
id, quoteNetNames( signal ).ToStdString() ) );
1901 wxString ref = tuner->GetSymbolRef();
1902 KIID symbolId = tuner->GetSymbol( &sheetPath );
1908 reporter.
Report( wxString::Format(
_(
"%s not found" ), ref ) );
1916 reporter.
Report( wxString::Format(
_(
"%s is not tunable" ), ref ) );
1920 double floatVal = tuner->GetValue().ToDouble();
1933 wxTextFile file( aPath );
1938 wxString firstLine = file.GetFirstLine();
1940 bool legacy = firstLine.StartsWith( wxT(
"version " ) ) || firstLine.ToLong( &
dummy );
1965 wxFileName filename( aPath );
1969 simulator()->Settings()->SetWorkbookFilename( filename.GetFullPath() );
1977 wxFFileInputStream fp( aPath, wxT(
"rt" ) );
1978 wxStdInputStream fstream( fp );
1985 nlohmann::json js = nlohmann::json::parse( fstream,
nullptr,
true,
true );
1987 std::map<SIM_PLOT_TAB*, nlohmann::json> traceInfo;
1989 for(
const nlohmann::json& tab_js : js[
"tabs" ] )
1991 wxString simCommand;
1995 for(
const nlohmann::json& cmd : tab_js[
"commands" ] )
1997 if( cmd ==
".kicad adjustpaths" )
1999 else if( cmd ==
".save all" )
2001 else if( cmd ==
".probe alli" )
2003 else if( cmd ==
".probe allp" )
2005 else if( cmd ==
".kicad esavenone" )
2008 simCommand += wxString( cmd.get<wxString>() ).Trim();
2018 if( tab_js.contains(
"traces" ) )
2019 traceInfo[plotTab] = tab_js[
"traces" ];
2021 if( tab_js.contains(
"measurements" ) )
2023 for(
const nlohmann::json& m_js : tab_js[
"measurements" ] )
2024 plotTab->
Measurements().emplace_back( m_js[
"expr" ], m_js[
"format" ] );
2028 plotTab->
ShowGrid( tab_js[
"showGrid" ] );
2030 if( tab_js.contains(
"fixedY1scale" ) )
2032 const nlohmann::json& scale_js = tab_js[
"fixedY1scale" ];
2033 plotTab->
SetY1Scale(
true, scale_js[
"min" ], scale_js[
"max" ] );
2037 if( tab_js.contains(
"fixedY2scale" ) )
2039 const nlohmann::json& scale_js = tab_js[
"fixedY2scale" ];
2040 plotTab->
SetY2Scale(
true, scale_js[
"min" ], scale_js[
"max" ] );
2044 if( tab_js.contains(
"fixedY3scale" ) )
2047 const nlohmann::json& scale_js = tab_js[
"fixedY3scale" ];
2048 plotTab->
SetY3Scale(
true, scale_js[
"min" ], scale_js[
"max" ] );
2052 if( tab_js.contains(
"legend" ) )
2054 const nlohmann::json& legend_js = tab_js[
"legend" ];
2059 if( tab_js.contains(
"margins" ) )
2061 const nlohmann::json& margins_js = tab_js[
"margins" ];
2063 margins_js[
"right" ],
2064 margins_js[
"bottom" ],
2065 margins_js[
"left" ] );
2072 if( js.contains(
"user_defined_signals" ) )
2074 for(
const nlohmann::json& signal_js : js[
"user_defined_signals" ] )
2080 int aCursorId,
const nlohmann::json& aCursor_js )
2082 if( aCursorId == 1 || aCursorId == 2 )
2086 cursor->SetName( aSignalName );
2087 cursor->SetCoordX( aCursor_js[
"position" ] );
2089 aTrace->SetCursor( aCursorId,
cursor );
2097 for(
const auto& [ plotTab, traces_js ] : traceInfo )
2099 for(
const nlohmann::json& trace_js : traces_js )
2101 wxString signalName = trace_js[
"signal" ];
2103 TRACE* trace = plotTab->GetOrAddTrace( vectorName, trace_js[
"trace_type" ] );
2107 if( trace_js.contains(
"cursor1" ) )
2108 addCursor( plotTab, trace, signalName, 1, trace_js[
"cursor1" ] );
2110 if( trace_js.contains(
"cursor2" ) )
2111 addCursor( plotTab, trace, signalName, 2, trace_js[
"cursor2" ] );
2113 if( trace_js.contains(
"cursorD" ) )
2114 addCursor( plotTab, trace, signalName, 3, trace_js[
"cursorD" ] );
2116 if( trace_js.contains(
"color" ) )
2119 color.Set( wxString( trace_js[
"color"].get<wxString>() ) );
2121 plotTab->UpdateTraceStyle( trace );
2126 plotTab->UpdatePlotColors();
2134 firstTab->SetLastSchTextSimCommand( js[
"last_sch_text_sim_command" ] );
2137 catch( nlohmann::json::parse_error& error )
2139 wxLogTrace(
traceSettings, wxT(
"Json parse error reading %s: %s" ), aPath, error.what() );
2143 catch( nlohmann::json::type_error& error )
2145 wxLogTrace(
traceSettings, wxT(
"Json type error reading %s: %s" ), aPath, error.what() );
2149 catch( nlohmann::json::invalid_iterator& error )
2151 wxLogTrace(
traceSettings, wxT(
"Json invalid_iterator error reading %s: %s" ), aPath, error.what() );
2155 catch( nlohmann::json::out_of_range& error )
2157 wxLogTrace(
traceSettings, wxT(
"Json out_of_range error reading %s: %s" ), aPath, error.what() );
2163 wxLogTrace(
traceSettings, wxT(
"Error reading %s" ), aPath );
2175 wxFileName filename = aPath;
2180 file.Create( filename.GetFullPath(),
true );
2182 if( !file.IsOpened() )
2185 nlohmann::json tabs_js = nlohmann::json::array();
2196 nlohmann::json commands_js = nlohmann::json::array();
2203 commands_js.push_back(
".kicad adjustpaths" );
2206 commands_js.push_back(
".save all" );
2209 commands_js.push_back(
".probe alli" );
2212 commands_js.push_back(
".probe allp" );
2215 commands_js.push_back(
".kicad esavenone" );
2217 nlohmann::json tab_js = nlohmann::json(
2219 {
"commands", commands_js } } );
2223 nlohmann::json traces_js = nlohmann::json::array();
2225 auto findSignalName =
2226 [&](
const wxString& aVectorName ) -> wxString
2228 wxString vectorName;
2231 if( aVectorName.EndsWith(
_(
" (phase)" ) ) )
2232 suffix =
_(
" (phase)" );
2233 else if( aVectorName.EndsWith(
_(
" (gain)" ) ) )
2234 suffix =
_(
" (gain)" );
2236 vectorName = aVectorName.Left( aVectorName.Length() - suffix.Length() );
2241 return signal + suffix;
2247 for(
const auto& [
name, trace] : plotTab->GetTraces() )
2249 nlohmann::json trace_js = nlohmann::json(
2250 { {
"trace_type", (int) trace->GetType() },
2251 {
"signal", findSignalName( trace->GetDisplayName() ) },
2256 trace_js[
"cursor1"] = nlohmann::json(
2257 { {
"position",
cursor->GetCoords().x },
2264 trace_js[
"cursor2"] = nlohmann::json(
2265 { {
"position",
cursor->GetCoords().x },
2270 if( trace->GetCursor( 1 ) || trace->GetCursor( 2 ) )
2272 trace_js[
"cursorD"] = nlohmann::json(
2277 traces_js.push_back( trace_js );
2280 nlohmann::json measurements_js = nlohmann::json::array();
2282 for(
const auto& [
measurement, format ] : plotTab->Measurements() )
2284 measurements_js.push_back( nlohmann::json( { {
"expr",
measurement },
2285 {
"format", format } } ) );
2288 tab_js[
"traces" ] = traces_js;
2289 tab_js[
"measurements" ] = measurements_js;
2290 tab_js[
"dottedSecondary" ] = plotTab->GetDottedSecondary();
2291 tab_js[
"showGrid" ] = plotTab->IsGridShown();
2295 if( plotTab->GetY1Scale( &min, &max ) )
2296 tab_js[
"fixedY1scale" ] = nlohmann::json( { {
"min", min }, {
"max", max } } );
2298 if( plotTab->GetY2Scale( &min, &max ) )
2299 tab_js[
"fixedY2scale" ] = nlohmann::json( { {
"min", min }, {
"max", max } } );
2301 if( plotTab->GetY3Scale( &min, &max ) )
2302 tab_js[
"fixedY3scale" ] = nlohmann::json( { {
"min", min }, {
"max", max } } );
2304 if( plotTab->IsLegendShown() )
2306 tab_js[
"legend" ] = nlohmann::json( { {
"x", plotTab->GetLegendPosition().x },
2307 {
"y", plotTab->GetLegendPosition().y } } );
2310 mpWindow* plotWin = plotTab->GetPlotWin();
2312 tab_js[
"margins" ] = nlohmann::json( { {
"left", plotWin->
GetMarginLeft() },
2318 tabs_js.push_back( tab_js );
2321 nlohmann::json userDefinedSignals_js = nlohmann::json::array();
2324 userDefinedSignals_js.push_back( signal );
2326 nlohmann::json js = nlohmann::json( { {
"version", 6 },
2327 {
"tabs", tabs_js },
2328 {
"user_defined_signals", userDefinedSignals_js } } );
2339 std::stringstream buffer;
2340 buffer << std::setw( 2 ) << js << std::endl;
2342 bool res = file.Write( buffer.str() );
2349 simulator()->Settings()->SetWorkbookFilename( filename.GetFullPath() );
2367 default: wxFAIL_MSG( wxS(
"Unhandled simulation type" ) );
return SPT_UNKNOWN;
2386 &source, &
scale, &pts, &fStart, &fStop, &saveAll );
2401 for(
size_t page = 0; page <
m_plotNotebook->GetPageCount(); page++ )
2446 std::vector<std::pair<wxString, wxString>>& measurements = plotTab->Measurements();
2448 measurements.clear();
2486 simulator()->Command(
"setplot " + simTab->GetSpicePlotName().ToStdString() );
2500 for(
const auto& [
measurement, format ] : plotTab->Measurements() )
2508 if( plotTab->GetSimType() ==
ST_TRAN || plotTab->GetSimType() ==
ST_AC
2509 || plotTab->GetSimType() ==
ST_DC || plotTab->GetSimType() ==
ST_SP )
2546 CURSOR* cursor1 =
nullptr;
2547 wxString cursor1Name;
2548 wxString cursor1Units;
2549 CURSOR* cursor2 =
nullptr;
2550 wxString cursor2Name;
2551 wxString cursor2Units;
2554 [&](
TRACE* aTrace ) -> wxString
2575 [&](
TRACE* aTrace ) -> wxString
2596 [
this](
double aValue,
int aCursorId,
int aCol ) -> wxString
2609 cursor1Name = getNameY( trace );
2610 cursor1Units = getUnitsY( trace );
2612 wxRealPoint coords =
cursor->GetCoords();
2632 cursor2Name = getNameY( trace );
2633 cursor2Units = getUnitsY( trace );
2635 wxRealPoint coords =
cursor->GetCoords();
2650 if( cursor1 && cursor2 && cursor1Units == cursor2Units )
2659 signal = wxString::Format( wxS(
"%s[2 - 1]" ), cursor2->
GetName() );
2661 signal = wxString::Format( wxS(
"%s - %s" ), cursor2->
GetName(), cursor1->
GetName() );
2673 wxString valColName =
_(
"Value" );
2675 if( !cursor1Name.IsEmpty() )
2677 if( cursor2Name.IsEmpty() || cursor1Name == cursor2Name )
2678 valColName = cursor1Name;
2680 else if( !cursor2Name.IsEmpty() )
2682 valColName = cursor2Name;
2699 plotTab->ResetScales(
true );
2719 std::vector<wxString> signals;
2721 for(
const std::string& vec :
simulator()->AllVectors() )
2722 signals.emplace_back( vec );
2730 std::vector<wxString> signals;
2732 for(
const wxString& signal :
m_signals )
2733 signals.emplace_back( signal );
2736 signals.emplace_back( signal );
2768 if( simType ==
ST_NOISE && aFinal )
2770 m_simConsole->AppendText(
_(
"\n\nSimulation results:\n\n" ) );
2777 simulator()->CurrentPlotName().Mid( 5 ).ToLong( &number );
2779 for(
const std::string& vec :
simulator()->AllVectors() )
2781 std::vector<double> val_list =
simulator()->GetRealVector( vec, 1 );
2784 msg.Printf( wxS(
"%s: %sV\n" ), vec, value );
2790 simulator()->Command( fmt::format(
"setplot noise{}", number - 1 ) );
2795 wxCHECK_RET( plotTab, wxT(
"not a SIM_PLOT_TAB" ) );
2804 std::map<TRACE*, TRACE_INFO> traceMap;
2807 traceMap[ trace ] = { wxEmptyString,
SPT_UNKNOWN,
false };
2812 for(
const wxString& signal :
m_signals )
2817 if(
TRACE* trace = plotTab->
GetTrace( vectorName, traceType ) )
2818 traceMap[ trace ] = { vectorName, traceType,
false };
2826 if( simType ==
ST_AC )
2832 if(
TRACE* trace = plotTab->
GetTrace( vectorName, subType ) )
2833 traceMap[ trace ] = { vectorName, subType, !aFinal };
2836 else if( simType ==
ST_SP )
2842 if(
TRACE* trace = plotTab->
GetTrace( vectorName, subType ) )
2843 traceMap[trace] = { vectorName, subType, !aFinal };
2848 if(
TRACE* trace = plotTab->
GetTrace( vectorName, traceType ) )
2849 traceMap[ trace ] = { vectorName, traceType, !aFinal };
2855 for(
const auto& [ trace, traceInfo ] : traceMap )
2857 if( traceInfo.Vector.IsEmpty() )
2861 for(
const auto& [ trace,
info ] : traceMap )
2863 std::vector<double> data_x;
2865 if( !
info.Vector.IsEmpty() )
2883 else if( simType ==
ST_OP && aFinal )
2885 m_simConsole->AppendText(
_(
"\n\nSimulation results:\n\n" ) );
2888 for(
const std::string& vec :
simulator()->AllVectors() )
2890 std::vector<double> val_list =
simulator()->GetRealVector( vec, 1 );
2892 if( val_list.empty() )
2899 const size_t tab = 25;
2900 size_t padding = ( signal.length() < tab ) ? ( tab - signal.length() ) : 1;
2904 case SPT_VOLTAGE: value.Append( wxS(
"V" ) );
break;
2905 case SPT_CURRENT: value.Append( wxS(
"A" ) );
break;
2906 case SPT_POWER: value.Append( wxS(
"W" ) );
break;
2907 default: value.Append( wxS(
"?" ) );
break;
2910 msg.Printf( wxT(
"%s%s\n" ),
2911 ( signal + wxT(
":" ) ).Pad( padding, wxUniChar(
' ' ) ),
2918 signal = signal.SubString( 2, signal.Length() - 2 );
2921 signal += wxS(
":power" );
2926 else if( simType ==
ST_PZ && aFinal )
2928 m_simConsole->AppendText(
_(
"\n\nSimulation results:\n\n" ) );
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
void showPopupMenu(wxMenu &menu, wxGridEvent &aEvent) override
void doPopupSelection(wxCommandEvent &event) override
SIMULATOR_FRAME_UI * m_parent
CURSORS_GRID_TRICKS(SIMULATOR_FRAME_UI *aParent, WX_GRID *aGrid)
The SIMULATOR_FRAME holds the main user-interface for running simulations.
const wxRealPoint & GetCoords() const
void SetCoordX(double aValue)
bool Find(const wxString &aTerm, int &aMatchersTriggered, int &aPosition)
Look in all existing matchers, return the earliest match of any of the existing.
virtual void Refresh(bool aEraseBackground=true, const wxRect *aRect=nullptr) override
Add mouse and command handling (such as cut, copy, and paste) to a WX_GRID instance.
virtual void doPopupSelection(wxCommandEvent &event)
virtual void showPopupMenu(wxMenu &menu, wxGridEvent &aEvent)
WX_GRID * m_grid
I don't own the grid, but he owns me.
A color representation with 4 components: red, green, blue, alpha.
wxString ToCSSString() const
PROJECT & Prj() const
Return a reference to the PROJECT associated with this KIWAY.
Hold a translatable error message and may be used when throwing exceptions containing a translated er...
const wxString What() const
void doPopupSelection(wxCommandEvent &event) override
void showPopupMenu(wxMenu &menu, wxGridEvent &aEvent) override
SIMULATOR_FRAME_UI * m_parent
MEASUREMENTS_GRID_TRICKS(SIMULATOR_FRAME_UI *aParent, WX_GRID *aGrid)
static void ConvertToSpiceMarkup(wxString *aNetName)
Remove formatting wrappers and replace illegal spice net name characters with underscores.
@ OPTION_SAVE_ALL_CURRENTS
@ OPTION_SAVE_ALL_VOLTAGES
@ OPTION_SAVE_ALL_DISSIPATIONS
@ OPTION_ADJUST_INCLUDE_PATHS
@ OPTION_ADJUST_PASSIVE_VALS
const SPICE_ITEM * FindItem(const wxString &aRefName) const
Find and return the item corresponding to aRefName.
A singleton reporter that reports to nowhere.
virtual const wxString GetProjectPath() const
Return the full path of the project.
Holds all the data relating to one schematic.
void SetOperatingPoint(const wxString &aSignal, double aValue)
Set operating points from a .op simulation.
void ClearOperatingPoints()
Clear operating points from a .op simulation.
SCH_DRAW_PANEL * GetCanvas() const override
Return a pointer to GAL-based canvas of given EDA draw frame.
EESCHEMA_SETTINGS * eeconfig() const
Schematic editor (Eeschema) main window.
void RefreshOperatingPointDisplay()
Refresh the display of any operaintg points.
void OnModify() override
Must be called after a schematic change in order to set the "modify" flag and update other data struc...
SCHEMATIC & Schematic() const
void UpdateItem(EDA_ITEM *aItem, bool isAddOrDelete=false, bool aUpdateRtree=false) override
Mark an item for refresh.
Base class for any item which can be embedded within the SCHEMATIC container class,...
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
SCH_ITEM * GetItem(const KIID &aID) const
Fetch a SCH_ITEM by ID.
void GetFields(std::vector< SCH_FIELD * > &aVector, bool aVisibleOnly) override
Populate a std::vector with SCH_FIELDs.
const wxString GetRef(const SCH_SHEET_PATH *aSheet, bool aIncludeUnit=false) const override
void doPopupSelection(wxCommandEvent &event) override
void showPopupMenu(wxMenu &menu, wxGridEvent &aEvent) override
SIMULATOR_FRAME_UI * m_parent
SIGNALS_GRID_TRICKS(SIMULATOR_FRAME_UI *aParent, WX_GRID *aGrid)
Class SIMULATOR_FRAME_UI_BASE.
wxBoxSizer * m_sizerTuners
WX_GRID * m_measurementsGrid
wxSplitterWindow * m_splitterLeftRight
wxSplitterWindow * m_splitterMeasurements
wxTextCtrl * m_simConsole
wxSplitterWindow * m_splitterCursors
wxSplitterWindow * m_splitterPlotAndConsole
wxSplitterWindow * m_splitterSignals
wxAuiNotebook * m_plotNotebook
The SIMULATOR_FRAME_UI holds the main user-interface for running simulations.
SIM_TAB * NewSimTab(const wxString &aSimCommand)
Create a new simulation tab for a given simulation type.
void SetUserDefinedSignals(const std::map< int, wxString > &aSignals)
void updatePlotCursors()
Update the cursor values (in the grid) and graphics (in the plot window).
void OnSimRefresh(bool aFinal)
void onPlotClose(wxAuiNotebookEvent &event) override
int m_splitterTuneValuesSashPosition
void onPlotChanged(wxAuiNotebookEvent &event) override
void rebuildSignalsGrid(wxString aFilter)
Rebuild the filtered list of signals in the signals grid.
void DoFourier(const wxString &aSignal, const wxString &aFundamental)
void rebuildMeasurementsGrid()
Rebuild the measurements grid for the current plot.
std::list< TUNER_SLIDER * > m_tuners
SPICE expressions need quoted versions of the netnames since KiCad allows '-' and '/' in netnames.
void rebuildSignalsList()
Rebuild the list of signals available from the netlist.
bool loadLegacyWorkbook(const wxString &aPath)
int m_splitterCursorsSashPosition
void UpdateMeasurement(int aRow)
Update a measurement in the measurements grid.
wxString getNoiseSource() const
std::vector< wxString > SimPlotVectors() const
unsigned int m_plotNumber
void SetSubWindowsSashSize()
void applyUserDefinedSignals()
Apply user-defined signals to the SPICE session.
std::map< wxString, wxString > m_quotedNetnames
SIM_PREFERENCES m_preferences
void DeleteMeasurement(int aRow)
Delete a row from the measurements grid.
SCH_EDIT_FRAME * m_schematicFrame
wxString vectorNameFromSignalName(SIM_PLOT_TAB *aPlotTab, const wxString &aSignalName, int *aTraceType)
Get the simulator output vector name for a given signal name and type.
void updateSignalsGrid()
Update the values in the signals grid.
int m_splitterLeftRightSashPosition
void onCursorsGridCellChanged(wxGridEvent &aEvent) override
void onPlotDragged(wxAuiNotebookEvent &event) override
std::vector< wxString > Signals() const
bool SaveWorkbook(const wxString &aPath)
Save plot, signal, cursor, measurement, etc.
std::vector< wxString > m_signals
SIM_TAB * GetCurrentSimTab() const
Return the currently opened plot panel (or NULL if there is none).
void updateMeasurementsFromGrid()
bool LoadWorkbook(const wxString &aPath)
Load plot, signal, cursor, measurement, etc.
SPICE_VALUE_FORMAT GetMeasureFormat(int aRow) const
Get/Set the format of a value in the measurements grid.
std::map< int, wxString > m_userDefinedSignals
void UpdateTunerValue(const SCH_SHEET_PATH &aSheetPath, const KIID &aSymbol, const wxString &aRef, const wxString &aValue)
Safely update a field of the associated symbol without dereferencing the symbol.
void AddTrace(const wxString &aName, SIM_TRACE_TYPE aType)
Add a new trace to the current plot.
void onPlotClosed(wxAuiNotebookEvent &event) override
void RemoveTuner(TUNER_SLIDER *aTuner)
Remove an existing tuner.
void SaveSettings(EESCHEMA_SETTINGS *aCfg)
std::shared_ptr< SPICE_CIRCUIT_MODEL > circuitModel() const
void OnFilterText(wxCommandEvent &aEvent) override
void onMeasurementsGridCellChanged(wxGridEvent &aEvent) override
void applyTuners()
Apply component values specified using tuner sliders to the current netlist.
bool loadJsonWorkbook(const wxString &aPath)
void OnFilterMouseMoved(wxMouseEvent &aEvent) override
void AddMeasurement(const wxString &aCmd)
Add a measurement to the measurements grid.
void onPlotChanging(wxAuiNotebookEvent &event) override
std::shared_ptr< SPICE_SIMULATOR > simulator() const
void onPlotCursorUpdate(wxCommandEvent &aEvent)
void onSignalsGridCellChanged(wxGridEvent &aEvent) override
void SetCursorFormat(int aCursorId, int aValueCol, const SPICE_VALUE_FORMAT &aFormat)
void InitWorkbook()
Load the currently active workbook stored in the project settings.
void ToggleDarkModePlots()
SIM_TRACE_TYPE getXAxisType(SIM_TYPE aType) const
Return X axis for a given simulation type.
void OnPlotSettingsChanged()
void SetMeasureFormat(int aRow, const SPICE_VALUE_FORMAT &aFormat)
int m_splitterSignalsSashPosition
void OnSimReport(const wxString &aMsg)
void ApplyPreferences(const SIM_PREFERENCES &aPrefs)
Called when settings are changed via the common Preferences dialog.
const SPICE_CIRCUIT_MODEL * GetExporter() const
Return the netlist exporter object used for simulations.
int m_splitterPlotAndConsoleSashPosition
SIMULATOR_FRAME * m_simulatorFrame
void ShowChangedLanguage()
void AddTuner(const SCH_SHEET_PATH &aSheetPath, SCH_SYMBOL *aSymbol)
Add a tuner for a symbol.
SPICE_VALUE_FORMAT GetCursorFormat(int aCursorId, int aValueCol) const
Get/Set the number of significant digits and the range for formatting a cursor value.
void OnUpdateUI(wxUpdateUIEvent &event) override
void updateTrace(const wxString &aVectorName, int aTraceType, SIM_PLOT_TAB *aPlotTab, std::vector< double > *aDataX=nullptr, bool aClearData=false)
Update a trace in a particular SIM_PLOT_TAB.
SIMULATOR_FRAME_UI(SIMULATOR_FRAME *aSimulatorFrame, SCH_EDIT_FRAME *aSchematicFrame)
SPICE_VALUE_FORMAT m_cursorFormats[3][2]
void LoadSettings(EESCHEMA_SETTINGS *aCfg)
The SIMULATOR_FRAME holds the main user-interface for running simulations.
bool LoadSimulator(const wxString &aSimCommand, unsigned aSimOptions)
Check and load the current netlist into the simulator.
std::shared_ptr< SPICE_CIRCUIT_MODEL > GetCircuitModel() const
SIM_TYPE GetCurrentSimType() const
void OnModify() override
Must be called after a model change in order to set the "modify" flag and do other frame-specific pro...
int GetCurrentOptions() const
std::shared_ptr< SPICE_SIMULATOR > GetSimulator() const
SIM_MODEL & CreateModel(SIM_MODEL::TYPE aType, const std::vector< SCH_PIN * > &aPins, REPORTER &aReporter)
virtual const PARAM * GetTunerParam() const
const SPICE_GENERATOR & SpiceGenerator() const
void WriteFields(std::vector< SCH_FIELD > &aFields) const
void SetParamValue(int aParamIndex, const std::string &aValue, SIM_VALUE::NOTATION aNotation=SIM_VALUE::NOTATION::SI)
static void FillDefaultColorList(bool aWhiteBg)
Fills m_colorList by a default set of colors.
bool DeleteTrace(const wxString &aVectorName, int aTraceType)
wxString GetLabelY1() const
mpWindow * GetPlotWin() const
void ShowGrid(bool aEnable)
wxString GetUnitsY2() const
void SetY2Scale(bool aLock, double aMin, double aMax)
TRACE * GetTrace(const wxString &aVecName, int aType) const
wxString GetLabelX() const
const std::map< wxString, TRACE * > & GetTraces() const
wxString GetLabelY3() const
void SetY1Scale(bool aLock, double aMin, double aMax)
void SetY3Scale(bool aLock, double aMin, double aMax)
std::vector< std::pair< wxString, wxString > > & Measurements()
void UpdateTraceStyle(TRACE *trace)
Update plot colors.
void SetLegendPosition(const wxPoint &aPosition)
void ResetScales(bool aIncludeX)
Update trace line style.
void ShowLegend(bool aEnable)
wxString GetLabelY2() const
void SetTraceData(TRACE *aTrace, std::vector< double > &aX, std::vector< double > &aY, int aSweepCount, size_t aSweepSize)
void EnableCursor(TRACE *aTrace, int aCursorId, const wxString &aSignalName)
wxString GetUnitsX() const
void EnsureThirdYAxisExists()
TRACE * GetOrAddTrace(const wxString &aVectorName, int aType)
void SetDottedSecondary(bool aEnable)
Draw secondary signal traces (current or phase) with dotted lines.
void ApplyPreferences(const SIM_PREFERENCES &aPrefs) override
wxString GetUnitsY1() const
void DisableCursor(TRACE *aTrace, int aCursorId)
Reset scale ranges to fit the current traces.
wxString GetUnitsY3() const
int GetSimOptions() const
SIM_TYPE GetSimType() const
const wxString & GetSimCommand() const
static bool IsPlottable(SIM_TYPE aSimType)
void SetSimOptions(int aOptions)
wxString GetLastSchTextSimCommand() const
void SetSpicePlotName(const wxString &aPlotName)
static std::string ToSpice(const std::string &aString)
Special netlist exporter flavor that allows one to override simulation commands.
static SIM_TYPE CommandToSimType(const wxString &aCmd)
Return simulation type basing on a simulation command directive.
virtual std::string TunerCommand(const SPICE_ITEM &aItem, double aValue) const
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 ToString() const
Return string value as when converting double to string (e.g.
wxString ToSpiceString() const
Return string value in Spice format (e.g.
~SUPPRESS_GRID_CELL_EVENTS()
SUPPRESS_GRID_CELL_EVENTS(SIMULATOR_FRAME_UI *aFrame)
SIMULATOR_FRAME_UI * m_frame
void SetTraceColour(const wxColour &aColour)
bool HasCursor(int aCursorId)
CURSOR * GetCursor(int aCursorId)
Custom widget to handle quick component values modification and simulation on the fly.
void ClearRows()
wxWidgets recently added an ASSERT which fires if the position is greater than or equal to the number...
A wrapper for reporting to a wxString object.
bool HasMessage() const override
Returns true if the reporter client is non-empty.
REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED) override
Report a string with a given severity.
const wxString & GetMessages() const
A KICAD version of wxTextEntryDialog which supports the various improvements/work-arounds from DIALOG...
wxString GetValue() const
const wxString & GetName() const
Get layer name.
const wxPen & GetPen() const
Get pen set for this layer.
Canvas for plotting mpLayer implementations.
int GetMarginLeft() const
void SetMargins(int top, int right, int bottom, int left)
Set window margins, creating a blank area where some kinds of layers cannot draw.
void UpdateAll()
Refresh display.
int GetMarginRight() const
int GetMarginBottom() const
bool AddLayer(mpLayer *layer, bool refreshDisplay=true)
Add a plot layer to the canvas.
void Fit() override
Set view to fit global bounding box of all plot layers and refresh display.
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
This file is part of the common library.
Abstract pattern-matching tool and implementations.
@ GRIDTRICKS_FIRST_CLIENT_ID
static const std::string WorkbookFileExtension
KICOMMON_API wxFont GetStatusFont(wxWindow *aWindow)
SIM_TYPE
< Possible simulation types
void sortSignals(std::vector< wxString > &signals)
wxString vectorNameFromSignalId(int aUserDefinedSignalId)
MEASUREMENTS_GIRD_COLUMNS
@ MYID_DELETE_MEASUREMENT
SIM_TRACE_TYPE operator|(SIM_TRACE_TYPE aFirst, SIM_TRACE_TYPE aSecond)
std::vector< FAB_LAYER_COLOR > dummy
wxString UnescapeString(const wxString &aSource)
int measurements_panel_height
SIM_PREFERENCES preferences
Contains preferences pertaining to the simulator.
Definition of file extensions used in Kicad.