22#include <wx/filedlg.h>
23#include <wx/wfstream.h>
24#include <wx/zipstrm.h>
41#define MSG_NO_MORE_LAYER _( "<b>No more available layers</b> in GerbView to load files" )
42#define MSG_NOT_LOADED _( "<b>Not loaded:</b> <i>%s</i>" )
43#define MSG_OOM _( "<b>Memory was exhausted reading:</b> <i>%s</i>" )
50 if( !filename.IsEmpty() )
64 if( !filename.IsEmpty() )
76 GetMenuBar()->Refresh();
85 if( !filename.IsEmpty() )
97 GetMenuBar()->Refresh();
106 if( !filename.IsEmpty() )
118 GetMenuBar()->Refresh();
124 const wxString& dialogFiletypes,
125 const wxString& dialogTitle,
const int filetype )
127 static int lastGerberFileWildcard = 0;
128 wxArrayString filenamesList;
129 wxFileName filename = aFileName;
130 wxString currentPath;
132 if( !filename.IsOk() )
135 if( filename.DirExists() )
136 currentPath = filename.GetPath();
143 if( currentPath.EndsWith(
'\\' ) || currentPath.EndsWith(
'/' ) )
144 currentPath.RemoveLast();
147 wxFileDialog dlg(
this, dialogTitle, currentPath, filename.GetFullName(), dialogFiletypes,
148 wxFD_OPEN | wxFD_FILE_MUST_EXIST | wxFD_MULTIPLE | wxFD_CHANGE_DIR );
152 wxArrayString dummy1, dummy2;
153 const int nWildcards = wxParseCommonDialogsFilter( dialogFiletypes, dummy1, dummy2 );
155 if( lastGerberFileWildcard >= 0 && lastGerberFileWildcard < nWildcards )
156 dlg.SetFilterIndex( lastGerberFileWildcard );
158 if( dlg.ShowModal() == wxID_CANCEL )
161 lastGerberFileWildcard = dlg.GetFilterIndex();
162 dlg.GetPaths( filenamesList );
163 m_mruPath = currentPath = dlg.GetDirectory();
167 filenamesList.Add( aFileName );
168 currentPath = filename.GetPath();
177 std::vector<int> fileTypesVec( filenamesList.Count(), filetype );
207 wxFileName filename = aFileName;
219 filetypes =
_(
"Gerber files" ) + wxT(
" (*.g*; *.pho)|" )
221 "gtp",
"gbp",
"gta",
"gba",
"gko",
"gpt",
"gpb",
"gm1",
"gm2",
222 "gm3",
"gm4",
"gm5",
"gm6",
"gm7",
"gm8",
"gm9",
"g1",
"g2",
223 "g3",
"g4",
"g5",
"g6",
"g7",
"g8",
"g9" } )
237 filetypes +=
_(
"Mechanical layers" )
239 {
"gm1",
"gm2",
"gm3",
"gm4",
"gm5",
"gm6",
"gm7",
"gm8",
"gm9" } )
255 filetypes << wxT(
"|" );
264 const wxArrayString& aFilenameList,
265 std::vector<int>* aFileType )
267 wxCHECK_MSG( aFilenameList.Count() == aFileType->size(),
false,
268 "Mismatch in file names and file types count" );
282 std::unique_ptr<WX_PROGRESS_REPORTER> progress =
nullptr;
284 for(
unsigned ii = 0; ii < aFilenameList.GetCount(); ii++ )
286 filename = aFilenameList[ii];
288 if( !filename.IsAbsolute() )
289 filename.SetPath( aPath );
293 if( !filename.FileExists() )
296 warning << wxT(
"<b>" ) <<
_(
"File not found:" ) << wxT(
"</b><br>" )
297 << filename.GetFullPath() << wxT(
"<br>" );
307 txt.Printf(
_(
"<b>A gerber job file cannot be loaded as a plot file</b> "
309 filename.GetFullName() );
318 if( !progress && ( aFilenameList.GetCount() > 1 ) )
320 progress = std::make_unique<WX_PROGRESS_REPORTER>(
this,
_(
"Load Files" ), 1,
PR_CAN_ABORT );
321 progress->SetMaxProgress( aFilenameList.GetCount() - 1 );
322 progress->Report( wxString::Format(
_(
"Loading %u/%zu %s..." ),
324 aFilenameList.GetCount(),
329 progress->Report( wxString::Format(
_(
"Loading %u/%zu %s..." ),
331 aFilenameList.GetCount(),
333 progress->KeepRefreshing();
346 while( ii < aFilenameList.GetCount() )
348 filename = aFilenameList[ii++];
349 wxString txt = wxString::Format(
MSG_NOT_LOADED, filename.GetFullName() );
361 if( ( *aFileType )[ii] == 2 )
364 ( *aFileType )[ii] = 1;
366 ( *aFileType )[ii] = 0;
369 switch( ( *aFileType )[ii] )
379 firstLoadedLayer = layer;
394 firstLoadedLayer = layer;
400 wxString txt = wxString::Format(
MSG_NOT_LOADED, filename.GetFullName() );
404 catch(
const std::bad_alloc& )
406 wxString txt = wxString::Format(
MSG_OOM, filename.GetFullName() );
413 progress->AdvanceProgress();
444 bool foundX2Gerbers =
false;
450 wxFileName fn( aFullFileName );
451 wxString unzipDir = fn.GetPath();
453 wxFFileInputStream zipFile( aFullFileName );
455 if( !zipFile.IsOk() )
459 msg.Printf(
_(
"Zip file '%s' cannot be opened." ), aFullFileName );
473 wxFileName temp_fn(
"$tempfile.tmp" );
474 temp_fn.MakeAbsolute( unzipDir );
475 wxString unzipped_tempfile = temp_fn.GetFullPath();
479 wxZipInputStream zipArchive( zipFile );
481 bool reported_no_more_layer =
false;
484 while( ( entry = zipArchive.GetNextEntry() ) !=
nullptr )
489 wxString fname = entry->GetName();
490 wxFileName uzfn = fname;
491 wxString curr_ext = uzfn.GetExt().Lower();
501 msg.Printf(
_(
"Skipped file '%s' (gerber job file)." ), entry->GetName() );
520 if( !reported_no_more_layer )
523 reported_no_more_layer =
true;
538 wxFFileOutputStream temporary_ofile( unzipped_tempfile );
540 if( temporary_ofile.Ok() )
541 temporary_ofile.Write( zipArchive );
548 msg.Printf(
_(
"<b>Unable to create temporary file '%s'.</b>" ),
573 msg.Printf(
_(
"Skipped file '%s' (unknown type)." ), entry->GetName() );
598 firstLoadedLayer = layer;
604 wxRemoveFile( unzipped_tempfile );
612 msg.Printf(
_(
"<b>unzipped file %s read error</b>" ), unzipped_tempfile );
625 foundX2Gerbers =
true;
650#define ZipFileExtension "zip"
652 wxFileName filename = aFullFileName;
653 wxString currentPath;
655 if( !filename.IsOk() )
658 if( filename.DirExists() )
659 currentPath = filename.GetPath();
663 wxFileDialog dlg(
this,
_(
"Open Zip File" ), currentPath, filename.GetFullName(),
665 wxFD_OPEN | wxFD_FILE_MUST_EXIST | wxFD_CHANGE_DIR );
669 if( dlg.ShowModal() == wxID_CANCEL )
672 filename = dlg.GetPath();
673 currentPath = wxGetCwd();
678 currentPath = filename.GetPath();
684 if( filename.IsOk() )
726 wxString fn = file.GetFullPath();
733 gerbFn +=
'"' + file.GetFullPath() +
'"';
738 if( !gerbFn.IsEmpty() )
std::vector< wxFileName > m_AcceptedFiles
void UpdateFileHistory(const wxString &FullFileName, FILE_HISTORY *aFileHistory=nullptr)
Update the list of recently opened files.
virtual void ClearFileHistory()
Remove all files from the file history.
std::map< const wxString, TOOL_ACTION * > m_acceptedExts
Associate file extensions with action to execute.
wxString GetFileFromHistory(int cmdId, const wxString &type, FILE_HISTORY *aFileHistory=nullptr)
Fetch the file name from the file history list.
void ReCreateMenuBar()
Recreate the menu bar.
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.
virtual EDA_DRAW_PANEL_GAL * GetCanvas() const
Return a pointer to GAL-based canvas of given EDA draw frame.
virtual KIGFX::VIEW * GetView() const
Return a pointer to the #VIEW instance used in the panel.
virtual void Refresh(bool aEraseBackground=true, const wxRect *aRect=nullptr) override
static bool TestFileIsExcellon(const wxString &aFullFileName)
Performs a heuristics-based check of whether the file is an Excellon drill file.
unsigned GetLoadedImageCount()
Get number of loaded images.
static void GetGerberLayerFromFilename(const wxString &filename, enum GERBER_ORDER_ENUM &order, wxString &matchedExtension)
Utility function to guess which PCB layer of a gerber/drill file corresponds to based on its file ext...
Hold the image data and parameters for one gerber file and layer parameters.
wxString m_FileName
Full File Name for this layer.
static bool TestFileIsRS274(const wxString &aFullFileName)
Performs a heuristics-based check of whether the file is an RS274 gerber file.
bool m_IsX2_file
True if a X2 gerber attribute was found in file.
void OnDrlFileHistory(wxCommandEvent &event)
Delete the current data and load a drill file in Excellon format selected from history list on curren...
void SortLayersByX2Attributes()
LSET GetVisibleLayers() const
A proxy function that calls the correspondent function in m_BoardSettings.
bool Read_EXCELLON_File(const wxString &aFullFileName)
bool LoadFileOrShowDialog(const wxString &aFileName, const wxString &dialogFiletypes, const wxString &dialogTitle, const int filetype)
Loads the file provided or shows a dialog to get the file(s) from the user.
bool LoadGerberJobFile(const wxString &aFileName)
Load a Gerber job file, and load gerber files found in job files.
void OnClearDrlFileHistory(wxCommandEvent &aEvent)
GERBER_FILE_IMAGE_LIST * GetImagesList() const
Accessors to GERBER_FILE_IMAGE_LIST and GERBER_FILE_IMAGE data.
void syncLayerBox(bool aRebuildLayerBox=false)
Update the currently "selected" layer within m_SelLayerBox.
bool LoadGerberFiles(const wxString &aFileName)
Load a given Gerber file or selected file(s), if the filename is empty.
bool unarchiveFiles(const wxString &aFullFileName, REPORTER *aReporter=nullptr)
Extract gerber and drill files from the zip archive, and load them.
FILE_HISTORY m_jobFileHistory
void OnJobFileHistory(wxCommandEvent &event)
Delete the current data and load a gerber job file selected from the history list.
void OnZipFileHistory(wxCommandEvent &event)
Delete the current data and load a zip archive file selected from the history list.
int GetActiveLayer() const
Return the active layer.
GERBER_LAYER_WIDGET * m_LayersManager
void SetActiveLayer(int aLayer, bool doLayerWidgetUpdate=true)
change the currently active layer to aLayer and update the GERBER_LAYER_WIDGET.
void SetVisibleLayers(const LSET &aLayerMask)
A proxy function that calls the correspondent function in m_BoardSettings.
void ClearFileHistory() override
Remove all files from the file history.
bool Read_GERBER_File(const wxString &GERBER_FullFileName)
void SortLayersByFileExtension()
GERBER_FILE_IMAGE * GetGbrImage(int aIdx) const
bool LoadListOfGerberAndDrillFiles(const wxString &aPath, const wxArrayString &aFilenameList, std::vector< int > *aFileType)
Load a list of Gerber and NC drill files and updates the view based on them.
bool LoadAutodetectedFiles(const wxString &aFileName)
Load a given file or selected file(s), if the filename is empty.
void ReFillLayerWidget()
Change out all the layers in m_Layers; called upon loading new gerber files.
FILE_HISTORY m_zipFileHistory
int getNextAvailableLayer() const
Find the next empty layer.
bool LoadZipArchiveFile(const wxString &aFileName)
Load a zipped archive file.
void OnClearGbrFileHistory(wxCommandEvent &aEvent)
void OnClearZipFileHistory(wxCommandEvent &aEvent)
void DoWithAcceptedFiles() override
Execute action on accepted dropped file.
void OnGbrFileHistory(wxCommandEvent &event)
Delete the current data and loads a Gerber file selected from history list on current layer.
FILE_HISTORY m_drillFileHistory
bool LoadExcellonFiles(const wxString &aFileName)
Load a drill (EXCELLON) file or many files.
void OnClearJobFileHistory(wxCommandEvent &aEvent)
void ListSet(const wxString &aList)
Add a list of items.
Hold a (potentially large) number of VIEW_ITEMs and renders them on a graphics device provided by the...
void SetLayerHasNegatives(int aLayer, bool aNegatives=true)
Set the status of negatives presense in a particular layer.
LSET is a set of PCB_LAYER_IDs.
A pure virtual class used to derive REPORTER objects from.
virtual REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)
Report a string with a given severity.
A wrapper for reporting to a wxString object.
#define MSG_NO_MORE_LAYER
#define NO_AVAILABLE_LAYERS
static const std::string GerberJobFileExtension
static const std::string GerberFileExtension
static const std::string ArchiveFileExtension
static wxString AllFilesWildcard()
static wxString DrillFileWildcard()
static wxString ZipFileWildcard()
#define GERBER_DRAW_LAYER(x)
IbisParser parser & reporter
wxString AddFileExtListToFilter(const std::vector< std::string > &aExts)
Build the wildcard extension file dialog wildcard filter to add to the base message dialog.
Definition of file extensions used in Kicad.