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