KiCad PCB EDA Suite
eeschema/dialogs/dialog_netlist.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright (C) 2013-2017 Jean-Pierre Charras, [email protected]
5 * Copyright (C) 2013 Wayne Stambaugh <[email protected]>
6 * Copyright (C) 1992-2021 KiCad Developers, see AUTHORS.txt for contributors.
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, you may find one here:
20 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
21 * or you may search the http://www.gnu.org website for the version 2 license,
22 * or you may write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
24 */
25
26/* Functions relative to the dialog creating the netlist for Pcbnew. The dialog is a notebook
27 * with 4 fixed netlist formats:
28 * Pcbnew
29 * ORCADPCB2
30 * CADSTAR
31 * SPICE
32 * and up to CUSTOMPANEL_COUNTMAX user programmable formats. These external converters are
33 * referred to as plugins, but they are really just external binaries.
34 */
35
36#include <pgm_base.h>
37#include <kiface_base.h>
38#include <gestfich.h>
39#include <sch_edit_frame.h>
40#include <general.h>
41#include <netlist.h>
42#include <dialogs/dialog_netlist_base.h>
44#include <invoke_sch_dialog.h>
46#include <eeschema_settings.h>
47#include <schematic.h>
48#include <paths.h>
49
50#include <eeschema_id.h>
51#include <wx/checkbox.h>
52#include <wx/filedlg.h>
53#include <wx/msgdlg.h>
54#include <wx/regex.h>
55
56
57
58#define CUSTOMPANEL_COUNTMAX 8 // Max number of netlist plugins
59
60
61/* panel (notebook page) identifiers */
63 PANELPCBNEW = 0, /* Handle Netlist format Pcbnew */
64 PANELORCADPCB2, /* Handle Netlist format OracdPcb2 */
65 PANELCADSTAR, /* Handle Netlist format CadStar */
66 PANELSPICE, /* Handle Netlist format Spice */
67 PANELSPICEMODEL, /* Handle Netlist format Spice Model (subcircuit) */
68 PANELCUSTOMBASE /* First auxiliary panel (custom netlists).
69 * others use PANELCUSTOMBASE+1, PANELCUSTOMBASE+2.. */
70};
71
72
73/* wxPanels for creating the NoteBook pages for each netlist format: */
74class NETLIST_PAGE_DIALOG : public wxPanel
75{
76
77public:
87 NETLIST_PAGE_DIALOG( wxNotebook* aParent, const wxString& aTitle,
88 NETLIST_TYPE_ID aIdNetType, bool aCustom );
90
94 const wxString GetPageNetFmtName() { return m_pageNetFmtName; }
95
97 // opt to reformat passive component values (e.g. 1M -> 1Meg):
98 wxCheckBox* m_CurSheetAsRoot;
99 wxCheckBox* m_SaveAllVoltages;
100 wxCheckBox* m_SaveAllCurrents;
102 wxTextCtrl* m_TitleStringCtrl;
103 wxBoxSizer* m_LeftBoxSizer;
104 wxBoxSizer* m_RightBoxSizer;
106 wxBoxSizer* m_LowBoxSizer;
107
108 bool IsCustom() const { return m_custom; }
109
110private:
112
114};
115
116
117/* Dialog frame for creating netlists */
119{
120public:
123
124private:
126
127 void InstallCustomPages();
128 NETLIST_PAGE_DIALOG* AddOneCustomPage( const wxString & aTitle,
129 const wxString & aCommandString,
130 NETLIST_TYPE_ID aNetTypeId );
131 void InstallPageSpice();
133
134 bool TransferDataFromWindow() override;
135 void NetlistUpdateOpt();
136
138
139 // Called when changing the notebook page (and therefore the current netlist format)
140 void OnNetlistTypeSelection( wxNotebookEvent& event ) override;
141
145 void OnAddGenerator( wxCommandEvent& event ) override;
146
150 void OnDelGenerator( wxCommandEvent& event ) override;
151
155 void OnRunExternSpiceCommand( wxCommandEvent& event );
156
160 void OnRunSpiceButtUI( wxUpdateUIEvent& event );
161
166
176 bool FilenamePrms( NETLIST_TYPE_ID aType, wxString* aExt, wxString* aWildCard );
177
179
180public:
183};
184
185
187{
188public:
190
191 const wxString GetGeneratorTitle() { return m_textCtrlName->GetValue(); }
192 const wxString GetGeneratorTCommandLine() { return m_textCtrlCommand->GetValue(); }
193
194 bool TransferDataFromWindow() override;
195
196private:
197 /*
198 * Browse plugin files, and set m_CommandStringCtrl field
199 */
200 void OnBrowseGenerators( wxCommandEvent& event ) override;
201
203};
204
205
206/* Event id for notebook page buttons: */
214
215
216BEGIN_EVENT_TABLE( NETLIST_DIALOG, NETLIST_DIALOG_BASE )
219END_EVENT_TABLE()
220
221
222NETLIST_PAGE_DIALOG::NETLIST_PAGE_DIALOG( wxNotebook* aParent, const wxString& aTitle,
223 NETLIST_TYPE_ID aIdNetType, bool aCustom ) :
224 wxPanel( aParent, -1, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL )
225{
226 m_IdNetType = aIdNetType;
227 m_pageNetFmtName = aTitle;
228 m_CommandStringCtrl = nullptr;
229 m_CurSheetAsRoot = nullptr;
230 m_TitleStringCtrl = nullptr;
231 m_SaveAllVoltages = nullptr;
232 m_SaveAllCurrents = nullptr;
233 m_custom = aCustom;
234
235 aParent->AddPage( this, aTitle, false );
236
237 wxBoxSizer* MainBoxSizer = new wxBoxSizer( wxVERTICAL );
238 SetSizer( MainBoxSizer );
239 wxBoxSizer* UpperBoxSizer = new wxBoxSizer( wxHORIZONTAL );
240 m_LowBoxSizer = new wxBoxSizer( wxVERTICAL );
241 MainBoxSizer->Add( UpperBoxSizer, 0, wxGROW | wxALL, 5 );
242 MainBoxSizer->Add( m_LowBoxSizer, 0, wxGROW | wxALL, 5 );
243
244 m_LeftBoxSizer = new wxBoxSizer( wxVERTICAL );
245 m_RightBoxSizer = new wxBoxSizer( wxVERTICAL );
246 m_RightOptionsBoxSizer = new wxBoxSizer( wxVERTICAL );
247 UpperBoxSizer->Add( m_LeftBoxSizer, 0, wxGROW | wxALL, 5 );
248 UpperBoxSizer->Add( m_RightBoxSizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5 );
249 UpperBoxSizer->Add( m_RightOptionsBoxSizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5 );
250}
251
252
254 NETLIST_DIALOG_BASE( parent )
255{
256 m_Parent = parent;
257
259
261 page = nullptr;
262
263 // Add notebook pages:
265 new NETLIST_PAGE_DIALOG( m_NoteBook, wxT( "KiCad" ), NET_TYPE_PCBNEW, false );
266
268 new NETLIST_PAGE_DIALOG( m_NoteBook, wxT( "OrcadPCB2" ), NET_TYPE_ORCADPCB2, false );
269
271 new NETLIST_PAGE_DIALOG( m_NoteBook, wxT( "CadStar" ), NET_TYPE_CADSTAR, false );
272
276
277 SetupStandardButtons( { { wxID_OK, _( "Export Netlist" ) },
278 { wxID_CANCEL, _( "Close" ) } } );
279
280 for( int ii = 0; (ii < 4 + CUSTOMPANEL_COUNTMAX) && m_PanelNetType[ii]; ++ii )
281 {
282 if( m_PanelNetType[ii]->GetPageNetFmtName() == settings.m_NetFormatName )
283 {
284 m_NoteBook->ChangeSelection( ii );
285 break;
286 }
287 }
288
289 // Now all widgets have the size fixed, call FinishDialogSettings
291
293}
294
295
296void NETLIST_DIALOG::OnRunExternSpiceCommand( wxCommandEvent& event )
297{
298 // Run the external spice simulator command
300
302 wxString simulatorCommand = settings.m_SpiceCommandString;
303
304 unsigned netlist_opt = 0;
305
306 // Calculate the netlist filename and options
307 wxFileName fn = m_Parent->Schematic().GetFileName();
308 fn.SetExt( wxT( "cir" ) );
309
310 if( settings.m_SpiceAdjustPassiveValues )
312
313 if( settings.m_SpiceSaveAllVoltages )
315
316 if( settings.m_SpiceSaveAllCurrents )
318
319 // Build the command line
320 wxString commandLine = simulatorCommand;
321 commandLine.Replace( "%I", fn.GetFullPath(), true );
322
323 if( m_Parent->ReadyToNetlist( _( "Simulator requires a fully annotated schematic." ) ) )
324 {
325 m_Parent->WriteNetListFile( NET_TYPE_SPICE, fn.GetFullPath(), netlist_opt, nullptr );
326 commandLine.Trim( true ).Trim( false );
327
328 if( !commandLine.IsEmpty() )
329 wxExecute( commandLine, wxEXEC_ASYNC );
330 }
331}
332
333
334void NETLIST_DIALOG::OnRunSpiceButtUI( wxUpdateUIEvent& aEvent )
335{
336 bool disable = m_PanelNetType[PANELSPICE]->m_CommandStringCtrl->IsEmpty();
337 aEvent.Enable( !disable );
338}
339
340
342{
344 new NETLIST_PAGE_DIALOG( m_NoteBook, wxT( "Spice" ), NET_TYPE_SPICE, false );
345
347
348 page->m_CurSheetAsRoot = new wxCheckBox( page, ID_CUR_SHEET_AS_ROOT,
349 _( "Use current sheet as root" ) );
350 page->m_CurSheetAsRoot->SetToolTip( _( "Export netlist only for the current sheet" ) );
351 page->m_CurSheetAsRoot->SetValue( settings.m_SpiceCurSheetAsRoot );
352 page->m_LeftBoxSizer->Add( page->m_CurSheetAsRoot, 0, wxGROW | wxBOTTOM | wxRIGHT, 5 );
353
354 page->m_SaveAllVoltages = new wxCheckBox( page, ID_SAVE_ALL_VOLTAGES,
355 _( "Save all voltages" ) );
356 page->m_SaveAllVoltages->SetToolTip( _( "Write a directive to save all voltages (.save all)" ) );
357 page->m_SaveAllVoltages->SetValue( settings.m_SpiceSaveAllVoltages );
358 page->m_RightBoxSizer->Add( page->m_SaveAllVoltages, 0, wxBOTTOM | wxRIGHT, 5 );
359
360 page->m_SaveAllCurrents = new wxCheckBox( page, ID_SAVE_ALL_CURRENTS,
361 _( "Save all currents" ) );
362 page->m_SaveAllCurrents->SetToolTip( _( "Write a directive to save all currents (.probe alli)" ) );
363 page->m_SaveAllCurrents->SetValue( settings.m_SpiceSaveAllCurrents );
364 page->m_RightBoxSizer->Add( page->m_SaveAllCurrents, 0, wxBOTTOM | wxRIGHT, 5 );
365
366
367 wxString simulatorCommand = settings.m_SpiceCommandString;
368 wxStaticText* spice_label = new wxStaticText( page, -1, _( "External simulator command:" ) );
369 spice_label->SetToolTip( _( "Enter the command line to run spice\n"
370 "Usually <path to spice binary> %I\n"
371 "%I will be replaced by the actual spice netlist name" ) );
372 page->m_LowBoxSizer->Add( spice_label, 0, wxGROW | wxLEFT | wxRIGHT | wxBOTTOM, 5 );
373
374 page->m_CommandStringCtrl = new wxTextCtrl( page, -1, simulatorCommand,
375 wxDefaultPosition, wxDefaultSize );
376
377 page->m_CommandStringCtrl->SetInsertionPoint( 1 );
378 page->m_LowBoxSizer->Add( page->m_CommandStringCtrl, 0,
379 wxGROW | wxLEFT | wxRIGHT | wxBOTTOM, 5 );
380
381 // Add button to run spice command
382 wxButton* button = new wxButton( page, ID_RUN_SIMULATOR,
383 _( "Create Netlist and Run Simulator Command" ) );
384 page->m_LowBoxSizer->Add( button, 0, wxGROW | wxBOTTOM | wxLEFT | wxRIGHT, 5 );
385}
386
387
389{
391 new NETLIST_PAGE_DIALOG( m_NoteBook, wxT( "Spice Model" ), NET_TYPE_SPICE_MODEL, false );
392
394
395 page->m_CurSheetAsRoot = new wxCheckBox( page, ID_CUR_SHEET_AS_ROOT,
396 _( "Use current sheet as root" ) );
397 page->m_CurSheetAsRoot->SetToolTip( _( "Export netlist only for the current sheet" ) );
398 page->m_CurSheetAsRoot->SetValue( settings.m_SpiceModelCurSheetAsRoot );
399 page->m_LeftBoxSizer->Add( page->m_CurSheetAsRoot, 0, wxGROW | wxBOTTOM | wxRIGHT, 5 );
400}
401
402
404{
405 NETLIST_PAGE_DIALOG* currPage;
406
407 auto cfg = dynamic_cast<EESCHEMA_SETTINGS*>( Kiface().KifaceSettings() );
408 wxASSERT( cfg );
409
410 if( cfg )
411 {
412 for( size_t i = 0;
413 i < CUSTOMPANEL_COUNTMAX && i < cfg->m_NetlistPanel.plugins.size();
414 i++ )
415 {
416 // pairs of (title, command) are stored
417 wxString title = cfg->m_NetlistPanel.plugins[i].name;
418
419 if( i >= cfg->m_NetlistPanel.plugins.size() )
420 break; // No more panel to install
421
422 wxString command = cfg->m_NetlistPanel.plugins[i].command;
423
424 currPage = AddOneCustomPage( title, command,
425 static_cast<NETLIST_TYPE_ID>( NET_TYPE_CUSTOM1 + i ) );
426
427 m_PanelNetType[PANELCUSTOMBASE + i] = currPage;
428 }
429 }
430}
431
432
434 const wxString& aCommandString,
435 NETLIST_TYPE_ID aNetTypeId )
436{
437 NETLIST_PAGE_DIALOG* currPage = new NETLIST_PAGE_DIALOG( m_NoteBook, aTitle, aNetTypeId, true );
438
439 currPage->m_LowBoxSizer->Add( new wxStaticText( currPage, -1, _( "Title:" ) ), 0,
440 wxGROW | wxLEFT | wxRIGHT | wxTOP, 5 );
441
442 currPage->m_TitleStringCtrl = new wxTextCtrl( currPage, -1, aTitle,
443 wxDefaultPosition, wxDefaultSize );
444
445 currPage->m_TitleStringCtrl->SetInsertionPoint( 1 );
446 currPage->m_LowBoxSizer->Add( currPage->m_TitleStringCtrl, 0,
447 wxGROW | wxTOP | wxLEFT | wxRIGHT | wxBOTTOM, 5 );
448
449 currPage->m_LowBoxSizer->Add( new wxStaticText( currPage, -1, _( "Netlist command:" ) ), 0,
450 wxGROW | wxLEFT | wxRIGHT | wxTOP, 5 );
451
452 currPage->m_CommandStringCtrl = new wxTextCtrl( currPage, -1, aCommandString,
453 wxDefaultPosition, wxDefaultSize );
454
455 currPage->m_CommandStringCtrl->SetInsertionPoint( 1 );
456 currPage->m_LowBoxSizer->Add( currPage->m_CommandStringCtrl, 0,
457 wxGROW | wxTOP | wxLEFT | wxRIGHT | wxBOTTOM, 5 );
458
459 return currPage;
460}
461
462
463void NETLIST_DIALOG::OnNetlistTypeSelection( wxNotebookEvent& event )
464{
466}
467
468
470{
471 bool saveAllVoltages = m_PanelNetType[ PANELSPICE ]->m_SaveAllVoltages->IsChecked();
472 bool saveAllCurrents = m_PanelNetType[ PANELSPICE ]->m_SaveAllCurrents->IsChecked();
473 wxString spiceCmdString = m_PanelNetType[ PANELSPICE ]->m_CommandStringCtrl->GetValue();
474 bool curSheetAsRoot = m_PanelNetType[ PANELSPICE ]->m_CurSheetAsRoot->GetValue();
475 bool spiceModelCurSheetAsRoot = m_PanelNetType[ PANELSPICEMODEL ]->m_CurSheetAsRoot->GetValue();
476
478
479 settings.m_SpiceSaveAllVoltages = saveAllVoltages;
480 settings.m_SpiceSaveAllCurrents = saveAllCurrents;
481 settings.m_SpiceCommandString = spiceCmdString;
482 settings.m_SpiceCurSheetAsRoot = curSheetAsRoot;
483 settings.m_SpiceModelCurSheetAsRoot = spiceModelCurSheetAsRoot;
484 settings.m_NetFormatName = m_PanelNetType[m_NoteBook->GetSelection()]->GetPageNetFmtName();
485}
486
487
489{
490 wxFileName fn;
491 wxString fileWildcard;
492 wxString fileExt;
493 wxString title = _( "Save Netlist File" );
494
496
497 NETLIST_PAGE_DIALOG* currPage;
498 currPage = (NETLIST_PAGE_DIALOG*) m_NoteBook->GetCurrentPage();
499
500 unsigned netlist_opt = 0;
501
502 // Calculate the netlist filename
504 FilenamePrms( currPage->m_IdNetType, &fileExt, &fileWildcard );
505
506 // Set some parameters
507 switch( currPage->m_IdNetType )
508 {
509 case NET_TYPE_SPICE:
510 // Set spice netlist options:
511 if( currPage->m_SaveAllVoltages->GetValue() )
513 if( currPage->m_SaveAllCurrents->GetValue() )
515 if( currPage->m_CurSheetAsRoot->GetValue() )
517 break;
518
520 if( currPage->m_CurSheetAsRoot->GetValue() )
522 break;
523
524 case NET_TYPE_CADSTAR:
525 break;
526
527 case NET_TYPE_PCBNEW:
528 break;
529
531 break;
532
533 default: // custom, NET_TYPE_CUSTOM1 and greater
534 {
535 title.Printf( _( "%s Export" ), currPage->m_TitleStringCtrl->GetValue() );
536 break;
537 }
538 }
539
540 fn.SetExt( fileExt );
541
542 if( fn.GetPath().IsEmpty() )
543 fn.SetPath( wxPathOnly( Prj().GetProjectFullName() ) );
544
545 wxString fullpath = fn.GetFullPath();
546 wxString fullname = fn.GetFullName();
547 wxString path = fn.GetPath();
548
549 // full name does not and should not include the path, per wx docs.
550 wxFileDialog dlg( this, title, path, fullname, fileWildcard, wxFD_SAVE );
551
552 if( dlg.ShowModal() == wxID_CANCEL )
553 return false;
554
555 fullpath = dlg.GetPath(); // directory + filename
556
558
559 if( currPage->m_CommandStringCtrl )
560 m_Parent->SetNetListerCommand( currPage->m_CommandStringCtrl->GetValue() );
561 else
562 m_Parent->SetNetListerCommand( wxEmptyString );
563
564 if( m_Parent->ReadyToNetlist( _( "Exporting netlist requires a fully annotated schematic." ) ) )
565 m_Parent->WriteNetListFile( currPage->m_IdNetType, fullpath, netlist_opt, nullptr );
566
568
569 return true;
570}
571
572
573bool NETLIST_DIALOG::FilenamePrms( NETLIST_TYPE_ID aType, wxString * aExt, wxString * aWildCard )
574{
575 wxString fileExt;
576 wxString fileWildcard;
577 bool ret = true;
578
579 switch( aType )
580 {
581 case NET_TYPE_SPICE:
582 fileExt = wxT( "cir" );
583 fileWildcard = SpiceNetlistFileWildcard();
584 break;
585
586 case NET_TYPE_CADSTAR:
587 fileExt = wxT( "frp" );
588 fileWildcard = CadstarNetlistFileWildcard();
589 break;
590
593 fileWildcard = OrCadPcb2NetlistFileWildcard();
594 break;
595
596 case NET_TYPE_PCBNEW:
597 fileExt = NetlistFileExtension;
598 fileWildcard = NetlistFileWildcard();
599 break;
600
601 default: // custom, NET_TYPE_CUSTOM1 and greater
602 fileWildcard = AllFilesWildcard();
603 ret = false;
604 }
605
606 if( aExt )
607 *aExt = fileExt;
608
609 if( aWildCard )
610 *aWildCard = fileWildcard;
611
612 return ret;
613}
614
615
617{
619
620 EESCHEMA_SETTINGS* cfg = dynamic_cast<EESCHEMA_SETTINGS*>( Kiface().KifaceSettings() );
621 wxASSERT( cfg );
622
623 if( !cfg )
624 return;
625
626 cfg->m_NetlistPanel.plugins.clear();
627
628 // Update existing custom pages
629 for( int ii = 0; ii < CUSTOMPANEL_COUNTMAX; ii++ )
630 {
632
633 if( currPage == nullptr )
634 break;
635
636 wxString title = currPage->m_TitleStringCtrl->GetValue();
637 wxString command = currPage->m_CommandStringCtrl->GetValue();
638
639 if( title.IsEmpty() || command.IsEmpty() )
640 continue;
641
642 cfg->m_NetlistPanel.plugins.emplace_back( title, wxEmptyString );
643 cfg->m_NetlistPanel.plugins.back().command = command;
644 }
645}
646
647
648void NETLIST_DIALOG::OnDelGenerator( wxCommandEvent& event )
649{
650 NETLIST_PAGE_DIALOG* currPage = (NETLIST_PAGE_DIALOG*) m_NoteBook->GetCurrentPage();
651
652 if( !currPage->IsCustom() )
653 return;
654
655 currPage->m_CommandStringCtrl->SetValue( wxEmptyString );
656 currPage->m_TitleStringCtrl->SetValue( wxEmptyString );
657
659
660 if( IsQuasiModal() )
662 else
663 EndDialog( NET_PLUGIN_CHANGE );
664}
665
666
667void NETLIST_DIALOG::OnAddGenerator( wxCommandEvent& event )
668{
670
671 if( dlg.ShowModal() != wxID_OK )
672 return;
673
674 // Creates a new custom plugin page
675 wxString title = dlg.GetGeneratorTitle();
676
677 // Verify it does not exists
678 int netTypeId = PANELCUSTOMBASE; // the first not used type id
679 NETLIST_PAGE_DIALOG* currPage;
680
681 for( int ii = 0; ii < CUSTOMPANEL_COUNTMAX; ii++ )
682 {
683 netTypeId = PANELCUSTOMBASE + ii;
684 currPage = m_PanelNetType[ii + PANELCUSTOMBASE];
685
686 if( currPage == nullptr )
687 break;
688
689 if( currPage->GetPageNetFmtName() == title )
690 {
691 wxMessageBox( _("This plugin already exists.") );
692 return;
693 }
694 }
695
696 wxString cmd = dlg.GetGeneratorTCommandLine();
697 currPage = AddOneCustomPage( title,cmd, (NETLIST_TYPE_ID)netTypeId );
698 m_PanelNetType[netTypeId] = currPage;
700
701 if( IsQuasiModal() )
703 else
704 EndDialog( NET_PLUGIN_CHANGE );
705}
706
707
710{
711 m_Parent = parent;
713 GetSizer()->SetSizeHints( this );
714}
715
716
718{
719 if( !wxDialog::TransferDataFromWindow() )
720 return false;
721
722 if( m_textCtrlCommand->GetValue() == wxEmptyString )
723 {
724 wxMessageBox( _( "You must provide a netlist generator command string" ) );
725 return false;
726 }
727
728 if( m_textCtrlName->GetValue() == wxEmptyString )
729 {
730 wxMessageBox( _( "You must provide a netlist generator title" ) );
731 return false;
732 }
733
734 return true;
735}
736
737
739{
740 wxString FullFileName, Path;
741
742#ifndef __WXMAC__
743 Path = Pgm().GetExecutablePath();
744#else
745 Path = PATHS::GetOSXKicadDataDir() + wxT( "/plugins" );
746#endif
747
748 FullFileName = wxFileSelector( _( "Generator File" ), Path, FullFileName,
749 wxEmptyString, wxFileSelectorDefaultWildcardStr,
750 wxFD_OPEN, this );
751
752 if( FullFileName.IsEmpty() )
753 return;
754
755 // Creates a default command line, suitable for external tool xslproc or python, based on
756 // the plugin extension ("xsl" or "exe" or "py")
757 wxString cmdLine;
758 wxFileName fn( FullFileName );
759 wxString ext = fn.GetExt();
760
761 if( ext == wxT( "xsl" ) )
762 cmdLine.Printf( wxT( "xsltproc -o \"%%O\" \"%s\" \"%%I\"" ), FullFileName );
763 else if( ext == wxT( "exe" ) || ext.IsEmpty() )
764 cmdLine.Printf( wxT( "\"%s\" > \"%%O\" < \"%%I\"" ), FullFileName );
765 else if( ext == wxT( "py" ) || ext.IsEmpty() )
766 cmdLine.Printf( wxT( "python \"%s\" \"%%I\" \"%%O\"" ), FullFileName );
767 else
768 cmdLine.Printf( wxT( "\"%s\"" ), FullFileName );
769
770 m_textCtrlCommand->SetValue( cmdLine );
771
772 // We need a title for this panel
773 // Propose a default value if empty ( i.e. the short filename of the script)
774 if( m_textCtrlName->GetValue().IsEmpty() )
775 m_textCtrlName->SetValue( fn.GetName() );
776}
777
778
780{
781 NETLIST_PAGE_DIALOG* currPage = (NETLIST_PAGE_DIALOG*) m_NoteBook->GetCurrentPage();
782
783 if( currPage == nullptr )
784 return;
785
786 m_buttonDelGenerator->Enable( currPage->IsCustom() );
787}
788
789
791{
792 NETLIST_DIALOG dlg( aCaller );
793
794 int ret = dlg.ShowModal();
795 aCaller->SaveProjectSettings();
796
797 return ret;
798}
KIFACE_BASE & Kiface()
Global KIFACE_BASE "get" accessor.
void SetupStandardButtons(std::map< int, wxString > aLabels={})
bool IsQuasiModal() const
Definition: dialog_shim.h:106
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...
virtual void ClearMsgPanel()
Clear all messages from the message panel.
PANEL_NETLIST m_NetlistPanel
APP_SETTINGS_BASE * KifaceSettings() const
Definition: kiface_base.h:93
PROJECT & Prj() const
Return a reference to the PROJECT associated with this KIWAY.
Class NETLIST_DIALOG_ADD_GENERATOR_BASE.
void OnBrowseGenerators(wxCommandEvent &event) override
NETLIST_PAGE_DIALOG * m_PanelNetType[5+CUSTOMPANEL_COUNTMAX]
void OnRunSpiceButtUI(wxUpdateUIEvent &event)
Enable (if the command line is not empty or disable the button to run spice command.
NETLIST_PAGE_DIALOG * AddOneCustomPage(const wxString &aTitle, const wxString &aCommandString, NETLIST_TYPE_ID aNetTypeId)
NETLIST_DIALOG(SCH_EDIT_FRAME *parent)
void OnAddGenerator(wxCommandEvent &event) override
Add a new panel for a new netlist plugin.
void WriteCurrentNetlistSetup()
Write the current netlist options setup in the configuration.
void OnRunExternSpiceCommand(wxCommandEvent &event)
Run the external spice simulator command.
void OnDelGenerator(wxCommandEvent &event) override
Remove a panel relative to a netlist plugin.
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...
void OnNetlistTypeSelection(wxNotebookEvent &event) override
NETLIST_PAGE_DIALOG(wxNotebook *aParent, const wxString &aTitle, NETLIST_TYPE_ID aIdNetType, bool aCustom)
Create a setup page for one netlist format.
These settings were stored in SCH_BASE_FRAME previously.
wxString GetFileName() const override
Helper to retrieve the filename from the root sheet screen.
Definition: schematic.cpp:166
SCHEMATIC_SETTINGS & Settings() const
Definition: schematic.cpp:172
Schematic editor (Eeschema) main window.
void SaveProjectSettings() override
Save changes to the project settings to the project (.pro) file.
bool ReadyToNetlist(const wxString &aAnnotateMessage)
Check if we are ready to write a netlist file for the current schematic.
bool WriteNetListFile(int aFormat, const wxString &aFullFileName, unsigned aNetlistOptions, REPORTER *aReporter=nullptr)
Create a netlist file.
SCHEMATIC & Schematic() const
void SetNetListerCommand(const wxString &aCommand)
#define _(s)
#define CUSTOMPANEL_COUNTMAX
int InvokeDialogNetList(SCH_EDIT_FRAME *aCaller)
@ ID_END_EESCHEMA_ID_LIST
Definition: eeschema_id.h:83
EVT_UPDATE_UI(ID_LOAD_FOOTPRINT_FROM_BOARD, FOOTPRINT_EDIT_FRAME::OnUpdateLoadFootprintFromBoard) EVT_UPDATE_UI(ID_ADD_FOOTPRINT_TO_BOARD
const std::string NetlistFileExtension
const std::string OrCadPcb2NetlistFileExtension
wxString NetlistFileWildcard()
wxString OrCadPcb2NetlistFileWildcard()
wxString CadstarNetlistFileWildcard()
wxString AllFilesWildcard()
wxString SpiceNetlistFileWildcard()
#define NET_PLUGIN_CHANGE
Create and shows NETLIST_DIALOG and returns whatever NETLIST_DIALOG::ShowModal() returns.
NETLIST_TYPE_ID
netlist types
Definition: netlist.h:35
@ NET_TYPE_CADSTAR
Definition: netlist.h:40
@ NET_TYPE_ORCADPCB2
Definition: netlist.h:39
@ NET_TYPE_SPICE
Definition: netlist.h:41
@ NET_TYPE_SPICE_MODEL
Definition: netlist.h:42
@ NET_TYPE_PCBNEW
Definition: netlist.h:38
@ NET_TYPE_CUSTOM1
Definition: netlist.h:43
see class PGM_BASE
KIWAY Kiway & Pgm(), KFCTL_STANDALONE
The global Program "get" accessor.
Definition: single_top.cpp:111
std::vector< NETLIST_PLUGIN_SETTINGS > plugins
Definition of file extensions used in Kicad.