29#include <fmt/format.h>
30#include <wx/wfstream.h>
31#include <wx/stdstream.h>
57 int res = (int) aFirst | (
int) aSecond;
118 void showPopupMenu( wxMenu& menu, wxGridEvent& aEvent )
override;
142 if( panel->GetSimType() ==
ST_TRAN || panel->GetSimType() ==
ST_AC
143 || panel->GetSimType() ==
ST_DC || panel->GetSimType() ==
ST_SP )
151 if( panel->GetSimType() ==
ST_AC || panel->GetSimType() ==
ST_SP )
164 if( panel->GetSimType() ==
ST_TRAN )
166 menu.AppendSeparator();
167 menu.Append(
MYID_FOURIER,
_(
"Perform Fourier Analysis..." ) );
170 menu.AppendSeparator();
181 std::vector<wxString> signals;
183 wxGridCellCoordsArray cells1 =
m_grid->GetSelectionBlockTopLeft();
184 wxGridCellCoordsArray cells2 =
m_grid->GetSelectionBlockBottomRight();
186 for(
size_t i = 0; i < cells1.Count(); i++ )
190 for(
int j = cells1[i].GetRow(); j < cells2[i].GetRow() + 1; j++ )
192 signals.push_back(
m_grid->GetCellValue( j, cells1[i].GetCol() ) );
197 wxGridCellCoordsArray cells3 =
m_grid->GetSelectedCells();
199 for(
size_t i = 0; i < cells3.Count(); i++ )
202 signals.push_back(
m_grid->GetCellValue( cells3[i].GetRow(), cells3[i].GetCol() ) );
205 if( signals.size() < 1 )
208 auto addMeasurement =
209 [
this](
const wxString& cmd, wxString signal )
211 if( signal.EndsWith(
_(
" (phase)" ) ) )
214 if( signal.EndsWith(
_(
" (gain)" ) ) || signal.EndsWith(
_(
" (amplitude)" ) ) )
216 signal = signal.Left( signal.length() - 7 );
218 if( signal.Upper().StartsWith( wxS(
"V(" ) ) )
219 signal = wxS(
"vdb" ) + signal.Mid( 1 );
227 for(
const wxString& signal : signals )
228 addMeasurement( wxS(
"MIN" ), signal );
232 for(
const wxString& signal : signals )
233 addMeasurement( wxS(
"MAX" ), signal );
237 for(
const wxString& signal : signals )
238 addMeasurement( wxS(
"AVG" ), signal );
242 for(
const wxString& signal : signals )
243 addMeasurement( wxS(
"RMS" ), signal );
247 for(
const wxString& signal : signals )
248 addMeasurement( wxS(
"PP" ), signal );
252 for(
const wxString& signal : signals )
253 addMeasurement( wxS(
"MIN_AT" ), signal );
257 for(
const wxString& signal : signals )
258 addMeasurement( wxS(
"MAX_AT" ), signal );
262 for(
const wxString& signal : signals )
263 addMeasurement( wxS(
"INTEG" ), signal );
268 wxString fundamental = wxT(
"1K" );
270 if( signals.size() == 1 )
271 title.Printf(
_(
"Fourier Analysis of %s" ), signals[0] );
273 title =
_(
"Fourier Analyses of Multiple Signals" );
277 if( dlg.ShowModal() != wxID_OK )
283 for(
const wxString& signal : signals )
304 void showPopupMenu( wxMenu& menu, wxGridEvent& aEvent )
override;
324 menu.AppendSeparator();
334 [
this](
int row ) -> wxString
338 if( signal.EndsWith(
"[2 - 1]" ) )
339 signal = signal.Left( signal.length() - 7 );
350 if( formatDialog.ShowModal() == wxID_OK )
352 for(
int row = 0; row <
m_grid->GetNumberRows(); ++row )
354 if( getSignalName( row ) == getSignalName(
m_menuRow ) )
377 void showPopupMenu( wxMenu& menu, wxGridEvent& aEvent )
override;
403 menu.AppendSeparator();
416 if( formatDialog.ShowModal() == wxID_OK )
425 std::vector<int> measurements;
427 wxGridCellCoordsArray cells1 =
m_grid->GetSelectionBlockTopLeft();
428 wxGridCellCoordsArray cells2 =
m_grid->GetSelectionBlockBottomRight();
430 for(
size_t i = 0; i < cells1.Count(); i++ )
434 for(
int j = cells1[i].GetRow(); j < cells2[i].GetRow() + 1; j++ )
435 measurements.push_back( j );
439 wxGridCellCoordsArray cells3 =
m_grid->GetSelectedCells();
441 for(
size_t i = 0; i < cells3.Count(); i++ )
444 measurements.push_back( cells3[i].GetRow() );
447 if( measurements.size() < 1 )
452 sort( measurements.begin(), measurements.end(), std::greater<>() );
454 for(
int row : measurements )
487#define ID_SIM_REFRESH 10207
488#define REFRESH_INTERVAL 50
494 m_SuppressGridEvents( 0 ),
495 m_simulatorFrame( aSimulatorFrame ),
496 m_schematicFrame( aSchematicFrame ),
514 wxGridCellAttr* attr =
new wxGridCellAttr;
518 attr =
new wxGridCellAttr;
522 attr =
new wxGridCellAttr;
526 attr =
new wxGridCellAttr;
530 for(
int cursorId = 0; cursorId < 3; ++cursorId )
536 attr =
new wxGridCellAttr;
546 [&]( wxTimerEvent& aEvent )
555#ifndef wxHAS_NATIVE_TABART
573 for(
int ii = 0; ii < (int)
m_plotNotebook->GetPageCount(); ++ii )
582 pageTitle.Prepend( wxString::Format(
_(
"Analysis %u - " ), ii+1 ) );
602 tuner->ShowChangedLanguage();
631 if( !
simulator()->Settings()->GetWorkbookFilename().IsEmpty() )
633 wxFileName filename =
simulator()->Settings()->GetWorkbookFilename();
637 simulator()->Settings()->SetWorkbookFilename(
"" );
641 wxString schTextSimCommand =
circuitModel()->GetSchTextSimCommand();
643 if( !schTextSimCommand.IsEmpty() )
676 std::sort( signals.begin(), signals.end(),
677 [](
const wxString& lhs,
const wxString& rhs )
680 if( lhs.Upper().StartsWith(
'V' ) && !rhs.Upper().StartsWith(
'V' ) )
682 else if( !lhs.Upper().StartsWith(
'V' ) && rhs.Upper().StartsWith(
'V' ) )
685 return StrNumCmp( lhs, rhs, true ) < 0;
702 std::vector<wxString> signals;
706 wxStringTokenizer tokenizer( plotPanel->
GetSimCommand(), wxT(
" \t\r\n" ), wxTOKEN_STRTOK );
708 while( tokenizer.HasMoreTokens() && tokenizer.GetNextToken().Lower() != wxT(
"fft" ) )
711 while( tokenizer.HasMoreTokens() )
712 signals.emplace_back( tokenizer.GetNextToken() );
719 for(
const wxString& signal :
m_signals )
720 signals.push_back( signal );
724 if( simType ==
ST_AC )
726 signals.push_back( signal +
_(
" (gain)" ) );
727 signals.push_back( signal +
_(
" (phase)" ) );
729 else if( simType ==
ST_SP )
731 signals.push_back( signal +
_(
" (amplitude)" ) );
732 signals.push_back( signal +
_(
" (phase)" ) );
736 signals.push_back( signal );
743 if( aFilter.IsEmpty() )
744 aFilter = wxS(
"*" );
749 for(
const wxString& signal : signals )
751 if( matcher.
Find( signal.Upper() ) )
755 TRACE* trace = plotPanel ? plotPanel->
GetTrace( vectorName, traceType ) :
nullptr;
762 wxGridCellAttr* attr =
new wxGridCellAttr;
768 wxGridCellAttr* attr =
new wxGridCellAttr;
769 attr->SetRenderer(
new wxGridCellBoolRenderer() );
771 attr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
778 if( !plotPanel || !trace )
780 wxGridCellAttr* attr =
new wxGridCellAttr;
785 attr =
new wxGridCellAttr;
789 attr =
new wxGridCellAttr;
795 wxGridCellAttr* attr =
new wxGridCellAttr;
796 attr =
new wxGridCellAttr;
799 attr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
804 attr =
new wxGridCellAttr;
805 attr->SetRenderer(
new wxGridCellBoolRenderer() );
807 attr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
810 attr =
new wxGridCellAttr;
811 attr->SetRenderer(
new wxGridCellBoolRenderer() );
813 attr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
829 wxString unconnected = wxString( wxS(
"unconnected-(" ) );
834 unconnected.Replace(
'(',
'_' );
837 [&](
const wxString& aSignalName )
839 if( simType ==
ST_AC )
841 m_signals.push_back( aSignalName +
_(
" (gain)" ) );
842 m_signals.push_back( aSignalName +
_(
" (phase)" ) );
844 else if( simType ==
ST_SP )
846 m_signals.push_back( aSignalName +
_(
" (amplitude)" ) );
847 m_signals.push_back( aSignalName +
_(
" (phase)" ) );
858 for(
const std::string& net :
circuitModel()->GetNets() )
863 if( netname ==
"GND" || netname ==
"0" || netname.StartsWith( unconnected ) )
867 addSignal( wxString::Format( wxS(
"V(%s)" ), netname ) );
877 for(
const std::string&
name : item.model->SpiceGenerator().CurrentNames( item ) )
887 if( item.model->GetPinCount() >= 2 )
889 wxString
name = item.model->SpiceGenerator().ItemName( item );
890 addSignal( wxString::Format( wxS(
"P(%s)" ),
name ) );
897 addSignal( wxS(
"inoise_spectrum" ) );
898 addSignal( wxS(
"onoise_spectrum" ) );
901 if( simType ==
ST_SP )
903 std::vector<std::string> portnums;
907 wxString
name = item.model->SpiceGenerator().ItemName( item );
910 if( !
name.StartsWith(
"V" ) )
919 for(
const std::string& portnum1 : portnums )
921 for(
const std::string& portnum2 : portnums )
923 addSignal( wxString::Format( wxS(
"S_%s_%s" ), portnum1, portnum2 ) );
929 for(
const wxString& directive :
circuitModel()->GetDirectives() )
931 wxStringTokenizer tokenizer( directive, wxT(
"\r\n" ), wxTOKEN_STRTOK );
933 while( tokenizer.HasMoreTokens() )
935 wxString line = tokenizer.GetNextToken();
936 wxString directiveParams;
938 if( line.Upper().StartsWith( wxS(
".PROBE" ), &directiveParams ) )
939 addSignal( directiveParams.Trim(
true ).Trim(
false ) );
963 wxString pageTitle(
simulator()->TypeToName( simType,
true ) );
964 pageTitle.Prepend( wxString::Format(
_(
"Analysis %u - " ), (
unsigned int) ++
m_plotNumber ) );
980 wxPoint pos = aEvent.GetPosition();
981 wxRect ctrlRect =
m_filter->GetScreenRect();
982 int buttonWidth = ctrlRect.GetHeight();
984 if(
m_filter->IsSearchButtonVisible() && pos.x < buttonWidth )
985 SetCursor( wxCURSOR_ARROW );
986 else if(
m_filter->IsCancelButtonVisible() && pos.x > ctrlRect.GetWidth() - buttonWidth )
987 SetCursor( wxCURSOR_ARROW );
989 SetCursor( wxCURSOR_IBEAM );
995 return wxString::Format( wxS(
"user%d" ), aUserDefinedSignalId );
1004 const wxString& aSignalName,
1007 std::map<wxString, int> suffixes;
1023 wxUniChar firstChar = aSignalName.Upper()[0];
1025 if( firstChar ==
'V' )
1027 else if( firstChar ==
'I' )
1029 else if( firstChar ==
'P' )
1035 wxString
name = aSignalName;
1037 for(
const auto& [ candidate, type ] : suffixes )
1039 if(
name.EndsWith( candidate ) )
1041 name =
name.Left(
name.Length() - candidate.Length() );
1044 *aTraceType |= type;
1052 if(
name == signal )
1070 int row = aEvent.GetRow();
1071 int col = aEvent.GetCol();
1079 if(
text == wxS(
"1" ) )
1106 for(
int ii = 0; ii <
m_signalsGrid->GetNumberRows(); ++ii )
1112 bool enable = ii == row &&
text == wxS(
"1" );
1114 plotTab->
EnableCursor( vectorName, traceType,
id, enable, signalName );
1134 int row = aEvent.GetRow();
1135 int col = aEvent.GetCol();
1141 CURSOR* cursor1 =
nullptr;
1142 CURSOR* cursor2 =
nullptr;
1155 if( cursorName == wxS(
"1" ) && cursor1 )
1157 else if( cursorName == wxS(
"2" ) && cursor2 )
1159 else if( cursorName ==
_(
"Diff" ) && cursor1 && cursor2 )
1167 wxFAIL_MSG( wxT(
"All other columns are supposed to be read-only!" ) );
1200 int row = aEvent.GetRow();
1201 int col = aEvent.GetCol();
1211 wxFAIL_MSG( wxT(
"All other columns are supposed to be read-only!" ) );
1219 for( row = rowCount - 1; row >= 0; row-- )
1229 int killRows = emptyRows - 1;
1232 else if( emptyRows == 0 )
1243 if( plotTab->GetLegendPosition() != plotTab->m_LastLegendPosition )
1265 static wxRegEx measureParamsRegEx( wxT(
"^"
1269 "([a-zA-Z]*)\\(([^\\)]+)\\)" ) );
1278 if(
text.IsEmpty() )
1285 wxString resultName = wxString::Format( wxS(
"meas_result_%u" ), aRow );
1286 wxString result = wxS(
"?" );
1288 if( measureParamsRegEx.Matches(
text ) )
1290 wxString func = measureParamsRegEx.GetMatch(
text, 1 ).Upper();
1291 wxString signalType = measureParamsRegEx.GetMatch(
text, 2 ).Upper();
1292 wxString deviceName = measureParamsRegEx.GetMatch(
text, 3 );
1296 if( signalType.EndsWith( wxS(
"DB" ) ) )
1298 units = wxS(
"dB" );
1300 else if( signalType.StartsWith(
'I' ) )
1304 else if( signalType.StartsWith(
'P' ) )
1308 text = func +
" " + deviceName +
":power";
1315 if( func.EndsWith( wxS(
"_AT" ) ) )
1318 units = wxS(
"Hz" );
1322 else if( func.StartsWith( wxS(
"INTEG" ) ) )
1327 if ( signalType.StartsWith(
'P' ) )
1330 units += wxS(
".s" );
1340 units += wxS(
"·Hz" );
1348 units += wxS(
"·?" );
1359 wxString cmd = wxString::Format( wxS(
"meas %s %s %s" ), simType, resultName,
text );
1360 simulator()->Command(
"echo " + cmd.ToStdString() );
1361 simulator()->Command( cmd.ToStdString() );
1363 std::vector<double> resultVec =
simulator()->GetGainVector( resultName.ToStdString() );
1365 if( resultVec.size() > 0 )
1380 wxString ref = aSymbol->
GetRef( &aSheetPath );
1385 if( tuner->GetSymbolRef() == ref )
1411 const wxString& aRef,
const wxString& aValue )
1419 + wxString::Format(
_(
"%s not found" ), aRef ) );
1432 + wxString::Format(
_(
"%s is not tunable" ), aRef ) );
1498 wxString cmd = wxString::Format( wxS(
"fourier %s %s" ),
1502 simulator()->Command( cmd.ToStdString() );
1516 m_simConsole->AppendText(
_(
"Error: no current simulation.\n" ) );
1525 m_simConsole->AppendText(
_(
"Error: simulation type not defined.\n" ) );
1531 m_simConsole->AppendText(
_(
"Error: simulation type doesn't support plotting.\n" ) );
1537 wxCHECK( plotTab, );
1539 if( simType ==
ST_AC )
1544 else if( simType ==
ST_SP )
1575 if( aNewSignals.count(
id ) == 0 )
1580 plotTab->
DeleteTrace( vectorName, traceType | subType );
1585 plotTab->
DeleteTrace( vectorName, traceType | subType );
1598 if(
TRACE* trace = plotTab->
GetTrace( vectorName, traceType | subType ) )
1599 trace->SetName( aNewSignals.at(
id ) );
1606 if(
TRACE* trace = plotTab->
GetTrace( vectorName, traceType | subType ) )
1607 trace->SetName( aNewSignals.at(
id ) );
1612 if(
TRACE* trace = plotTab->
GetTrace( vectorName, traceType ) )
1613 trace->SetName( aNewSignals.at(
id ) );
1641 wxString simVectorName = aVectorName;
1644 simVectorName = simVectorName.AfterFirst(
'(' ).BeforeLast(
')' ) + wxS(
":power" );
1649 simulator()->Command( wxString::Format( wxT(
"print %s" ), aVectorName ).ToStdString() );
1654 std::vector<double> data_x;
1655 std::vector<double> data_y;
1657 if( !aDataX || aClearData )
1661 if( aDataX->empty() && !aClearData )
1663 wxString xAxisName(
simulator()->GetXAxis( simType ) );
1665 if( xAxisName.IsEmpty() )
1668 *aDataX =
simulator()->GetGainVector( (
const char*) xAxisName.c_str() );
1671 unsigned int size = aDataX->size();
1677 data_y =
simulator()->GetGainVector( (
const char*) simVectorName.c_str(), size );
1679 data_y =
simulator()->GetPhaseVector( (
const char*) simVectorName.c_str(), size );
1681 wxFAIL_MSG( wxT(
"Plot type missing AC_PHASE or AC_MAG bit" ) );
1686 data_y =
simulator()->GetGainVector( (
const char*) simVectorName.c_str(), size );
1688 data_y =
simulator()->GetPhaseVector( (
const char*) simVectorName.c_str(), size );
1690 wxFAIL_MSG( wxT(
"Plot type missing AC_PHASE or SPT_SP_AMP bit" ) );
1695 data_y =
simulator()->GetGainVector( (
const char*) simVectorName.c_str(), -1 );
1701 data_y =
simulator()->GetGainVector( (
const char*) simVectorName.c_str(), size );
1705 wxFAIL_MSG( wxT(
"Unhandled plot type" ) );
1712 if( simType ==
ST_DC
1720 size_t outer = ( size_t )( ( source2.
m_vend - v ) / source2.
m_vincrement ).ToDouble();
1721 size_t inner = aDataX->size() / ( outer + 1 );
1723 wxASSERT( aDataX->size() % ( outer + 1 ) == 0 );
1725 for(
size_t idx = 0; idx <= outer; idx++ )
1729 if( data_y.size() >= size )
1731 std::vector<double> sub_x( aDataX->begin() + offset,
1732 aDataX->begin() + offset + inner );
1733 std::vector<double> sub_y( data_y.begin() + offset,
1734 data_y.begin() + offset + inner );
1746 if( data_y.size() >= size )
1756 for(
int row = 0; row <
m_signalsGrid->GetNumberRows(); ++row )
1762 if(
TRACE* trace = plotTab ? plotTab->
GetTrace( vectorName, traceType ) :
nullptr )
1766 wxGridCellAttr* attr =
new wxGridCellAttr;
1769 attr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
1775 attr =
new wxGridCellAttr;
1776 attr->SetRenderer(
new wxGridCellBoolRenderer() );
1777 attr->SetReadOnly();
1778 attr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
1781 attr =
new wxGridCellAttr;
1782 attr->SetRenderer(
new wxGridCellBoolRenderer() );
1783 attr->SetReadOnly();
1784 attr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
1787 if( trace->HasCursor( 1 ) )
1792 if( trace->HasCursor( 2 ) )
1801 wxGridCellAttr* attr =
new wxGridCellAttr;
1802 attr->SetReadOnly();
1806 attr =
new wxGridCellAttr;
1807 attr->SetReadOnly();
1811 attr =
new wxGridCellAttr;
1812 attr->SetReadOnly();
1822 auto quoteNetNames =
1823 [&]( wxString aExpression ) -> wxString
1826 aExpression.Replace( netname, quotedNetname );
1833 std::string cmd =
"let user{} = {}";
1835 simulator()->Command(
"echo " + fmt::format( cmd,
id, signal.ToStdString() ) );
1836 simulator()->Command( fmt::format( cmd,
id, quoteNetNames( signal ).ToStdString() ) );
1849 wxString ref = tuner->GetSymbolRef();
1850 KIID symbolId = tuner->GetSymbol( &sheetPath );
1856 reporter.
Report( wxString::Format(
_(
"%s not found" ), ref ) );
1864 reporter.
Report( wxString::Format(
_(
"%s is not tunable" ), ref ) );
1868 double floatVal = tuner->GetValue().ToDouble();
1880 wxTextFile file( aPath );
1885 wxString firstLine = file.GetFirstLine();
1887 bool legacy = firstLine.StartsWith( wxT(
"version " ) ) || firstLine.ToLong( &
dummy );
1912 wxFileName filename( aPath );
1916 simulator()->Settings()->SetWorkbookFilename( filename.GetFullPath() );
1924 wxFFileInputStream fp( aPath, wxT(
"rt" ) );
1925 wxStdInputStream fstream( fp );
1932 nlohmann::json js = nlohmann::json::parse( fstream,
nullptr,
true,
true );
1934 std::map<SIM_PLOT_TAB*, nlohmann::json> traceInfo;
1936 for(
const nlohmann::json& tab_js : js[
"tabs" ] )
1938 wxString simCommand;
1941 for(
const nlohmann::json& cmd : tab_js[
"commands" ] )
1943 if( cmd ==
".kicad adjustpaths" )
1945 else if( cmd ==
".save all" )
1947 else if( cmd ==
".probe alli" )
1949 else if( cmd ==
".probe allp" )
1952 simCommand += wxString( cmd.get<wxString>() ).Trim();
1962 if( tab_js.contains(
"traces" ) )
1963 traceInfo[plotTab] = tab_js[
"traces" ];
1965 if( tab_js.contains(
"measurements" ) )
1967 for(
const nlohmann::json& m_js : tab_js[
"measurements" ] )
1968 plotTab->
Measurements().emplace_back( m_js[
"expr" ], m_js[
"format" ] );
1972 plotTab->
ShowGrid( tab_js[
"showGrid" ] );
1974 if( tab_js.contains(
"fixedY1scale" ) )
1976 const nlohmann::json& scale_js = tab_js[
"fixedY1scale" ];
1977 plotTab->
SetY1Scale(
true, scale_js[
"min" ], scale_js[
"max" ] );
1981 if( tab_js.contains(
"fixedY2scale" ) )
1983 const nlohmann::json& scale_js = tab_js[
"fixedY2scale" ];
1984 plotTab->
SetY2Scale(
true, scale_js[
"min" ], scale_js[
"max" ] );
1988 if( tab_js.contains(
"fixedY3scale" ) )
1990 const nlohmann::json& scale_js = tab_js[
"fixedY3scale" ];
1991 plotTab->
SetY3Scale(
true, scale_js[
"min" ], scale_js[
"max" ] );
1995 if( tab_js.contains(
"legend" ) )
1997 const nlohmann::json& legend_js = tab_js[
"legend" ];
2002 if( tab_js.contains(
"margins" ) )
2004 const nlohmann::json& margins_js = tab_js[
"margins" ];
2006 margins_js[
"right" ],
2007 margins_js[
"bottom" ],
2008 margins_js[
"left" ] );
2015 if( js.contains(
"user_defined_signals" ) )
2017 for(
const nlohmann::json& signal_js : js[
"user_defined_signals" ] )
2023 int aCursorId,
const nlohmann::json& aCursor_js )
2025 if( aCursorId == 1 || aCursorId == 2 )
2029 cursor->SetName( aSignalName );
2030 cursor->SetPen( wxPen( aTrace->GetTraceColour() ) );
2031 cursor->SetCoordX( aCursor_js[
"position" ] );
2033 aTrace->SetCursor( aCursorId,
cursor );
2041 for(
const auto& [ plotTab, traces_js ] : traceInfo )
2043 for(
const nlohmann::json& trace_js : traces_js )
2045 wxString signalName = trace_js[
"signal" ];
2047 TRACE* trace = plotTab->GetOrAddTrace( vectorName, trace_js[
"trace_type" ] );
2051 if( trace_js.contains(
"cursor1" ) )
2052 addCursor( plotTab, trace, signalName, 1, trace_js[
"cursor1" ] );
2054 if( trace_js.contains(
"cursor2" ) )
2055 addCursor( plotTab, trace, signalName, 2, trace_js[
"cursor2" ] );
2057 if( trace_js.contains(
"cursorD" ) )
2058 addCursor( plotTab, trace, signalName, 3, trace_js[
"cursorD" ] );
2060 if( trace_js.contains(
"color" ) )
2063 color.Set( wxString( trace_js[
"color"].get<wxString>() ) );
2065 plotTab->UpdateTraceStyle( trace );
2070 plotTab->UpdatePlotColors();
2079 wxCHECK( simTab,
false );
2081 simTab->SetLastSchTextSimCommand( js[
"last_sch_text_sim_command" ] );
2084 catch( nlohmann::json::parse_error& error )
2086 wxLogTrace(
traceSettings, wxT(
"Json parse error reading %s: %s" ), aPath, error.what() );
2099 wxFileName filename = aPath;
2104 file.Create( filename.GetFullPath(),
true );
2106 if( !file.IsOpened() )
2109 nlohmann::json tabs_js = nlohmann::json::array();
2120 nlohmann::json commands_js = nlohmann::json::array();
2127 commands_js.push_back(
".kicad adjustpaths" );
2130 commands_js.push_back(
".save all" );
2133 commands_js.push_back(
".probe alli" );
2136 commands_js.push_back(
".probe allp" );
2138 nlohmann::json tab_js = nlohmann::json(
2140 {
"commands", commands_js } } );
2144 nlohmann::json traces_js = nlohmann::json::array();
2146 auto findSignalName =
2147 [&](
const wxString& aVectorName ) -> wxString
2158 for(
const auto& [
name, trace] : plotTab->GetTraces() )
2160 nlohmann::json trace_js = nlohmann::json(
2161 { {
"trace_type", (int) trace->GetType() },
2162 {
"signal", findSignalName( trace->GetName() ) },
2167 trace_js[
"cursor1"] = nlohmann::json(
2168 { {
"position",
cursor->GetCoords().x },
2175 trace_js[
"cursor2"] = nlohmann::json(
2176 { {
"position",
cursor->GetCoords().x },
2181 if( trace->GetCursor( 1 ) || trace->GetCursor( 2 ) )
2183 trace_js[
"cursorD"] = nlohmann::json(
2188 traces_js.push_back( trace_js );
2191 nlohmann::json measurements_js = nlohmann::json::array();
2193 for(
const auto& [
measurement, format ] : plotTab->Measurements() )
2195 measurements_js.push_back( nlohmann::json( { {
"expr",
measurement },
2196 {
"format", format } } ) );
2199 tab_js[
"traces" ] = traces_js;
2200 tab_js[
"measurements" ] = measurements_js;
2201 tab_js[
"dottedSecondary" ] = plotTab->GetDottedSecondary();
2202 tab_js[
"showGrid" ] = plotTab->IsGridShown();
2206 if( plotTab->GetY1Scale( &min, &max ) )
2207 tab_js[
"fixedY1scale" ] = nlohmann::json( { {
"min", min }, {
"max", max } } );
2209 if( plotTab->GetY2Scale( &min, &max ) )
2210 tab_js[
"fixedY2scale" ] = nlohmann::json( { {
"min", min }, {
"max", max } } );
2212 if( plotTab->GetY3Scale( &min, &max ) )
2213 tab_js[
"fixedY3scale" ] = nlohmann::json( { {
"min", min }, {
"max", max } } );
2215 if( plotTab->IsLegendShown() )
2217 tab_js[
"legend" ] = nlohmann::json( { {
"x", plotTab->GetLegendPosition().x },
2218 {
"y", plotTab->GetLegendPosition().y } } );
2221 mpWindow* plotWin = plotTab->GetPlotWin();
2223 tab_js[
"margins" ] = nlohmann::json( { {
"left", plotWin->
GetMarginLeft() },
2229 tabs_js.push_back( tab_js );
2232 nlohmann::json userDefinedSignals_js = nlohmann::json::array();
2235 userDefinedSignals_js.push_back( signal );
2237 nlohmann::json js = nlohmann::json( { {
"version", 6 },
2238 {
"tabs", tabs_js },
2239 {
"user_defined_signals", userDefinedSignals_js } } );
2250 std::stringstream buffer;
2251 buffer << std::setw( 2 ) << js << std::endl;
2253 bool res = file.Write( buffer.str() );
2260 simulator()->Settings()->SetWorkbookFilename( filename.GetFullPath() );
2278 default: wxFAIL_MSG( wxS(
"Unhandled simulation type" ) );
return SPT_UNKNOWN;
2297 &source, &
scale, &pts, &fStart, &fStop, &saveAll );
2312 for(
size_t page = 0; page <
m_plotNotebook->GetPageCount(); page++ )
2357 std::vector<std::pair<wxString, wxString>>& measurements = plotTab->Measurements();
2359 measurements.clear();
2397 simulator()->Command(
"setplot " + simTab->GetSpicePlotName().ToStdString() );
2411 for(
const auto& [
measurement, format ] : plotTab->Measurements() )
2419 if( plotTab->GetSimType() ==
ST_TRAN || plotTab->GetSimType() ==
ST_AC
2420 || plotTab->GetSimType() ==
ST_DC || plotTab->GetSimType() ==
ST_SP )
2457 CURSOR* cursor1 =
nullptr;
2458 wxString cursor1Name;
2459 wxString cursor1Units;
2460 CURSOR* cursor2 =
nullptr;
2461 wxString cursor2Name;
2462 wxString cursor2Units;
2465 [&](
TRACE* aTrace ) -> wxString
2469 else if( aTrace->GetType() &
SPT_POWER )
2476 [&](
TRACE* aTrace ) -> wxString
2480 else if( aTrace->GetType() &
SPT_POWER )
2487 [
this](
double aValue,
int aCursorId,
int aCol ) -> wxString
2500 cursor1Name = getNameY( trace );
2501 cursor1Units = getUnitsY( trace );
2503 wxRealPoint coords =
cursor->GetCoords();
2523 cursor2Name = getNameY( trace );
2524 cursor2Units = getUnitsY( trace );
2526 wxRealPoint coords =
cursor->GetCoords();
2541 if( cursor1 && cursor2 && cursor1Units == cursor2Units )
2550 signal = wxString::Format( wxS(
"%s[2 - 1]" ), cursor2->
GetName() );
2552 signal = wxString::Format( wxS(
"%s - %s" ), cursor2->
GetName(), cursor1->
GetName() );
2564 wxString valColName =
_(
"Value" );
2566 if( !cursor1Name.IsEmpty() )
2568 if( cursor2Name.IsEmpty() || cursor1Name == cursor2Name )
2569 valColName = cursor1Name;
2571 else if( !cursor2Name.IsEmpty() )
2573 valColName = cursor2Name;
2590 plotTab->ResetScales(
true );
2610 std::vector<wxString> signals;
2612 for(
const std::string& vec :
simulator()->AllVectors() )
2613 signals.emplace_back( vec );
2621 std::vector<wxString> signals;
2623 for(
const wxString& signal :
m_signals )
2624 signals.emplace_back( signal );
2627 signals.emplace_back( signal );
2656 if( simType ==
ST_NOISE && aFinal )
2658 m_simConsole->AppendText(
_(
"\n\nSimulation results:\n\n" ) );
2665 simulator()->CurrentPlotName().Mid( 5 ).ToLong( &number );
2667 for(
const std::string& vec :
simulator()->AllVectors() )
2669 std::vector<double> val_list =
simulator()->GetRealVector( vec, 1 );
2672 msg.Printf( wxS(
"%s: %sV\n" ), vec, value );
2678 simulator()->Command( fmt::format(
"setplot noise{}", number - 1 ) );
2683 wxCHECK_RET( plotTab, wxT(
"not a SIM_PLOT_TAB" ) );
2692 std::map<TRACE*, TRACE_INFO> traceMap;
2695 traceMap[ trace ] = { wxEmptyString,
SPT_UNKNOWN,
false };
2700 for(
const wxString& signal :
m_signals )
2705 if(
TRACE* trace = plotTab->
GetTrace( vectorName, traceType ) )
2706 traceMap[ trace ] = { vectorName, traceType,
false };
2714 if( simType ==
ST_AC )
2720 if(
TRACE* trace = plotTab->
GetTrace( vectorName, subType ) )
2721 traceMap[ trace ] = { vectorName, subType, !aFinal };
2724 else if( simType ==
ST_SP )
2730 if(
TRACE* trace = plotTab->
GetTrace( vectorName, subType ) )
2731 traceMap[trace] = { vectorName, subType, !aFinal };
2736 if(
TRACE* trace = plotTab->
GetTrace( vectorName, traceType ) )
2737 traceMap[ trace ] = { vectorName, traceType, !aFinal };
2743 for(
const auto& [ trace, traceInfo ] : traceMap )
2745 if( traceInfo.Vector.IsEmpty() )
2749 for(
const auto& [ trace,
info ] : traceMap )
2751 std::vector<double> data_x;
2753 if( !
info.Vector.IsEmpty() )
2771 else if( simType ==
ST_OP && aFinal )
2773 m_simConsole->AppendText(
_(
"\n\nSimulation results:\n\n" ) );
2776 for(
const std::string& vec :
simulator()->AllVectors() )
2778 std::vector<double> val_list =
simulator()->GetRealVector( vec, 1 );
2783 const size_t tab = 25;
2784 size_t padding = ( signal.length() < tab ) ? ( tab - signal.length() ) : 1;
2788 case SPT_VOLTAGE: value.Append( wxS(
"V" ) );
break;
2789 case SPT_CURRENT: value.Append( wxS(
"A" ) );
break;
2790 case SPT_POWER: value.Append( wxS(
"W" ) );
break;
2791 default: value.Append( wxS(
"?" ) );
break;
2794 msg.Printf( wxT(
"%s%s\n" ),
2795 ( signal + wxT(
":" ) ).Pad( padding, wxUniChar(
' ' ) ),
2801 if( signal.StartsWith( wxS(
"V(" ) ) || signal.StartsWith( wxS(
"I(" ) ) )
2802 signal = signal.SubString( 2, signal.Length() - 2 );
2807 else if( simType ==
ST_PZ && aFinal )
2809 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)
@ 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 std::string &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.
const wxString GetRef(const SCH_SHEET_PATH *aSheet, bool aIncludeUnit=false) const
Return the reference for the given sheet path.
void GetFields(std::vector< SCH_FIELD * > &aVector, bool aVisibleOnly)
Populate a std::vector with SCH_FIELDs.
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
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)
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< LIB_PIN * > &aPins, REPORTER &aReporter)
virtual const PARAM * GetTunerParam() const
const SPICE_GENERATOR & SpiceGenerator() const
void SetParamValue(int aParamIndex, const std::string &aValue, SIM_VALUE::NOTATION aNotation=SIM_VALUE::NOTATION::SI)
void WriteFields(std::vector< T > &aFields) const
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 SetTraceData(TRACE *aTrace, std::vector< double > &aX, std::vector< double > &aY)
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
wxString GetUnitsX() const
TRACE * GetOrAddTrace(const wxString &aVectorName, int aType)
void SetDottedSecondary(bool aEnable)
Draw secondary signal traces (current or phase) with dotted lines.
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
void EnableMouseWheelPan(bool enabled)
Enable/disable trackpad friendly panning (2-axis scroll wheel)
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
const std::string WorkbookFileExtension
const wxChar *const traceSettings
Flag to enable debug output of settings operations and management.
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
KIWAY Kiway & Pgm(), KFCTL_STANDALONE
The global Program "get" accessor.
std::vector< FAB_LAYER_COLOR > dummy
wxString UnescapeString(const wxString &aSource)
int measurements_panel_height
Definition of file extensions used in Kicad.