53#include <wx/checkbox.h> 
   54#include <wx/filedlg.h> 
   56#include <wx/process.h> 
   58#include <wx/txtstrm.h> 
   67std::vector<wxString> SplitCommandLine( 
const wxString& aCommand )
 
   69    std::vector<wxString> args;
 
   71    bool                  inSingle = 
false;
 
   72    bool                  inDouble = 
false;
 
   73    bool                  argStarted = 
false;
 
   75    for( wxUniChar c : aCommand )
 
   77        if( c == 
'"' && !inSingle )
 
   84        if( c == 
'\'' && !inDouble )
 
   91        if( ( c == 
' ' || c == 
'\t' || c == 
'\n' || c == 
'\r' ) && !inSingle && !inDouble )
 
   93            if( argStarted || !current.IsEmpty() )
 
   95                args.emplace_back( current );
 
  107    if( argStarted || !current.IsEmpty() )
 
  108        args.emplace_back( current );
 
  115#define CUSTOMPANEL_COUNTMAX 8   
  217        wxPanel( aParent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ),
 
  230    aParent->AddPage( 
this, aTitle, 
false );
 
  232    wxBoxSizer* MainBoxSizer = 
new wxBoxSizer( wxVERTICAL );
 
  233    SetSizer( MainBoxSizer );
 
  234    wxBoxSizer* UpperBoxSizer = 
new wxBoxSizer( wxHORIZONTAL );
 
  236    MainBoxSizer->Add( UpperBoxSizer, 0, wxEXPAND | wxALL, 5 );
 
  243    UpperBoxSizer->Add( 
m_RightBoxSizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5 );
 
 
  266    wxStaticText*        label = 
nullptr;
 
  269    label = 
new wxStaticText( page, wxID_ANY, 
_( 
"Export netlist in KiCad format" ) );
 
  274    label = 
new wxStaticText( page, wxID_ANY, 
_( 
"Export netlist in OrcadPCB2 format" ) );
 
  279    label = 
new wxStaticText( page, wxID_ANY, 
_( 
"Export netlist in Allegro format" ) );
 
  284    label = 
new wxStaticText( page, wxID_ANY, 
_( 
"Export netlist in CadStar format" ) );
 
  289    label = 
new wxStaticText( page, wxID_ANY, 
_( 
"Export netlist in PADS format" ) );
 
  303                                { wxID_CANCEL, 
_( 
"Close" )          } } );
 
  307        SetTitle( 
m_job->GetSettingsDialogTitle() );
 
 
  346    wxStaticText* label = 
new wxStaticText( pg, wxID_ANY, 
_( 
"Export netlist in SPICE format" ) );
 
  350    pg->
m_CurSheetAsRoot->SetToolTip( 
_( 
"Export netlist only for the current sheet" ) );
 
  354    pg->
m_SaveAllVoltages->SetToolTip( 
_( 
"Write a directive to save all voltages (.save all)" ) );
 
  358    pg->
m_SaveAllCurrents->SetToolTip( 
_( 
"Write a directive to save all currents (.probe alli)" ) );
 
  363                                              "(.probe p(<item>))" ) );
 
  367    pg->
m_SaveAllEvents->SetToolTip( 
_( 
"If not set, write a directive to prevent the saving of digital event data " 
  374                                                  "Usually '<path to SPICE binary> \"%I\"'\n" 
  375                                                  "%I will be replaced by the netlist filepath" ) );
 
 
  391    wxStaticText* label = 
new wxStaticText( pg, wxID_ANY, 
_( 
"Export netlist as a SPICE .subckt model" ) );
 
  392    pg->m_LeftBoxSizer->Add( label, 0, wxBOTTOM, 10 );
 
  395    pg->m_CurSheetAsRoot->SetToolTip( 
_( 
"Export netlist only for the current sheet" ) );
 
  396    pg->m_LeftBoxSizer->Add( pg->m_CurSheetAsRoot, 0, wxEXPAND | wxBOTTOM | wxRIGHT, 5 );
 
 
  421                                                              const wxString& aCommandString,
 
  426    pg->
m_LowBoxSizer->Add( 
new wxStaticText( pg, wxID_ANY, 
_( 
"Title:" ) ), 0,
 
  427                            wxEXPAND | wxLEFT | wxRIGHT | wxTOP, 5 );
 
  438    pg->
