24#include <wx/filedlg.h>
25#include <wx/wfstream.h>
26#include <wx/zipstrm.h>
43#define MSG_NO_MORE_LAYER _( "<b>No more available layers</b> in GerbView to load files" )
44#define MSG_NOT_LOADED _( "<b>Not loaded:</b> <i>%s</i>" )
45#define MSG_OOM _( "<b>Memory was exhausted reading:</b> <i>%s</i>" )
58 if( !filename.IsEmpty() )
69 GetMenuBar()->Refresh();
78 if( !filename.IsEmpty() )
90 GetMenuBar()->Refresh();
99 if( !filename.IsEmpty() )
111 GetMenuBar()->Refresh();
120 if( !filename.IsEmpty() )
132 GetMenuBar()->Refresh();
138 const wxString& dialogFiletypes,
139 const wxString& dialogTitle,
const int filetype )
141 static int lastGerberFileWildcard = 0;
142 wxArrayString filenamesList;
143 wxFileName filename = aFileName;
144 wxString currentPath;
146 if( !filename.IsOk() )
149 if( filename.DirExists() )
150 currentPath = filename.GetPath();
157 if( currentPath.EndsWith(
'\\' ) || currentPath.EndsWith(
'/' ) )
158 currentPath.RemoveLast();
161 wxFileDialog dlg(
this, dialogTitle, currentPath, filename.GetFullName(), dialogFiletypes,
162 wxFD_OPEN | wxFD_FILE_MUST_EXIST | wxFD_MULTIPLE | wxFD_CHANGE_DIR );
166 wxArrayString dummy1, dummy2;
167 const int nWildcards = wxParseCommonDialogsFilter( dialogFiletypes, dummy1, dummy2 );
169 if( lastGerberFileWildcard >= 0 && lastGerberFileWildcard < nWildcards )
170 dlg.SetFilterIndex( lastGerberFileWildcard );
172 if( dlg.ShowModal() == wxID_CANCEL )
175 lastGerberFileWildcard = dlg.GetFilterIndex();
176 dlg.GetPaths( filenamesList );
177 m_mruPath = currentPath = dlg.GetDirectory();
181 filenamesList.Add( aFileName );
182 currentPath = filename.GetPath();
191 std::vector<int> fileTypesVec( filenamesList.Count(), filetype );
221 wxFileName filename = aFileName;
233 filetypes =
_(
"Gerber files" ) + wxT(
" (*.g*; *.pho)|" )
235 "gtp",
"gbp",
"gta",
"gba",
"gko",
"gpt",
"gpb",
"gm1",
"gm2",
236 "gm3",
"gm4",
"gm5",
"gm6",
"gm7",
"gm8",
"gm9",
"g1",
"g2",
237 "g3",
"g4",
"g5",
"g6",
"g7",
"g8",
"g9" } )
251 filetypes +=
_(
"Mechanical layers" )
253 {
"gm1",
"gm2",
"gm3",
"gm4",
"gm5",
"gm6",
"gm7",
"gm8",
"gm9" } )
269 filetypes << wxT(
"|" );
278 const wxArrayString& aFilenameList,
279 std::vector<int>* aFileType )
281 wxCHECK_MSG( aFilenameList.Count() == aFileType->size(),
false,
282 "Mismatch in file names and file types count" );
296 std::unique_ptr<WX_PROGRESS_REPORTER> progress =
nullptr;
298 for(
unsigned ii = 0; ii < aFilenameList.GetCount(); ii++ )
300 filename = aFilenameList[ii];
302 if( !filename.IsAbsolute() )
303 filename.SetPath( aPath );
307 if( !filename.FileExists() )
310 warning << wxT(
"<b>" ) <<
_(
"File not found:" ) << wxT(
"</b><br>" )
311 << filename.GetFullPath() << wxT(
"<br>" );
321 txt.Printf(
_(
"<b>A gerber job file cannot be loaded as a plot file</b> "
323 filename.GetFullName() );
332 if( !progress && ( aFilenameList.GetCount() > 1 ) )
334 progress = std::make_unique<WX_PROGRESS_REPORTER>(
this,
_(
"Load Files" ), 1,
PR_CAN_ABORT );
335 progress->SetMaxProgress( aFilenameList.GetCount() - 1 );
336 progress->Report( wxString::Format(
_(
"Loading %u/%zu %s..." ),
338 aFilenameList.GetCount(),
343 progress->Report( wxString::Format(
_(
"Loading %u/%zu %s..." ),
345 aFilenameList.GetCount(),
347 progress->KeepRefreshing();
360 while( ii < aFilenameList.GetCount() )
362 filename = aFilenameList[ii++];
363 wxString txt = wxString::Format(
MSG_NOT_LOADED, filename.GetFullName() );
375 if( ( *aFileType )[ii] == 2 )
378 ( *aFileType )[ii] = 1;
380 ( *aFileType )[ii] = 0;
385 ( *aFileType )[ii] = 0;
388 bool read_ok =
false;
390 switch( ( *aFileType )[ii] )
402 firstLoadedLayer = layer;
419 firstLoadedLayer = layer;
431 wxString txt = wxString::Format(
MSG_NOT_LOADED, filename.GetFullName() );
435 catch(
const std::bad_alloc& )
437 wxString txt = wxString::Format(
MSG_OOM, filename.GetFullName() );
444 progress->AdvanceProgress();
475 bool foundX2Gerbers =
false;
480 wxFFileInputStream zipFile( aFullFileName );
482 if( !zipFile.IsOk() )
486 msg.Printf(
_(
"Zip file '%s' cannot be opened." ), aFullFileName );
500 wxString unzipped_tempfile = wxFileName::CreateTempFileName( wxS(
"gerbview" ) );
502 if( unzipped_tempfile.IsEmpty() )
506 msg.Printf(
_(
"Unable to create a temporary file to unzip '%s'." ), aFullFileName );
514 wxZipInputStream zipArchive( zipFile );
515 bool reported_no_more_layer =
false;
518 while( std::unique_ptr<wxZipEntry> entry{ zipArchive.GetNextEntry() } )
523 wxString fname = entry->GetName();
525 if( aMembers && aMembers->Index( fname ) == wxNOT_FOUND )
528 wxFileName uzfn = fname;
529 wxString curr_ext = uzfn.GetExt().Lower();
539 msg.Printf(
_(
"Skipped file '%s' (gerber job file)." ), entry->GetName() );
558 if( !reported_no_more_layer )
561 reported_no_more_layer =
true;
575 wxFFileOutputStream temporary_ofile( unzipped_tempfile );
577 if( !temporary_ofile.Ok() )
583 msg.Printf(
_(
"<b>Unable to create temporary file '%s'.</b>" ),
592 temporary_ofile.Write( zipArchive );
596 const bool writeOk = temporary_ofile.IsOk();
597 const bool closeOk = temporary_ofile.Close();
599 if( !writeOk || !closeOk )
605 msg.Printf(
_(
"<b>Unable to write temporary file '%s'.</b>" ),
620 bool isExcellonDrill = ( isDrillExt && !isGerberDrill )
626 if( !isExcellonDrill && !isGerberDrill && !isGerberLayer )
630 msg.Printf(
_(
"Skipped file '%s' (unknown type)." ), entry->GetName() );
639 if( isExcellonDrill )
643 else if( isGerberDrill || isGerberLayer )
658 firstLoadedLayer = layer;
667 msg.Printf(
_(
"<b>unzipped file %s read error</b>" ), unzipped_tempfile );
681 foundX2Gerbers =
true;
689 wxRemoveFile( unzipped_tempfile );
708#define ZipFileExtension "zip"
710 wxFileName filename = aFullFileName;
711 wxString currentPath;
713 if( !filename.IsOk() )
716 if( filename.DirExists() )
717 currentPath = filename.GetPath();
721 wxFileDialog dlg(
this,
_(
"Open Zip File" ), currentPath, filename.GetFullName(),
723 wxFD_OPEN | wxFD_FILE_MUST_EXIST | wxFD_CHANGE_DIR );
727 if( dlg.ShowModal() == wxID_CANCEL )
730 filename = dlg.GetPath();
731 currentPath = wxGetCwd();
736 currentPath = filename.GetPath();
742 if( filename.IsOk() )
784 wxString fn = file.GetFullPath();
791 gerbFn +=
'"' + file.GetFullPath() +
'"';
796 if( !gerbFn.IsEmpty() )
std::vector< wxFileName > m_AcceptedFiles
void UpdateFileHistory(const wxString &FullFileName, FILE_HISTORY *aFileHistory=nullptr)
Update the list of recently opened files.
FILE_HISTORY & GetFileHistory()
Get the frame's main file history.
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 KIGFX::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.
void ClearFileHistory()
Clear all entries from the file history.
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.
wxString m_ArchiveFileName
Archive containing this layer, if loaded from a ZIP 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.
FILE_HISTORY m_jobFileHistory
void OnJobFileHistory(wxCommandEvent &event)
Delete the current data and load a gerber job file selected from the history list.
bool LoadZipArchiveFile(const wxString &aFileName, const wxArrayString *aMembers=nullptr)
Load a zipped archive file.
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.
void OnClearGbrFileHistory(wxCommandEvent &aEvent)
bool unarchiveFiles(const wxString &aFullFileName, REPORTER *aReporter=nullptr, const wxArrayString *aMembers=nullptr)
Extract gerber and drill files from the zip archive, and load them.
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.
static bool isGerberFormatInsteadOfExcellon(const wxString &aFileName)
#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.