Try and sort out the mess that is trace names and trace titles.
Fixes https://gitlab.com/kicad/code/kicad/issues/14016
This commit is contained in:
parent
51d46c0e73
commit
beb177fa79
|
@ -237,42 +237,42 @@ void SIGNALS_GRID_TRICKS::doPopupSelection( wxCommandEvent& event )
|
|||
|
||||
if( event.GetId() == MYID_MEASURE_MIN )
|
||||
{
|
||||
for( wxString signal : signals )
|
||||
for( const wxString& signal : signals )
|
||||
m_parent->AddMeasurement( wxString::Format( wxS( "MIN %s" ), signal ) );
|
||||
}
|
||||
else if( event.GetId() == MYID_MEASURE_MAX )
|
||||
{
|
||||
for( wxString signal : signals )
|
||||
for( const wxString& signal : signals )
|
||||
m_parent->AddMeasurement( wxString::Format( wxS( "MAX %s" ), signal ) );
|
||||
}
|
||||
else if( event.GetId() == MYID_MEASURE_AVG )
|
||||
{
|
||||
for( wxString signal : signals )
|
||||
for( const wxString& signal : signals )
|
||||
m_parent->AddMeasurement( wxString::Format( wxS( "AVG %s" ), signal ) );
|
||||
}
|
||||
else if( event.GetId() == MYID_MEASURE_RMS )
|
||||
{
|
||||
for( wxString signal : signals )
|
||||
for( const wxString& signal : signals )
|
||||
m_parent->AddMeasurement( wxString::Format( wxS( "RMS %s" ), signal ) );
|
||||
}
|
||||
else if( event.GetId() == MYID_MEASURE_PP )
|
||||
{
|
||||
for( wxString signal : signals )
|
||||
for( const wxString& signal : signals )
|
||||
m_parent->AddMeasurement( wxString::Format( wxS( "PP %s" ), signal ) );
|
||||
}
|
||||
else if( event.GetId() == MYID_MEASURE_MIN_AT )
|
||||
{
|
||||
for( wxString signal : signals )
|
||||
for( const wxString& signal : signals )
|
||||
m_parent->AddMeasurement( wxString::Format( wxS( "MIN_AT %s" ), signal ) );
|
||||
}
|
||||
else if( event.GetId() == MYID_MEASURE_MAX_AT )
|
||||
{
|
||||
for( wxString signal : signals )
|
||||
for( const wxString& signal : signals )
|
||||
m_parent->AddMeasurement( wxString::Format( wxS( "MAX_AT %s" ), signal ) );
|
||||
}
|
||||
else if( event.GetId() == MYID_MEASURE_INTEGRAL )
|
||||
{
|
||||
for( wxString signal : signals )
|
||||
for( const wxString& signal : signals )
|
||||
m_parent->AddMeasurement( wxString::Format( wxS( "INTEG %s" ), signal ) );
|
||||
}
|
||||
else
|
||||
|
@ -963,16 +963,7 @@ void SIM_PLOT_FRAME::rebuildSignalsList()
|
|||
// Add user-defined signals
|
||||
for( int ii = 0; ii < (int) m_userDefinedSignals.size(); ++ii )
|
||||
{
|
||||
static wxRegEx regEx( wxS( "(^|[^a-z0-9_])([VIP])\\(" ), wxRE_ICASE );
|
||||
const wxString& signal = m_userDefinedSignals[ii];
|
||||
|
||||
if( regEx.Matches( signal ) )
|
||||
{
|
||||
wxString vecType = regEx.GetMatch( signal, 2 );
|
||||
wxString spiceVecName = wxString::Format( wxS( "%s(user%d)" ), vecType, ii );
|
||||
|
||||
addSignal( signal, spiceVecName );
|
||||
}
|
||||
addSignal( m_userDefinedSignals[ii], wxString::Format( wxS( "user%d" ), ii ) );
|
||||
}
|
||||
|
||||
std::sort( m_signals.begin(), m_signals.end(),
|
||||
|
@ -1133,12 +1124,6 @@ wxString SIM_PLOT_FRAME::getTraceName( const wxString& aSignalName )
|
|||
}
|
||||
|
||||
|
||||
wxString SIM_PLOT_FRAME::getTraceName( int aRow )
|
||||
{
|
||||
return getTraceName( m_signalsGrid->GetCellValue( aRow, COL_SIGNAL_NAME ) );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* AC-small-signal analyses have two traces per signal, so we suffix the names.
|
||||
*/
|
||||
|
@ -1165,10 +1150,35 @@ void SIM_PLOT_FRAME::onSignalsGridCellChanged( wxGridEvent& aEvent )
|
|||
|
||||
if( col == COL_SIGNAL_SHOW )
|
||||
{
|
||||
wxString gainSuffix = _( " (gain)" );
|
||||
wxString phaseSuffix = _( " (phase)" );
|
||||
wxString signal = m_signalsGrid->GetCellValue( row, COL_SIGNAL_NAME );
|
||||
wxUniChar firstChar = signal.Upper()[0];
|
||||
wxString traceName = getTraceName( signal );
|
||||
int traceType = SPT_UNKNOWN;
|
||||
|
||||
if( firstChar == 'V' )
|
||||
traceType = SPT_VOLTAGE;
|
||||
else if( firstChar == 'I' )
|
||||
traceType = SPT_CURRENT;
|
||||
else if( firstChar == 'P' )
|
||||
traceType = SPT_POWER;
|
||||
|
||||
if( traceName.EndsWith( gainSuffix ) )
|
||||
{
|
||||
traceType |= SPT_AC_MAG;
|
||||
traceName = traceName.Left( traceName.Length() - gainSuffix.Length() );
|
||||
}
|
||||
else if( traceName.EndsWith( phaseSuffix ) )
|
||||
{
|
||||
traceType |= SPT_AC_PHASE;
|
||||
traceName = traceName.Left( traceName.Length() - phaseSuffix.Length() );
|
||||
}
|
||||
|
||||
if( text == wxS( "1" ) )
|
||||
addTrace( getTraceName( row ) );
|
||||
addTrace( traceName, (SIM_TRACE_TYPE) traceType );
|
||||
else
|
||||
removeTrace( getTraceName( row ) );
|
||||
removeTrace( traceName, (SIM_TRACE_TYPE) traceType );
|
||||
|
||||
// Update enabled/visible states of other controls
|
||||
updateSignalsGrid();
|
||||
|
@ -1177,7 +1187,8 @@ void SIM_PLOT_FRAME::onSignalsGridCellChanged( wxGridEvent& aEvent )
|
|||
else if( col == COL_SIGNAL_COLOR )
|
||||
{
|
||||
KIGFX::COLOR4D color( m_signalsGrid->GetCellValue( row, COL_SIGNAL_COLOR ) );
|
||||
TRACE* trace = plot->GetTrace( getTraceName( row ) );
|
||||
wxString signal = m_signalsGrid->GetCellValue( row, COL_SIGNAL_NAME );
|
||||
TRACE* trace = plot->GetTrace( getTraceName( signal ) );
|
||||
|
||||
if( trace )
|
||||
{
|
||||
|
@ -1191,9 +1202,11 @@ void SIM_PLOT_FRAME::onSignalsGridCellChanged( wxGridEvent& aEvent )
|
|||
{
|
||||
for( int ii = 0; ii < m_signalsGrid->GetNumberRows(); ++ii )
|
||||
{
|
||||
wxString signal = m_signalsGrid->GetCellValue( ii, COL_SIGNAL_NAME );
|
||||
int id = col == COL_CURSOR_1 ? 1 : 2;
|
||||
bool enable = ii == row && text == wxS( "1" );
|
||||
|
||||
plot->EnableCursor( getTraceName( ii ), col == COL_CURSOR_1 ? 1 : 2, enable );
|
||||
plot->EnableCursor( signal, getTraceName( signal ), id, enable );
|
||||
OnModify();
|
||||
}
|
||||
|
||||
|
@ -1626,11 +1639,18 @@ void SIM_PLOT_FRAME::doAddPlot( const wxString& aName, SIM_TRACE_TYPE aType )
|
|||
|
||||
|
||||
void SIM_PLOT_FRAME::SetUserDefinedSignals( const std::vector<wxString>& aNewSignals )
|
||||
{
|
||||
SIM_PLOT_PANEL* plotPanel = GetCurrentPlot();
|
||||
|
||||
if( plotPanel )
|
||||
{
|
||||
for( const wxString& signal : m_userDefinedSignals )
|
||||
{
|
||||
if( !alg::contains( aNewSignals, signal ) )
|
||||
removeTrace( m_userDefinedSignalToSpiceVecName[ signal ] );
|
||||
plotPanel->DeleteTrace( m_userDefinedSignalToSpiceVecName[ signal ] );
|
||||
}
|
||||
|
||||
plotPanel->GetPlotWin()->Fit();
|
||||
}
|
||||
|
||||
m_userDefinedSignals = aNewSignals;
|
||||
|
@ -1645,59 +1665,27 @@ void SIM_PLOT_FRAME::SetUserDefinedSignals( const std::vector<wxString>& aNewSig
|
|||
}
|
||||
|
||||
|
||||
void SIM_PLOT_FRAME::addTrace( const wxString& aSignalName )
|
||||
void SIM_PLOT_FRAME::addTrace( const wxString& aSignalName, SIM_TRACE_TYPE aTraceType )
|
||||
{
|
||||
if( aSignalName.IsEmpty() )
|
||||
return;
|
||||
|
||||
wxString baseSignal = aSignalName;
|
||||
wxString gainSuffix = _( " (gain)" );
|
||||
wxString phaseSuffix = _( " (phase)" );
|
||||
wxUniChar firstChar = aSignalName.Upper()[0];
|
||||
int traceType = SPT_UNKNOWN;
|
||||
|
||||
if( firstChar == 'V' )
|
||||
traceType = SPT_VOLTAGE;
|
||||
else if( firstChar == 'I' )
|
||||
traceType = SPT_CURRENT;
|
||||
else if( firstChar == 'P' )
|
||||
traceType = SPT_POWER;
|
||||
|
||||
if( aSignalName.EndsWith( gainSuffix ) )
|
||||
{
|
||||
traceType |= SPT_AC_MAG;
|
||||
baseSignal = aSignalName.Left( aSignalName.Length() - gainSuffix.Length() );
|
||||
}
|
||||
else if( aSignalName.EndsWith( phaseSuffix ) )
|
||||
{
|
||||
traceType |= SPT_AC_PHASE;
|
||||
baseSignal = aSignalName.Left( aSignalName.Length() - phaseSuffix.Length() );
|
||||
if( SIM_PLOT_PANEL* plotPanel = GetCurrentPlot() )
|
||||
updateTrace( aSignalName, (SIM_TRACE_TYPE) aTraceType, plotPanel );
|
||||
}
|
||||
|
||||
if( traceType != SPT_UNKNOWN )
|
||||
|
||||
void SIM_PLOT_FRAME::removeTrace( const wxString& aSignalName, SIM_TRACE_TYPE aTraceType )
|
||||
{
|
||||
if( SIM_PLOT_PANEL* plotPanel = GetCurrentPlot() )
|
||||
updateTrace( baseSignal, (SIM_TRACE_TYPE) traceType, plotPanel );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SIM_PLOT_FRAME::removeTrace( const wxString& aSignalName )
|
||||
{
|
||||
SIM_PLOT_PANEL* plotPanel = GetCurrentPlot();
|
||||
|
||||
if( !plotPanel )
|
||||
return;
|
||||
|
||||
wxASSERT( plotPanel->TraceShown( aSignalName ) );
|
||||
|
||||
if( plotPanel->DeleteTrace( aSignalName ) )
|
||||
OnModify();
|
||||
|
||||
plotPanel->DeleteTrace( getTraceTitle( aSignalName, aTraceType ) );
|
||||
plotPanel->GetPlotWin()->Fit();
|
||||
}
|
||||
|
||||
updateSignalsGrid();
|
||||
updateCursors();
|
||||
OnModify();
|
||||
}
|
||||
|
||||
|
||||
|
@ -1817,7 +1805,9 @@ void SIM_PLOT_FRAME::updateSignalsGrid()
|
|||
|
||||
for( int row = 0; row < m_signalsGrid->GetNumberRows(); ++row )
|
||||
{
|
||||
if( TRACE* trace = plot ? plot->GetTrace( getTraceName( row ) ) : nullptr )
|
||||
wxString signal = m_signalsGrid->GetCellValue( row, COL_SIGNAL_NAME );
|
||||
|
||||
if( TRACE* trace = plot ? plot->GetTrace( getTraceName( signal ) ) : nullptr )
|
||||
{
|
||||
m_signalsGrid->SetCellValue( row, COL_SIGNAL_SHOW, wxS( "1" ) );
|
||||
|
||||
|
@ -2053,9 +2043,18 @@ bool SIM_PLOT_FRAME::LoadWorkbook( const wxString& aPath )
|
|||
return false;
|
||||
}
|
||||
|
||||
param = file.GetNextLine();
|
||||
wxString baseName = name;
|
||||
wxString gainSuffix = _( " (gain)" );
|
||||
wxString phaseSuffix = _( " (phase)" );
|
||||
|
||||
addTrace( name );
|
||||
if( baseName.EndsWith( gainSuffix ) )
|
||||
baseName = baseName.Left( baseName.Length() - gainSuffix.Length() );
|
||||
else if( baseName.EndsWith( phaseSuffix ) )
|
||||
baseName = baseName.Left( baseName.Length() - phaseSuffix.Length() );
|
||||
|
||||
addTrace( baseName, (SIM_TRACE_TYPE) traceType );
|
||||
|
||||
param = file.GetNextLine();
|
||||
|
||||
SIM_PLOT_PANEL* plotPanel = GetCurrentPlot();
|
||||
TRACE* trace = plotPanel ? plotPanel->GetTrace( name ) : nullptr;
|
||||
|
@ -2063,17 +2062,16 @@ bool SIM_PLOT_FRAME::LoadWorkbook( const wxString& aPath )
|
|||
if( version >= 4 && trace )
|
||||
{
|
||||
auto addCursor =
|
||||
[]( int aCursorId, SIM_PLOT_PANEL* aPlotPanel, TRACE* aTrace, double x )
|
||||
[&]( int aCursorId, TRACE* aTrace, double x )
|
||||
{
|
||||
CURSOR* cursor = new CURSOR( aTrace, aPlotPanel );
|
||||
mpWindow* win = aPlotPanel->GetPlotWin();
|
||||
CURSOR* cursor = new CURSOR( aTrace, plotPanel );
|
||||
|
||||
cursor->SetName( aTrace->GetName() );
|
||||
cursor->SetName( name );
|
||||
cursor->SetPen( wxPen( aTrace->GetTraceColour() ) );
|
||||
cursor->SetCoordX( x );
|
||||
|
||||
aTrace->SetCursor( aCursorId, cursor );
|
||||
win->AddLayer( cursor );
|
||||
plotPanel->GetPlotWin()->AddLayer( cursor );
|
||||
};
|
||||
|
||||
wxArrayString items = wxSplit( param, '|' );
|
||||
|
@ -2097,7 +2095,7 @@ bool SIM_PLOT_FRAME::LoadWorkbook( const wxString& aPath )
|
|||
parts[0].AfterFirst( '=' ).ToDouble( &val );
|
||||
m_cursorFormats[0][0].FromString( parts[1] );
|
||||
m_cursorFormats[0][1].FromString( parts[2] );
|
||||
addCursor( 1, plotPanel, trace, val );
|
||||
addCursor( 1, trace, val );
|
||||
}
|
||||
}
|
||||
else if( item.StartsWith( wxS( "cursor2" ) ) )
|
||||
|
@ -2110,7 +2108,7 @@ bool SIM_PLOT_FRAME::LoadWorkbook( const wxString& aPath )
|
|||
parts[0].AfterFirst( '=' ).ToDouble( &val );
|
||||
m_cursorFormats[1][0].FromString( parts[1] );
|
||||
m_cursorFormats[1][1].FromString( parts[2] );
|
||||
addCursor( 2, plotPanel, trace, val );
|
||||
addCursor( 2, trace, val );
|
||||
}
|
||||
}
|
||||
else if( item.StartsWith( wxS( "cursorD" ) ) )
|
||||
|
@ -2165,6 +2163,28 @@ bool SIM_PLOT_FRAME::LoadWorkbook( const wxString& aPath )
|
|||
LoadSimulator();
|
||||
|
||||
rebuildSignalsList();
|
||||
|
||||
if( SIM_PLOT_PANEL* plotPanel = GetCurrentPlot() )
|
||||
{
|
||||
for( const auto& [ traceName, trace ] : plotPanel->GetTraces() )
|
||||
{
|
||||
for( int cursorId : { 1, 2 } )
|
||||
{
|
||||
if( CURSOR* cursor = trace->GetCursor( cursorId ) )
|
||||
{
|
||||
for( const auto& [ signalName, vecName ] : m_userDefinedSignalToSpiceVecName )
|
||||
{
|
||||
if( vecName == traceName )
|
||||
{
|
||||
cursor->SetName( signalName );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rebuildSignalsGrid( m_filter->GetValue() );
|
||||
updateSignalsGrid();
|
||||
updateCursors();
|
||||
|
@ -2576,6 +2596,9 @@ void SIM_PLOT_FRAME::updateCursors()
|
|||
auto formatValue =
|
||||
[this]( double aValue, int aCursorId, int aCol ) -> wxString
|
||||
{
|
||||
if( !m_simFinished && aCol == 1 )
|
||||
return wxS( "--" );
|
||||
else
|
||||
return SPICE_VALUE( aValue ).ToString( m_cursorFormats[ aCursorId ][ aCol ] );
|
||||
};
|
||||
|
||||
|
@ -2843,7 +2866,7 @@ void SIM_PLOT_FRAME::onSimFinished( wxCommandEvent& aEvent )
|
|||
if( placeholder.m_current )
|
||||
updateTrace( placeholder.m_name, placeholder.m_type, plotPanel );
|
||||
else
|
||||
removeTrace( placeholder.m_name );
|
||||
removeTrace( placeholder.m_name, placeholder.m_type );
|
||||
}
|
||||
|
||||
rebuildSignalsGrid( m_filter->GetValue() );
|
||||
|
@ -2890,6 +2913,8 @@ void SIM_PLOT_FRAME::onSimFinished( wxCommandEvent& aEvent )
|
|||
|
||||
m_schematicFrame->RefreshOperatingPointDisplay();
|
||||
|
||||
updateCursors();
|
||||
|
||||
for( int row = 0; row < m_measurementsGrid->GetNumberRows(); ++row )
|
||||
UpdateMeasurement( row );
|
||||
|
||||
|
|
|
@ -262,13 +262,12 @@ private:
|
|||
*/
|
||||
void doAddPlot( const wxString& aName, SIM_TRACE_TYPE aType );
|
||||
|
||||
void addTrace( const wxString& aSignalName );
|
||||
void addTrace( const wxString& aSignalName, SIM_TRACE_TYPE aType );
|
||||
|
||||
/**
|
||||
* For user-defined traces we have a separate SPICE vector name.
|
||||
*/
|
||||
wxString getTraceName( const wxString& aSignalName );
|
||||
wxString getTraceName( int aRow );
|
||||
|
||||
/**
|
||||
* AC-small-signal analyses have specific trace titles. Other analyses use the raw signal
|
||||
|
@ -279,17 +278,16 @@ private:
|
|||
/**
|
||||
* Remove a plot with a specific title.
|
||||
*
|
||||
* @param aSignalName is the full plot title (e.g. I(Net-C1-Pad1)).
|
||||
* @param aName is the SPICE vector name, such as "I(Net-C1-Pad1)".
|
||||
*/
|
||||
void removeTrace( const wxString& aSignalName );
|
||||
void removeTrace( const wxString& aName, SIM_TRACE_TYPE aTraceType );
|
||||
|
||||
/**
|
||||
* Update a trace in a particular SIM_PLOT_PANEL. If the panel does not contain the given
|
||||
* trace, then add it.
|
||||
*
|
||||
* @param aName is the device/net name.
|
||||
* @param aName is the SPICE vector name, such as "I(Net-C1-Pad1)".
|
||||
* @param aTraceType describes the type of plot.
|
||||
* @param aParam is the parameter for the device/net (e.g. I, Id, V).
|
||||
* @param aPlotPanel is the panel that should receive the update.
|
||||
*/
|
||||
void updateTrace( const wxString& aName, SIM_TRACE_TYPE aTraceType, SIM_PLOT_PANEL* aPlotPanel );
|
||||
|
|
|
@ -802,9 +802,10 @@ bool SIM_PLOT_PANEL::DeleteTrace( const wxString& aName )
|
|||
}
|
||||
|
||||
|
||||
void SIM_PLOT_PANEL::EnableCursor( const wxString& aName, int aCursorId, bool aEnable )
|
||||
void SIM_PLOT_PANEL::EnableCursor( const wxString& aSignalName, const wxString aTraceName,
|
||||
int aCursorId, bool aEnable )
|
||||
{
|
||||
TRACE* t = GetTrace( aName );
|
||||
TRACE* t = GetTrace( aTraceName );
|
||||
|
||||
if( t == nullptr || t->HasCursor( aCursorId ) == aEnable )
|
||||
return;
|
||||
|
@ -816,7 +817,7 @@ void SIM_PLOT_PANEL::EnableCursor( const wxString& aName, int aCursorId, bool aE
|
|||
int width = win->GetXScreen() - win->GetMarginLeft() - win->GetMarginRight();
|
||||
int center = win->GetMarginLeft() + KiROUND( width * ( aCursorId == 1 ? 0.4 : 0.6 ) );
|
||||
|
||||
cursor->SetName( aName );
|
||||
cursor->SetName( aSignalName );
|
||||
cursor->SetX( center );
|
||||
cursor->SetPen( wxPen( m_colors.GetPlotColor( SIM_PLOT_COLORS::COLOR_SET::CURSOR ) ) );
|
||||
|
||||
|
|
|
@ -282,7 +282,7 @@ public:
|
|||
}
|
||||
|
||||
///< Toggle cursor for a particular trace.
|
||||
void EnableCursor( const wxString& aName, int aCursorId, bool aEnable );
|
||||
void EnableCursor( const wxString& aSignalName, const wxString aTraceName, int aCursorId, bool aEnable );
|
||||
|
||||
///< Reset scale ranges to fit the current traces.
|
||||
void ResetScales();
|
||||
|
|
Loading…
Reference in New Issue