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, jp.charras@wanadoo.fr
5  * Copyright (C) 2013 Wayne Stambaugh <stambaughw@gmail.com>
6  * Copyright (C) 1992-2020 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 <fctsys.h>
37 #include <pgm_base.h>
38 #include <kiface_i.h>
39 #include <gestfich.h>
40 #include <sch_edit_frame.h>
41 #include <general.h>
42 #include <netlist.h>
43 #include <dialogs/dialog_netlist_base.h>
45 #include <invoke_sch_dialog.h>
47 #include <eeschema_settings.h>
48 #include <schematic.h>
49 
50 #include <eeschema_id.h>
51 #include <wx/regex.h>
52 
53 
54 #define CUSTOMPANEL_COUNTMAX 8 // Max number of netlist plugins
55 
56 
57 /* panel (notebook page) identifiers */
59  PANELPCBNEW = 0, /* Handle Netlist format Pcbnew */
60  PANELORCADPCB2, /* Handle Netlist format OracdPcb2 */
61  PANELCADSTAR, /* Handle Netlist format CadStar */
62  PANELSPICE, /* Handle Netlist format Pspice */
63  PANELCUSTOMBASE /* First auxiliary panel (custom netlists).
64  * others use PANELCUSTOMBASE+1, PANELCUSTOMBASE+2.. */
65 };
66 
67 
68 /* wxPanels for creating the NoteBook pages for each netlist format: */
69 class NETLIST_PAGE_DIALOG : public wxPanel
70 {
71 public:
73  wxCheckBox* m_IsCurrentFormat;
74  // opt to reformat passive component values (e.g. 1M -> 1Meg):
75  wxCheckBox* m_AdjustPassiveValues;
76  wxTextCtrl* m_CommandStringCtrl;
77  wxTextCtrl* m_TitleStringCtrl;
78  wxBoxSizer* m_LeftBoxSizer;
79  wxBoxSizer* m_RightBoxSizer;
81  wxBoxSizer* m_LowBoxSizer;
82 
83 private:
84  wxString m_pageNetFmtName;
85 
86 public:
93  NETLIST_PAGE_DIALOG( wxNotebook* parent, const wxString& title,
94  NETLIST_TYPE_ID id_NetType );
96 
102  const wxString GetPageNetFmtName() { return m_pageNetFmtName; }
103 };
104 
105 
106 /* Dialog frame for creating netlists */
108 {
109  friend class NETLIST_PAGE_DIALOG;
110 
111 public:
115 
116 protected:
118 
119 public:
120  // Constructor and destructor
121  NETLIST_DIALOG( SCH_EDIT_FRAME* parent );
123 
124 private:
125  void InstallCustomPages();
126  NETLIST_PAGE_DIALOG* AddOneCustomPage( const wxString & aTitle,
127  const wxString & aCommandString,
128  NETLIST_TYPE_ID aNetTypeId );
129  void InstallPageSpice();
130  bool TransferDataFromWindow() override;
131  void NetlistUpdateOpt();
132 
133  // Called when changing the notebook page (and therefore the current netlist format)
134  void OnNetlistTypeSelection( wxNotebookEvent& event ) override;
135 
136  // called when checking the "Default format" wxCheckBox in the current page of the notbook
137  void SelectDefaultNetlistType( wxCommandEvent& event );
138 
143  void OnAddGenerator( wxCommandEvent& event ) override;
144 
149  void OnDelGenerator( wxCommandEvent& event ) override;
150 
154  void OnRunExternSpiceCommand( wxCommandEvent& event );
155 
159  void OnRunSpiceButtUI( wxUpdateUIEvent& event );
160 
166 
176  bool FilenamePrms( NETLIST_TYPE_ID aType,
177  wxString * aExt, wxString * aWildCard );
178 
179  DECLARE_EVENT_TABLE()
180 };
181 
182 
184 {
185 private:
187 
188 public:
190 
191  const wxString GetGeneratorTitle() { return m_textCtrlName->GetValue(); }
192  const wxString GetGeneratorTCommandLine() { return m_textCtrlCommand->GetValue(); }
193 
194 private:
199  void OnOKClick( wxCommandEvent& event ) override;
200 
201  /*
202  * Browse plugin files, and set m_CommandStringCtrl field
203  */
204  void OnBrowseGenerators( wxCommandEvent& event ) override;
205 };
206 
207 
208 /* Event id for notebook page buttons: */
215 };
216 
217 
218 BEGIN_EVENT_TABLE( NETLIST_DIALOG, NETLIST_DIALOG_BASE )
222 END_EVENT_TABLE()
223 
224 
225 
227  const wxString& title,
228  NETLIST_TYPE_ID id_NetType ) :
229  wxPanel( parent, -1, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL )
230 {
231  m_IdNetType = id_NetType;
232  m_pageNetFmtName = title;
233  m_CommandStringCtrl = NULL;
234  m_TitleStringCtrl = NULL;
235  m_IsCurrentFormat = NULL;
236  m_AdjustPassiveValues = NULL;
237 
238  wxString netfmtName = ((NETLIST_DIALOG*)parent->GetParent())->m_DefaultNetFmtName;
239 
240  bool selected = m_pageNetFmtName == netfmtName;
241 
242  parent->AddPage( this, title, selected );
243 
244  wxBoxSizer* MainBoxSizer = new wxBoxSizer( wxVERTICAL );
245  SetSizer( MainBoxSizer );
246  wxBoxSizer* UpperBoxSizer = new wxBoxSizer( wxHORIZONTAL );
247  m_LowBoxSizer = new wxBoxSizer( wxVERTICAL );
248  MainBoxSizer->Add( UpperBoxSizer, 0, wxGROW | wxALL, 5 );
249  MainBoxSizer->Add( m_LowBoxSizer, 0, wxGROW | wxALL, 5 );
250 
251  m_LeftBoxSizer = new wxBoxSizer( wxVERTICAL );
252  m_RightBoxSizer = new wxBoxSizer( wxVERTICAL );
253  m_RightOptionsBoxSizer = new wxBoxSizer( wxVERTICAL );
254  UpperBoxSizer->Add( m_LeftBoxSizer, 0, wxGROW | wxALL, 5 );
255  UpperBoxSizer->Add( m_RightBoxSizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5 );
256  UpperBoxSizer->Add( m_RightOptionsBoxSizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5 );
257 
258  wxStaticText* text = new wxStaticText( this, -1, _( "Options:" ) );
259  m_LeftBoxSizer->Add( text, 0, wxGROW | wxBOTTOM | wxRIGHT, 5 );
260 
261  m_IsCurrentFormat = new wxCheckBox( this, ID_CURRENT_FORMAT_IS_DEFAULT, _( "Default format" ) );
262  m_LeftBoxSizer->Add( m_IsCurrentFormat, 0, wxGROW | wxBOTTOM | wxRIGHT, 5 );
263  m_IsCurrentFormat->SetValue( selected );
264 
265  if( selected )
266  ((NETLIST_DIALOG*)parent->GetParent())->m_asFormatSelected = true;
267 }
268 
269 
270 
272  NETLIST_DIALOG_BASE( parent )
273 {
274  m_Parent = parent;
275 
277 
279 
280  for( NETLIST_PAGE_DIALOG*& page : m_PanelNetType)
281  page = NULL;
282 
283  // Add notebook pages:
284  m_asFormatSelected = false; // Will be set to true, if a format is selected
285 
286  m_PanelNetType[PANELPCBNEW] = new NETLIST_PAGE_DIALOG( m_NoteBook, wxT( "Pcbnew" ),
287  NET_TYPE_PCBNEW );
288 
289  m_PanelNetType[PANELORCADPCB2] = new NETLIST_PAGE_DIALOG( m_NoteBook, wxT( "OrcadPCB2" ),
291 
292  m_PanelNetType[PANELCADSTAR] = new NETLIST_PAGE_DIALOG( m_NoteBook, wxT( "CadStar" ),
294 
297 
298  // Ensure a netlist format is selected:
299  if( !m_asFormatSelected )
300  {
301  m_PanelNetType[PANELPCBNEW]->m_IsCurrentFormat->SetValue( true );
302  m_NoteBook->SetSelection( PANELPCBNEW );
304  // call OnNetlistTypeSelection to update some widgets.
305  // SetSelection() do nothing if the current page is already PANELPCBNEW
306  wxNotebookEvent event;
307  OnNetlistTypeSelection( event );
308  }
309 
310  // We use a sdbSizer here to get the order right, which is platform-dependent
311  m_sdbSizer2OK->SetLabel( _( "Export Netlist" ) );
312  m_sdbSizer2Cancel->SetLabel( _( "Close" ) );
313  m_buttonSizer->Layout();
314 
315  m_sdbSizer2OK->SetDefault();
316 
317  // Now all widgets have the size fixed, call FinishDialogSettings
319 }
320 
321 
322 void NETLIST_DIALOG::OnRunExternSpiceCommand( wxCommandEvent& event )
323 {
324  // Run the external spice simulator command
326 
328  wxString simulatorCommand = settings.m_SpiceCommandString;
329 
330  unsigned netlist_opt = 0;
331 
332  // Calculate the netlist filename and options
333  wxFileName fn = m_Parent->Schematic().GetFileName();
334  fn.SetExt( wxT( "cir" ) );
335 
336  if( settings.m_SpiceAdjustPassiveValues )
337  netlist_opt |= NET_ADJUST_PASSIVE_VALS;
338 
339  // Build the command line
340  wxString commandLine = simulatorCommand;
341  commandLine.Replace( "%I", fn.GetFullPath(), true );
342 
343  if( m_Parent->ReadyToNetlist( false, false ) )
344  m_Parent->WriteNetListFile( NET_TYPE_SPICE, fn.GetFullPath(), netlist_opt, nullptr );
345  else
346  {
347  wxMessageBox( _( "Schematic netlist not available" ) );
348  return;
349  }
350 
351  wxExecute( commandLine, wxEXEC_ASYNC );
352 }
353 
354 
355 void NETLIST_DIALOG::OnRunSpiceButtUI( wxUpdateUIEvent& aEvent )
356 {
357  bool disable = m_PanelNetType[PANELSPICE]->m_CommandStringCtrl->IsEmpty();
358  aEvent.Enable( !disable );
359 }
360 
361 
363 {
365  new NETLIST_PAGE_DIALOG( m_NoteBook, wxT( "Spice" ), NET_TYPE_SPICE );
366 
368 
369  page->m_AdjustPassiveValues = new wxCheckBox( page, ID_USE_NETCODE_AS_NETNAME,
370  _( "Reformat passive symbol values" ) );
371  page->m_AdjustPassiveValues->SetToolTip( _( "Reformat passive symbol values e.g. 1M -> 1Meg" ) );
372  page->m_AdjustPassiveValues->SetValue( settings.m_SpiceAdjustPassiveValues );
373  page->m_LeftBoxSizer->Add( page->m_AdjustPassiveValues, 0, wxGROW | wxBOTTOM | wxRIGHT, 5 );
374 
375  wxString simulatorCommand = settings.m_SpiceCommandString;
376  wxStaticText* spice_label = new wxStaticText( page, -1, _( "External simulator command:" ) );
377  spice_label->SetToolTip( _( "Enter the command line to run spice\n"
378  "Usually <path to spice binary> %I\n"
379  "%I will be replaced by the actual spice netlist name") );
380  page->m_LowBoxSizer->Add( spice_label, 0, wxGROW | wxLEFT | wxRIGHT | wxBOTTOM, 5 );
381 
382  page->m_CommandStringCtrl = new wxTextCtrl( page, -1, simulatorCommand,
383  wxDefaultPosition, wxDefaultSize );
384 
385  page->m_CommandStringCtrl->SetInsertionPoint( 1 );
386  page->m_LowBoxSizer->Add( page->m_CommandStringCtrl, 0,
387  wxGROW | wxLEFT | wxRIGHT | wxBOTTOM, 5 );
388 
389  // Add button to run spice command
390  wxButton* button = new wxButton( page, ID_RUN_SIMULATOR,
391  _( "Create Netlist and Run Simulator Command" ) );
392  page->m_LowBoxSizer->Add( button, 0, wxGROW | wxBOTTOM | wxLEFT | wxRIGHT, 5 );
393 }
394 
395 
397 {
398  NETLIST_PAGE_DIALOG* currPage;
399 
400  auto cfg = dynamic_cast<EESCHEMA_SETTINGS*>( Kiface().KifaceSettings() );
401  wxASSERT( cfg );
402 
403  if( cfg )
404  {
405  for( size_t i = 0;
406  i < CUSTOMPANEL_COUNTMAX && i < cfg->m_NetlistPanel.custom_command_titles.size();
407  i++ )
408  {
409  // pairs of (title, command) are stored
410  wxString title = cfg->m_NetlistPanel.custom_command_titles[i];
411 
412  if( i >= cfg->m_NetlistPanel.custom_command_paths.size() )
413  break; // No more panel to install
414 
415  wxString command = cfg->m_NetlistPanel.custom_command_paths[i];
416 
417  currPage = AddOneCustomPage( title, command,
418  static_cast<NETLIST_TYPE_ID>( NET_TYPE_CUSTOM1 + i ) );
419 
420  m_PanelNetType[PANELCUSTOMBASE + i] = currPage;
421  }
422  }
423 }
424 
425 
427  const wxString & aCommandString,
428  NETLIST_TYPE_ID aNetTypeId )
429 {
430  NETLIST_PAGE_DIALOG* currPage = new NETLIST_PAGE_DIALOG( m_NoteBook, aTitle, aNetTypeId );
431 
432  currPage->m_LowBoxSizer->Add( new wxStaticText( currPage, -1, _( "Title:" ) ), 0,
433  wxGROW | wxLEFT | wxRIGHT | wxTOP, 5 );
434 
435  currPage->m_TitleStringCtrl = new wxTextCtrl( currPage, -1, aTitle,
436  wxDefaultPosition, wxDefaultSize );
437 
438  currPage->m_TitleStringCtrl->SetInsertionPoint( 1 );
439  currPage->m_LowBoxSizer->Add( currPage->m_TitleStringCtrl, 0,
440  wxGROW | wxTOP | wxLEFT | wxRIGHT | wxBOTTOM, 5 );
441 
442  currPage->m_LowBoxSizer->Add( new wxStaticText( currPage, -1, _( "Netlist command:" ) ), 0,
443  wxGROW | wxLEFT | wxRIGHT | wxTOP, 5 );
444 
445  currPage->m_CommandStringCtrl = new wxTextCtrl( currPage, -1, aCommandString,
446  wxDefaultPosition, wxDefaultSize );
447 
448  currPage->m_CommandStringCtrl->SetInsertionPoint( 1 );
449  currPage->m_LowBoxSizer->Add( currPage->m_CommandStringCtrl, 0,
450  wxGROW | wxTOP | wxLEFT | wxRIGHT | wxBOTTOM, 5 );
451 
452  return currPage;
453 }
454 
455 
456 void NETLIST_DIALOG::SelectDefaultNetlistType( wxCommandEvent& event )
457 {
458  for( NETLIST_PAGE_DIALOG*& page : m_PanelNetType)
459  {
460  if( page )
461  page->m_IsCurrentFormat->SetValue( false );
462  }
463 
464  NETLIST_PAGE_DIALOG* currPage = (NETLIST_PAGE_DIALOG*) m_NoteBook->GetCurrentPage();
465 
466  if( currPage == NULL )
467  return;
468 
470 
473  currPage->m_IsCurrentFormat->SetValue( true );
474 }
475 
476 
477 void NETLIST_DIALOG::OnNetlistTypeSelection( wxNotebookEvent& event )
478 {
479  NETLIST_PAGE_DIALOG* currPage = (NETLIST_PAGE_DIALOG*) m_NoteBook->GetCurrentPage();
480 
481  if( currPage == NULL )
482  return;
483 
484  m_buttonDelGenerator->Enable( currPage->m_IdNetType >= NET_TYPE_CUSTOM1 );
485 }
486 
487 
489 {
490  bool adjust = m_PanelNetType[ PANELSPICE ]->m_AdjustPassiveValues->IsChecked();
491  wxString spice_cmd_string = m_PanelNetType[ PANELSPICE ]->m_CommandStringCtrl->GetValue();
492 
494 
495  settings.m_SpiceAdjustPassiveValues = adjust;
496  settings.m_SpiceCommandString = spice_cmd_string;
497  settings.m_NetFormatName = wxEmptyString;
498 
499  for( NETLIST_PAGE_DIALOG*& page : m_PanelNetType )
500  {
501  if( page == nullptr )
502  break;
503 
504  if( page->m_IsCurrentFormat->GetValue() )
505  settings.m_NetFormatName = page->GetPageNetFmtName();
506  }
507 }
508 
509 
511 {
512  wxFileName fn;
513  wxString fileWildcard;
514  wxString fileExt;
515  wxString title = _( "Save Netlist File" );
516 
518 
519  NETLIST_PAGE_DIALOG* currPage;
520  currPage = (NETLIST_PAGE_DIALOG*) m_NoteBook->GetCurrentPage();
521 
522  unsigned netlist_opt = 0;
523 
524  // Calculate the netlist filename
525  fn = m_Parent->Schematic().GetFileName();
526  FilenamePrms( currPage->m_IdNetType, &fileExt, &fileWildcard );
527 
528  // Set some parameters
529  switch( currPage->m_IdNetType )
530  {
531  case NET_TYPE_SPICE:
532  // Set spice netlist options:
533  if( currPage->m_AdjustPassiveValues->GetValue() )
534  netlist_opt |= NET_ADJUST_PASSIVE_VALS;
535  break;
536 
537  case NET_TYPE_CADSTAR:
538  break;
539 
540  case NET_TYPE_PCBNEW:
541  break;
542 
543  case NET_TYPE_ORCADPCB2:
544  break;
545 
546  default: // custom, NET_TYPE_CUSTOM1 and greater
547  {
548  wxString command = currPage->m_CommandStringCtrl->GetValue();
549  wxRegEx extRE( wxT( ".*\\.([[:alnum:]][[:alnum:]][[:alnum:]][[:alnum:]]?)\\.xslt?\".*" ) );
550 
551  if( extRE.Matches( command ) )
552  fileExt = extRE.GetMatch( command, 1 );
553 
554  title.Printf( _( "%s Export" ), currPage->m_TitleStringCtrl->GetValue().GetData() );
555  }
556  break;
557  }
558 
559  fn.SetExt( fileExt );
560 
561  if( fn.GetPath().IsEmpty() )
562  fn.SetPath( wxPathOnly( Prj().GetProjectFullName() ) );
563 
564  wxString fullpath = fn.GetFullPath();
565  wxString fullname = fn.GetFullName();
566  wxString path = fn.GetPath();
567 
568  // fullname does not and should not include the path, per wx docs.
569  wxFileDialog dlg( this, title, path, fullname, fileWildcard, wxFD_SAVE );
570 
571  if( dlg.ShowModal() == wxID_CANCEL )
572  return false;
573 
574  fullpath = dlg.GetPath(); // directory + filename
575 
577 
578  if( currPage->m_CommandStringCtrl )
579  m_Parent->SetNetListerCommand( currPage->m_CommandStringCtrl->GetValue() );
580  else
581  m_Parent->SetNetListerCommand( wxEmptyString );
582 
583  if( m_Parent->ReadyToNetlist( false, false ) )
584  m_Parent->WriteNetListFile( currPage->m_IdNetType, fullpath, netlist_opt, nullptr );
585  else
586  wxMessageBox( _( "Schematic netlist not available" ) );
587 
589 
590  return true;
591 }
592 
593 
594 bool NETLIST_DIALOG::FilenamePrms( NETLIST_TYPE_ID aType, wxString * aExt, wxString * aWildCard )
595 {
596  wxString fileExt;
597  wxString fileWildcard;
598  bool ret = true;
599 
600  switch( aType )
601  {
602  case NET_TYPE_SPICE:
603  fileExt = wxT( "cir" );
604  fileWildcard = SpiceNetlistFileWildcard();
605  break;
606 
607  case NET_TYPE_CADSTAR:
608  fileExt = wxT( "frp" );
609  fileWildcard = CadstarNetlistFileWildcard();
610  break;
611 
612  case NET_TYPE_PCBNEW:
613  case NET_TYPE_ORCADPCB2:
614  fileExt = NetlistFileExtension;
615  fileWildcard = NetlistFileWildcard();
616  break;
617 
618  default: // custom, NET_TYPE_CUSTOM1 and greater
619  fileWildcard = AllFilesWildcard();
620  ret = false;
621  }
622 
623  if( aExt )
624  *aExt = fileExt;
625 
626  if( aWildCard )
627  *aWildCard = fileWildcard;
628 
629  return ret;
630 }
631 
632 
634 {
635  wxString msg;
636 
638 
639  EESCHEMA_SETTINGS* cfg = dynamic_cast<EESCHEMA_SETTINGS*>( Kiface().KifaceSettings() );
640  wxASSERT( cfg );
641 
642  if( cfg )
643  {
646 
647  // Update existing custom pages
648  for( int ii = 0; ii < CUSTOMPANEL_COUNTMAX; ii++ )
649  {
651 
652  if( currPage == NULL )
653  break;
654 
655  wxString title = currPage->m_TitleStringCtrl->GetValue();
656 
657  if( title.IsEmpty() )
658  continue;
659 
660  cfg->m_NetlistPanel.custom_command_titles.emplace_back( title.ToStdString() );
661  cfg->m_NetlistPanel.custom_command_paths.emplace_back(
662  currPage->m_CommandStringCtrl->GetValue().ToStdString() );
663  }
664  }
665 }
666 
667 
668 void NETLIST_DIALOG::OnDelGenerator( wxCommandEvent& event )
669 {
670  NETLIST_PAGE_DIALOG* currPage = (NETLIST_PAGE_DIALOG*) m_NoteBook->GetCurrentPage();
671 
672  currPage->m_CommandStringCtrl->SetValue( wxEmptyString );
673  currPage->m_TitleStringCtrl->SetValue( wxEmptyString );
674 
675  if( currPage->m_IsCurrentFormat->IsChecked() )
676  {
677  currPage->m_IsCurrentFormat->SetValue( false );
678  m_PanelNetType[PANELPCBNEW]->m_IsCurrentFormat->SetValue( true );
679  }
680 
682  EndModal( NET_PLUGIN_CHANGE );
683 }
684 
685 
686 void NETLIST_DIALOG::OnAddGenerator( wxCommandEvent& event )
687 {
688  NETLIST_DIALOG_ADD_GENERATOR dlg( this );
689 
690  if( dlg.ShowModal() != wxID_OK )
691  return;
692 
693  // Creates a new custom plugin page
694  wxString title = dlg.GetGeneratorTitle();
695 
696  // Verify it does not exists
697  int netTypeId = PANELCUSTOMBASE; // the first not used type id
698  NETLIST_PAGE_DIALOG* currPage;
699 
700  for( int ii = 0; ii < CUSTOMPANEL_COUNTMAX; ii++ )
701  {
702  netTypeId = PANELCUSTOMBASE + ii;
703  currPage = m_PanelNetType[ii + PANELCUSTOMBASE];
704 
705  if( currPage == NULL )
706  break;
707 
708  if( currPage->GetPageNetFmtName() == title )
709  {
710  wxMessageBox( _("This plugin already exists.") );
711  return;
712  }
713  }
714 
715  wxString cmd = dlg.GetGeneratorTCommandLine();
716  currPage = AddOneCustomPage( title,cmd, (NETLIST_TYPE_ID)netTypeId );
717  m_PanelNetType[netTypeId] = currPage;
719 
720  // Close and reopen dialog to rebuild the dialog after changes
721  EndModal( NET_PLUGIN_CHANGE );
722 }
723 
724 
727 {
728  m_Parent = parent;
729  m_sdbSizerOK->SetDefault();
730  GetSizer()->SetSizeHints( this );
731 }
732 
733 
734 void NETLIST_DIALOG_ADD_GENERATOR::OnOKClick( wxCommandEvent& event )
735 {
736  if( m_textCtrlCommand->GetValue() == wxEmptyString )
737  {
738  wxMessageBox( _( "Error. You must provide a command String" ) );
739  return;
740  }
741 
742  if( m_textCtrlName->GetValue() == wxEmptyString )
743  {
744  wxMessageBox( _( "Error. You must provide a Title" ) );
745  return;
746  }
747 
748  EndModal( wxID_OK );
749 }
750 
751 
753 {
754  wxString FullFileName, Path;
755 
756 #ifndef __WXMAC__
757  Path = Pgm().GetExecutablePath();
758 #else
759  Path = GetOSXKicadDataDir() + wxT( "/plugins" );
760 #endif
761  FullFileName = EDA_FILE_SELECTOR( _( "Generator files:" ), Path, FullFileName,
762  wxEmptyString, wxFileSelectorDefaultWildcardStr,
763  this, wxFD_OPEN, true );
764  if( FullFileName.IsEmpty() )
765  return;
766 
767  // Creates a default command line, suitable for external tool xslproc or python, based on
768  // the plugin extension ("xsl" or "exe" or "py")
769  wxString cmdLine;
770  wxFileName fn( FullFileName );
771  wxString ext = fn.GetExt();
772 
773  if( ext == wxT("xsl" ) )
774  cmdLine.Printf(wxT("xsltproc -o \"%%O\" \"%s\" \"%%I\""), FullFileName );
775  else if( ext == wxT("exe" ) || ext.IsEmpty() )
776  cmdLine.Printf(wxT("\"%s\" > \"%%O\" < \"%%I\""), FullFileName );
777  else if( ext == wxT("py" ) || ext.IsEmpty() )
778  cmdLine.Printf(wxT("python \"%s\" \"%%I\" \"%%O\""), FullFileName );
779  else
780  cmdLine.Printf(wxT("\"%s\""), FullFileName );
781 
782  m_textCtrlCommand->SetValue( cmdLine );
783 
784  /* Get a title for this page */
785  wxString title = m_textCtrlName->GetValue();
786 
787  if( title.IsEmpty() )
788  wxMessageBox( _( "Do not forget to choose a title for this netlist control page" ) );
789 }
790 
791 
793 {
794  NETLIST_DIALOG dlg( aCaller );
795 
796  SCHEMATIC_SETTINGS& settings = aCaller->Schematic().Settings();
797 
798  wxString curr_default_netformat = settings.m_NetFormatName;
799 
800  int ret = dlg.ShowModal();
801 
802  // Update the default netlist and store it in prj config if it was explicitely changed.
803  settings.m_NetFormatName = dlg.m_DefaultNetFmtName; // can have temporary changed
804 
805  if( curr_default_netformat != dlg.m_DefaultNetFmtName )
806  aCaller->SaveProjectSettings();
807 
808  return ret;
809 }
const std::string NetlistFileExtension
void OnDelGenerator(wxCommandEvent &event) override
Function OnDelGenerator Remove a panel relative to a netlist plugin.
KIWAY Kiway & Pgm(), KFCTL_STANDALONE
The global Program "get" accessor.
Definition: single_top.cpp:104
void OnRunExternSpiceCommand(wxCommandEvent &event)
Run the external spice simulator command.
bool WriteNetListFile(int aFormat, const wxString &aFullFileName, unsigned aNetlistOptions, REPORTER *aReporter=NULL)
Create a netlist file.
This file is part of the common library TODO brief description.
void SaveProjectSettings() override
Save changes to the project settings to the project (.pro) file.
bool FilenamePrms(NETLIST_TYPE_ID aType, wxString *aExt, wxString *aWildCard)
Function FilenamePrms returns the filename extension and the wildcard string for this curr or a void ...
NETLIST_PAGE_DIALOG(wxNotebook *parent, const wxString &title, NETLIST_TYPE_ID id_NetType)
Constructor to create a setup page for one netlist format.
wxString SpiceNetlistFileWildcard()
SCHEMATIC_SETTINGS & Settings() const
Definition: schematic.cpp:124
void FinishDialogSettings()
In all dialogs, we must call the same functions to fix minimal dlg size, the default position and per...
void OnOKClick(wxCommandEvent &event) override
Function OnOKClick Validate info relative to a new netlist plugin.
void OnAddGenerator(wxCommandEvent &event) override
Function OnAddGenerator Add a new panel for a new netlist plugin.
Schematic editor (Eeschema) main window.
bool ReadyToNetlist(bool aSilent=false, bool aSilentAnnotate=false)
Checks if we are ready to write a netlist file for the current schematic.
wxString GetFileName() const
Helper to retrieve the filename from the root sheet screen.
Definition: schematic.cpp:118
wxString AllFilesWildcard()
NETLIST_TYPE_ID
netlist types
Definition: netlist.h:35
Class NETLIST_DIALOG_ADD_GENERATOR_BASE.
std::vector< wxString > custom_command_titles
void WriteCurrentNetlistSetup()
Function WriteCurrentNetlistSetup Write the current netlist options setup in the configuration.
#define NULL
NETLIST_DIALOG(SCH_EDIT_FRAME *parent)
#define CUSTOMPANEL_COUNTMAX
wxString NetlistFileWildcard()
PROJECT & Prj() const
Function Prj returns a reference to the PROJECT "associated with" this KIWAY.
KIFACE_I & Kiface()
Global KIFACE_I "get" accessor.
wxString EDA_FILE_SELECTOR(const wxString &aTitle, const wxString &aPath, const wxString &aFileName, const wxString &aExtension, const wxString &aWildcard, wxWindow *aParent, int aStyle, const bool aKeepWorkingDirectory, const wxPoint &aPosition, wxString *aMruPath)
Function EDA_FILE_SELECTOR.
Definition: gestfich.cpp:52
SCHEMATIC & Schematic() const
Definition of file extensions used in Kicad.
void OnBrowseGenerators(wxCommandEvent &event) override
virtual void ClearMsgPanel()
Clear all messages from the message panel.
NETLIST_PAGE_DIALOG * m_PanelNetType[4+CUSTOMPANEL_COUNTMAX]
NETLIST_PAGE_DIALOG * AddOneCustomPage(const wxString &aTitle, const wxString &aCommandString, NETLIST_TYPE_ID aNetTypeId)
see class PGM_BASE
#define _(s)
Definition: 3d_actions.cpp:33
GERBVIEW_FRAME::OnZipFileHistory GERBVIEW_FRAME::OnToggleShowLayerManager GERBVIEW_FRAME::OnSelectHighlightChoice EVT_UPDATE_UI(ID_TOOLBARH_GERBVIEW_SELECT_ACTIVE_LAYER, GERBVIEW_FRAME::OnUpdateLayerSelectBox) EVT_UPDATE_UI_RANGE(ID_TB_OPTIONS_SHOW_GBR_MODE_0
#define NET_PLUGIN_CHANGE
Create and shows NETLIST_DIALOG and returns whatever NETLIST_DIALOG::ShowModal() returns.
These settings were stored in SCH_BASE_FRAME previously.
void OnRunSpiceButtUI(wxUpdateUIEvent &event)
Enable (if the command line is not empty or disable the button to run spice command.
std::vector< wxString > custom_command_paths
void SetNetListerCommand(const wxString &aCommand)
void OnNetlistTypeSelection(wxNotebookEvent &event) override
PANEL_NETLIST m_NetlistPanel
const wxString GetPageNetFmtName()
function GetPageNetFmtName
int InvokeDialogNetList(SCH_EDIT_FRAME *aCaller)
void SelectDefaultNetlistType(wxCommandEvent &event)
wxString CadstarNetlistFileWildcard()