260 if( outputPath.IsEmpty() )
261 outputPath = wxFileName( aJob.
m_filename ).GetPath();
263 wxFileName outputFn( outputPath );
268 if( outputFn.GetPath().IsEmpty() && outputFn.HasName() )
269 outputFn.MakeAbsolute();
276 msg.Printf(
_(
"Cannot create output directory '%s'." ), outputFn.GetFullPath() );
284 if( outputFn.IsDir() && !outputFn.IsDirWritable() )
286 msg.Printf(
_(
"Insufficient permissions to folder '%s'." ), outputFn.GetPath() );
294 if( outputIsSingleFile )
296 bool writeable = outputFn.FileExists() ? outputFn.IsFileWritable() : outputFn.IsDirWritable();
300 msg.Printf(
_(
"Insufficient permissions to save file '%s'." ), outputFn.GetFullPath() );
309 wxFileName tempFile( outputFn.GetFullPath() );
311 if( outputIsSingleFile )
313 if( outputFn.Exists() )
317 msg = wxString::Format(
_(
"Output files '%s' already exists. Do you want to overwrite it?" ),
318 outputFn.GetFullPath() );
320 KIDIALOG errorDlg( aParentFrame, msg,
_(
"Confirmation" ), wxOK | wxCANCEL | wxICON_WARNING );
321 errorDlg.SetOKLabel(
_(
"Overwrite" ) );
326 if( !wxRemoveFile( outputFn.GetFullPath() ) )
328 msg.Printf(
_(
"Cannot remove existing output file '%s'." ), outputFn.GetFullPath() );
335 msg = wxString::Format(
_(
"Output file '%s' already exists." ), outputFn.GetFullPath() );
344 tempFile.AssignDir( wxFileName::GetTempDir() );
345 tempFile.AppendDir(
"kicad" );
346 tempFile.AppendDir(
"odb" );
348 if( !wxFileName::Mkdir( tempFile.GetFullPath(), wxS_DIR_DEFAULT, wxPATH_MKDIR_FULL ) )
350 msg.Printf(
_(
"Cannot create temporary output directory." ) );
361 wxDir testDir( tempFile.GetFullPath() );
363 if( testDir.IsOpened() && ( testDir.HasFiles() || testDir.HasSubDirs() ) )
367 msg = wxString::Format(
_(
"Output directory '%s' already exists and is not empty. "
368 "Do you want to overwrite it?" ),
369 tempFile.GetFullPath() );
371 KIDIALOG errorDlg( aParentFrame, msg,
_(
"Confirmation" ), wxOK | wxCANCEL | wxICON_WARNING );
372 errorDlg.SetOKLabel(
_(
"Overwrite" ) );
377 if( !tempFile.Rmdir( wxPATH_RMDIR_RECURSIVE ) )
379 msg.Printf(
_(
"Cannot remove existing output directory '%s'." ), tempFile.GetFullPath() );
386 msg = wxString::Format(
_(
"Output directory '%s' already exists." ), tempFile.GetFullPath() );
396 std::map<std::string, UTF8> props;
399 props[
"sigfig"] = wxString::Format(
"%d", aJob.
m_precision );
407 pi->SetReporter( aReporter );
408 pi->SetProgressReporter( aProgressReporter );
409 pi->SaveBoard( tempFile.GetFullPath(), aBoard, &props );
416 msg = wxString::Format(
_(
"Error generating ODBPP files '%s'.\n%s" ),
417 tempFile.GetFullPath(), ioe.
What() );
422 wxFileName::Rmdir( tempFile.GetFullPath() );
428 auto ret =
tp.submit_task( saveFile );
430 std::future_status status = ret.wait_for( std::chrono::milliseconds( 250 ) );
432 while( status != std::future_status::ready )
434 if( aProgressReporter )
437 status = ret.wait_for( std::chrono::milliseconds( 250 ) );
445 catch(
const std::exception& e )
449 aReporter->
Report( wxString::Format(
"Exception in ODB++ generation: %s", e.what() ),
458 if( aProgressReporter )
459 aProgressReporter->
AdvancePhase(
_(
"Compressing output" ) );
461 wxFFileOutputStream fnout( outputFn.GetFullPath() );
462 wxZipOutputStream zipStream( fnout );
464 std::function<void(
const wxString&,
const wxString& )> addDirToZip =
465 [&](
const wxString& dirPath,
const wxString& parentPath )
467 wxDir dir( dirPath );
470 bool cont = dir.GetFirst( &fileName, wxEmptyString, wxDIR_DEFAULT );
474 wxFileName fileInZip( dirPath, fileName );
475 wxString relativePath = fileName;
477 if( !parentPath.IsEmpty() )
478 relativePath = parentPath + wxString( wxFileName::GetPathSeparator() ) + fileName;
480 if( wxFileName::DirExists( fileInZip.GetFullPath() ) )
482 zipStream.PutNextDirEntry( relativePath );
483 addDirToZip( fileInZip.GetFullPath(), relativePath );
487 wxFFileInputStream fileStream( fileInZip.GetFullPath() );
488 zipStream.PutNextEntry( relativePath );
489 fileStream.Read( zipStream );
491 cont = dir.GetNext( &fileName );
495 addDirToZip( tempFile.GetFullPath(), wxEmptyString );
500 tempFile.Rmdir( wxPATH_RMDIR_RECURSIVE );
504 wxFFileOutputStream fnout( outputFn.GetFullPath() );
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 )