m_LowBoxSizer->Add( 
new wxStaticText( pg, wxID_ANY, 
_( 
"Netlist command:" ) ), 0,
 
  439                            wxEXPAND | wxLEFT | wxRIGHT | wxTOP, 5 );
 
 
  461    wxString    fileWildcard;
 
  463    wxString    title = 
_( 
"Save Netlist File" );
 
  471                m_job->format = format;
 
  488    bool     runExternalSpiceCommand = 
false;
 
  489    unsigned netlist_opt = 0;
 
  548    if( runExternalSpiceCommand )
 
  551        fullpath = fn.GetFullPath();
 
  555        fn.SetExt( fileExt );
 
  557        if( fn.GetPath().IsEmpty() )
 
  558           fn.SetPath( wxPathOnly( 
Prj().GetProjectFullName() ) );
 
  560        wxString fullname = fn.GetFullName();
 
  561        wxString 
path     = fn.GetPath();
 
  564        wxFileDialog dlg( 
this, title, 
path, fullname, fileWildcard, wxFD_SAVE );
 
  566        if( dlg.ShowModal() == wxID_CANCEL )
 
  569        fullpath = dlg.GetPath();   
 
  580    if( !
m_editFrame->ReadyToNetlist( 
_( 
"Exporting netlist requires a fully annotated schematic." ) ) )
 
  585    if( runExternalSpiceCommand )
 
  589        commandLine.Replace( wxS( 
"%I" ), fullpath, 
true );
 
  590        commandLine.Trim( 
true ).Trim( 
false );
 
  592        if( !commandLine.IsEmpty() )
 
  594            std::vector<wxString> argsStrings = SplitCommandLine( commandLine );
 
  596            if( !argsStrings.empty() )
 
  598                std::vector<const wxChar*> argv;
 
  599                argv.reserve( argsStrings.size() + 1 );
 
  601                for( wxString& arg : argsStrings )
 
  602                    argv.emplace_back( arg.wc_str() );
 
  604                argv.emplace_back( 
nullptr );
 
  607                wxGetEnvMap( &env.env );
 
  611                for( 
const auto& [key, value] : envVars )
 
  613                    if( !value.GetValue().IsEmpty() )
 
  614                        env.env[key] = value.GetValue();
 
  617                wxFileName netlistFile( fullpath );
 
  619                if( !netlistFile.IsAbsolute() )
 
  620                    netlistFile.MakeAbsolute( 
Prj().GetProjectPath() );
 
  622                    netlistFile.MakeAbsolute();
 
  624                wxString cwd = netlistFile.GetPath();
 
  631                wxProcess* 
process = 
new wxProcess( GetEventHandler(), wxID_ANY );
 
  634                long pid = wxExecute( argv.data(), wxEXEC_ASYNC, 
process, &env );
 
  641                    reporter.
