266 if( outputPath.IsEmpty() )
267 outputPath = wxFileName( aJob.
m_filename ).GetPath();
269 wxFileName outputFn( outputPath );
274 if( outputFn.GetPath().IsEmpty() && outputFn.HasName() )
275 outputFn.MakeAbsolute();
282 msg.Printf(
_(
"Cannot create output directory '%s'." ), outputFn.GetFullPath() );
290 if( outputFn.IsDir() && !outputFn.IsDirWritable() )
292 msg.Printf(
_(
"Insufficient permissions to folder '%s'." ), outputFn.GetPath() );
300 if( outputIsSingleFile )
302 bool writeable = outputFn.FileExists() ? outputFn.IsFileWritable() : outputFn.IsDirWritable();
306 msg.Printf(
_(
"Insufficient permissions to save file '%s'." ), outputFn.GetFullPath() );
315 wxFileName tempFile( outputFn.GetFullPath() );
317 if( outputIsSingleFile )
319 if( outputFn.Exists() )
323 msg = wxString::Format(
_(
"Output files '%s' already exists. Do you want to overwrite it?" ),
324 outputFn.GetFullPath() );
326 KIDIALOG errorDlg( aParentFrame, msg,
_(
"Confirmation" ), wxOK | wxCANCEL | wxICON_WARNING );
327 errorDlg.SetOKLabel(
_(
"Overwrite" ) );
332 if( !wxRemoveFile( outputFn.GetFullPath() ) )
334 msg.Printf(
_(
"Cannot remove existing output file '%s'." ), outputFn.GetFullPath() );
341 tempFile.AssignDir( wxFileName::GetTempDir() );
342 tempFile.AppendDir(
"kicad" );
343 tempFile.AppendDir(
"odb" );
345 if( !wxFileName::Mkdir( tempFile.GetFullPath(), wxS_DIR_DEFAULT, wxPATH_MKDIR_FULL ) )
347 msg.Printf(
_(
"Cannot create temporary output directory." ) );
358 wxDir testDir( tempFile.GetFullPath() );
360 if( testDir.IsOpened() && ( testDir.HasFiles() || testDir.HasSubDirs() ) )
364 msg = wxString::Format(
_(
"Output directory '%s' already exists and is not empty. "
365 "Do you want to overwrite it?" ),
366 tempFile.GetFullPath() );
368 KIDIALOG errorDlg( aParentFrame, msg,
_(
"Confirmation" ), wxOK | wxCANCEL | wxICON_WARNING );
369 errorDlg.SetOKLabel(
_(
"Overwrite" ) );
374 if( !tempFile.Rmdir( wxPATH_RMDIR_RECURSIVE ) )
376 msg.Printf(
_(
"Cannot remove existing output directory '%s'." ), tempFile.GetFullPath() );
384 std::map<std::string, UTF8> props;
387 props[
"sigfig"] = wxString::Format(
"%d", aJob.
m_precision );
395 pi->SetReporter( aReporter );
396 pi->SetProgressReporter( aProgressReporter );
397 pi->SaveBoard( tempFile.GetFullPath(), aBoard, &props );
404 msg = wxString::Format(
_(
"Error generating ODBPP files '%s'.\n%s" ),
405 tempFile.GetFullPath(), ioe.
What() );
410 wxFileName::Rmdir( tempFile.GetFullPath() );
416 auto ret =
tp.submit_task( saveFile );
418 std::future_status status = ret.wait_for( std::chrono::milliseconds( 250 ) );
420 while( status != std::future_status::ready )
422 if( aProgressReporter )
425 status = ret.wait_for( std::chrono::milliseconds( 250 ) );
433 catch(
const std::exception& e )
437 aReporter->
Report( wxString::Format(
"Exception in ODB++ generation: %s", e.what() ),
446 if( aProgressReporter )
447 aProgressReporter->
AdvancePhase(
_(
"Compressing output" ) );
449 wxFFileOutputStream fnout( outputFn.GetFullPath() );
453 if( FILE* fp = fnout.GetFile()->fp() )
456 wxZipOutputStream zipStream( fnout );
458 std::function<void(
const wxString&,
const wxString& )> addDirToZip =
459 [&](
const wxString& dirPath,
const wxString& parentPath )
461 wxDir dir( dirPath );
464 bool cont = dir.GetFirst( &fileName, wxEmptyString, wxDIR_DEFAULT );
468 wxFileName fileInZip( dirPath, fileName );
469 wxString relativePath = fileName;
471 if( !parentPath.IsEmpty() )
472 relativePath = parentPath + wxString( wxFileName::GetPathSeparator() ) + fileName;
474 if( wxFileName::DirExists( fileInZip.GetFullPath() ) )
476 zipStream.PutNextDirEntry( relativePath );
477 addDirToZip( fileInZip.GetFullPath(), relativePath );
481 wxFFileInputStream fileStream( fileInZip.GetFullPath() );
482 zipStream.PutNextEntry( relativePath );
483 fileStream.Read( zipStream );
485 cont = dir.GetNext( &fileName );
489 addDirToZip( tempFile.GetFullPath(), wxEmptyString );
494 tempFile.Rmdir( wxPATH_RMDIR_RECURSIVE );
498 wxFFileOutputStream fnout( outputFn.GetFullPath() );
502 if( FILE* fp = fnout.GetFile()->fp() )
505 wxZlibOutputStream zlibStream( fnout, -1, wxZLIB_GZIP );
506 wxTarOutputStream tarStream( zlibStream );
508 std::function<void(
const wxString&,
const wxString& )> addDirToTar =
509 [&](
const wxString& dirPath,
const wxString& parentPath )
511 wxDir dir( dirPath );
514 bool cont = dir.GetFirst( &fileName, wxEmptyString, wxDIR_DEFAULT );
517 wxFileName fileInTar( dirPath, fileName );
518 wxString relativePath = fileName;
520 if( !parentPath.IsEmpty() )
521 relativePath = parentPath + wxString( wxFileName::GetPathSeparator() ) + fileName;
523 if( wxFileName::DirExists( fileInTar.GetFullPath() ) )
525 tarStream.PutNextDirEntry( relativePath );
526 addDirToTar( fileInTar.GetFullPath(), relativePath );
530 wxFFileInputStream fileStream( fileInTar.GetFullPath() );
531 tarStream.PutNextEntry( relativePath, wxDateTime::Now(), fileStream.GetLength() );
532 fileStream.Read( tarStream );
534 cont = dir.GetNext( &fileName );
538 addDirToTar( tempFile.GetFullPath(),
539 tempFile.GetPath( wxPATH_NO_SEPARATOR ).AfterLast( tempFile.GetPathSeparator() ) );
545 tempFile.Rmdir( wxPATH_RMDIR_RECURSIVE );
548 if( aProgressReporter )