KiCad PCB EDA Suite
gerbview/files.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) 2017 Jean-Pierre Charras, jp.charras at wanadoo.fr
5  * Copyright (C) 2004-2019 KiCad Developers, see AUTHORS.txt for contributors.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, you may find one here:
19  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
20  * or you may search the http://www.gnu.org website for the version 2 license,
21  * or you may write to the Free Software Foundation, Inc.,
22  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
23  */
24 
25 #include <wx/wfstream.h>
26 #include <wx/zipstrm.h>
27 #include <reporter.h>
29 #include <gerbview_frame.h>
30 #include <gerbview_id.h>
31 #include <gerber_file_image.h>
32 #include <gerber_file_image_list.h>
33 #include <excellon_image.h>
37 
38 // HTML Messages used more than one time:
39 #define MSG_NO_MORE_LAYER _( "<b>No more available layers</b> in Gerbview to load files" )
40 #define MSG_NOT_LOADED _( "\n<b>Not loaded:</b> <i>%s</i>" )
41 
42 
43 void GERBVIEW_FRAME::OnGbrFileHistory( wxCommandEvent& event )
44 {
45  wxString fn;
46 
47  fn = GetFileFromHistory( event.GetId(), _( "Gerber files" ) );
48 
49  if( !fn.IsEmpty() )
50  {
51  Erase_Current_DrawLayer( false );
52  LoadGerberFiles( fn );
53  }
54 }
55 
56 void GERBVIEW_FRAME::OnClearGbrFileHistory( wxCommandEvent& aEvent )
57 {
59 }
60 
61 
62 void GERBVIEW_FRAME::OnDrlFileHistory( wxCommandEvent& event )
63 {
64  wxString fn;
65 
66  fn = GetFileFromHistory( event.GetId(), _( "Drill files" ), &m_drillFileHistory );
67 
68  if( !fn.IsEmpty() )
69  {
70  Erase_Current_DrawLayer( false );
71  LoadExcellonFiles( fn );
72  }
73 }
74 
75 
76 void GERBVIEW_FRAME::OnClearDrlFileHistory( wxCommandEvent& aEvent )
77 {
79 }
80 
81 
82 void GERBVIEW_FRAME::OnZipFileHistory( wxCommandEvent& event )
83 {
84  wxString filename;
85  filename = GetFileFromHistory( event.GetId(), _( "Zip files" ), &m_zipFileHistory );
86 
87  if( !filename.IsEmpty() )
88  {
89  Erase_Current_DrawLayer( false );
90  LoadZipArchiveFile( filename );
91  }
92 }
93 
94 
95 void GERBVIEW_FRAME::OnClearZipFileHistory( wxCommandEvent& aEvent )
96 {
98 }
99 
100 
101 void GERBVIEW_FRAME::OnJobFileHistory( wxCommandEvent& event )
102 {
103  wxString filename = GetFileFromHistory( event.GetId(), _( "Job files" ), &m_jobFileHistory );
104 
105  if( !filename.IsEmpty() )
106  LoadGerberJobFile( filename );
107 }
108 
109 
110 void GERBVIEW_FRAME::OnClearJobFileHistory( wxCommandEvent& aEvent )
111 {
113 }
114 
115 
116 bool GERBVIEW_FRAME::LoadGerberFiles( const wxString& aFullFileName )
117 {
118  static int lastGerberFileWildcard = 0;
119  wxString filetypes;
120  wxArrayString filenamesList;
121  wxFileName filename = aFullFileName;
122  wxString currentPath;
123 
124  if( !filename.IsOk() )
125  {
126  /* Standard gerber filetypes
127  * (See http://en.wikipedia.org/wiki/Gerber_File)
128  * The .gbr (.pho in legacy files) extension is the default used in Pcbnew; however
129  * there are a lot of other extensions used for gerber files. Because the first letter
130  * is usually g, we accept g* as extension.
131  * (Mainly internal copper layers do not have specific extension, and filenames are like
132  * *.g1, *.g2 *.gb1 ...)
133  * Now (2014) Ucamco (the company which manages the Gerber format) encourages use of .gbr
134  * only and the Gerber X2 file format.
135  */
136  filetypes = _( "Gerber files (.g* .lgr .pho)" );
137  filetypes << wxT("|");
138  filetypes += wxT("*.g*;*.G*;*.pho;*.PHO" );
139  filetypes << wxT("|");
140 
141  /* Special gerber filetypes */
142  filetypes += _( "Top layer (*.GTL)|*.GTL;*.gtl|" );
143  filetypes += _( "Bottom layer (*.GBL)|*.GBL;*.gbl|" );
144  filetypes += _( "Bottom solder resist (*.GBS)|*.GBS;*.gbs|" );
145  filetypes += _( "Top solder resist (*.GTS)|*.GTS;*.gts|" );
146  filetypes += _( "Bottom overlay (*.GBO)|*.GBO;*.gbo|" );
147  filetypes += _( "Top overlay (*.GTO)|*.GTO;*.gto|" );
148  filetypes += _( "Bottom paste (*.GBP)|*.GBP;*.gbp|" );
149  filetypes += _( "Top paste (*.GTP)|*.GTP;*.gtp|" );
150  filetypes += _( "Keep-out layer (*.GKO)|*.GKO;*.gko|" );
151  filetypes += _( "Mechanical layers (*.GMx)|*.GM1;*.gm1;*.GM2;*.gm2;*.GM3;*.gm3|" );
152  filetypes += _( "Top Pad Master (*.GPT)|*.GPT;*.gpt|" );
153  filetypes += _( "Bottom Pad Master (*.GPB)|*.GPB;*.gpb|" );
154 
155  // All filetypes
156  filetypes += AllFilesWildcard();
157 
158  // Use the current working directory if the file name path does not exist.
159  if( filename.DirExists() )
160  currentPath = filename.GetPath();
161  else
162  {
163  currentPath = m_mruPath;
164 
165  // On wxWidgets 3.1 (bug?) the path in wxFileDialog is ignored when
166  // finishing by the dir separator. Remove it if any:
167  if( currentPath.EndsWith( '\\' ) || currentPath.EndsWith( '/' ) )
168  currentPath.RemoveLast();
169  }
170 
171  wxFileDialog dlg( this, _( "Open Gerber File(s)" ), currentPath, filename.GetFullName(),
172  filetypes,
173  wxFD_OPEN | wxFD_FILE_MUST_EXIST | wxFD_MULTIPLE | wxFD_CHANGE_DIR );
174  dlg.SetFilterIndex( lastGerberFileWildcard );
175 
176  if( dlg.ShowModal() == wxID_CANCEL )
177  return false;
178 
179  lastGerberFileWildcard = dlg.GetFilterIndex();
180  dlg.GetPaths( filenamesList );
181  m_mruPath = currentPath = dlg.GetDirectory();
182  }
183  else
184  {
185  filenamesList.Add( aFullFileName );
186  m_mruPath = currentPath = filename.GetPath();
187  }
188 
189  Erase_Current_DrawLayer( false );
190 
191  // Set the busy cursor
192  wxBusyCursor wait;
193 
194  return LoadListOfGerberAndDrillFiles( currentPath, filenamesList );
195 }
196 
197 
199  const wxArrayString& aFilenameList,
200  const std::vector<int>* aFileType )
201 {
202  wxFileName filename;
203 
204  // Read gerber files: each file is loaded on a new GerbView layer
205  bool success = true;
206  int layer = GetActiveLayer();
207  LSET visibility = GetVisibleLayers();
208 
209  // Manage errors when loading files
210  wxString msg;
211  WX_STRING_REPORTER reporter( &msg );
212 
213  // Create progress dialog (only used if more than 1 file to load
214  std::unique_ptr<WX_PROGRESS_REPORTER> progress = nullptr;
215 
216  for( unsigned ii = 0; ii < aFilenameList.GetCount(); ii++ )
217  {
218  filename = aFilenameList[ii];
219 
220  if( !filename.IsAbsolute() )
221  filename.SetPath( aPath );
222 
223  // Check for non existing files, to avoid creating broken or useless data
224  // and report all in one error list:
225  if( !filename.FileExists() )
226  {
227  wxString warning;
228  warning << "<b>" << _( "File not found:" ) << "</b><br>"
229  << filename.GetFullPath() << "<br>";
230  reporter.Report( warning, RPT_SEVERITY_WARNING );
231  success = false;
232  continue;
233  }
234 
235  m_lastFileName = filename.GetFullPath();
236 
237  if( !progress && ( aFilenameList.GetCount() > 1 ) )
238  {
239  progress = std::make_unique<WX_PROGRESS_REPORTER>( this,
240  _( "Loading Gerber files..." ), 1, false );
241  progress->SetMaxProgress( aFilenameList.GetCount() - 1 );
242  progress->Report( wxString::Format( _("Loading %u/%zu %s" ), ii+1,
243  aFilenameList.GetCount(), m_lastFileName ) );
244  }
245  else if( progress )
246  {
247  progress->Report( wxString::Format( _("Loading %u/%zu %s" ), ii+1,
248  aFilenameList.GetCount(), m_lastFileName ) );
249  progress->KeepRefreshing();
250  }
251 
252  SetActiveLayer( layer, false );
253 
254  visibility[ layer ] = true;
255 
256  if( aFileType && (*aFileType)[ii] == 1 )
257  {
258  LoadExcellonFiles( filename.GetFullPath() );
259  layer = GetActiveLayer(); // Loading NC drill file changes the active layer
260  }
261  else
262  {
263  if( filename.GetExt() == GerberJobFileExtension.c_str() )
264  {
265  //We cannot read a gerber job file as a gerber plot file: skip it
266  wxString txt;
267  txt.Printf(
268  _( "<b>A gerber job file cannot be loaded as a plot file</b> <i>%s</i>" ),
269  filename.GetFullName() );
270  success = false;
271  reporter.Report( txt, RPT_SEVERITY_ERROR );
272  }
273  else if( Read_GERBER_File( filename.GetFullPath() ) )
274  {
276 
277  layer = getNextAvailableLayer( layer );
278 
279  if( layer == NO_AVAILABLE_LAYERS && ii < aFilenameList.GetCount()-1 )
280  {
281  success = false;
283 
284  // Report the name of not loaded files:
285  ii += 1;
286  while( ii < aFilenameList.GetCount() )
287  {
288  filename = aFilenameList[ii++];
289  wxString txt = wxString::Format( MSG_NOT_LOADED, filename.GetFullName() );
290  reporter.Report( txt, RPT_SEVERITY_ERROR );
291  }
292  break;
293  }
294 
295  SetActiveLayer( layer, false );
296  }
297  }
298 
299  if( progress )
300  progress->AdvanceProgress();
301  }
302 
303  if( !success )
304  {
305  wxSafeYield(); // Allows slice of time to redraw the screen
306  // to refresh widgets, before displaying messages
307  HTML_MESSAGE_BOX mbox( this, _( "Errors" ) );
308  mbox.ListSet( msg );
309  mbox.ShowModal();
310  }
311 
312  SetVisibleLayers( visibility );
313 
314  Zoom_Automatique( false );
315 
316  // Synchronize layers tools with actual active layer:
318 
319  // TODO: it would be nice if we could set the active layer to one of the
320  // ones that was just loaded, but to maintain the previous user experience
321  // we need to set it to a blank layer in case they load another file.
322  // We can't start with the next available layer when loading files because
323  // some users expect the behavior of overwriting the active layer on load.
324  SetActiveLayer( getNextAvailableLayer( layer ), true );
325 
327  syncLayerBox( true );
328 
329  GetCanvas()->Refresh();
330 
331  return success;
332 }
333 
334 
335 bool GERBVIEW_FRAME::LoadExcellonFiles( const wxString& aFullFileName )
336 {
337  wxString filetypes;
338  wxArrayString filenamesList;
339  wxFileName filename = aFullFileName;
340  wxString currentPath;
341 
342  if( !filename.IsOk() )
343  {
344  filetypes = DrillFileWildcard();
345  filetypes << wxT( "|" );
346 
347  /* All filetypes */
348  filetypes += AllFilesWildcard();
349 
350  /* Use the current working directory if the file name path does not exist. */
351  if( filename.DirExists() )
352  currentPath = filename.GetPath();
353  else
354  currentPath = m_mruPath;
355 
356  wxFileDialog dlg( this, _( "Open NC (Excellon) Drill File(s)" ),
357  currentPath, filename.GetFullName(), filetypes,
358  wxFD_OPEN | wxFD_FILE_MUST_EXIST | wxFD_MULTIPLE | wxFD_CHANGE_DIR );
359 
360  if( dlg.ShowModal() == wxID_CANCEL )
361  return false;
362 
363  dlg.GetPaths( filenamesList );
364  currentPath = wxGetCwd();
365  m_mruPath = currentPath;
366  }
367  else
368  {
369  filenamesList.Add( aFullFileName );
370  currentPath = filename.GetPath();
371  m_mruPath = currentPath;
372  }
373 
374  // Read Excellon drill files: each file is loaded on a new GerbView layer
375  bool success = true;
376  int layer = GetActiveLayer();
377 
378  // Manage errors when loading files
379  wxString msg;
380  WX_STRING_REPORTER reporter( &msg );
381 
382  for( unsigned ii = 0; ii < filenamesList.GetCount(); ii++ )
383  {
384  filename = filenamesList[ii];
385 
386  if( !filename.IsAbsolute() )
387  filename.SetPath( currentPath );
388 
389  m_lastFileName = filename.GetFullPath();
390 
391  SetActiveLayer( layer, false );
392 
393  if( Read_EXCELLON_File( filename.GetFullPath() ) )
394  {
395  // Update the list of recent drill files.
396  UpdateFileHistory( filename.GetFullPath(), &m_drillFileHistory );
397 
398  layer = getNextAvailableLayer( layer );
399 
400  if( layer == NO_AVAILABLE_LAYERS && ii < filenamesList.GetCount()-1 )
401  {
402  success = false;
404 
405  // Report the name of not loaded files:
406  ii += 1;
407  while( ii < filenamesList.GetCount() )
408  {
409  filename = filenamesList[ii++];
410  wxString txt = wxString::Format( MSG_NOT_LOADED, filename.GetFullName() );
411  reporter.Report( txt, RPT_SEVERITY_ERROR );
412  }
413  break;
414  }
415 
416  SetActiveLayer( layer, false );
417  }
418  }
419 
420  if( !success )
421  {
422  HTML_MESSAGE_BOX mbox( this, _( "Errors" ) );
423  mbox.ListSet( msg );
424  mbox.ShowModal();
425  }
426 
427  Zoom_Automatique( false );
428 
429  // Synchronize layers tools with actual active layer:
433  syncLayerBox();
434 
435  return success;
436 }
437 
438 
439 bool GERBVIEW_FRAME::unarchiveFiles( const wxString& aFullFileName, REPORTER* aReporter )
440 {
441  wxString msg;
442 
443  // Extract the path of aFullFileName. We use it to store temporary files
444  wxFileName fn( aFullFileName );
445  wxString unzipDir = fn.GetPath();
446 
447  wxFFileInputStream zipFile( aFullFileName );
448 
449  if( !zipFile.IsOk() )
450  {
451  if( aReporter )
452  {
453  msg.Printf( _( "Zip file \"%s\" cannot be opened" ), aFullFileName );
454  aReporter->Report( msg, RPT_SEVERITY_ERROR );
455  }
456 
457  return false;
458  }
459 
460  // Update the list of recent zip files.
461  UpdateFileHistory( aFullFileName, &m_zipFileHistory );
462 
463  // The unzipped file in only a temporary file. Give it a filename
464  // which cannot conflict with an usual filename.
465  // TODO: make Read_GERBER_File() and Read_EXCELLON_File() able to
466  // accept a stream, and avoid using a temp file.
467  wxFileName temp_fn( "$tempfile.tmp" );
468  temp_fn.MakeAbsolute( unzipDir );
469  wxString unzipped_tempfile = temp_fn.GetFullPath();
470 
471 
472  bool success = true;
473  wxZipInputStream zipArchive( zipFile );
474  wxZipEntry* entry;
475  bool reported_no_more_layer = false;
476 
477  while( ( entry = zipArchive.GetNextEntry() ) )
478  {
479  wxString fname = entry->GetName();
480  wxFileName uzfn = fname;
481  wxString curr_ext = uzfn.GetExt().Lower();
482 
483  // The archive contains Gerber and/or Excellon drill files. Use the right loader.
484  // However it can contain a few other files (reports, pdf files...),
485  // which will be skipped.
486  // Gerber files ext is usually "gbr", but can be also another value, starting by "g"
487  // old gerber files ext from kicad is .pho
488  // drill files do not have a well defined ext
489  // It is .drl in kicad, but .txt in Altium for instance
490  // Allows only .drl for drill files.
491  if( curr_ext[0] != 'g' && curr_ext != "pho" && curr_ext != "drl" )
492  {
493  if( aReporter )
494  {
495  msg.Printf( _( "Info: skip file \"%s\" (unknown type)\n" ), entry->GetName() );
496  aReporter->Report( msg, RPT_SEVERITY_WARNING );
497  }
498 
499  continue;
500  }
501 
502  if( curr_ext == GerberJobFileExtension.c_str() )
503  {
504  //We cannot read a gerber job file as a gerber plot file: skip it
505  if( aReporter )
506  {
507  msg.Printf( _( "Info: skip file \"%s\" (gerber job file)\n" ), entry->GetName() );
508  aReporter->Report( msg, RPT_SEVERITY_WARNING );
509  }
510 
511  continue;
512  }
513 
514  int layer = GetActiveLayer();
515 
516  if( layer == NO_AVAILABLE_LAYERS )
517  {
518  success = false;
519 
520  if( aReporter )
521  {
522  if( !reported_no_more_layer )
524 
525  reported_no_more_layer = true;
526 
527  // Report the name of not loaded files:
528  msg.Printf( MSG_NOT_LOADED, entry->GetName() );
529  aReporter->Report( msg, RPT_SEVERITY_ERROR );
530  }
531 
532  delete entry;
533  continue;
534  }
535 
536  // Create the unzipped temporary file:
537  {
538  wxFFileOutputStream temporary_ofile( unzipped_tempfile );
539 
540  if( temporary_ofile.Ok() )
541  temporary_ofile.Write( zipArchive );
542  else
543  {
544  success = false;
545 
546  if( aReporter )
547  {
548  msg.Printf( _( "<b>Unable to create temporary file \"%s\"</b>\n"),
549  unzipped_tempfile );
550  aReporter->Report( msg, RPT_SEVERITY_ERROR );
551  }
552  }
553  }
554 
555  bool read_ok = true;
556 
557  if( curr_ext[0] == 'g' || curr_ext == "pho" )
558  {
559  // Read gerber files: each file is loaded on a new GerbView layer
560  read_ok = Read_GERBER_File( unzipped_tempfile );
561  }
562  else // if( curr_ext == "drl" )
563  {
564  read_ok = Read_EXCELLON_File( unzipped_tempfile );
565  }
566 
567  delete entry;
568 
569  // The unzipped file is only a temporary file, delete it.
570  wxRemoveFile( unzipped_tempfile );
571 
572  if( !read_ok )
573  {
574  success = false;
575 
576  if( aReporter )
577  {
578  msg.Printf( _("<b>unzipped file %s read error</b>\n"), unzipped_tempfile );
579  aReporter->Report( msg, RPT_SEVERITY_ERROR );
580  }
581  }
582  else
583  {
584  GERBER_FILE_IMAGE* gerber_image = GetGbrImage( layer );
585 
586  if( gerber_image )
587  gerber_image->m_FileName = fname;
588 
589  layer = getNextAvailableLayer( layer );
590  SetActiveLayer( layer, false );
591  }
592  }
593 
594  return success;
595 }
596 
597 
598 bool GERBVIEW_FRAME::LoadZipArchiveFile( const wxString& aFullFileName )
599 {
600 #define ZipFileExtension "zip"
601 
602  wxFileName filename = aFullFileName;
603  wxString currentPath;
604 
605  if( !filename.IsOk() )
606  {
607  // Use the current working directory if the file name path does not exist.
608  if( filename.DirExists() )
609  currentPath = filename.GetPath();
610  else
611  currentPath = m_mruPath;
612 
613  wxFileDialog dlg( this, _( "Open Zip File" ), currentPath, filename.GetFullName(),
614  ZipFileWildcard(), wxFD_OPEN | wxFD_FILE_MUST_EXIST | wxFD_CHANGE_DIR );
615 
616  if( dlg.ShowModal() == wxID_CANCEL )
617  return false;
618 
619  filename = dlg.GetPath();
620  currentPath = wxGetCwd();
621  m_mruPath = currentPath;
622  }
623  else
624  {
625  currentPath = filename.GetPath();
626  m_mruPath = currentPath;
627  }
628 
629  wxString msg;
630  WX_STRING_REPORTER reporter( &msg );
631 
632  if( filename.IsOk() )
633  unarchiveFiles( filename.GetFullPath(), &reporter );
634 
635  Zoom_Automatique( false );
636 
637  // Synchronize layers tools with actual active layer:
641  syncLayerBox();
642 
643  if( !msg.IsEmpty() )
644  {
645  wxSafeYield(); // Allows slice of time to redraw the screen
646  // to refresh widgets, before displaying messages
647  HTML_MESSAGE_BOX mbox( this, _( "Messages" ) );
648  mbox.ListSet( msg );
649  mbox.ShowModal();
650  }
651 
652  return true;
653 }
wxString m_lastFileName
wxString m_mruPath
void syncLayerBox(bool aRebuildLayerBox=false)
Function syncLayerBox updates the currently "selected" layer within m_SelLayerBox The currently activ...
LSET GetVisibleLayers() const
Function GetVisibleLayers is a proxy function that calls the correspondent function in m_BoardSetting...
void OnClearDrlFileHistory(wxCommandEvent &aEvent)
FILE_HISTORY m_jobFileHistory
GERBER_LAYER_WIDGET * m_LayersManager
virtual EDA_DRAW_PANEL_GAL * GetCanvas() const
Return a pointer to GAL-based canvas of given EDA draw frame.
bool Read_GERBER_File(const wxString &GERBER_FullFileName)
Definition: readgerb.cpp:40
GERBER_FILE_IMAGE holds the Image data and parameters for one gerber file and layer parameters (TODO:...
void SetActiveLayer(int aLayer, bool doLayerWidgetUpdate=true)
Function SetActiveLayer will change the currently active layer to aLayer and update the GERBER_LAYER_...
void OnGbrFileHistory(wxCommandEvent &event)
Function OnGbrFileHistory deletes the current data and loads a Gerber file selected from history list...
wxString ZipFileWildcard()
REPORTER is a pure virtual class used to derive REPORTER objects from.
Definition: reporter.h:64
void Erase_Current_DrawLayer(bool query)
void OnClearZipFileHistory(wxCommandEvent &aEvent)
virtual REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)=0
Function Report is a pure virtual function to override in the derived object.
wxString AllFilesWildcard()
void UpdateFileHistory(const wxString &FullFileName, FILE_HISTORY *aFileHistory=nullptr)
Update the list of recently opened files.
bool LoadGerberJobFile(const wxString &aFileName)
Load a Gerber job file, and load gerber files found in job files.
wxString GetFileFromHistory(int cmdId, const wxString &type, FILE_HISTORY *aFileHistory=nullptr)
Fetches the file name from the file history list.
void OnClearJobFileHistory(wxCommandEvent &aEvent)
FILE_HISTORY m_zipFileHistory
#define MSG_NOT_LOADED
virtual void Zoom_Automatique(bool aWarpPointer)
Redraw the screen with best zoom level and the best centering that shows all the page or the board.
LSET is a set of PCB_LAYER_IDs.
bool unarchiveFiles(const wxString &aFullFileName, REPORTER *aReporter=nullptr)
Extracts gerber and drill files from the zip archive, and load them.
#define NO_AVAILABLE_LAYERS
bool LoadGerberFiles(const wxString &aFileName)
function LoadGerberFiles Load a photoplot (Gerber) file or many files.
bool LoadListOfGerberAndDrillFiles(const wxString &aPath, const wxArrayString &aFilenameList, const std::vector< int > *aFileType=nullptr)
Loads a list of Gerber and NC drill files and updates the view based on them.
void ListSet(const wxString &aList)
Add a list of items.
GERBER_FILE_IMAGE * GetGbrImage(int aIdx) const
bool LoadZipArchiveFile(const wxString &aFileName)
function LoadZipArchiveFileLoadZipArchiveFile Load a zipped archive file.
void UpdateLayerIcons()
Function UpdateLayerIcons Update all layer manager icons (layers only) Useful when loading a file or ...
const std::string GerberJobFileExtension
Definition of file extensions used in Kicad.
void OnClearGbrFileHistory(wxCommandEvent &aEvent)
HTML_MESSAGE_BOX.
FILE_HISTORY m_drillFileHistory
#define MSG_NO_MORE_LAYER
wxString DrillFileWildcard()
virtual void Refresh(bool aEraseBackground=true, const wxRect *aRect=NULL) override
Update the board display after modifying it by a python script (note: it is automatically called by a...
WX_STRING_REPORTER is a wrapper for reporting to a wxString object.
Definition: reporter.h:161
void ClearFileHistory(FILE_HISTORY *aFileHistory=nullptr)
Removes all files from the file history.
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Function Format outputs a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
int GetActiveLayer() const
Function SetActiveLayer returns the active layer.
void OnJobFileHistory(wxCommandEvent &event)
deletes the current data and load a gerber job file selected from the history list.
REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED) override
Function Report is a pure virtual function to override in the derived object.
Definition: reporter.cpp:54
#define _(s)
Definition: 3d_actions.cpp:33
void OnDrlFileHistory(wxCommandEvent &event)
Function OnDrlFileHistory deletes the current data and load a drill file in Excellon format selected ...
bool LoadExcellonFiles(const wxString &aFileName)
function LoadExcellonFiles Load a drill (EXCELLON) file or many files.
void OnZipFileHistory(wxCommandEvent &event)
Function OnZipFileHistory deletes the current data and load a zip archive file selected from the hist...
void SetVisibleLayers(LSET aLayerMask)
Function SetVisibleLayers is a proxy function that calls the correspondent function in m_BoardSetting...
int getNextAvailableLayer(int aLayer=0) const
Function getNextAvailableLayer finds the next empty layer starting at aLayer and returns it to the ca...
void ReFillLayerWidget()
Function ReFillLayerWidget changes out all the layers in m_Layers; called upon loading new gerber fil...
bool Read_EXCELLON_File(const wxString &aFullFileName)