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