Support for simulation options in workbook and simulation command dlg.

Fixes https://gitlab.com/kicad/code/kicad/issues/13524

Fixes https://gitlab.com/kicad/code/kicad/issues/13523

Fixes https://gitlab.com/kicad/code/kicad/issues/13431
This commit is contained in:
Jeff Young 2023-01-14 00:17:33 +00:00
parent e7e2085b2a
commit 098d2b30a2
16 changed files with 399 additions and 139 deletions

View File

@ -351,13 +351,13 @@ void DIALOG_EXPORT_NETLIST::InstallPageSpice()
_( "Save all voltages" ) );
page->m_SaveAllVoltages->SetToolTip( _( "Write a directive to save all voltages (.save all)" ) );
page->m_SaveAllVoltages->SetValue( settings.m_SpiceSaveAllVoltages );
page->m_RightBoxSizer->Add( page->m_SaveAllVoltages, 0, wxBOTTOM | wxRIGHT, 5 );
page->m_LeftBoxSizer->Add( page->m_SaveAllVoltages, 0, wxBOTTOM | wxRIGHT, 5 );
page->m_SaveAllCurrents = new wxCheckBox( page, ID_SAVE_ALL_CURRENTS,
_( "Save all currents" ) );
page->m_SaveAllCurrents->SetToolTip( _( "Write a directive to save all currents (.probe alli)" ) );
page->m_SaveAllCurrents->SetValue( settings.m_SpiceSaveAllCurrents );
page->m_RightBoxSizer->Add( page->m_SaveAllCurrents, 0, wxBOTTOM | wxRIGHT, 5 );
page->m_LeftBoxSizer->Add( page->m_SaveAllCurrents, 0, wxBOTTOM | wxRIGHT, 5 );
wxString simulatorCommand = settings.m_SpiceCommandString;

View File

@ -28,6 +28,7 @@
#define DIALOG_SIM_COMMAND_H
#include "dialog_sim_command_base.h"
#include <netlist_exporter_spice.h>
#include <sim/spice_value.h>
#include <wx/valnum.h>
@ -57,6 +58,29 @@ public:
return res;
}
int GetSimOptions() const
{
int options = NETLIST_EXPORTER_SPICE::OPTION_DEFAULT_FLAGS;
if( !m_fixIncludePaths->GetValue() )
options &= ~NETLIST_EXPORTER_SPICE::OPTION_ADJUST_INCLUDE_PATHS;
if( !m_saveAllVoltages->GetValue() )
options &= ~NETLIST_EXPORTER_SPICE::OPTION_SAVE_ALL_VOLTAGES;
if( !m_saveAllCurrents->GetValue() )
options &= ~NETLIST_EXPORTER_SPICE::OPTION_SAVE_ALL_CURRENTS;
return options;
}
void SetSimOptions( int aOptions )
{
m_fixIncludePaths->SetValue( aOptions & NETLIST_EXPORTER_SPICE::OPTION_ADJUST_INCLUDE_PATHS );
m_saveAllVoltages->SetValue( aOptions & NETLIST_EXPORTER_SPICE::OPTION_SAVE_ALL_VOLTAGES );
m_saveAllCurrents->SetValue( aOptions & NETLIST_EXPORTER_SPICE::OPTION_SAVE_ALL_CURRENTS );
}
bool TransferDataFromWindow() override;
bool TransferDataToWindow() override;

View File

