46#include <wx/wfstream.h>
47#include <wx/zipstrm.h>
65 path = brdFile.GetPath();
82 m_parent( aEditFrame ),
104 wxFileName fn(
Prj().AbsolutePath(
path ) );
106 wxDirDialog dlg(
this,
_(
"Export ODB++ File" ), fn.GetPath() );
108 if( dlg.ShowModal() == wxID_CANCEL )
180 if( outputPath.IsEmpty() )
181 outputPath = wxFileName( aJob.
m_filename ).GetPath();
183 wxFileName pcbFileName( outputPath );
188 if( pcbFileName.GetPath().IsEmpty() && pcbFileName.HasName() )
189 pcbFileName.MakeAbsolute();
193 if( pcbFileName.IsDir() && !pcbFileName.IsDirWritable() )
195 msg.Printf(
_(
"Insufficient permissions to folder '%s'." ), pcbFileName.GetPath() );
197 else if( !pcbFileName.FileExists() && !pcbFileName.IsDirWritable() )
199 msg.Printf(
_(
"Insufficient permissions to save file '%s'." ), pcbFileName.GetFullPath() );
201 else if( pcbFileName.FileExists() && !pcbFileName.IsFileWritable() )
203 msg.Printf(
_(
"Insufficient permissions to save file '%s'." ), pcbFileName.GetFullPath() );
214 if( !wxFileName::DirExists( pcbFileName.GetFullPath() ) )
217 if( !wxFileName::Mkdir( pcbFileName.GetFullPath(), wxS_DIR_DEFAULT, wxPATH_MKDIR_FULL ) )
219 msg.Printf(
_(
"Cannot create output directory '%s'." ), pcbFileName.GetFullPath() );
228 wxFileName zipFileName( pcbFileName.GetFullPath(),
229 wxString::Format( wxS(
"%s-odb.zip" ),
232 wxFileName tempFile( pcbFileName.GetFullPath(),
"" );
236 if( zipFileName.Exists() )
240 msg = wxString::Format(
_(
"Output files '%s' already exists. "
241 "Do you want to overwrite it?" ),
242 zipFileName.GetFullPath() );
244 KIDIALOG errorDlg( aParentFrame, msg,
_(
"Confirmation" ),
245 wxOK | wxCANCEL | wxICON_WARNING );
246 errorDlg.SetOKLabel(
_(
"Overwrite" ) );
251 if( !wxRemoveFile( zipFileName.GetFullPath() ) )
253 msg.Printf(
_(
"Cannot remove existing output file '%s'." ),
254 zipFileName.GetFullPath() );
261 msg = wxString::Format(
_(
"Output file '%s' already exists." ),
262 zipFileName.GetFullPath() );
271 tempFile.AssignDir( wxFileName::GetTempDir() );
272 tempFile.AppendDir(
"kicad" );
273 tempFile.AppendDir(
"odb" );
275 if( !wxFileName::Mkdir( tempFile.GetFullPath(), wxS_DIR_DEFAULT, wxPATH_MKDIR_FULL ) )
277 msg.Printf(
_(
"Cannot create temporary output directory." ) );
288 wxFileName odbDir( tempFile );
289 odbDir.AppendDir(
"odb" );
290 wxDir testDir( odbDir.GetFullPath() );
292 if( testDir.IsOpened() && ( testDir.HasFiles() || testDir.HasSubDirs() ) )
296 msg = wxString::Format(
_(
"Output directory '%s' already exists and is not empty. "
297 "Do you want to overwrite it?" ),
298 odbDir.GetFullPath() );
300 KIDIALOG errorDlg( aParentFrame, msg,
_(
"Confirmation" ),
301 wxOK | wxCANCEL | wxICON_WARNING );
302 errorDlg.SetOKLabel(
_(
"Overwrite" ) );
307 if( !odbDir.Rmdir( wxPATH_RMDIR_RECURSIVE ) )
309 msg.Printf(
_(
"Cannot remove existing output directory '%s'." ),
310 odbDir.GetFullPath() );
317 msg = wxString::Format(
_(
"Output directory '%s' already exists." ),
318 odbDir.GetFullPath() );
330 std::map<std::string, UTF8> props;
333 props[
"sigfig"] = wxString::Format(
"%d", aJob.
m_precision );
341 pi->SetReporter( aReporter );
342 pi->SetProgressReporter( aProgressReporter );
343 pi->SaveBoard( tempFile.GetFullPath(), aBoard, &props );
350 msg = wxString::Format(
_(
"Error generating ODBPP files '%s'.\n%s" ),
351 tempFile.GetFullPath(), ioe.
What() );
356 wxFileName::Rmdir( tempFile.GetFullPath() );
362 auto ret =
tp.submit( saveFile );
364 std::future_status status = ret.wait_for( std::chrono::milliseconds( 250 ) );
366 while( status != std::future_status::ready )
368 if( aProgressReporter)
371 status = ret.wait_for( std::chrono::milliseconds( 250 ) );
379 catch(
const std::exception& e )
383 aReporter->
Report( wxString::Format(
"Exception in ODB++ generation: %s", e.what() ),
392 if( aProgressReporter )
393 aProgressReporter->
AdvancePhase(
_(
"Compressing output" ) );
395 wxFFileOutputStream fnout( zipFileName.GetFullPath() );
396 wxZipOutputStream zipStream( fnout );
398 std::function<void(
const wxString&,
const wxString& )> addDirToZip =
399 [&](
const wxString& dirPath,
const wxString& parentPath )
401 wxDir dir( dirPath );
404 bool cont = dir.GetFirst( &fileName, wxEmptyString, wxDIR_DEFAULT );
408 wxFileName fileInZip( dirPath, fileName );
409 wxString relativePath =
412 : parentPath + wxString( wxFileName::GetPathSeparator() )
415 if( wxFileName::DirExists( fileInZip.GetFullPath() ) )
417 zipStream.PutNextDirEntry( relativePath );
418 addDirToZip( fileInZip.GetFullPath(), relativePath );
422 wxFFileInputStream fileStream( fileInZip.GetFullPath() );
423 zipStream.PutNextEntry( relativePath );
424 fileStream.Read( zipStream );
426 cont = dir.GetNext( &fileName );
430 addDirToZip( tempFile.GetFullPath(), wxEmptyString );
435 tempFile.Rmdir( wxPATH_RMDIR_RECURSIVE );
438 if( aProgressReporter )
wxBitmapBundle KiBitmapBundle(BITMAPS aBitmap)
Information pertinent to a Pcbnew printed circuit board.
const wxString & GetFileName() const
PROJECT * GetProject() const
Class DIALOG_EXPORT_ODBPP_BASE.
wxTextCtrl * m_outputFileName
STD_BITMAP_BUTTON * m_browseButton
wxCheckBox * m_cbCompress
bool TransferDataFromWindow() override
static void GenerateODBPPFiles(const JOB_EXPORT_PCB_ODB &aJob, BOARD *aBoard, PCB_EDIT_FRAME *aParentFrame=nullptr, PROGRESS_REPORTER *aProgressReporter=nullptr, REPORTER *aErrorReporter=nullptr)
void onBrowseClicked(wxCommandEvent &event) override
JOB_EXPORT_PCB_ODB * m_job
DIALOG_EXPORT_ODBPP(PCB_EDIT_FRAME *aParent)
PCB_EDIT_FRAME * m_parent
void onOKClick(wxCommandEvent &event) override
void SetupStandardButtons(std::map< int, wxString > aLabels={})
void finishDialogSettings()
In all dialogs, we must call the same functions to fix minimal dlg size, the default position and per...
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
virtual const wxString What() const
A composite of Problem() and Where()
ODB_COMPRESSION m_compressionMode
void SetOutputPath(const wxString &aPath)
wxString GetOutputPath() const
Helper class to create more flexible dialogs, including 'do not show again' checkbox handling.
PROJECT & Prj() const
Return a reference to the PROJECT associated with this KIWAY.
DIALOG_EXPORT_ODBPP m_ExportODBPP
The main frame for Pcbnew.
void SetLastPath(LAST_PATH_TYPE aType, const wxString &aLastPath)
Set the path of the last file successfully read.
wxString GetLastPath(LAST_PATH_TYPE aType)
Get the last path for a particular type.
static PCB_IO * PluginFind(PCB_FILE_T aFileType)
Return a #PLUGIN which the caller can use to import, export, save, or load design documents.
virtual SETTINGS_MANAGER & GetSettingsManager() const
A progress reporter interface for use in multi-threaded environments.
virtual bool KeepRefreshing(bool aWait=false)=0
Update the UI (if any).
virtual void AdvancePhase()=0
Use the next available virtual zone of the dialog progress bar.
virtual void SetCurrentProgress(double aProgress)=0
Set the progress value to aProgress (0..1).
virtual const wxString GetProjectName() const
Return the short name of the project.
A pure virtual class used to derive REPORTER objects from.
virtual REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)=0
Report a string with a given severity.
T * GetAppSettings(const wxString &aFilename)
Returns a handle to the a given settings by type If the settings have already been loaded,...
static void ResolvePossibleSymlinks(wxFileName &aFilename)
const wxString ExpandEnvVarSubstitutions(const wxString &aString, const PROJECT *aProject)
Replace any environment variable & text variable references with their values.
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
This file is part of the common library.
static wxString s_oemColumn
std::unique_ptr< T > IO_RELEASER
Helper to hold and release an IO_BASE object when exceptions are thrown.
This file is part of the common library.
PGM_BASE & Pgm()
The global Program "get" accessor.
BS::thread_pool thread_pool
thread_pool & GetKiCadThreadPool()
Get a reference to the current thread pool.