KiCad PCB EDA Suite
pcbnew/dialogs/dialog_netlist.cpp
Go to the documentation of this file.
1 
6 /*
7  * This program source code file is part of KiCad, a free EDA CAD application.
8  *
9  * Copyright (C) 1992-2013 KiCad Developers, see change_log.txt for contributors.
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version 2
14  * of the License, or (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, you may find one here:
23  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
24  * or you may search the http://www.gnu.org website for the version 2 license,
25  * or you may write to the Free Software Foundation, Inc.,
26  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
27  */
28 
29 #include <fctsys.h>
30 #include <project.h>
31 #include <kiface_i.h>
32 #include <confirm.h>
33 #include <macros.h>
34 #include <dialog_helpers.h>
35 #include <html_messagebox.h>
36 #include <base_units.h>
37 #include <wxPcbStruct.h>
38 #include <pcb_netlist.h>
39 #include <netlist_reader.h>
40 #include <reporter.h>
41 
42 #include <pcbnew_config.h>
44 #include <class_board.h>
45 #include <class_module.h>
46 #include <ratsnest_data.h>
48 
49 #include <dialog_netlist.h>
50 #include <wx_html_report_panel.h>
51 
52 #define NETLIST_SILENTMODE_KEY wxT("SilentMode")
53 #define NETLIST_FILTER_MESSAGES_KEY wxT("NetlistReportFilterMsg")
54 #define NETLIST_DELETESINGLEPADNETS_KEY wxT("NetlistDeleteSinglePadNets")
55 
57 {
58  /* Setup the netlist file name to the last netlist file read,
59  * or the board file name if the last filename is empty or last file not existing.
60  */
61  wxString netlistName = GetLastNetListRead();
62 
63  wxFileName fn = netlistName;
64 
65  if( !fn.IsOk() || !fn.FileExists() )
66  {
67  fn = GetBoard()->GetFileName();
68  fn.SetExt( NetlistFileExtension );
69 
70  if( fn.GetName().IsEmpty() )
71  netlistName.Clear();
72  else
73  netlistName = fn.GetFullPath();
74  }
75 
76  DIALOG_NETLIST dlg( this, DC, netlistName );
77 
78  dlg.ShowModal();
79 
80  // Save project settings if needed.
81  // Project settings are saved in the corresponding <board name>.pro file
82  bool configChanged = !GetLastNetListRead().IsEmpty() && ( netlistName != GetLastNetListRead() );
83 
84  if( configChanged && !GetBoard()->GetFileName().IsEmpty()
85  && IsOK( NULL, _( "The project configuration has changed. Do you want to save it?" ) ) )
86  {
87  fn = Prj().AbsolutePath( GetBoard()->GetFileName() );
88  fn.SetExt( ProjectFileExtension );
89 
90  wxString pro_name = fn.GetFullPath();
91 
92  Prj().ConfigSave( Kiface().KifaceSearch(), GROUP_PCB,
93  GetProjectFileParameters(), pro_name );
94  }
95 }
96 
97 
99  const wxString & aNetlistFullFilename )
100  : DIALOG_NETLIST_FBP( aParent )
101 {
102  m_parent = aParent;
103  m_dc = aDC;
105 
107  bool tmp = m_config->Read( NETLIST_DELETESINGLEPADNETS_KEY, 0l );
108  m_rbSingleNets->SetSelection( tmp == 0 ? 0 : 1);
109  m_NetlistFilenameCtrl->SetValue( aNetlistFullFilename );
110  m_checkBoxSilentMode->SetValue( m_silentMode );
111 
112  int severities = m_config->Read( NETLIST_FILTER_MESSAGES_KEY, -1l );
113  m_MessageWindow->SetVisibleSeverities( severities );
114 
115  // Update sizes and sizers:
116  m_MessageWindow->MsgPanelSetMinSize( wxSize( -1, 150 ) );
117  GetSizer()->SetSizeHints( this );
118 }
119 
121 {
122  m_config->Write( NETLIST_SILENTMODE_KEY, (long) m_silentMode );
124  (long) m_rbSingleNets->GetSelection() );
127 }
128 
129 
130 void DIALOG_NETLIST::OnOpenNetlistClick( wxCommandEvent& event )
131 {
132  wxString lastPath = wxFileName( Prj().GetProjectFullName() ).GetPath();
133 
134  wxString lastNetlistRead = m_parent->GetLastNetListRead();
135 
136  if( !lastNetlistRead.IsEmpty() && !wxFileName::FileExists( lastNetlistRead ) )
137  {
138  lastNetlistRead = wxEmptyString;
139  }
140  else
141  {
142  wxFileName fn = lastNetlistRead;
143  lastPath = fn.GetPath();
144  lastNetlistRead = fn.GetFullName();
145  }
146 
147  wxLogDebug( wxT( "Last net list read path '%s', file name '%s'." ),
148  GetChars( lastPath ), GetChars( lastNetlistRead ) );
149 
150  wxFileDialog FilesDialog( this, _( "Select Netlist" ), lastPath, lastNetlistRead,
151  NetlistFileWildcard, wxFD_DEFAULT_STYLE | wxFD_FILE_MUST_EXIST );
152 
153  if( FilesDialog.ShowModal() != wxID_OK )
154  return;
155 
156  m_NetlistFilenameCtrl->SetValue( FilesDialog.GetPath() );
157 }
158 
159 void DIALOG_NETLIST::OnReadNetlistFileClick( wxCommandEvent& event )
160 {
161  wxString netlistFileName = m_NetlistFilenameCtrl->GetValue();
162  wxFileName fn = netlistFileName;
163 
164  if( !fn.IsOk() )
165  {
166  wxMessageBox( _("Please, choose a valid netlist file") );
167  return;
168  }
169 
170  if( !fn.FileExists() )
171  {
172  wxMessageBox( _("The netlist file does not exist") );
173  return;
174  }
175 
176  // Give the user a chance to bail out when making changes from a netlist.
177  if( !m_checkDryRun->GetValue() && !m_silentMode
178  && !m_parent->GetBoard()->IsEmpty()
179  && !IsOK( NULL, _( "The changes made by reading the netlist cannot be undone. Are you "
180  "sure you want to read the netlist?" ) ) )
181  return;
182 
184  REPORTER& reporter = m_MessageWindow->Reporter();
185 
186  wxBusyCursor busy;
187 
188  wxString msg;
189  msg.Printf( _( "Reading netlist file \"%s\".\n" ), GetChars( netlistFileName ) );
190  reporter.Report( msg, REPORTER::RPT_INFO );
191 
192  if( m_Select_By_Timestamp->GetSelection() == 1 )
193  msg = _( "Using time stamps to match components and footprints.\n" );
194  else
195  msg = _( "Using references to match components and footprints.\n" );
196 
197  reporter.Report( msg, REPORTER::RPT_INFO );
198  m_MessageWindow->SetLazyUpdate( true ); // use a "lazy" update to speed up the creation of the report
199  // (The window is not updated for each message)
200 
201  m_parent->ReadPcbNetlist( netlistFileName, wxEmptyString, &reporter,
202  m_ChangeExistingFootprintCtrl->GetSelection() == 1,
203  m_DeleteBadTracks->GetSelection() == 1,
204  m_RemoveExtraFootprintsCtrl->GetSelection() == 1,
205  m_Select_By_Timestamp->GetSelection() == 1,
206  m_rbSingleNets->GetSelection() == 1,
207  m_checkDryRun->GetValue() );
208  // The creation of the report was made without window update:
209  // the full page must be displayed
211 }
212 
213 
214 void DIALOG_NETLIST::OnTestFootprintsClick( wxCommandEvent& event )
215 {
216  if( m_parent->GetBoard()->m_Modules == NULL )
217  {
218  DisplayInfoMessage( this, _( "No footprints" ) );
219  return;
220  }
221 
222  // Lists of duplicates, missing references and not in netlist footprints:
223  std::vector <MODULE*> duplicate;
224  wxArrayString missing;
225  std::vector <MODULE*> notInNetlist;
226  wxString netlistFilename = m_NetlistFilenameCtrl->GetValue();
227 
228  if( !verifyFootprints( netlistFilename, wxEmptyString, duplicate, missing, notInNetlist ) )
229  return;
230 
231  #define ERR_CNT_MAX 100 // Max number of errors to output in dialog
232  // to avoid a too long message list
233 
234  wxString list; // The messages to display
235 
236  m_parent->SetLastNetListRead( netlistFilename );
237 
238  int err_cnt = 0;
239 
240  // Search for duplicate footprints.
241  if( duplicate.size() == 0 )
242  list << wxT("<p><b>") << _( "No duplicate." ) << wxT("</b></p>");
243  else
244  {
245  list << wxT("<p><b>") << _( "Duplicates:" ) << wxT("</b></p>");
246 
247  for( unsigned ii = 0; ii < duplicate.size(); ii++ )
248  {
249  MODULE* module = duplicate[ii];
250 
251  if( module->GetReference().IsEmpty() )
252  list << wxT("<br>") << wxT("[noref)");
253  else
254  list << wxT("<br>") << module->GetReference();
255 
256  list << wxT(" (<i>") << module->GetValue() << wxT("</i>)");
257  list << wxT(" @ ");
258  list << CoordinateToString( module->GetPosition().x ),
259  list << wxT(", ") << CoordinateToString( module->GetPosition().y ),
260  err_cnt++;
261 
262  if( ERR_CNT_MAX < err_cnt )
263  break;
264  }
265  }
266 
267  // Search for missing modules on board.
268  if( missing.size() == 0 )
269  list << wxT("<p><b>") << _( "No missing footprints." ) << wxT("</b></p>");
270  else
271  {
272  list << wxT("<p><b>") << _( "Missing:" ) << wxT("</b></p>");
273 
274  for( unsigned ii = 0; ii < missing.size(); ii += 2 )
275  {
276  list << wxT("<br>") << missing[ii];
277  list << wxT(" (<i>") << missing[ii+1] << wxT("</i>)");
278  err_cnt++;
279 
280  if( ERR_CNT_MAX < err_cnt )
281  break;
282  }
283  }
284 
285 
286  // Search for modules found on board but not in net list.
287  if( notInNetlist.size() == 0 )
288  list << wxT( "<p><b>" ) << _( "No extra footprints." ) << wxT( "</b></p>" );
289  else
290  {
291  list << wxT( "<p><b>" ) << _( "Not in Netlist:" ) << wxT( "</b></p>" );
292 
293  for( unsigned ii = 0; ii < notInNetlist.size(); ii++ )
294  {
295  MODULE* module = notInNetlist[ii];
296 
297  if( module->GetReference().IsEmpty() )
298  list << wxT( "<br>" ) << wxT( "[noref)" );
299  else
300  list << wxT( "<br>" ) << module->GetReference() ;
301 
302  list << wxT( " (<i>" ) << module->GetValue() << wxT( "</i>)" );
303  list << wxT( " @ " );
304  list << CoordinateToString( module->GetPosition().x ),
305  list << wxT( ", " ) << CoordinateToString( module->GetPosition().y ),
306  err_cnt++;
307 
308  if( ERR_CNT_MAX < err_cnt )
309  break;
310  }
311  }
312 
313  if( ERR_CNT_MAX < err_cnt )
314  {
315  list << wxT( "<p><b>" )
316  << _( "Too many errors: some are skipped" )
317  << wxT( "</b></p>" );
318  }
319 
320  HTML_MESSAGE_BOX dlg( this, _( "Check footprints" ) );
321  dlg.AddHTML_Text( list );
322  dlg.ShowModal();
323 }
324 
325 
330 void DIALOG_NETLIST::OnCompileRatsnestClick( wxCommandEvent& event )
331 {
332  // Rebuild the board connectivity:
333  if( m_parent->IsGalCanvasActive() )
335 
336  m_parent->Compile_Ratsnest( m_dc, true );
337 }
338 
339 
344 void DIALOG_NETLIST::OnCancelClick( wxCommandEvent& event )
345 {
346  EndModal( wxID_CANCEL );
347 }
348 
349 
350 void DIALOG_NETLIST::OnSaveMessagesToFile( wxCommandEvent& aEvent )
351 {
352  wxFileName fn;
353 
354  if( !m_parent->GetLastNetListRead().IsEmpty() )
355  {
357  fn.SetExt( wxT( "txt" ) );
358  }
359  else
360  {
361  fn = wxPathOnly( Prj().GetProjectFullName() );
362  }
363 
364  wxFileDialog dlg( this, _( "Save contents of message window" ), fn.GetPath(), fn.GetName(),
365  TextWildcard, wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
366 
367  if( dlg.ShowModal() != wxID_OK )
368  return;
369 
370  fn = dlg.GetPath();
371 
372  if( fn.GetExt().IsEmpty() )
373  fn.SetExt( wxT( "txt" ) );
374 
375  wxFile f( fn.GetFullPath(), wxFile::write );
376 
377  if( !f.IsOpened() )
378  {
379  wxString msg;
380 
381  msg.Printf( _( "Cannot write message contents to file \"%s\"." ),
382  GetChars( fn.GetFullPath() ) );
383  wxMessageBox( msg, _( "File Write Error" ), wxOK | wxICON_ERROR, this );
384  return;
385  }
386 }
387 
388 
389 void DIALOG_NETLIST::OnUpdateUISaveMessagesToFile( wxUpdateUIEvent& aEvent )
390 {
391  //aEvent.Enable( !m_MessageWindow->IsEmpty() );
392 }
393 
394 
395 void DIALOG_NETLIST::OnUpdateUIValidNetlistFile( wxUpdateUIEvent& aEvent )
396 {
397  aEvent.Enable( !m_NetlistFilenameCtrl->GetValue().IsEmpty() );
398 }
399 
400 
401 bool DIALOG_NETLIST::verifyFootprints( const wxString& aNetlistFilename,
402  const wxString & aCmpFilename,
403  std::vector< MODULE* >& aDuplicates,
404  wxArrayString& aMissing,
405  std::vector< MODULE* >& aNotInNetlist )
406 {
407  wxString msg;
408  MODULE* module;
409  MODULE* nextModule;
410  NETLIST netlist;
411  wxBusyCursor dummy; // Shows an hourglass while calculating.
412  NETLIST_READER* netlistReader;
413  COMPONENT* component;
414 
415  try
416  {
417  netlistReader = NETLIST_READER::GetNetlistReader( &netlist, aNetlistFilename,
418  aCmpFilename );
419 
420  if( netlistReader == NULL )
421  {
422  msg.Printf( _( "Cannot open netlist file \"%s\"." ), GetChars( aNetlistFilename ) );
423  wxMessageBox( msg, _( "Netlist Load Error." ), wxOK | wxICON_ERROR );
424  return false;
425  }
426 
427  std::unique_ptr< NETLIST_READER > nlr( netlistReader );
428  netlistReader->LoadNetlist();
429  }
430  catch( const IO_ERROR& ioe )
431  {
432  msg.Printf( _( "Error loading netlist file:\n%s" ), ioe.What().GetData() );
433  wxMessageBox( msg, _( "Netlist Load Error" ), wxOK | wxICON_ERROR );
434  return false;
435  }
436 
437  BOARD* pcb = m_parent->GetBoard();
438 
439  // Search for duplicate footprints.
440  module = pcb->m_Modules;
441 
442  for( ; module != NULL; module = module->Next() )
443  {
444  nextModule = module->Next();
445 
446  for( ; nextModule != NULL; nextModule = nextModule->Next() )
447  {
448  if( module->GetReference().CmpNoCase( nextModule->GetReference() ) == 0 )
449  {
450  aDuplicates.push_back( module );
451  break;
452  }
453  }
454  }
455 
456  // Search for component footprints in the netlist but not on the board.
457  for( unsigned ii = 0; ii < netlist.GetCount(); ii++ )
458  {
459  component = netlist.GetComponent( ii );
460 
461  module = pcb->FindModuleByReference( component->GetReference() );
462 
463  if( module == NULL )
464  {
465  aMissing.Add( component->GetReference() );
466  aMissing.Add( component->GetValue() );
467  }
468  }
469 
470  // Search for component footprints found on board but not in netlist.
471  module = pcb->m_Modules;
472 
473  for( ; module != NULL; module = module->Next() )
474  {
475 
476  component = netlist.GetComponentByReference( module->GetReference() );
477 
478  if( component == NULL )
479  aNotInNetlist.push_back( module );
480  }
481 
482  return true;
483 }
void SetVisibleSeverities(int aSeverities)
Set the visible severity filter.
void Add(BOARD_ITEM *aBoardItem, ADD_MODE aMode=ADD_INSERT) override
>
wxString CoordinateToString(int aValue, bool aConvertToMils)
Function CoordinateToString is a helper to convert the integer coordinate aValue to a string in inche...
Definition: base_units.cpp:117
void SetLazyUpdate(bool aLazyUpdate)
Sets the lasy update.
VTBL_ENTRY void ConfigSave(const SEARCH_STACK &aSList, const wxString &aGroupName, const PARAM_CFG_ARRAY &aParams, const wxString &aFileName=wxEmptyString)
Function ConfigSave saves the current "project" parameters into the wxConfigBase* derivative...
Definition: project.cpp:307
void OnSaveMessagesToFile(wxCommandEvent &aEvent) override
PARAM_CFG_ARRAY GetProjectFileParameters()
Function GetProjectFileParameters returns a project file parameter list for Pcbnew.
wxCheckBox * m_checkBoxSilentMode
PCB_EDIT_FRAME * m_parent
Implementation of conversion functions that require both schematic and board internal units...
This file is part of the common library.
const wxString ProjectFileExtension
void SetLastNetListRead(const wxString &aNetListFile)
Set the last net list successfully read by the net list dialog box.
Definition: pcbframe.cpp:983
DIALOG_NETLIST(PCB_EDIT_FRAME *aParent, wxDC *aDC, const wxString &aNetlistFullFilename)
Class BOARD to handle a board.
wxConfigBase * m_config
const wxPoint & GetPosition() const override
Definition: class_module.h:144
Class that computes missing connections on a PCB.
MODULE * Next() const
Definition: class_module.h:100
const wxString NetlistFileExtension
static NETLIST_READER * GetNetlistReader(NETLIST *aNetlist, const wxString &aNetlistFileName, const wxString &aCompFootprintFileName=wxEmptyString)
Function GetNetlistReader attempts to determine the net list file type of aNetlistFileName and return...
MODULE * FindModuleByReference(const wxString &aReference) const
Function FindModuleByReference searches for a MODULE within this board with the given reference desig...
BOARD * GetBoard() const
const wxString & GetValue() const
Function GetValue.
Definition: class_module.h:440
wxRadioBox * m_rbSingleNets
wxRadioBox * m_RemoveExtraFootprintsCtrl
Class REPORTER is a pure virtual class used to derive REPORTER objects from.
Definition: reporter.h:61
void OnTestFootprintsClick(wxCommandEvent &event) override
const wxString TextWildcard
void ReadPcbNetlist(const wxString &aNetlistFileName, const wxString &aCmpFileName, REPORTER *aReporter, bool aChangeFootprint, bool aDeleteBadTracks, bool aDeleteExtraFootprints, bool aSelectByTimestamp, bool aDeleteSinglePadNets, bool aIsDryRun)
Function ReadPcbNetlist reads aNetlistFileName and updates the footprints (load missing footprints an...
KIFACE_I & Kiface()
Global KIFACE_I "get" accessor.
Definition: kicad.cpp:52
This file contains miscellaneous commonly used macros and functions.
const wxString & GetReference() const
Definition: pcb_netlist.h:149
const wxString & GetValue() const
Definition: pcb_netlist.h:151
PROJECT & Prj() const
Function Prj returns a reference to the PROJECT "associated with" this KIWAY.
#define NETLIST_DELETESINGLEPADNETS_KEY
virtual void LoadNetlist()=0
Function LoadNetlist loads the contents of the netlist file into aNetlist.
#define NETLIST_FILTER_MESSAGES_KEY
Class NETLIST stores all of information read from a netlist along with the flags used to update the N...
Definition: pcb_netlist.h:205
void OnOpenNetlistClick(wxCommandEvent &event) override
const wxString & GetFileName() const
Definition: class_board.h:237
bool IsEmpty() const
Definition: class_board.h:263
REPORTER & Reporter()
returns the reporter object that reports to this panel
const wxString NetlistFileWildcard
#define NETLIST_SILENTMODE_KEY
Subclass of DIALOG_DISPLAY_HTML_TEXT_BASE, which is generated by wxFormBuilder.
void ProcessBoard()
Function ProcessBoard() Prepares data for computing (computes a list of current nodes and connections...
VTBL_ENTRY const wxString AbsolutePath(const wxString &aFileName) const
Function AbsolutePath fixes up aFileName if it is relative to the project's directory to be an absolu...
Definition: project.cpp:371
The common library.
Helper dialog and control classes.
wxConfigBase * KifaceSettings() const
Definition: kiface_i.h:101
Class NETLIST_READER is a pure virtual class to derive a specific type of netlist reader from...
Configuration parameters for Pcbnew.
bool IsGalCanvasActive() const
Function IsGalCanvasActive is used to check which canvas (GAL-based or standard) is currently in use...
Definition: draw_frame.h:795
Class HTML_MESSAGE_BOX.
RN_DATA * GetRatsnest() const
Function GetRatsnest() returns list of missing connections between components/tracks.
Definition: class_board.h:287
Class COMPONENT is used to store components and all of their related information found in a netlist...
Definition: pcb_netlist.h:83
void Compile_Ratsnest(wxDC *aDC, bool aDisplayStatus)
Function Compile_Ratsnest Create the entire board ratsnest.
Definition: ratsnest.cpp:165
COMPONENT * GetComponent(unsigned aIndex)
Function GetComponent returns the COMPONENT at aIndex.
Definition: pcb_netlist.h:256
void DisplayInfoMessage(wxWindow *parent, const wxString &text, int displaytime)
Function DisplayInfoMessage displays an informational message box with aMessage.
Definition: confirm.cpp:89
wxString GetLastNetListRead()
Get the last net list read with the net list dialog box.
Definition: pcbframe.cpp:968
virtual const wxString What() const
A composite of Problem() and Where()
Definition: exceptions.cpp:33
wxRadioBox * m_DeleteBadTracks
void Flush()
Forces updating the HTML page, after the report is built in lazy mode
static const wxChar * GetChars(const wxString &s)
Function GetChars returns a wxChar* to the actual wxChar* data within a wxString, and is helpful for ...
Definition: macros.h:92
void Clear()
clears the report panel
static LIB_PART * dummy()
Used when a LIB_PART is not found in library to draw a dummy shape This component is a 400 mils squar...
Class BOARD holds information pertinent to a Pcbnew printed circuit board.
Definition: class_board.h:166
const wxString & GetReference() const
Function GetReference.
Definition: class_module.h:412
DLIST< MODULE > m_Modules
Definition: class_board.h:243
wxTextCtrl * m_NetlistFilenameCtrl
void AddHTML_Text(const wxString &message)
Function AddHTML_Text adds html text (without any change) to message list.
void OnCancelClick(wxCommandEvent &event) override
void OnUpdateUIValidNetlistFile(wxUpdateUIEvent &aEvent) override
void OnCompileRatsnestClick(wxCommandEvent &event) override
virtual REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_UNDEFINED)=0
Function Report is a pure virtual function to override in the derived object.
wxRadioBox * m_ChangeExistingFootprintCtrl
void MsgPanelSetMinSize(const wxSize &aMinSize)
Set the min size of the area which displays html messages:
COMPONENT * GetComponentByReference(const wxString &aReference)
Function GetComponentByReference returns a COMPONENT by aReference.
void OnUpdateUISaveMessagesToFile(wxUpdateUIEvent &aEvent) override
Module description (excepted pads)
Class DIALOG_NETLIST_FBP.
bool verifyFootprints(const wxString &aNetlistFilename, const wxString &aCmpFilename, std::vector< MODULE * > &aDuplicate, wxArrayString &aMissing, std::vector< MODULE * > &aNotInNetlist)
Function verifyFootprints compares the netlist to the board and builds a list of duplicate, missing, and extra footprints.
wxCheckBox * m_checkDryRun
unsigned GetCount() const
Function GetCount.
Definition: pcb_netlist.h:247
#define GROUP_PCB
Names of sub sections where to store project info in *.pro project config files.
Definition: config_params.h:43
void OnReadNetlistFileClick(wxCommandEvent &event) override
Struct IO_ERROR is a class used to hold an error message and may be used when throwing exceptions con...
Definition: ki_exception.h:47
bool IsOK(wxWindow *aParent, const wxString &aMessage)
Function IsOK displays a yes/no dialog with aMessage and returns the user response.
Definition: confirm.cpp:111
WX_HTML_REPORT_PANEL * m_MessageWindow
#define ERR_CNT_MAX
wxRadioBox * m_Select_By_Timestamp