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" );
280 if( dlg.ShowModal() != wxID_OK )
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 )
601 pageTitle.Prepend( wxString::Format(
_(
"Analysis %u - " ), ii+1 ) );
621 tuner->ShowChangedLanguage();
659 for( std::size_t i = 0; i < pageCount; ++i )
662 auto simTab =
dynamic_cast<SIM_TAB*
>( page );
663 wxASSERT( simTab !=
nullptr );
664 simTab->ApplyPreferences( aPrefs );
671 if( !
simulator()->Settings()->GetWorkbookFilename().IsEmpty() )
673 wxFileName filename =
simulator()->Settings()->GetWorkbookFilename();
677 simulator()->Settings()->SetWorkbookFilename(
"" );
681 wxString schTextSimCommand =
circuitModel()->GetSchTextSimCommand();
683 if( !schTextSimCommand.IsEmpty() )
716 std::sort( signals.begin(), signals.end(),
717 [](
const wxString& lhs,
const wxString& rhs )
720 if( lhs.Upper().StartsWith(
'V' ) && !rhs.Upper().StartsWith(
'V' ) )
722 else if( !lhs.Upper().StartsWith(
'V' ) && rhs.Upper().StartsWith(
'V' ) )
725 return StrNumCmp( lhs, rhs, true ) < 0;
742 std::vector<wxString> signals;
746 wxStringTokenizer tokenizer( plotPanel->
GetSimCommand(), wxT(
" \t\r\n" ), wxTOKEN_STRTOK );
748 while( tokenizer.HasMoreTokens() && tokenizer.GetNextToken().Lower() != wxT(
"fft" ) )
751 while( tokenizer.HasMoreTokens() )
752 signals.emplace_back( tokenizer.GetNextToken() );
759 for(
const wxString& signal :
m_signals )
760 signals.push_back( signal );
764 if( simType ==
ST_AC )
766 signals.push_back( signal +
_(
" (gain)" ) );
767 signals.push_back( signal +
_(
" (phase)" ) );
769 else if( simType ==
ST_SP )
771 signals.push_back( signal +
_(
" (amplitude)" ) );
772 signals.push_back( signal +
_(
" (phase)" ) );
776 signals.push_back( signal );
783 if( aFilter.IsEmpty() )
784 aFilter = wxS(
"*" );
789 for(
const wxString& signal : signals )
791 if( matcher.
Find( signal.Upper() ) )
800 wxGridCellAttr* attr =
new wxGridCellAttr;
801 attr->SetRenderer(
new wxGridCellBoolRenderer() );
803 attr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
808 attr =
new wxGridCellAttr;
813 attr =
new wxGridCellAttr;
817 attr =
new wxGridCellAttr;
825 attr =
new wxGridCellAttr;
828 attr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
833 attr =
new wxGridCellAttr;
834 attr->SetRenderer(
new wxGridCellBoolRenderer() );
836 attr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
839 attr =
new wxGridCellAttr;
840 attr->SetRenderer(
new wxGridCellBoolRenderer() );
842 attr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
858 wxString unconnected = wxString( wxS(
"unconnected-(" ) );
863 unconnected.Replace(
'(',
'_' );
866 [&](
const wxString& aSignalName )
868 if( simType ==
ST_AC )
870 m_signals.push_back( aSignalName +
_(
" (gain)" ) );
871 m_signals.push_back( aSignalName +
_(
" (phase)" ) );
873 else if( simType ==
ST_SP )
875 m_signals.push_back( aSignalName +
_(
" (amplitude)" ) );
876 m_signals.push_back( aSignalName +
_(
" (phase)" ) );
893 if( netname ==
"GND" || netname ==
"0" || netname.StartsWith( unconnected ) )
897 addSignal( wxString::Format( wxS(
"V(%s)" ), netname ) );
907 for(
const std::string&
name : item.model->SpiceGenerator().CurrentNames( item ) )
917 if( item.model->GetPinCount() >= 2 )
919 wxString
name = item.model->SpiceGenerator().ItemName( item );
920 addSignal( wxString::Format( wxS(
"P(%s)" ),
name ) );
927 addSignal( wxS(
"inoise_spectrum" ) );
928 addSignal( wxS(
"onoise_spectrum" ) );
931 if( simType ==
ST_SP )
933 std::vector<std::string> portnums;
937 wxString
name = item.model->SpiceGenerator().ItemName( item );
940 if( !
name.StartsWith(
"V" ) )
943 std::string portnum =
"";
945 if(
const SIM_MODEL::PARAM* portnum_param = item.model->FindParam(
"portnum" ) )
949 portnums.push_back( portnum );
952 for(
const std::string& portnum1 : portnums )
954 for(
const std::string& portnum2 : portnums )
956 addSignal( wxString::Format( wxS(
"S_%s_%s" ), portnum1, portnum2 ) );
962 for(
const wxString& directive :
circuitModel()->GetDirectives() )
964 wxStringTokenizer directivesTokenizer( directive, wxT(
"\r\n" ), wxTOKEN_STRTOK );
966 while( directivesTokenizer.HasMoreTokens() )
968 wxString line = directivesTokenizer.GetNextToken().Upper();
969 wxString directiveParams;
971 if( line.StartsWith( wxS(
".SAVE" ), &directiveParams )
972 || line.StartsWith( wxS(
".PROBE" ), &directiveParams ) )
974 wxStringTokenizer paramsTokenizer( directiveParams, wxT(
" \t" ), wxTOKEN_STRTOK );
976 while( paramsTokenizer.HasMoreTokens() )
977 addSignal( paramsTokenizer.GetNextToken() );
1000 wxString pageTitle(
simulator()->TypeToName( simType,
true ) );
1001 pageTitle.Prepend( wxString::Format(
_(
"Analysis %u - " ), (
unsigned int) ++
m_plotNumber ) );
1017 wxPoint pos = aEvent.GetPosition();
1018 wxRect ctrlRect =
m_filter->GetScreenRect();
1019 int buttonWidth = ctrlRect.GetHeight();
1021 if(
m_filter->IsSearchButtonVisible() && pos.x < buttonWidth )
1022 SetCursor( wxCURSOR_ARROW );
1023 else if(
m_filter->IsCancelButtonVisible() && pos.x > ctrlRect.GetWidth() - buttonWidth )
1024 SetCursor( wxCURSOR_ARROW );
1026 SetCursor( wxCURSOR_IBEAM );
1032 return wxString::Format( wxS(
"user%d" ), aUserDefinedSignalId );
1041 const wxString& aSignalName,
1044 std::map<wxString, int> suffixes;
1060 wxUniChar firstChar = aSignalName.Upper()[0];
1062 if( firstChar ==
'V' )
1064 else if( firstChar ==
'I' )
1066 else if( firstChar ==
'P' )
1072 wxString
name = aSignalName;
1074 for(
const auto& [ candidate, type ] : suffixes )
1076 if(
name.EndsWith( candidate ) )
1078 name =
name.Left(
name.Length() - candidate.Length() );
1081 *aTraceType |= type;
1089 if(
name == signal )
1107 int row = aEvent.GetRow();
1108 int col = aEvent.GetCol();
1116 if(
text == wxS(
"1" ) )
1143 for(
int ii = 0; ii <
m_signalsGrid->GetNumberRows(); ++ii )
1149 bool enable = ii == row &&
text == wxS(
"1" );
1151 plotTab->
EnableCursor( vectorName, traceType,
id, enable, signalName );
1171 int row = aEvent.GetRow();
1172 int col = aEvent.GetCol();
1178 CURSOR* cursor1 =
nullptr;
1179 CURSOR* cursor2 =
nullptr;
1192 if( cursorName == wxS(
"1" ) && cursor1 )
1194 else if( cursorName == wxS(
"2" ) && cursor2 )
1196 else if( cursorName ==
_(
"Diff" ) && cursor1 && cursor2 )
1204 wxFAIL_MSG( wxT(
"All other columns are supposed to be read-only!" ) );
1237 int row = aEvent.GetRow();
1238 int col = aEvent.GetCol();
1249 wxFAIL_MSG( wxT(
"All other columns are supposed to be read-only!" ) );
1257 for( row = rowCount - 1; row >= 0; row-- )
1267 int killRows = emptyRows - 1;
1270 else if( emptyRows == 0 )
1281 if( plotTab->GetLegendPosition() != plotTab->m_LastLegendPosition )
1283 plotTab->m_LastLegendPosition = plotTab->GetLegendPosition();
1306 static wxRegEx measureParamsRegEx( wxT(
"^"
1310 "([a-zA-Z]*)\\(([^\\)]+)\\)" ) );
1319 if(
text.IsEmpty() )
1326 wxString resultName = wxString::Format( wxS(
"meas_result_%u" ), aRow );
1327 wxString result = wxS(
"?" );
1329 if( measureParamsRegEx.Matches(
text ) )
1331 wxString func = measureParamsRegEx.GetMatch(
text, 1 ).Upper();
1332 wxString signalType = measureParamsRegEx.GetMatch(
text, 2 ).Upper();
1333 wxString deviceName = measureParamsRegEx.GetMatch(
text, 3 );
1337 if( signalType.EndsWith( wxS(
"DB" ) ) )
1339 units = wxS(
"dB" );
1341 else if( signalType.StartsWith(
'I' ) )
1345 else if( signalType.StartsWith(
'P' ) )
1349 text = func +
" " + deviceName +
":power";
1356 if( func.EndsWith( wxS(
"_AT" ) ) )
1359 units = wxS(
"Hz" );
1363 else if( func.StartsWith( wxS(
"INTEG" ) ) )
1368 if ( signalType.StartsWith(
'P' ) )
1371 units += wxS(
".s" );
1381 units += wxS(
"·Hz" );
1389 units += wxS(
"·?" );
1402 wxString cmd = wxString::Format( wxS(
"meas %s %s %s" ), simType, resultName,
text );
1403 simulator()->Command(
"echo " + cmd.ToStdString() );
1404 simulator()->Command( cmd.ToStdString() );
1406 std::vector<double> resultVec =
simulator()->GetGainVector( resultName.ToStdString() );
1408 if( resultVec.size() > 0 )
1423 wxString ref = aSymbol->
GetRef( &aSheetPath );
1428 if( tuner->GetSymbolRef() == ref )
1454 const wxString& aRef,
const wxString& aValue )
1462 + wxString::Format(
_(
"%s not found" ), aRef ) );
1475 + wxString::Format(
_(
"%s is not tunable" ), aRef ) );
1541 wxString cmd = wxString::Format( wxS(
"fourier %s %s" ),
1545 simulator()->Command( cmd.ToStdString() );
1559 m_simConsole->AppendText(
_(
"Error: no current simulation.\n" ) );
1568 m_simConsole->AppendText(
_(
"Error: simulation type not defined.\n" ) );
1574 m_simConsole->AppendText(
_(
"Error: simulation type doesn't support plotting.\n" ) );
1580 wxCHECK( plotTab, );
1582 if( simType ==
ST_AC )
1587 else if( simType ==
ST_SP )
1618 if( aNewSignals.count(
id ) == 0 )
1623 plotTab->
DeleteTrace( vectorName, traceType | subType );
1628 plotTab->
DeleteTrace( vectorName, traceType | subType );
1641 if(
TRACE* trace = plotTab->
GetTrace( vectorName, traceType | subType ) )
1642 trace->SetName( aNewSignals.at(
id ) );
1649 if(
TRACE* trace = plotTab->
GetTrace( vectorName, traceType | subType ) )
1650 trace->SetName( aNewSignals.at(
id ) );
1655 if(
TRACE* trace = plotTab->
GetTrace( vectorName, traceType ) )
1656 trace->SetName( aNewSignals.at(
id ) );
1684 wxString simVectorName = aVectorName;
1687 simVectorName = simVectorName.AfterFirst(
'(' ).BeforeLast(
')' ) + wxS(
":power" );
1692 simulator()->Command( wxString::Format( wxT(
"print %s" ), aVectorName ).ToStdString() );
1697 std::vector<double> data_x;
1698 std::vector<double> data_y;
1700 if( !aDataX || aClearData )
1704 if( aDataX->empty() && !aClearData )
1706 wxString xAxisName(
simulator()->GetXAxis( simType ) );
1708 if( xAxisName.IsEmpty() )
1711 *aDataX =
simulator()->GetGainVector( (
const char*) xAxisName.c_str() );
1714 unsigned int size = aDataX->size();
1720 data_y =
simulator()->GetGainVector( (
const char*) simVectorName.c_str(), size );
1722 data_y =
simulator()->GetPhaseVector( (
const char*) simVectorName.c_str(), size );
1724 wxFAIL_MSG( wxT(
"Plot type missing AC_PHASE or AC_MAG bit" ) );
1729 data_y =
simulator()->GetGainVector( (
const char*) simVectorName.c_str(), size );
1731 data_y =
simulator()->GetPhaseVector( (
const char*) simVectorName.c_str(), size );
1733 wxFAIL_MSG( wxT(
"Plot type missing AC_PHASE or SPT_SP_AMP bit" ) );
1738 data_y =
simulator()->GetGainVector( (
const char*) simVectorName.c_str(), -1 );
1744 data_y =
simulator()->GetGainVector( (
const char*) simVectorName.c_str(), size );
1748 wxFAIL_MSG( wxT(
"Unhandled plot type" ) );
1753 size_t sweepSize = std::numeric_limits<size_t>::max();
1755 if( simType ==
ST_DC
1762 sweepSize = aDataX->size() / sweepCount;
1767 if( data_y.size() >= size )
1768 aPlotTab->
SetTraceData( trace, *aDataX, data_y, sweepCount, sweepSize );
1777 for(
int row = 0; row <
m_signalsGrid->GetNumberRows(); ++row )
1783 if(
TRACE* trace = plotTab ? plotTab->
GetTrace( vectorName, traceType ) :
nullptr )
1787 wxGridCellAttr* attr =
new wxGridCellAttr;
1790 attr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
1796 attr =
new wxGridCellAttr;
1797 attr->SetRenderer(
new wxGridCellBoolRenderer() );
1798 attr->SetReadOnly();
1799 attr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
1802 attr =
new wxGridCellAttr;
1803 attr->SetRenderer(
new wxGridCellBoolRenderer() );
1804 attr->SetReadOnly();
1805 attr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
1808 if( trace->HasCursor( 1 ) )
1813 if( trace->HasCursor( 2 ) )
1822 wxGridCellAttr* attr =
new wxGridCellAttr;
1823 attr->SetReadOnly();
1827 attr =
new wxGridCellAttr;
1828 attr->SetReadOnly();
1832 attr =
new wxGridCellAttr;
1833 attr->SetReadOnly();
1843 auto quoteNetNames =
1844 [&]( wxString aExpression ) -> wxString
1847 aExpression.Replace( netname, quotedNetname );
1854 constexpr const char* cmd =
"let user{} = {}";
1856 simulator()->Command(
"echo " + fmt::format( cmd,
id, signal.ToStdString() ) );
1857 simulator()->Command( fmt::format( cmd,
id, quoteNetNames( signal ).ToStdString() ) );
1870 wxString ref = tuner->GetSymbolRef();
1871 KIID symbolId = tuner->GetSymbol( &sheetPath );
1877 reporter.
Report( wxString::Format(
_(
"%s not found" ), ref ) );
1885 reporter.
Report( wxString::Format(
_(
"%s is not tunable" ), ref ) );
1889 double floatVal = tuner->GetValue().ToDouble();
1901 wxTextFile file( aPath );
1906 wxString firstLine = file.GetFirstLine();
1908 bool legacy = firstLine.StartsWith( wxT(
"version " ) ) || firstLine.ToLong( &
dummy );
1933 wxFileName filename( aPath );
1937 simulator()->Settings()->SetWorkbookFilename( filename.GetFullPath() );
1945 wxFFileInputStream fp( aPath, wxT(
"rt" ) );
1946 wxStdInputStream fstream( fp );
1953 nlohmann::json js = nlohmann::json::parse( fstream,
nullptr,
true,
true );
1955 std::map<SIM_PLOT_TAB*, nlohmann::json> traceInfo;
1957 for(
const nlohmann::json& tab_js : js[
"tabs" ] )
1959 wxString simCommand;
1963 for(
const nlohmann::json& cmd : tab_js[
"commands" ] )
1965 if( cmd ==
".kicad adjustpaths" )
1967 else if( cmd ==
".save all" )
1969 else if( cmd ==
".probe alli" )
1971 else if( cmd ==
".probe allp" )
1973 else if( cmd ==
".kicad esavenone" )
1976 simCommand += wxString( cmd.get<wxString>() ).Trim();
1986 if( tab_js.contains(
"traces" ) )
1987 traceInfo[plotTab] = tab_js[
"traces" ];
1989 if( tab_js.contains(
"measurements" ) )
1991 for(
const nlohmann::json& m_js : tab_js[
"measurements" ] )
1992 plotTab->
Measurements().emplace_back( m_js[
"expr" ], m_js[
"format" ] );
1996 plotTab->
ShowGrid( tab_js[
"showGrid" ] );
1998 if( tab_js.contains(
"fixedY1scale" ) )
2000 const nlohmann::json& scale_js = tab_js[
"fixedY1scale" ];
2001 plotTab->
SetY1Scale(
true, scale_js[
"min" ], scale_js[
"max" ] );
2005 if( tab_js.contains(
"fixedY2scale" ) )
2007 const nlohmann::json& scale_js = tab_js[
"fixedY2scale" ];
2008 plotTab->
SetY2Scale(
true, scale_js[
"min" ], scale_js[
"max" ] );
2012 if( tab_js.contains(
"fixedY3scale" ) )
2015 const nlohmann::json& scale_js = tab_js[
"fixedY3scale" ];
2016 plotTab->
SetY3Scale(
true, scale_js[
"min" ], scale_js[
"max" ] );
2020 if( tab_js.contains(
"legend" ) )
2022 const nlohmann::json& legend_js = tab_js[
"legend" ];
2027 if( tab_js.contains(
"margins" ) )
2029 const nlohmann::json& margins_js = tab_js[
"margins" ];
2031 margins_js[
"right" ],
2032 margins_js[
"bottom" ],
2033 margins_js[
"left" ] );
2040 if( js.contains(
"user_defined_signals" ) )
2042 for(
const nlohmann::json& signal_js : js[
"user_defined_signals" ] )
2048 int aCursorId,
const nlohmann::json& aCursor_js )
2050 if( aCursorId == 1 || aCursorId == 2 )
2054 cursor->SetName( aSignalName );
2055 cursor->SetPen( wxPen( aTrace->GetTraceColour() ) );
2056 cursor->SetCoordX( aCursor_js[
"position" ] );
2058 aTrace->SetCursor( aCursorId,
cursor );
2066 for(
const auto& [ plotTab, traces_js ] : traceInfo )
2068 for(
const nlohmann::json& trace_js : traces_js )
2070 wxString signalName = trace_js[
"signal" ];
2072 TRACE* trace = plotTab->GetOrAddTrace( vectorName, trace_js[
"trace_type" ] );
2076 if( trace_js.contains(
"cursor1" ) )
2077 addCursor( plotTab, trace, signalName, 1, trace_js[
"cursor1" ] );
2079 if( trace_js.contains(
"cursor2" ) )
2080 addCursor( plotTab, trace, signalName, 2, trace_js[
"cursor2" ] );
2082 if( trace_js.contains(
"cursorD" ) )
2083 addCursor( plotTab, trace, signalName, 3, trace_js[
"cursorD" ] );
2085 if( trace_js.contains(
"color" ) )
2088 color.Set( wxString( trace_js[
"color"].get<wxString>() ) );
2090 plotTab->UpdateTraceStyle( trace );
2095 plotTab->UpdatePlotColors();
2104 wxCHECK( simTab,
false );
2106 simTab->SetLastSchTextSimCommand( js[
"last_sch_text_sim_command" ] );
2109 catch( nlohmann::json::parse_error& error )
2111 wxLogTrace(
traceSettings, wxT(
"Json parse error reading %s: %s" ), aPath, error.what() );
2115 catch( nlohmann::json::type_error& error )
2117 wxLogTrace(
traceSettings, wxT(
"Json type error reading %s: %s" ), aPath, error.what() );
2121 catch( nlohmann::json::invalid_iterator& error )
2123 wxLogTrace(
traceSettings, wxT(
"Json invalid_iterator error reading %s: %s" ), aPath, error.what() );
2127 catch( nlohmann::json::out_of_range& error )
2129 wxLogTrace(
traceSettings, wxT(
"Json out_of_range error reading %s: %s" ), aPath, error.what() );
2135 wxLogTrace(
traceSettings, wxT(
"Error reading %s" ), aPath );
2147 wxFileName filename = aPath;
2152 file.Create( filename.GetFullPath(),
true );
2154 if( !file.IsOpened() )
2157 nlohmann::json tabs_js = nlohmann::json::array();
2168 nlohmann::json commands_js = nlohmann::json::array();
2175 commands_js.push_back(
".kicad adjustpaths" );
2178 commands_js.push_back(
".save all" );
2181 commands_js.push_back(
".probe alli" );
2184 commands_js.push_back(
".probe allp" );
2187 commands_js.push_back(
".kicad esavenone" );
2189 nlohmann::json tab_js = nlohmann::json(
2191 {
"commands", commands_js } } );
2195 nlohmann::json traces_js = nlohmann::json::array();
2197 auto findSignalName =
2198 [&](
const wxString& aVectorName ) -> wxString
2200 wxString vectorName;
2203 if( aVectorName.EndsWith(
_(
" (phase)" ) ) )
2204 suffix =
_(
" (phase)" );
2205 else if( aVectorName.EndsWith(
_(
" (gain)" ) ) )
2206 suffix =
_(
" (gain)" );
2208 vectorName = aVectorName.Left( aVectorName.Length() - suffix.Length() );
2213 return signal + suffix;
2219 for(
const auto& [
name, trace] : plotTab->GetTraces() )
2221 nlohmann::json trace_js = nlohmann::json(
2222 { {
"trace_type", (int) trace->GetType() },
2223 {
"signal", findSignalName( trace->GetDisplayName() ) },
2228 trace_js[
"cursor1"] = nlohmann::json(
2229 { {
"position",
cursor->GetCoords().x },
2236 trace_js[
"cursor2"] = nlohmann::json(
2237 { {
"position",
cursor->GetCoords().x },
2242 if( trace->GetCursor( 1 ) || trace->GetCursor( 2 ) )
2244 trace_js[
"cursorD"] = nlohmann::json(
2249 traces_js.push_back( trace_js );
2252 nlohmann::json measurements_js = nlohmann::json::array();
2254 for(
const auto& [
measurement, format ] : plotTab->Measurements() )
2256 measurements_js.push_back( nlohmann::json( { {
"expr",
measurement },
2257 {
"format", format } } ) );
2260 tab_js[
"traces" ] = traces_js;
2261 tab_js[
"measurements" ] = measurements_js;
2262 tab_js[
"dottedSecondary" ] = plotTab->GetDottedSecondary();
2263 tab_js[
"showGrid" ] = plotTab->IsGridShown();
2267 if( plotTab->GetY1Scale( &min, &max ) )
2268 tab_js[
"fixedY1scale" ] = nlohmann::json( { {
"min", min }, {
"max", max } } );
2270 if( plotTab->GetY2Scale( &min, &max ) )
2271 tab_js[
"fixedY2scale" ] = nlohmann::json( { {
"min", min }, {
"max", max } } );
2273 if( plotTab->GetY3Scale( &min, &max ) )
2274 tab_js[
"fixedY3scale" ] = nlohmann::json( { {
"min", min }, {
"max", max } } );
2276 if( plotTab->IsLegendShown() )
2278 tab_js[
"legend" ] = nlohmann::json( { {
"x", plotTab->GetLegendPosition().x },
2279 {
"y", plotTab->GetLegendPosition().y } } );
2282 mpWindow* plotWin = plotTab->GetPlotWin();
2284 tab_js[
"margins" ] = nlohmann::json( { {
"left", plotWin->
GetMarginLeft() },
2290 tabs_js.push_back( tab_js );
2293 nlohmann::json userDefinedSignals_js = nlohmann::json::array();
2296 userDefinedSignals_js.push_back( signal );
2298 nlohmann::json js = nlohmann::json( { {
"version", 6 },
2299 {
"tabs", tabs_js },
2300 {
"user_defined_signals", userDefinedSignals_js } } );
2311 std::stringstream buffer;
2312 buffer << std::setw( 2 ) << js << std::endl;
2314 bool res = file.Write( buffer.str() );
2321 simulator()->Settings()->SetWorkbookFilename( filename.GetFullPath() );
2339 default: wxFAIL_MSG( wxS(
"Unhandled simulation type" ) );
return SPT_UNKNOWN;
2358 &source, &
scale, &pts, &fStart, &fStop, &saveAll );
2373 for(
size_t page = 0; page <
m_plotNotebook->GetPageCount(); page++ )
2418 std::vector<std::pair<wxString, wxString>>& measurements = plotTab->Measurements();
2420 measurements.clear();
2458 simulator()->Command(
"setplot " + simTab->GetSpicePlotName().ToStdString() );
2472 for(
const auto& [
measurement, format ] : plotTab->Measurements() )
2480 if( plotTab->GetSimType() ==
ST_TRAN || plotTab->GetSimType() ==
ST_AC
2481 || plotTab->GetSimType() ==
ST_DC || plotTab->GetSimType() ==
ST_SP )
2518 CURSOR* cursor1 =
nullptr;
2519 wxString cursor1Name;
2520 wxString cursor1Units;
2521 CURSOR* cursor2 =
nullptr;
2522 wxString cursor2Name;
2523 wxString cursor2Units;
2526 [&](
TRACE* aTrace ) -> wxString
2547 [&](
TRACE* aTrace ) -> wxString
2568 [
this](
double aValue,
int aCursorId,
int aCol ) -> wxString
2581 cursor1Name = getNameY( trace );
2582 cursor1Units = getUnitsY( trace );
2584 wxRealPoint coords =
cursor->GetCoords();
2604 cursor2Name = getNameY( trace );
2605 cursor2Units = getUnitsY( trace );
2607 wxRealPoint coords =
cursor->GetCoords();
2622 if( cursor1 && cursor2 && cursor1Units == cursor2Units )
2631 signal = wxString::Format( wxS(
"%s[2 - 1]" ), cursor2->
GetName() );
2633 signal = wxString::Format( wxS(
"%s - %s" ), cursor2->
GetName(), cursor1->
GetName() );
2645 wxString valColName =
_(
"Value" );
2647 if( !cursor1Name.IsEmpty() )
2649 if( cursor2Name.IsEmpty() || cursor1Name == cursor2Name )
2650 valColName = cursor1Name;
2652 else if( !cursor2Name.IsEmpty() )
2654 valColName = cursor2Name;
2671 plotTab->ResetScales(
true );
2691 std::vector<wxString> signals;
2693 for(
const std::string& vec :
simulator()->AllVectors() )
2694 signals.emplace_back( vec );
2702 std::vector<wxString> signals;
2704 for(
const wxString& signal :
m_signals )
2705 signals.emplace_back( signal );
2708 signals.emplace_back( signal );
2740 if( simType ==
ST_NOISE && aFinal )
2742 m_simConsole->AppendText(
_(
"\n\nSimulation results:\n\n" ) );
2749 simulator()->CurrentPlotName().Mid( 5 ).ToLong( &number );
2751 for(
const std::string& vec :
simulator()->AllVectors() )
2753 std::vector<double> val_list =
simulator()->GetRealVector( vec, 1 );
2756 msg.Printf( wxS(
"%s: %sV\n" ), vec, value );
2762 simulator()->Command( fmt::format(
"setplot noise{}", number - 1 ) );
2767 wxCHECK_RET( plotTab, wxT(
"not a SIM_PLOT_TAB" ) );
2776 std::map<TRACE*, TRACE_INFO> traceMap;
2779 traceMap[ trace ] = { wxEmptyString,
SPT_UNKNOWN,
false };
2784 for(
const wxString& signal :
m_signals )
2789 if(
TRACE* trace = plotTab->
GetTrace( vectorName, traceType ) )
2790 traceMap[ trace ] = { vectorName, traceType,
false };
2798 if( simType ==
ST_AC )
2804 if(
TRACE* trace = plotTab->
GetTrace( vectorName, subType ) )
2805 traceMap[ trace ] = { vectorName, subType, !aFinal };
2808 else if( simType ==
ST_SP )
2814 if(
TRACE* trace = plotTab->
GetTrace( vectorName, subType ) )
2815 traceMap[trace] = { vectorName, subType, !aFinal };
2820 if(
TRACE* trace = plotTab->
GetTrace( vectorName, traceType ) )
2821 traceMap[ trace ] = { vectorName, traceType, !aFinal };
2827 for(
const auto& [ trace, traceInfo ] : traceMap )
2829 if( traceInfo.Vector.IsEmpty() )
2833 for(
const auto& [ trace,
info ] : traceMap )
2835 std::vector<double> data_x;
2837 if( !
info.Vector.IsEmpty() )
2855 else if( simType ==
ST_OP && aFinal )
2857 m_simConsole->AppendText(
_(
"\n\nSimulation results:\n\n" ) );
2860 for(
const std::string& vec :
simulator()->AllVectors() )
2862 std::vector<double> val_list =
simulator()->GetRealVector( vec, 1 );
2864 if( val_list.empty() )
2871 const size_t tab = 25;
2872 size_t padding = ( signal.length() < tab ) ? ( tab - signal.length() ) : 1;
2876 case SPT_VOLTAGE: value.Append( wxS(
"V" ) );
break;
2877 case SPT_CURRENT: value.Append( wxS(
"A" ) );
break;
2878 case SPT_POWER: value.Append( wxS(
"W" ) );
break;
2879 default: value.Append( wxS(
"?" ) );
break;
2882 msg.Printf( wxT(
"%s%s\n" ),
2883 ( signal + wxT(
":" ) ).Pad( padding, wxUniChar(
' ' ) ),
2890 signal = signal.SubString( 2, signal.Length() - 2 );
2893 signal += wxS(
":power" );
2898 else if( simType ==
ST_PZ && aFinal )
2900 m_simConsole->AppendText(
_(
"\n\nSimulation results:\n\n" ) );
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)
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)
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)
void EnableCursor(const wxString &aVectorName, int aType, int aCursorId, bool aEnable, const wxString &aSignalName)
Reset scale ranges to fit the current traces.
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)
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
wxString GetUnitsY3() const
int GetSimOptions() const
virtual void OnLanguageChanged()=0
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)
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.
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
SIM_TRACE_TYPE operator|(SIM_TRACE_TYPE aFirst, SIM_TRACE_TYPE aSecond)
@ MYID_DELETE_MEASUREMENT
std::vector< FAB_LAYER_COLOR > dummy
wxString UnescapeString(const wxString &aSource)
int measurements_panel_height
SIM_PREFERENCES preferences
Contains preferences pertaining to the simulator.
constexpr ret_type KiROUND(fp_type v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition of file extensions used in Kicad.