Report( 
_( 
"Note: command line is usually: " 
  642                                        "<tt><path to SPICE binary> \"%I\"</tt>" ),
 
  650                    std::this_thread::sleep_for( std::chrono::seconds( 1 ) ); 
 
  652                    if( 
process->IsInputAvailable() )
 
  654                        wxInputStream* in = 
process->GetInputStream();
 
  655                        wxTextInputStream textstream( *in );
 
  657                        while( in->CanRead() )
 
  659                            wxString line = textstream.ReadLine();
 
  661                            if( !line.IsEmpty() )
 
  666                    if( 
process->IsErrorAvailable() )
 
  668                        wxInputStream* err = 
process->GetErrorStream();
 
  669                        wxTextInputStream textstream( *err );
 
  671                        while( err->CanRead() )
 
  673                            wxString line = textstream.ReadLine();
 
  675                            if( !line.IsEmpty() )
 
  677                                if( line.EndsWith( wxS( 
"failed with error 2!" ) ) )      
 
  680                                    reporter.
Report( 
_( 
"Note: command line is usually: " 
  681                                                        "<tt><path to SPICE binary> \"%I\"</tt>" ),
 
  684                                else if( line.EndsWith( wxS( 
"failed with error 8!" ) ) ) 
 
  686                                    reporter.
Report( 
_( 
"external simulator has the wrong format or " 
  689                                else if( line.EndsWith( 
"failed with error 13!" ) ) 
 
  712    return !runExternalSpiceCommand;
 
 
  719    wxString fileWildcard;
 
  764        *aWildCard = fileWildcard;
 
 
  782            wxString title = currPage->m_TitleStringCtrl->GetValue();
 
  783            wxString command = currPage->m_CommandStringCtrl->GetValue();
 
  785            if( title.IsEmpty() || command.IsEmpty() )
 
 
  829            wxMessageBox( 
_( 
"This plugin already exists." ) );
 
  843            wxMessageBox( 
_( 
"Maximum number of plugins already added to dialog." ) );
 
 
  872    if( !wxDialog::TransferDataFromWindow() )
 
  877        wxMessageBox( 
_( 
"You must provide a netlist generator title" ) );
 
 
  887    wxString FullFileName, Path;
 
  892    Path = PATHS::GetOSXKicadDataDir() + wxT( 
"/plugins" );
 
  895    FullFileName = wxFileSelector( 
_( 
"Generator File" ), Path, FullFileName, wxEmptyString,
 
  896                                   wxFileSelectorDefaultWildcardStr, wxFD_OPEN, 
this );
 
  898    if( FullFileName.IsEmpty() )
 
  904    wxFileName fn( FullFileName );
 
  905    wxString ext = fn.GetExt();
 
  907    if( ext == wxT( 
"xsl" ) )
 
  908        cmdLine.Printf( wxT( 
"xsltproc -o \"%%O\" \"%s\" \"%%I\"" ), FullFileName );
 
  909    else if( ext == wxT( 
"exe" ) || ext.IsEmpty() )
 
  910        cmdLine.Printf( wxT( 
"\"%s\" > \"%%O\" < \"%%I\"" ), FullFileName );
 
  911    else if( ext == wxT( 
"py" ) || ext.IsEmpty() )
 
  912        cmdLine.Printf( wxT( 
"python \"%s\" \"%%I\" \"%%O\"" ), FullFileName );
 
  914        cmdLine.Printf( wxT( 
"\"%s\"" ), FullFileName );
 
 
  929    if( currPage == 
nullptr )
 
 
KIFACE_BASE & Kiface()
Global KIFACE_BASE "get" accessor.
 
wxStaticText * m_staticTextOutputPath
 
DIALOG_EXPORT_NETLIST_BASE(wxWindow *parent, wxWindowID id=wxID_ANY, const wxString &title=_("Export Netlist"), const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxSize(-1,-1), long style=wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER)
 
wxButton * m_buttonDelGenerator
 
WX_HTML_REPORT_PANEL * m_MessagesBox
 
wxTextCtrl * m_outputPath
 
wxButton * m_buttonAddGenerator
 
void OnDelGenerator(wxCommandEvent &event) override
Remove a panel relative to a netlist plugin.
 
void WriteCurrentNetlistSetup()
Write the current netlist options setup in the configuration.
 
EXPORT_NETLIST_PAGE * AddOneCustomPage(const wxString &aTitle, const wxString &aCommandString, NETLIST_TYPE_ID aNetTypeId)
 
void InstallPageSpiceModel()
 
bool TransferDataFromWindow() override
 
std::vector< EXPORT_NETLIST_PAGE * > m_PanelNetType
 
void InstallCustomPages()
 
SCH_EDIT_FRAME * m_editFrame
 
JOB_EXPORT_SCH_NETLIST * m_job
 
void OnAddGenerator(wxCommandEvent &event) override
Add a new panel for a new netlist plugin.
 
void OnNetlistTypeSelection(wxNotebookEvent &event) override
 
bool FilenamePrms(NETLIST_TYPE_ID aType, wxString *aExt, wxString *aWildCard)
Return the filename extension and the wildcard string for this page or a void name if there is no def...
 
DIALOG_EXPORT_NETLIST(SCH_EDIT_FRAME *aEditFrame)
 
void updateGeneratorButtons()
 
void SetupStandardButtons(std::map< int, wxString > aLabels={})
 
bool IsQuasiModal() const
 
void EndQuasiModal(int retCode)
 
void finishDialogSettings()
In all dialogs, we must call the same functions to fix minimal dlg size, the default position and per...
 
wxWindow * m_initialFocusTarget
 
PANEL_NETLIST m_NetlistPanel
 
const wxString GetPageNetFmtName()
 
NETLIST_TYPE_ID m_IdNetType
 
wxCheckBox * m_SaveAllVoltages
 
wxString m_pageNetFmtName
 
wxBoxSizer * m_RightBoxSizer
 
wxCheckBox * m_CurSheetAsRoot
 
wxBoxSizer * m_LeftBoxSizer
 
~EXPORT_NETLIST_PAGE()=default
 
EXPORT_NETLIST_PAGE(wxNotebook *aParent, const wxString &aTitle, NETLIST_TYPE_ID aIdNetType, bool aCustom)
Create a setup page for one netlist format.
 
wxCheckBox * m_RunExternalSpiceCommand
 
wxCheckBox * m_SaveAllEvents
 
wxCheckBox * m_SaveAllCurrents
 
wxTextCtrl * m_CommandStringCtrl
 
wxBoxSizer * m_RightOptionsBoxSizer
 
wxCheckBox * m_SaveAllDissipations
 
wxTextCtrl * m_TitleStringCtrl
 
wxBoxSizer * m_LowBoxSizer
 
static std::map< JOB_EXPORT_SCH_NETLIST::FORMAT, wxString > & GetFormatNameMap()
 
APP_SETTINGS_BASE * KifaceSettings() const
 
PROJECT & Prj() const
Return a reference to the PROJECT associated with this KIWAY.
 
NETLIST_DIALOG_ADD_GENERATOR_BASE(wxWindow *parent, wxWindowID id=wxID_ANY, const wxString &title=_("Add Script-based Netlist Exporter"), const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxSize(-1,-1), long style=wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER)
 
wxTextCtrl * m_textCtrlCommand
 
wxTextCtrl * m_textCtrlName
 
const wxString GetGeneratorTCommandLine()
 
DIALOG_EXPORT_NETLIST * m_Parent
 
NETLIST_DIALOG_ADD_GENERATOR(DIALOG_EXPORT_NETLIST *parent)
 
const wxString GetGeneratorTitle()
 
void OnBrowseGenerators(wxCommandEvent &event) override
Browse plugin files, and set m_CommandStringCtrl field.
 
bool TransferDataFromWindow() override
 
@ OPTION_SAVE_ALL_CURRENTS
 
@ OPTION_SAVE_ALL_VOLTAGES
 
@ OPTION_SAVE_ALL_DISSIPATIONS
 
@ OPTION_CUR_SHEET_AS_ROOT
 
virtual ENV_VAR_MAP & GetLocalEnvVariables() const
 
virtual const wxString & GetExecutablePath() const
 
virtual const wxString GetProjectPath() const
Return the full path of the project.
 
A pure virtual class used to derive REPORTER objects from.
 
virtual REPORTER & ReportHead(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)
Places the report at the beginning of the list for objects that support ordering.
 
virtual REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)
Report a string with a given severity.
 
Schematic editor (Eeschema) main window.
 
void SaveProjectLocalSettings() override
Save changes to the project settings to the project (.pro) file.
 
@ ID_SAVE_ALL_DISSIPATIONS
 
#define CUSTOMPANEL_COUNTMAX
 
int InvokeDialogNetList(SCH_EDIT_FRAME *aCaller)
 
NETLIST_TYPE_ID
netlist types
 
@ ID_END_EESCHEMA_ID_LIST
 
static const std::string CadstarNetlistFileExtension
 
static const std::string NetlistFileExtension
 
static const std::string OrCadPcb2NetlistFileExtension
 
static const std::string SpiceFileExtension
 
static const std::string PADSNetlistFileExtension
 
static const std::string AllegroNetlistFileExtension
 
static wxString SpiceNetlistFileWildcard()
 
static wxString OrCadPcb2NetlistFileWildcard()
 
static wxString AllFilesWildcard()
 
static wxString AllegroNetlistFileWildcard()
 
static wxString CadstarNetlistFileWildcard()
 
static wxString PADSNetlistFileWildcard()
 
static wxString NetlistFileWildcard()
 
std::map< wxString, ENV_VAR_ITEM > ENV_VAR_MAP
 
#define NET_PLUGIN_CHANGE
Create and shows DIALOG_EXPORT_NETLIST and returns whatever DIALOG_EXPORT_NETLIST::ShowModal() return...
 
static PGM_BASE * process
 
PGM_BASE & Pgm()
The global program "get" accessor.
 
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
 
std::vector< NETLIST_PLUGIN_SETTINGS > plugins
 
Definition of file extensions used in Kicad.