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