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