diff --git a/pcbnew/exporters/gendrill_Excellon_writer.cpp b/pcbnew/exporters/gendrill_Excellon_writer.cpp index e9f5189a02..5c00d6c9f5 100644 --- a/pcbnew/exporters/gendrill_Excellon_writer.cpp +++ b/pcbnew/exporters/gendrill_Excellon_writer.cpp @@ -73,9 +73,10 @@ EXCELLON_WRITER::EXCELLON_WRITER( BOARD* aPcb ) } -void EXCELLON_WRITER::CreateDrillandMapFilesSet( const wxString& aPlotDirectory, bool aGenDrill, +bool EXCELLON_WRITER::CreateDrillandMapFilesSet( const wxString& aPlotDirectory, bool aGenDrill, bool aGenMap, REPORTER * aReporter ) { + bool success = true; wxFileName fn; wxString msg; @@ -116,6 +117,7 @@ void EXCELLON_WRITER::CreateDrillandMapFilesSet( const wxString& aPlotDirectory, { msg.Printf( _( "Failed to create file '%s'." ), fullFilename ); aReporter->Report( msg, RPT_SEVERITY_ERROR ); + success = false; } break; @@ -147,10 +149,12 @@ void EXCELLON_WRITER::CreateDrillandMapFilesSet( const wxString& aPlotDirectory, } if( aGenMap ) - CreateMapFilesSet( aPlotDirectory, aReporter ); + success &= CreateMapFilesSet( aPlotDirectory, aReporter ); if( aReporter ) aReporter->ReportTail( _( "Done." ), RPT_SEVERITY_INFO ); + + return success; } diff --git a/pcbnew/exporters/gendrill_Excellon_writer.h b/pcbnew/exporters/gendrill_Excellon_writer.h index 9911af6694..83a4f1ad7c 100644 --- a/pcbnew/exporters/gendrill_Excellon_writer.h +++ b/pcbnew/exporters/gendrill_Excellon_writer.h @@ -105,7 +105,7 @@ public: * @param aGenMap set to true to generate a drill map file. * @param aReporter is a #REPORTER to return activity or any message (can be NULL) */ - void CreateDrillandMapFilesSet( const wxString& aPlotDirectory, bool aGenDrill, bool aGenMap, + bool CreateDrillandMapFilesSet( const wxString& aPlotDirectory, bool aGenDrill, bool aGenMap, REPORTER* aReporter = nullptr ); private: diff --git a/pcbnew/exporters/gendrill_file_writer_base.cpp b/pcbnew/exporters/gendrill_file_writer_base.cpp index bea9a39e42..a532bab011 100644 --- a/pcbnew/exporters/gendrill_file_writer_base.cpp +++ b/pcbnew/exporters/gendrill_file_writer_base.cpp @@ -293,7 +293,7 @@ const wxString GENDRILL_WRITER_BASE::getDrillFileName( DRILL_LAYER_PAIR aPair, b return ret; } -void GENDRILL_WRITER_BASE::CreateMapFilesSet( const wxString& aPlotDirectory, +bool GENDRILL_WRITER_BASE::CreateMapFilesSet( const wxString& aPlotDirectory, REPORTER * aReporter ) { wxFileName fn; @@ -337,7 +337,7 @@ void GENDRILL_WRITER_BASE::CreateMapFilesSet( const wxString& aPlotDirectory, aReporter->Report( msg, RPT_SEVERITY_ERROR ); } - return; + return false; } else { @@ -349,6 +349,8 @@ void GENDRILL_WRITER_BASE::CreateMapFilesSet( const wxString& aPlotDirectory, } } } + + return true; } diff --git a/pcbnew/exporters/gendrill_file_writer_base.h b/pcbnew/exporters/gendrill_file_writer_base.h index e87d2f48d1..25c04bc62d 100644 --- a/pcbnew/exporters/gendrill_file_writer_base.h +++ b/pcbnew/exporters/gendrill_file_writer_base.h @@ -212,7 +212,7 @@ public: * @param aPlotDirectory is the output folder. * @param aReporter is a REPORTER to return activity or any message (can be NULL) */ - void CreateMapFilesSet( const wxString& aPlotDirectory, REPORTER* aReporter = nullptr ); + bool CreateMapFilesSet( const wxString& aPlotDirectory, REPORTER* aReporter = nullptr ); /** * Create a plain text report file giving a list of drill values and drill count for through diff --git a/pcbnew/exporters/gendrill_gerber_writer.cpp b/pcbnew/exporters/gendrill_gerber_writer.cpp index d4b3820245..649bc822f2 100644 --- a/pcbnew/exporters/gendrill_gerber_writer.cpp +++ b/pcbnew/exporters/gendrill_gerber_writer.cpp @@ -54,9 +54,10 @@ GERBER_WRITER::GERBER_WRITER( BOARD* aPcb ) } -void GERBER_WRITER::CreateDrillandMapFilesSet( const wxString& aPlotDirectory, bool aGenDrill, +bool GERBER_WRITER::CreateDrillandMapFilesSet( const wxString& aPlotDirectory, bool aGenDrill, bool aGenMap, REPORTER* aReporter ) { + bool success = true; // Note: In Gerber drill files, NPTH and PTH are always separate files m_merge_PTH_NPTH = false; @@ -100,6 +101,7 @@ void GERBER_WRITER::CreateDrillandMapFilesSet( const wxString& aPlotDirectory, b { msg.Printf( _( "Failed to create file '%s'." ), fullFilename ); aReporter->Report( msg, RPT_SEVERITY_ERROR ); + success = false; } break; @@ -118,10 +120,12 @@ void GERBER_WRITER::CreateDrillandMapFilesSet( const wxString& aPlotDirectory, b } if( aGenMap ) - CreateMapFilesSet( aPlotDirectory, aReporter ); + success &= CreateMapFilesSet( aPlotDirectory, aReporter ); if( aReporter ) aReporter->ReportTail( _( "Done." ), RPT_SEVERITY_INFO ); + + return success; } diff --git a/pcbnew/exporters/gendrill_gerber_writer.h b/pcbnew/exporters/gendrill_gerber_writer.h index c07d829c23..9ab3dd5fee 100644 --- a/pcbnew/exporters/gendrill_gerber_writer.h +++ b/pcbnew/exporters/gendrill_gerber_writer.h @@ -74,8 +74,10 @@ public: * @param aGenDrill set to true to generate the EXCELLON drill file. * @param aGenMap set to true to generate a drill map file. * @param aReporter is a #REPORTER to return activity or any message (can be NULL). + * + * @return True if successful, false if any error occurred */ - void CreateDrillandMapFilesSet( const wxString& aPlotDirectory, + bool CreateDrillandMapFilesSet( const wxString& aPlotDirectory, bool aGenDrill, bool aGenMap, REPORTER * aReporter = nullptr ); diff --git a/pcbnew/pcbnew_jobs_handler.cpp b/pcbnew/pcbnew_jobs_handler.cpp index be0f806dea..8e0c39390e 100644 --- a/pcbnew/pcbnew_jobs_handler.cpp +++ b/pcbnew/pcbnew_jobs_handler.cpp @@ -257,6 +257,7 @@ int PCBNEW_JOBS_HANDLER::JobExportPdf( JOB* aJob ) int PCBNEW_JOBS_HANDLER::JobExportGerbers( JOB* aJob ) { + int exitCode = CLI::EXIT_CODES::OK; JOB_EXPORT_PCB_GERBERS* aGerberJob = dynamic_cast( aJob ); if( aGerberJob == nullptr ) @@ -331,6 +332,11 @@ int PCBNEW_JOBS_HANDLER::JobExportGerbers( JOB* aJob ) PlotBoardLayers( brd, plotter, plotSequence, plotOpts ); plotter->EndPlot(); } + else + { + wxFprintf( stderr, _( "Failed to plot to '%s'.\n" ), fn.GetFullPath() ); + exitCode = CLI::EXIT_CODES::ERR_INVALID_OUTPUT_CONFLICT; + } delete plotter; } @@ -340,7 +346,7 @@ int PCBNEW_JOBS_HANDLER::JobExportGerbers( JOB* aJob ) BuildPlotFileName( &fn, aGerberJob->m_outputFile, wxT( "job" ), GerberJobFileExtension ); jobfile_writer.CreateJobFile( fn.GetFullPath() ); - return CLI::EXIT_CODES::OK; + return exitCode; } @@ -368,6 +374,7 @@ void PCBNEW_JOBS_HANDLER::populateGerberPlotOptionsFromJob( PCB_PLOT_PARAMS& int PCBNEW_JOBS_HANDLER::JobExportGerber( JOB* aJob ) { + int exitCode = CLI::EXIT_CODES::OK; JOB_EXPORT_PCB_GERBER* aGerberJob = dynamic_cast( aJob ); if( aGerberJob == nullptr ) @@ -402,10 +409,15 @@ int PCBNEW_JOBS_HANDLER::JobExportGerber( JOB* aJob ) plotOpts ); plotter->EndPlot(); } + else + { + wxFprintf( stderr, _( "Failed to plot to '%s'.\n" ), aGerberJob->m_outputFile ); + exitCode = CLI::EXIT_CODES::ERR_INVALID_OUTPUT_CONFLICT; + } delete plotter; - return CLI::EXIT_CODES::OK; + return exitCode; } static DRILL_PRECISION precisionListForInches( 2, 4 ); @@ -495,8 +507,11 @@ int PCBNEW_JOBS_HANDLER::JobExportDrill( JOB* aJob ) excellonWriter->SetRouteModeForOvalHoles( aDrillJob->m_excellonOvalDrillRoute ); excellonWriter->SetMapFileFormat( mapFormat ); - excellonWriter->CreateDrillandMapFilesSet( aDrillJob->m_outputDir, true, - aDrillJob->m_generateMap, nullptr ); + if( !excellonWriter->CreateDrillandMapFilesSet( aDrillJob->m_outputDir, true, + aDrillJob->m_generateMap, this ) ) + { + return CLI::EXIT_CODES::ERR_INVALID_OUTPUT_CONFLICT; + } } else if( aDrillJob->m_format == JOB_EXPORT_PCB_DRILL::DRILL_FORMAT::GERBER ) { @@ -512,8 +527,11 @@ int PCBNEW_JOBS_HANDLER::JobExportDrill( JOB* aJob ) gerberWriter->SetOptions( offset ); gerberWriter->SetMapFileFormat( mapFormat ); - gerberWriter->CreateDrillandMapFilesSet( aDrillJob->m_outputDir, true, - aDrillJob->m_generateMap, nullptr ); + if( !gerberWriter->CreateDrillandMapFilesSet( aDrillJob->m_outputDir, true, + aDrillJob->m_generateMap, this ) ) + { + return CLI::EXIT_CODES::ERR_INVALID_OUTPUT_CONFLICT; + } } return CLI::EXIT_CODES::OK; @@ -780,3 +798,14 @@ int PCBNEW_JOBS_HANDLER::doFpExportSvg( JOB_FP_EXPORT_SVG* aSvgJob, const FOOTPR return CLI::EXIT_CODES::OK; } + + +REPORTER& PCBNEW_JOBS_HANDLER::Report( const wxString& aText, SEVERITY aSeverity ) +{ + if( aSeverity == RPT_SEVERITY_ERROR ) + wxFprintf( stderr, wxS( "%s\n" ), aText ); + else + wxPrintf( wxS( "%s\n" ), aText ); + + return *this; +} \ No newline at end of file diff --git a/pcbnew/pcbnew_jobs_handler.h b/pcbnew/pcbnew_jobs_handler.h index 126ac87d78..33a45cd7cd 100644 --- a/pcbnew/pcbnew_jobs_handler.h +++ b/pcbnew/pcbnew_jobs_handler.h @@ -23,12 +23,13 @@ #include #include +#include class JOB_EXPORT_PCB_GERBER; class JOB_FP_EXPORT_SVG; class FOOTPRINT; -class PCBNEW_JOBS_HANDLER : public JOB_DISPATCHER +class PCBNEW_JOBS_HANDLER : public JOB_DISPATCHER, REPORTER { public: PCBNEW_JOBS_HANDLER(); @@ -43,6 +44,13 @@ public: int JobExportFpUpgrade( JOB* aJob ); int JobExportFpSvg( JOB* aJob ); + /* + * REPORTER INTERFACE + */ + REPORTER& Report( const wxString& aText, SEVERITY aSeverity = RPT_SEVERITY_UNDEFINED ) override; + + bool HasMessage() const override { return false; } + private: void populateGerberPlotOptionsFromJob( PCB_PLOT_PARAMS& aPlotOpts, JOB_EXPORT_PCB_GERBER* aJob );