@ -89,7 +89,7 @@ DIALOG_SIM_COMMAND_BASE::DIALOG_SIM_COMMAND_BASE( wxWindow* parent, wxWindowID i
gbSizer1->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
m_dcEnable2 = new wxCheckBox( m_pgDC, wxID_ANY, _("Source 2"), wxDefaultPosition, wxDefaultSize, 0 );
m_dcEnable2->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD, false, wxEmptyString ) );
m_dcEnable2->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, false, wxEmptyString ) );
gbSizer1->Add( m_dcEnable2, wxGBPosition( 0, 3 ), wxGBSpan( 1, 2 ), wxALIGN_CENTER_VERTICAL|wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
@ -115,7 +115,7 @@ DIALOG_SIM_COMMAND_BASE::DIALOG_SIM_COMMAND_BASE( wxWindow* parent, wxWindowID i
m_staticText411 = new wxStaticText( m_pgDC, wxID_ANY, _("Source 1"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText411->Wrap( -1 );
m_staticText411->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD, false, wxEmptyString ) );
m_staticText411->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, false, wxEmptyString ) );
gbSizer1->Add( m_staticText411, wxGBPosition( 0, 1 ), wxGBSpan( 1, 1 ), wxBOTTOM|wxRIGHT|wxLEFT, 5 );
@ -430,7 +430,13 @@ DIALOG_SIM_COMMAND_BASE::DIALOG_SIM_COMMAND_BASE( wxWindow* parent, wxWindowID i
m_fixIncludePaths = new wxCheckBox( this, wxID_ANY, _("Add full path for .include library directives"), wxDefaultPosition, wxDefaultSize, 0 );
m_fixIncludePaths->SetValue(true);
bSizer88->Add( m_fixIncludePaths, 0, wxBOTTOM|wxRIGHT|wxLEFT, 10 );
bSizer88->Add( m_fixIncludePaths, 0, wxBOTTOM|wxRIGHT|wxLEFT, 5 );
m_saveAllVoltages = new wxCheckBox( this, wxID_ANY, _("Save all voltages"), wxDefaultPosition, wxDefaultSize, 0 );
bSizer88->Add( m_saveAllVoltages, 0, wxBOTTOM|wxRIGHT|wxLEFT, 5 );
m_saveAllCurrents = new wxCheckBox( this, wxID_ANY, _("Save all currents"), wxDefaultPosition, wxDefaultSize, 0 );
bSizer88->Add( m_saveAllCurrents, 0, wxBOTTOM|wxRIGHT|wxLEFT, 5 );
m_compatibilityMode = new wxBoxSizer( wxHORIZONTAL );
@ -449,7 +455,7 @@ DIALOG_SIM_COMMAND_BASE::DIALOG_SIM_COMMAND_BASE( wxWindow* parent, wxWindowID i
bSizer88->Add( m_compatibilityMode, 1, wxEXPAND|wxBOTTOM, 5 );
bSizer1->Add( bSizer88, 0, wxEXPAND, 5 );
bSizer1->Add( bSizer88, 0, wxEXPAND|wxTOP|wxLEFT, 10 );
m_sdbSizer = new wxStdDialogButtonSizer();
m_sdbSizerOK = new wxButton( this, wxID_OK );

View File

@ -4851,8 +4851,8 @@
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxEXPAND</property>
<property name="border">10</property>
<property name="flag">wxEXPAND|wxTOP|wxLEFT</property>
<property name="proportion">0</property>
<object class="wxBoxSizer" expanded="1">
<property name="minimum_size"></property>
@ -4860,7 +4860,7 @@
<property name="orient">wxVERTICAL</property>
<property name="permission">none</property>
<object class="sizeritem" expanded="0">
<property name="border">10</property>
<property name="border">5</property>
<property name="flag">wxBOTTOM|wxRIGHT|wxLEFT</property>
<property name="proportion">0</property>
<object class="wxCheckBox" expanded="0">
@ -4923,6 +4923,134 @@
<property name="window_style"></property>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxBOTTOM|wxRIGHT|wxLEFT</property>
<property name="proportion">0</property>
<object class="wxCheckBox" expanded="1">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="checked">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Save all voltages</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_saveAllVoltages</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass">; ; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
<property name="validator_variable"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxBOTTOM|wxRIGHT|wxLEFT</property>
<property name="proportion">0</property>
<object class="wxCheckBox" expanded="1">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="checked">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Save all currents</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_saveAllCurrents</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass">; ; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
<property name="validator_variable"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxEXPAND|wxBOTTOM</property>

View File

@ -117,6 +117,8 @@ class DIALOG_SIM_COMMAND_BASE : public DIALOG_SHIM
wxTextCtrl* m_customTxt;
wxButton* m_loadDirectives;
wxCheckBox* m_fixIncludePaths;
wxCheckBox* m_saveAllVoltages;
wxCheckBox* m_saveAllCurrents;
wxBoxSizer* m_compatibilityMode;
wxChoice* m_compatibilityModeChoice;
wxStdDialogButtonSizer* m_sdbSizer;

View File

@ -620,19 +620,27 @@ void NETLIST_EXPORTER_SPICE::WriteDirectives( OUTPUTFORMATTER& aFormatter,
if( aNetlistOptions & OPTION_SAVE_ALL_CURRENTS )
aFormatter.Print( 0, ".probe alli\n" );
for( const std::string& directive : m_directives )
for( const wxString& directive : m_directives )
{
#ifdef KICAD_SPICE
if( NGSPICE_CIRCUIT_MODEL::IsSimCommand( directive ) )
bool simCommand = false;
if( directive.StartsWith( "." ) )
{
if( aNetlistOptions & OPTION_SIM_COMMAND )
aFormatter.Print( 0, "%s\n", directive.c_str() );
}
else
#endif
{
aFormatter.Print( 0, "%s\n", directive.c_str() );
wxString candidate = directive.Upper();
simCommand = ( candidate.StartsWith( wxT( ".AC" ) )
|| candidate.StartsWith( wxT( ".DC" ) )
|| candidate.StartsWith( wxT( ".TRAN" ) )
|| candidate.StartsWith( wxT( ".OP" ) )
|| candidate.StartsWith( wxT( ".DISTO" ) )
|| candidate.StartsWith( wxT( ".NOISE" ) )
|| candidate.StartsWith( wxT( ".PZ" ) )
|| candidate.StartsWith( wxT( ".SENS" ) )
|| candidate.StartsWith( wxT( ".TF" ) ) );
}
if( !simCommand || ( aNetlistOptions & OPTION_SIM_COMMAND ) )
aFormatter.Print( 0, "%s\n", UTF8( directive ).c_str() );
}
}

View File

@ -123,7 +123,7 @@ public:
*/
const SPICE_ITEM* FindItem( const std::string& aRefName ) const;
const std::vector<std::string>& GetDirectives() { return m_directives; }
const std::vector<wxString>& GetDirectives() { return m_directives; }
protected:
void ReadDirectives( unsigned aNetlistOptions );
@ -153,8 +153,7 @@ private:
SIM_LIB_MGR m_libMgr; ///< Holds libraries and models
NAME_GENERATOR m_modelNameGenerator; ///< Generates unique model names
NAME_GENERATOR m_netNameGenerator; ///< Generates unique net names (only unique for NC nets for now)
std::vector<std::string> m_directives; ///< Spice directives found in the schematic sheet
//std::map<std::string, std::unique_ptr<SIM_LIBRARY>> m_libraries; ///< Spice libraries
std::vector<wxString> m_directives; ///< Spice directives found in the schematic sheet
std::set<wxString> m_rawIncludes; ///< include directives found in symbols
std::set<std::string> m_nets;
std::list<SPICE_ITEM> m_items; ///< Items representing schematic symbols in Spice world

View File

@ -71,7 +71,7 @@ wxString NGSPICE_CIRCUIT_MODEL::GetSheetSimCommand()
ReadDirectives( 0 );
for( const std::string& directive : GetDirectives() )
for( const wxString& directive : GetDirectives() )
{
if( IsSimCommand( directive ) )
simCmd += wxString::Format( wxT( "%s\r\n" ), directive );

View File

@ -49,9 +49,9 @@ class NGSPICE_CIRCUIT_MODEL : public NETLIST_EXPORTER_SPICE, public SIMULATION_M
public:
NGSPICE_CIRCUIT_MODEL( SCHEMATIC_IFACE* aSchematic ) :
NETLIST_EXPORTER_SPICE( aSchematic ),
m_options( 0 )
{
}
m_options( NETLIST_EXPORTER_SPICE::OPTION_DEFAULT_FLAGS )
{}
virtual ~NGSPICE_CIRCUIT_MODEL() {}
/**
@ -64,10 +64,8 @@ public:
*/
SIM_PLOT_TYPE VectorToSignal( const std::string& aVector, wxString& aSignal ) const;
void SetOptions( int aOptions )
{
m_options = aOptions;
}
void SetSimOptions( int aOptions ) { m_options = aOptions; }
int GetSimOptions() const { return m_options; }
bool GetNetlist( OUTPUTFORMATTER* aFormatter, REPORTER& aReporter )
{

View File

@ -30,21 +30,19 @@
#include "ngspice_circuit_model.h"
SIM_PANEL_BASE::SIM_PANEL_BASE() : m_simCommand( wxEmptyString )
SIM_PANEL_BASE::SIM_PANEL_BASE() :
m_simCommand( wxEmptyString ),
m_simOptions( NETLIST_EXPORTER_SPICE::OPTION_DEFAULT_FLAGS )
{
}
SIM_PANEL_BASE::SIM_PANEL_BASE( const wxString& aCommand ) : m_simCommand( aCommand )
{
}
SIM_PANEL_BASE::SIM_PANEL_BASE( const wxString& aCommand, wxWindow* parent, wxWindowID id,
const wxPoint& pos, const wxSize& size, long style,
SIM_PANEL_BASE::SIM_PANEL_BASE( const wxString& aCommand, int aOptions, wxWindow* parent,
wxWindowID id, const wxPoint& pos, const wxSize& size, long style,
const wxString& name ) :
wxWindow( parent, id, pos, size, style, name ),
m_simCommand( aCommand )
m_simCommand( aCommand ),
m_simOptions( aOptions )
{
}
@ -75,10 +73,10 @@ SIM_TYPE SIM_PANEL_BASE::GetType() const
}
SIM_NOPLOT_PANEL::SIM_NOPLOT_PANEL( const wxString& aCommand, wxWindow* parent, wxWindowID id,
const wxPoint& pos, const wxSize& size, long style,
const wxString& name ) :
SIM_PANEL_BASE( aCommand, parent, id, pos, size, style, name )
SIM_NOPLOT_PANEL::SIM_NOPLOT_PANEL( const wxString& aCommand, int aOptions, wxWindow* parent,
wxWindowID id, const wxPoint& pos, const wxSize& size,
long style, const wxString& name ) :
SIM_PANEL_BASE( aCommand, aOptions, parent, id, pos, size, style, name )
{
m_sizer = new wxBoxSizer( wxVERTICAL );
m_sizer->Add( 0, 1, 1, wxEXPAND, 5 );

View File

@ -39,8 +39,7 @@ class SIM_PANEL_BASE : public wxWindow
public:
SIM_PANEL_BASE();
SIM_PANEL_BASE( const wxString& aCommand );
SIM_PANEL_BASE( const wxString& aCommand, wxWindow* parent, wxWindowID id,
SIM_PANEL_BASE( const wxString& aCommand, int aOptions, wxWindow* parent, wxWindowID id,
const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize,
long style = 0, const wxString& name = wxPanelNameStr );
virtual ~SIM_PANEL_BASE();
@ -64,15 +63,19 @@ protected:
m_simCommand = aSimCommand;
}
const int getSimOptions() const { return m_simOptions; }
void setSimOptions( int aOptions ) { m_simOptions = aOptions; }
private:
wxString m_simCommand;
int m_simOptions;
};
class SIM_NOPLOT_PANEL : public SIM_PANEL_BASE
{
public:
SIM_NOPLOT_PANEL( const wxString& aCommand, wxWindow* parent, wxWindowID id,
SIM_NOPLOT_PANEL( const wxString& aCommand, int aOptions, wxWindow* parent, wxWindowID id,
const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize,
long style = 0, const wxString& name = wxPanelNameStr );

View File

@ -454,15 +454,7 @@ void SIM_PLOT_FRAME::StartSimulation( const wxString& aSimCommand )
if( aSimCommand != wxEmptyString )
m_circuitModel->SetSimCommandOverride( aSimCommand );
// Make .save all and .probe all permanent for now.
int options = NETLIST_EXPORTER_SPICE::OPTION_DEFAULT_FLAGS
| NETLIST_EXPORTER_SPICE::OPTION_SAVE_ALL_VOLTAGES
| NETLIST_EXPORTER_SPICE::OPTION_SAVE_ALL_CURRENTS;
if( !m_simulator->Settings()->GetFixIncludePaths() )
options &= ~NETLIST_EXPORTER_SPICE::OPTION_ADJUST_INCLUDE_PATHS;
m_circuitModel->SetOptions( options );
m_circuitModel->SetSimOptions( getCurrentOptions() );
wxString errors;
WX_STRING_REPORTER reporter( &errors );
@ -515,7 +507,7 @@ void SIM_PLOT_FRAME::StartSimulation( const wxString& aSimCommand )
}
SIM_PANEL_BASE* SIM_PLOT_FRAME::NewPlotPanel( wxString aSimCommand )
SIM_PANEL_BASE* SIM_PLOT_FRAME::NewPlotPanel( wxString aSimCommand, int aOptions )
{
SIM_PANEL_BASE* plotPanel = nullptr;
SIM_TYPE simType = NGSPICE_CIRCUIT_MODEL::CommandToSimType( aSimCommand );
@ -523,7 +515,7 @@ SIM_PANEL_BASE* SIM_PLOT_FRAME::NewPlotPanel( wxString aSimCommand )
if( SIM_PANEL_BASE::IsPlottable( simType ) )
{
SIM_PLOT_PANEL* panel;
panel = new SIM_PLOT_PANEL( aSimCommand, m_workbook, this, wxID_ANY );
panel = new SIM_PLOT_PANEL( aSimCommand, aOptions, m_workbook, this, wxID_ANY );
panel->GetPlotWin()->EnableMouseWheelPan(
Pgm().GetCommonSettings()->m_Input.scroll_modifier_zoom != 0 );
@ -533,7 +525,7 @@ SIM_PANEL_BASE* SIM_PLOT_FRAME::NewPlotPanel( wxString aSimCommand )
else
{
SIM_NOPLOT_PANEL* panel;
panel = new SIM_NOPLOT_PANEL( aSimCommand, m_workbook, wxID_ANY );
panel = new SIM_NOPLOT_PANEL( aSimCommand, aOptions, m_workbook, wxID_ANY );
plotPanel = dynamic_cast<SIM_PANEL_BASE*>( panel );
}
@ -674,8 +666,8 @@ void SIM_PLOT_FRAME::addPlot( const wxString& aName, SIM_PLOT_TYPE aType )
if( !plotPanel || plotPanel->GetType() != simType )
{
plotPanel =
dynamic_cast<SIM_PLOT_PANEL*>( NewPlotPanel( m_circuitModel->GetSimCommand() ) );
plotPanel = dynamic_cast<SIM_PLOT_PANEL*>( NewPlotPanel( m_circuitModel->GetSimCommand(),
m_circuitModel->GetSimOptions() ) );
}
wxASSERT( plotPanel );
@ -949,9 +941,30 @@ bool SIM_PLOT_FRAME::loadWorkbook( const wxString& aPath )
if( !file.Open() )
return false;
long version = 1;
wxString firstLine = file.GetFirstLine();
wxString plotCountLine;
if( firstLine.StartsWith( wxT( "version " ) ) )
{
if( !firstLine.substr( 8 ).ToLong( &version ) )
{
DISPLAY_LOAD_ERROR( "Error loading workbook: Line %d is not an integer." );
file.Close();
return false;
}
plotCountLine = file.GetNextLine();
}
else
{
plotCountLine = firstLine;
}
long plotsCount;
if( !file.GetFirstLine().ToLong( &plotsCount ) ) // GetFirstLine instead of GetNextLine
if( !plotCountLine.ToLong( &plotsCount ) ) // GetFirstLine instead of GetNextLine
{
DISPLAY_LOAD_ERROR( "Error loading workbook: Line %d is not an integer." );
file.Close();
@ -971,8 +984,33 @@ bool SIM_PLOT_FRAME::loadWorkbook( const wxString& aPath )
return false;
}
wxString simCommand = UnescapeString( file.GetNextLine() );
NewPlotPanel( simCommand );
wxString command = UnescapeString( file.GetNextLine() );
wxString simCommand;
int simOptions = NETLIST_EXPORTER_SPICE::OPTION_DEFAULT_FLAGS;
wxStringTokenizer tokenizer( command, wxT( "\r\n" ), wxTOKEN_STRTOK );
if( version >= 2 )
{
simOptions &= ~NETLIST_EXPORTER_SPICE::OPTION_ADJUST_INCLUDE_PATHS;
simOptions &= ~NETLIST_EXPORTER_SPICE::OPTION_SAVE_ALL_VOLTAGES;
simOptions &= ~NETLIST_EXPORTER_SPICE::OPTION_SAVE_ALL_CURRENTS;
}
while( tokenizer.HasMoreTokens() )
{
wxString line = tokenizer.GetNextToken();
if( line.StartsWith( wxT( ".kicad adjustpaths" ) ) )
simOptions |= NETLIST_EXPORTER_SPICE::OPTION_ADJUST_INCLUDE_PATHS;
else if( line.StartsWith( wxT( ".save all" ) ) )
simOptions |= NETLIST_EXPORTER_SPICE::OPTION_SAVE_ALL_VOLTAGES;
else if( line.StartsWith( wxT( ".probe alli" ) ) )
simOptions |= NETLIST_EXPORTER_SPICE::OPTION_SAVE_ALL_CURRENTS;
else
simCommand += line + wxT( "\n" );
}
NewPlotPanel( simCommand, simOptions );
StartSimulation( simCommand );
// Perform simulation, so plots can be added with values
@ -1062,6 +1100,8 @@ bool SIM_PLOT_FRAME::saveWorkbook( const wxString& aPath )
file.Create();
}
file.AddLine( wxT( "version 2" ) );
file.AddLine( wxString::Format( wxT( "%llu" ), m_workbook->GetPageCount() ) );
for( size_t i = 0; i < m_workbook->GetPageCount(); i++ )
@ -1075,7 +1115,20 @@ bool SIM_PLOT_FRAME::saveWorkbook( const wxString& aPath )
}
file.AddLine( wxString::Format( wxT( "%d" ), basePanel->GetType() ) );
file.AddLine( EscapeString( m_workbook->GetSimCommand( basePanel ), CTX_LINE ) );
wxString command = m_workbook->GetSimCommand( basePanel );
int options = m_workbook->GetSimOptions( basePanel );
if( options & NETLIST_EXPORTER_SPICE::OPTION_ADJUST_INCLUDE_PATHS )
command += wxT( "\n.kicad adjustpaths" );
if( options & NETLIST_EXPORTER_SPICE::OPTION_SAVE_ALL_VOLTAGES )
command += wxT( "\n.save all" );
if( options & NETLIST_EXPORTER_SPICE::OPTION_SAVE_ALL_CURRENTS )
command += wxT( "\n.probe alli" );
file.AddLine( EscapeString( command, CTX_LINE ) );
const SIM_PLOT_PANEL* plotPanel = dynamic_cast<const SIM_PLOT_PANEL*>( basePanel );
@ -1161,7 +1214,7 @@ void SIM_PLOT_FRAME::menuNewPlot( wxCommandEvent& aEvent )
SIM_TYPE type = m_circuitModel->GetSimType();
if( SIM_PANEL_BASE::IsPlottable( type ) )
NewPlotPanel( m_circuitModel->GetSimCommand() );
NewPlotPanel( m_circuitModel->GetSimCommand(), m_circuitModel->GetSimOptions() );
}
@ -1489,7 +1542,14 @@ void SIM_PLOT_FRAME::onSettings( wxCommandEvent& event )
}
if( m_workbook->GetPageIndex( plotPanelWindow ) != wxNOT_FOUND )
{
dlg.SetSimCommand( m_workbook->GetSimCommand( plotPanelWindow ) );
dlg.SetSimOptions( m_workbook->GetSimOptions( plotPanelWindow ) );
}
else
{
dlg.SetSimOptions( NETLIST_EXPORTER_SPICE::OPTION_DEFAULT_FLAGS );
}
if( dlg.ShowModal() == wxID_OK )
{
@ -1501,12 +1561,14 @@ void SIM_PLOT_FRAME::onSettings( wxCommandEvent& event )
oldCommand = wxString();
const wxString& newCommand = dlg.GetSimCommand();
int newOptions = dlg.GetSimOptions();
SIM_TYPE newSimType = NGSPICE_CIRCUIT_MODEL::CommandToSimType( newCommand );
if( !plotPanelWindow )
{
m_circuitModel->SetSimCommandOverride( newCommand );
plotPanelWindow = NewPlotPanel( newCommand );
m_circuitModel->SetSimOptions( newOptions );
plotPanelWindow = NewPlotPanel( newCommand, newOptions );
}
// If it is a new simulation type, open a new plot. For the DC sim, check if sweep
// source type has changed (char 4 will contain 'v', 'i', 'r' or 't'.
@ -1514,7 +1576,7 @@ void SIM_PLOT_FRAME::onSettings( wxCommandEvent& event )
|| ( newSimType == ST_DC
&& oldCommand.Lower().GetChar( 4 ) != newCommand.Lower().GetChar( 4 ) ) )
{
plotPanelWindow = NewPlotPanel( newCommand );
plotPanelWindow = NewPlotPanel( newCommand, newOptions );
}
else
{
@ -1523,6 +1585,7 @@ void SIM_PLOT_FRAME::onSettings( wxCommandEvent& event )
// Update simulation command in the current plot
m_workbook->SetSimCommand( plotPanelWindow, newCommand );
m_workbook->SetSimOptions( plotPanelWindow, newOptions );
}
m_simulator->Init();
@ -1581,8 +1644,6 @@ void SIM_PLOT_FRAME::onTune( wxCommandEvent& event )
}
void SIM_PLOT_FRAME::onShowNetlist( wxCommandEvent& event )
{
class NETLIST_VIEW_DIALOG : public DIALOG_SHIM
{
public:
@ -1636,12 +1697,17 @@ void SIM_PLOT_FRAME::onShowNetlist( wxCommandEvent& event )
std::unique_ptr<SCINTILLA_TRICKS> m_scintillaTricks;
};
void SIM_PLOT_FRAME::onShowNetlist( wxCommandEvent& event )
{
if( m_schematicFrame == nullptr || m_simulator == nullptr )
return;
wxString errors;
WX_STRING_REPORTER reporter( &errors );
STRING_FORMATTER formatter;
m_circuitModel->SetSimOptions( getCurrentOptions() );
m_circuitModel->GetNetlist( &formatter, reporter );
NETLIST_VIEW_DIALOG dlg( this, errors.IsEmpty() ? formatter.GetString() : errors );
@ -1769,7 +1835,10 @@ void SIM_PLOT_FRAME::onSimFinished( wxCommandEvent& aEvent )
SIM_PANEL_BASE* plotPanelWindow = getCurrentPlotWindow();
if( !plotPanelWindow || plotPanelWindow->GetType() != simType )
plotPanelWindow = NewPlotPanel( m_circuitModel->GetSimCommand() );
{
plotPanelWindow = NewPlotPanel( m_circuitModel->GetSimCommand(),
m_circuitModel->GetSimOptions() );
}
// Sometimes (for instance with a directive like wrdata my_file.csv "my_signal")
// the simulator is in idle state (simulation is finished), but still running, during

View File

@ -69,10 +69,11 @@ public:
/**
* Create a new plot panel for a given simulation type and adds it to the main notebook.
*
* @param aSimType is requested simulation type.
* @param aSimCommand is requested simulation command.
* @param aSimOptions netlisting options
* @return The new plot panel.
*/
SIM_PANEL_BASE* NewPlotPanel( wxString aSimCommand );
SIM_PANEL_BASE* NewPlotPanel( wxString aSimCommand, int aSimOptions );
/**
* Add a voltage plot for a given net name.
@ -239,6 +240,14 @@ private:
return m_workbook->GetSimCommand( getCurrentPlotWindow() );
}
int getCurrentOptions() const
{
if( getCurrentPlotWindow() == nullptr )
return m_circuitModel->GetSimOptions();
else
return m_workbook->GetSimOptions( getCurrentPlotWindow() );
}
/**
* Return X axis for a given simulation type.
*/

View File

@ -301,10 +301,10 @@ void CURSOR::UpdateReference()
}
SIM_PLOT_PANEL::SIM_PLOT_PANEL( const wxString& aCommand, wxWindow* parent,
SIM_PLOT_PANEL::SIM_PLOT_PANEL( const wxString& aCommand, int aOptions, wxWindow* parent,
SIM_PLOT_FRAME* aMainFrame, wxWindowID id, const wxPoint& pos,
const wxSize& size, long style, const wxString& name )
: SIM_PANEL_BASE( aCommand, parent, id, pos, size, style, name ),
: SIM_PANEL_BASE( aCommand, aOptions, parent, id, pos, size, style, name ),
m_axis_x( nullptr ),
m_axis_y1( nullptr ),
m_axis_y2( nullptr ),

View File

@ -46,7 +46,10 @@ class CURSOR : public mpInfoLayer
public:
CURSOR( const TRACE* aTrace, SIM_PLOT_PANEL* aPlotPanel ) :
mpInfoLayer( wxRect( 0, 0, DRAG_MARGIN, DRAG_MARGIN ), wxTRANSPARENT_BRUSH ),
m_trace( aTrace ), m_updateRequired( true ), m_updateRef( false ), m_coords( 0.0, 0.0 ),
m_trace( aTrace ),
m_updateRequired( true ),
m_updateRef( false ),
m_coords( 0.0, 0.0 ),
m_window( nullptr )
{
SetDrawOutsideMargins( false );
@ -95,7 +98,9 @@ class TRACE : public mpFXYVector
{
public:
TRACE( const wxString& aName, SIM_PLOT_TYPE aType ) :
mpFXYVector( aName ), m_cursor( nullptr ), m_type( aType )
mpFXYVector( aName ),
m_cursor( nullptr ),
m_type( aType )
{
SetContinuity( true );
SetDrawOutsideMargins( false );
@ -178,10 +183,10 @@ class SIM_PLOT_PANEL : public SIM_PANEL_BASE
friend class SIM_WORKBOOK;
public:
SIM_PLOT_PANEL( const wxString& aCommand, wxWindow* parent, SIM_PLOT_FRAME* aMainFrame,
wxWindowID id, const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxDefaultSize, long style = 0,
const wxString& name = wxPanelNameStr );
SIM_PLOT_PANEL( const wxString& aCommand, int aOptions, wxWindow* parent,
SIM_PLOT_FRAME* aMainFrame, wxWindowID id,
const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize,
long style = 0, const wxString& name = wxPanelNameStr );
virtual ~SIM_PLOT_PANEL();

View File

@ -63,6 +63,17 @@ public:
return aPlotPanel->getSimCommand();
}
void SetSimOptions( SIM_PANEL_BASE* aPlotPanel, int aOptions )
{
aPlotPanel->setSimOptions( aOptions );
setModified();
}
int GetSimOptions( const SIM_PANEL_BASE* aPlotPanel )
{
return aPlotPanel->getSimOptions();
}
void ClrModified();
bool IsModified() const { return m_modified; }