269 if( outputPath.IsEmpty() )
270 outputPath = wxFileName( aJob.
m_filename ).GetPath();
272 wxFileName outputFn( outputPath );
277 if( outputFn.GetPath().IsEmpty() && outputFn.HasName() )
278 outputFn.MakeAbsolute();
285 msg.Printf(
_(
"Cannot create output directory '%s'." ), outputFn.GetFullPath() );
293 if( outputFn.IsDir() && !outputFn.IsDirWritable() )
295 msg.Printf(
_(
"Insufficient permissions to folder '%s'." ), outputFn.GetPath() );
303 if( outputIsSingleFile )
305 bool writeable = outputFn.FileExists() ? outputFn.IsFileWritable() : outputFn.IsDirWritable();
309 msg.Printf(
_(
"Insufficient permissions to save file '%s'." ), outputFn.GetFullPath() );
318 wxFileName tempFile( outputFn.GetFullPath() );
320 if( outputIsSingleFile )
322 if( outputFn.Exists() )
326 msg = wxString::Format(
_(
"Output files '%s' already exists. Do you want to overwrite it?" ),
327 outputFn.GetFullPath() );
329 KIDIALOG errorDlg( aParentFrame, msg,
_(
"Confirmation" ), wxOK | wxCANCEL | wxICON_WARNING );
330 errorDlg.SetOKLabel(
_(
"Overwrite" ) );
335 if( !wxRemoveFile( outputFn.GetFullPath() ) )
337 msg.Printf(
_(
"Cannot remove existing output file '%s'." ), 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() );
387 std::map<std::string, UTF8> props;
390 props[
"sigfig"] = wxString::Format(
"%d", aJob.
m_precision );
398 pi->SetReporter( aReporter );
399 pi->SetProgressReporter( aProgressReporter );
400 pi->SaveBoard( tempFile.GetFullPath(), aBoard, &props );
407 msg = wxString::Format(
_(
"Error generating ODBPP files '%s'.\n%s" ),
408 tempFile.GetFullPath(), ioe.
What() );
413 wxFileName::Rmdir( tempFile.GetFullPath() );
419 auto ret =
tp.submit_task( saveFile );
421 std::future_status status = ret.wait_for( std::chrono::milliseconds( 250 ) );
423 while( status != std::future_status::ready )
425 if( aProgressReporter )
428 status = ret.wait_for( std::chrono::milliseconds( 250 ) );
436 catch(
const std::exception& e )
440 aReporter->
Report( wxString::Format(
"Exception in ODB++ generation: %s", e.what() ),
449 if( aProgressReporter )
450 aProgressReporter->
AdvancePhase(
_(
"Compressing output" ) );
452 wxFFileOutputStream fnout( outputFn.GetFullPath() );
456 if( FILE* fp = fnout.GetFile()->fp() )
459 wxZipOutputStream zipStream( fnout );
461 std::function<void(
const wxString&,
const wxString& )> addDirToZip =
462 [&](
const wxString& dirPath,
const wxString& parentPath )
464 wxDir dir( dirPath );
467 bool cont = dir.GetFirst( &fileName, wxEmptyString, wxDIR_DEFAULT );
471 wxFileName fileInZip( dirPath, fileName );
472 wxString relativePath = fileName;
474 if( !parentPath.IsEmpty() )
475 relativePath = parentPath + wxString( wxFileName::GetPathSeparator() ) + fileName;
477 if( wxFileName::DirExists( fileInZip.GetFullPath() ) )
479 zipStream.PutNextDirEntry( relativePath );
480 addDirToZip( fileInZip.GetFullPath(), relativePath );
484 wxFFileInputStream fileStream( fileInZip.GetFullPath() );
485 zipStream.PutNextEntry( relativePath );
486 fileStream.Read( zipStream );
488 cont = dir.GetNext( &fileName );
492 addDirToZip( tempFile.GetFullPath(), wxEmptyString );
497 tempFile.Rmdir( wxPATH_RMDIR_RECURSIVE );
501 wxFFileOutputStream fnout( outputFn.GetFullPath() );
505 if( FILE* fp = fnout.GetFile()->fp() )
508 wxZlibOutputStream zlibStream( fnout, -1, wxZLIB_GZIP );
509 wxTarOutputStream tarStream( zlibStream );
511 std::function<void(
const wxString&,
const wxString& )> addDirToTar =
512 [&](
const wxString& dirPath,
const wxString& parentPath )
514 wxDir dir( dirPath );
517 bool cont = dir.GetFirst( &fileName, wxEmptyString, wxDIR_DEFAULT );
520 wxFileName fileInTar( dirPath, fileName );
521 wxString relativePath = fileName;
523 if( !parentPath.IsEmpty() )
524 relativePath = parentPath + wxString( wxFileName::GetPathSeparator() ) + fileName;
526 if( wxFileName::DirExists( fileInTar.GetFullPath() ) )
528 tarStream.PutNextDirEntry( relativePath );
529 addDirToTar( fileInTar.GetFullPath(), relativePath );
533 wxFFileInputStream fileStream( fileInTar.GetFullPath() );
534 tarStream.PutNextEntry( relativePath, wxDateTime::Now(), fileStream.GetLength() );
535 fileStream.Read( tarStream );
537 cont = dir.GetNext( &fileName );
541 addDirToTar( tempFile.GetFullPath(),
542 tempFile.GetPath( wxPATH_NO_SEPARATOR ).AfterLast( tempFile.GetPathSeparator() ) );
548 tempFile.Rmdir( wxPATH_RMDIR_RECURSIVE );
551 if( aProgressReporter )