diff --git a/common/jobs/job_dispatcher.cpp b/common/jobs/job_dispatcher.cpp index e2e5eb1959..2600aba429 100644 --- a/common/jobs/job_dispatcher.cpp +++ b/common/jobs/job_dispatcher.cpp @@ -42,16 +42,26 @@ void JOB_DISPATCHER::Register( const std::string& aJobTypeName, } -int JOB_DISPATCHER::RunJob( JOB* job ) +int JOB_DISPATCHER::RunJob( JOB* job, REPORTER* aReporter ) { + int result = CLI::EXIT_CODES::ERR_UNKNOWN; + REPORTER* existingReporter = m_reporter; + + if( aReporter ) + { + m_reporter = aReporter; + } + job->ClearExistingOutputs(); if( m_jobHandlers.count( job->GetType() ) ) { - return m_jobHandlers[job->GetType()]( job ); + result = m_jobHandlers[job->GetType()]( job ); } - return CLI::EXIT_CODES::ERR_UNKNOWN; + m_reporter = existingReporter; + + return result; } diff --git a/common/jobs/job_dispatcher.h b/common/jobs/job_dispatcher.h index d6368488e1..91c0e9ab26 100644 --- a/common/jobs/job_dispatcher.h +++ b/common/jobs/job_dispatcher.h @@ -38,7 +38,7 @@ public: JOB_DISPATCHER( KIWAY* aKiway ); void Register( const std::string& aJobTypeName, std::function aHandler, std::function aConfigHandler ); - int RunJob( JOB* aJob ); + int RunJob( JOB* aJob, REPORTER* aReporter ); bool HandleJobConfig( JOB* aJob, wxWindow* aParent ); void SetReporter( REPORTER* aReporter ); void SetProgressReporter( PROGRESS_REPORTER* aReporter ); diff --git a/common/jobs/jobset.cpp b/common/jobs/jobset.cpp index 8ad2596ef6..e74956e4e7 100644 --- a/common/jobs/jobset.cpp +++ b/common/jobs/jobset.cpp @@ -92,7 +92,9 @@ KICOMMON_API void from_json( const nlohmann::json& j, JOBSET_OUTPUT& f ) JOBSET_OUTPUT::JOBSET_OUTPUT() : m_type( JOBSET_OUTPUT_TYPE::FOLDER ), - m_lastRunSuccess() + m_outputHandler( nullptr ), + m_lastRunSuccess(), + m_lastRunReporters() { } @@ -100,12 +102,24 @@ JOBSET_OUTPUT::JOBSET_OUTPUT() : JOBSET_OUTPUT::JOBSET_OUTPUT( wxString id, JOBSET_OUTPUT_TYPE type ) : m_id( id ), m_type( type ), - m_lastRunSuccess() + m_outputHandler( nullptr ), + m_lastRunSuccess(), + m_lastRunReporters() { InitOutputHandler(); } +JOBSET_OUTPUT::~JOBSET_OUTPUT() +{ + for( auto& reporter : m_lastRunReporters ) + { + delete reporter.second; + } + m_lastRunReporters.clear(); +} + + void JOBSET_OUTPUT::InitOutputHandler() { if( m_type == JOBSET_OUTPUT_TYPE::FOLDER ) diff --git a/common/jobs/jobset.h b/common/jobs/jobset.h index a460da0dde..81d03972d7 100644 --- a/common/jobs/jobset.h +++ b/common/jobs/jobset.h @@ -28,6 +28,8 @@ #include #include +class REPORTER; + struct KICOMMON_API JOBSET_JOB { JOBSET_JOB() : m_job( nullptr ) {} @@ -53,6 +55,8 @@ struct KICOMMON_API JOBSET_OUTPUT JOBSET_OUTPUT( wxString id, JOBSET_OUTPUT_TYPE type ); + ~JOBSET_OUTPUT(); + void InitOutputHandler(); wxString m_id; @@ -63,6 +67,7 @@ struct KICOMMON_API JOBSET_OUTPUT ///< Transient property, not stored for now std::optional m_lastRunSuccess; std::unordered_map> m_lastRunSuccessMap; + std::unordered_map m_lastRunReporters; bool operator==( const JOBSET_OUTPUT& rhs ) const; diff --git a/common/kiway.cpp b/common/kiway.cpp index c9082e14c7..fae067baf0 100644 --- a/common/kiway.cpp +++ b/common/kiway.cpp @@ -706,11 +706,11 @@ bool KIWAY::ProcessEvent( wxEvent& aEvent ) } -int KIWAY::ProcessJob( KIWAY::FACE_T aFace, JOB* job ) +int KIWAY::ProcessJob( KIWAY::FACE_T aFace, JOB* job, REPORTER* aReporter ) { KIFACE* kiface = KiFACE( aFace ); - return kiface->HandleJob( job ); + return kiface->HandleJob( job, aReporter ); } diff --git a/eeschema/eeschema.cpp b/eeschema/eeschema.cpp index c654f0dba3..92a2ff215a 100644 --- a/eeschema/eeschema.cpp +++ b/eeschema/eeschema.cpp @@ -344,7 +344,7 @@ static struct IFACE : public KIFACE_BASE, public UNITS_PROVIDER const wxString& aSrcFilePath, wxString& aErrors ) override; - int HandleJob( JOB* aJob ) override; + int HandleJob( JOB* aJob, REPORTER* aReporter ) override; bool HandleJobConfig( JOB* aJob, wxWindow* aParent ) override; @@ -685,9 +685,9 @@ void IFACE::SaveFileAs( const wxString& aProjectBasePath, const wxString& aProje } -int IFACE::HandleJob( JOB* aJob ) +int IFACE::HandleJob( JOB* aJob, REPORTER* aReporter ) { - return m_jobHandler->RunJob( aJob ); + return m_jobHandler->RunJob( aJob, aReporter ); } diff --git a/include/kiway.h b/include/kiway.h index dbbdfd1564..b888933845 100644 --- a/include/kiway.h +++ b/include/kiway.h @@ -133,6 +133,7 @@ class KIWAY_PLAYER; class wxTopLevelWindow; class TOOL_ACTION; class JOB; +class REPORTER; /** @@ -241,7 +242,7 @@ struct KIFACE */ virtual void GetActions( std::vector& aActions ) const = 0; - virtual int HandleJob( JOB* aJob ) + virtual int HandleJob( JOB* aJob, REPORTER* aReporter ) { return 0; } @@ -431,7 +432,7 @@ public: bool ProcessEvent( wxEvent& aEvent ) override; - int ProcessJob( KIWAY::FACE_T aFace, JOB* aJob ); + int ProcessJob( KIWAY::FACE_T aFace, JOB* aJob, REPORTER* aReporter = nullptr ); bool ProcessJobConfigDialog( KIWAY::FACE_T aFace, JOB* aJob, wxWindow* aWindow ); /** diff --git a/kicad/dialogs/panel_jobs.cpp b/kicad/dialogs/panel_jobs.cpp index cd212217a8..5af565f65f 100644 --- a/kicad/dialogs/panel_jobs.cpp +++ b/kicad/dialogs/panel_jobs.cpp @@ -225,7 +225,9 @@ public: DIALOG_OUTPUT_RUN_RESULTS( wxWindow* aParent, JOBSET* aJobsFile, JOBSET_OUTPUT* aOutput ) : - DIALOG_OUTPUT_RUN_RESULTS_BASE( aParent ) + DIALOG_OUTPUT_RUN_RESULTS_BASE( aParent ), + m_jobsFile( aJobsFile ), + m_output( aOutput ) { m_staticTextOutputName->SetLabel( aOutput->m_outputHandler->GetOutputPath() ); @@ -264,6 +266,33 @@ public: } } + + virtual void OnJobListItemSelected( wxListEvent& event ) override + { + int itemIndex = event.GetIndex(); + + std::vector jobs = m_jobsFile->GetJobsForOutput( m_output ); + + if( itemIndex < jobs.size() ) + { + JOBSET_JOB& job = jobs[itemIndex]; + if( m_output->m_lastRunReporters.contains( job.m_id ) ) + { + WX_STRING_REPORTER* reporter = + static_cast( m_output->m_lastRunReporters[job.m_id] ); + m_textCtrlOutput->SetValue( reporter->GetMessages() ); + } + else + { + m_textCtrlOutput->SetValue( _( "No output available" ) ); + } + } + + } + +private: + JOBSET* m_jobsFile; + JOBSET_OUTPUT* m_output; }; diff --git a/kicad/dialogs/panel_jobs_base.cpp b/kicad/dialogs/panel_jobs_base.cpp index 72c1cae6a5..8f8cca56db 100644 --- a/kicad/dialogs/panel_jobs_base.cpp +++ b/kicad/dialogs/panel_jobs_base.cpp @@ -362,6 +362,9 @@ DIALOG_OUTPUT_RUN_RESULTS_BASE::DIALOG_OUTPUT_RUN_RESULTS_BASE( wxWindow* parent m_jobList = new wxListCtrl( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_REPORT|wxLC_SINGLE_SEL ); bSizer16->Add( m_jobList, 1, wxALL|wxEXPAND, 5 ); + m_textCtrlOutput = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_BESTWRAP|wxTE_MULTILINE|wxTE_READONLY ); + bSizer16->Add( m_textCtrlOutput, 1, wxALL|wxEXPAND, 5 ); + bMainSizer->Add( bSizer16, 1, wxEXPAND, 5 ); @@ -380,12 +383,14 @@ DIALOG_OUTPUT_RUN_RESULTS_BASE::DIALOG_OUTPUT_RUN_RESULTS_BASE( wxWindow* parent this->Centre( wxBOTH ); // Connect Events + m_jobList->Connect( wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler( DIALOG_OUTPUT_RUN_RESULTS_BASE::OnJobListItemSelected ), NULL, this ); m_sdbSizerOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_OUTPUT_RUN_RESULTS_BASE::OnButtonOk ), NULL, this ); } DIALOG_OUTPUT_RUN_RESULTS_BASE::~DIALOG_OUTPUT_RUN_RESULTS_BASE() { // Disconnect Events + m_jobList->Disconnect( wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler( DIALOG_OUTPUT_RUN_RESULTS_BASE::OnJobListItemSelected ), NULL, this ); m_sdbSizerOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_OUTPUT_RUN_RESULTS_BASE::OnButtonOk ), NULL, this ); } diff --git a/kicad/dialogs/panel_jobs_base.fbp b/kicad/dialogs/panel_jobs_base.fbp index 82d74703e8..9dc7c83f7b 100644 --- a/kicad/dialogs/panel_jobs_base.fbp +++ b/kicad/dialogs/panel_jobs_base.fbp @@ -2487,7 +2487,7 @@ - + bMainSizer wxVERTICAL @@ -2554,11 +2554,11 @@ -1 - + 5 wxEXPAND 1 - + bSizer16 wxHORIZONTAL @@ -2624,6 +2624,72 @@ + OnJobListItemSelected + + + + 5 + wxALL|wxEXPAND + 1 + + 1 + 1 + 1 + 1 + 0 + + 0 + 0 + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 0 + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + 0 + + 0 + + 1 + m_textCtrlOutput + 1 + + + protected + 1 + + Resizable + 1 + + wxTE_BESTWRAP|wxTE_MULTILINE|wxTE_READONLY + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + diff --git a/kicad/dialogs/panel_jobs_base.h b/kicad/dialogs/panel_jobs_base.h index 70a9a92c7f..938ddc5ef3 100644 --- a/kicad/dialogs/panel_jobs_base.h +++ b/kicad/dialogs/panel_jobs_base.h @@ -180,10 +180,12 @@ class DIALOG_OUTPUT_RUN_RESULTS_BASE : public DIALOG_SHIM protected: wxStaticText* m_staticTextOutputName; wxListCtrl* m_jobList; + wxTextCtrl* m_textCtrlOutput; wxStdDialogButtonSizer* m_sdbSizer; wxButton* m_sdbSizerOK; // Virtual event handlers, override them in your derived class + virtual void OnJobListItemSelected( wxListEvent& event ) { event.Skip(); } virtual void OnButtonOk( wxCommandEvent& event ) { event.Skip(); } diff --git a/kicad/jobs_runner.cpp b/kicad/jobs_runner.cpp index f4ff03ce92..aa7906a75d 100644 --- a/kicad/jobs_runner.cpp +++ b/kicad/jobs_runner.cpp @@ -100,6 +100,12 @@ bool JOBS_RUNNER::RunJobsForOutput( JOBSET_OUTPUT* aOutput, bool aBail ) aOutput->m_lastRunSuccessMap.clear(); + for( auto& reporter : aOutput->m_lastRunReporters ) + { + delete reporter.second; + } + aOutput->m_lastRunReporters.clear(); + wxString tempDirPath = tmp.GetFullPath(); if( !wxFileName::Mkdir( tempDirPath, wxS_DIR_DEFAULT ) ) { @@ -131,7 +137,7 @@ bool JOBS_RUNNER::RunJobsForOutput( JOBSET_OUTPUT* aOutput, bool aBail ) { msg += wxT( "|--------------------------------\n" ); msg += wxT( "| " ); - msg += wxString::Format( "Performing jobs" ); + msg += wxString::Format( "Performing jobs for output %s", aOutput->m_id ); msg += wxT( "\n" ); msg += wxT( "|--------------------------------\n" ); @@ -172,10 +178,17 @@ bool JOBS_RUNNER::RunJobsForOutput( JOBSET_OUTPUT* aOutput, bool aBail ) job.m_job->SetTempOutputDirectory( tempDirPath ); + REPORTER* reporterToUse = m_reporter; + if( !reporterToUse || reporterToUse == &NULL_REPORTER::GetInstance() ) + { + reporterToUse = new WX_STRING_REPORTER; + aOutput->m_lastRunReporters[job.m_id] = reporterToUse; + } + int result = 0; if( iface < KIWAY::KIWAY_FACE_COUNT ) { - result = m_kiway->ProcessJob( iface, job.m_job.get() ); + result = m_kiway->ProcessJob( iface, job.m_job.get(), reporterToUse ); } else { diff --git a/pcbnew/pcbnew.cpp b/pcbnew/pcbnew.cpp index d1ecc8f7f2..5bc04116bd 100644 --- a/pcbnew/pcbnew.cpp +++ b/pcbnew/pcbnew.cpp @@ -336,7 +336,7 @@ static struct IFACE : public KIFACE_BASE, public UNITS_PROVIDER const wxString& aNewProjectBasePath, const wxString& aNewProjectName, const wxString& aSrcFilePath, wxString& aErrors ) override; - int HandleJob( JOB* aJob ) override; + int HandleJob( JOB* aJob, REPORTER* aReporter ) override; bool HandleJobConfig( JOB* aJob, wxWindow* aParent ) override; @@ -568,9 +568,9 @@ void IFACE::SaveFileAs( const wxString& aProjectBasePath, const wxString& aSrcPr } -int IFACE::HandleJob( JOB* aJob ) +int IFACE::HandleJob( JOB* aJob, REPORTER* aReporter ) { - return m_jobHandler->RunJob( aJob ); + return m_jobHandler->RunJob( aJob, aReporter ); } diff --git a/pcbnew/pcbnew_jobs_handler.cpp b/pcbnew/pcbnew_jobs_handler.cpp index 6ca227848f..99c22b38c9 100644 --- a/pcbnew/pcbnew_jobs_handler.cpp +++ b/pcbnew/pcbnew_jobs_handler.cpp @@ -347,6 +347,7 @@ int PCBNEW_JOBS_HANDLER::JobExportStep( JOB* aJob ) case JOB_EXPORT_PCB_3D::FORMAT::STL: fn.SetExt( FILEEXT::StlFileExtension ); break; default: + m_reporter->Report( _( "Unknown export format" ), RPT_SEVERITY_ERROR ); return CLI::EXIT_CODES::ERR_UNKNOWN; // shouldnt have gotten here } @@ -421,6 +422,7 @@ int PCBNEW_JOBS_HANDLER::JobExportStep( JOB* aJob ) params.m_Format = EXPORTER_STEP_PARAMS::FORMAT::STL; break; default: + m_reporter->Report( _( "Unknown export format" ), RPT_SEVERITY_ERROR ); return CLI::EXIT_CODES::ERR_UNKNOWN; // shouldnt have gotten here }