diff options
Diffstat (limited to 'ui/batch_status_handler.cpp')
-rw-r--r-- | ui/batch_status_handler.cpp | 128 |
1 files changed, 78 insertions, 50 deletions
diff --git a/ui/batch_status_handler.cpp b/ui/batch_status_handler.cpp index 0edd289f..e06a0000 100644 --- a/ui/batch_status_handler.cpp +++ b/ui/batch_status_handler.cpp @@ -38,7 +38,8 @@ private: virtual std::shared_ptr<TraverseCallback> onDir (const Zchar* shortName, const Zstring& fullName) { return nullptr; } //DON'T traverse into subdirs virtual HandleLink onSymlink(const Zchar* shortName, const Zstring& fullName, const SymlinkInfo& details) { return LINK_SKIP; } - virtual HandleError onError (const std::wstring& msg) { assert(false); return ON_ERROR_IGNORE; } //errors are not really critical in this context + virtual HandleError reportDirError (const std::wstring& msg) { assert(false); return ON_ERROR_IGNORE; } //errors are not really critical in this context + virtual HandleError reportItemError(const std::wstring& msg, const Zchar* shortName) { assert(false); return ON_ERROR_IGNORE; } // const Zstring prefix_; std::vector<Zstring>& logfiles_; @@ -112,13 +113,14 @@ BatchStatusHandler::BatchStatusHandler(bool showProgress, lastSyncsLogFileSizeMax_(lastSyncsLogFileSizeMax), handleError_(handleError), returnCode_(returnCode), - syncStatusFrame(*this, *this, nullptr, showProgress, jobName, execWhenFinished, execFinishedHistory), - jobName_(jobName) + progressDlg(createProgressDialog(*this, [this] { this->onProgressDialogTerminate(); }, *this, nullptr, showProgress, jobName, execWhenFinished, execFinishedHistory)), + jobName_(jobName) { if (logfilesCountLimit != 0) //init log file: starts internal timer! { - if (!tryReportingError([&] { logFile = prepareNewLogfile(logfileDirectory, jobName, timeStamp); }, //throw FileError; return value always bound! - *this)) + zen::Opt<std::wstring> errMsg = tryReportingError2([&] { logFile = prepareNewLogfile(logfileDirectory, jobName, timeStamp); }, //throw FileError; return value always bound! + *this); + if (errMsg) { raiseReturnCode(returnCode_, FFS_RC_ABORTED); throw BatchAbortProcess(); @@ -202,59 +204,73 @@ BatchStatusHandler::~BatchStatusHandler() } catch (FileError&) {} - //decide whether to stay on status screen or exit immediately... - if (switchToGuiRequested) //-> avoid recursive yield() calls, thous switch not before ending batch mode + if (progressDlg) { - try + //decide whether to stay on status screen or exit immediately... + if (switchToGuiRequested) //-> avoid recursive yield() calls, thous switch not before ending batch mode { - switchBatchToGui_.execute(); //open FreeFileSync GUI + try + { + switchBatchToGui_.execute(); //open FreeFileSync GUI + } + catch (...) {} + progressDlg->closeWindowDirectly(); //progressDlg is not main window anymore } - catch (...) {} - syncStatusFrame.closeWindowDirectly(); //syncStatusFrame is not main window anymore - } - else - { - if (syncStatusFrame.getAsWindow()->IsShown()) - showFinalResults = true; - - //execute "on completion" command (even in case of ignored errors) - if (!abortIsRequested()) //if aborted (manually), we don't execute the command + else { - const std::wstring finalCommand = syncStatusFrame.getExecWhenFinishedCommand(); //final value (after possible user modification) - if (isCloseProgressDlgCommand(finalCommand)) - showFinalResults = false; //take precedence over current visibility status - else if (!finalCommand.empty()) + if (progressDlg->getAsWindow()->IsShown()) + showFinalResults = true; + + //execute "on completion" command (even in case of ignored errors) + if (!abortIsRequested()) //if aborted (manually), we don't execute the command { - auto cmdexp = expandMacros(utfCvrtTo<Zstring>(finalCommand)); - shellExecute(cmdexp); + const std::wstring finalCommand = progressDlg->getExecWhenFinishedCommand(); //final value (after possible user modification) + if (isCloseProgressDlgCommand(finalCommand)) + showFinalResults = false; //take precedence over current visibility status + else if (!finalCommand.empty()) + { + auto cmdexp = expandMacros(utfCvrtTo<Zstring>(finalCommand)); + shellExecute(cmdexp); + } } + + if (showFinalResults) //warning: wxWindow::Show() is called within processHasFinished()! + { + //notify about (logical) application main window => program won't quit, but stay on this dialog + setMainWindow(progressDlg->getAsWindow()); + + //notify to progressDlg that current process has ended + if (abortIsRequested()) + progressDlg->processHasFinished(SyncProgressDialog::RESULT_ABORTED, errorLog); //enable okay and close events + else if (totalErrors > 0) + progressDlg->processHasFinished(SyncProgressDialog::RESULT_FINISHED_WITH_ERROR, errorLog); + else if (totalWarnings > 0) + progressDlg->processHasFinished(SyncProgressDialog::RESULT_FINISHED_WITH_WARNINGS, errorLog); + else + progressDlg->processHasFinished(SyncProgressDialog::RESULT_FINISHED_WITH_SUCCESS, errorLog); + } + else + progressDlg->closeWindowDirectly(); //progressDlg is main window => program will quit directly } - if (showFinalResults) //warning: wxWindow::Show() is called within processHasFinished()! + //wait until progress dialog notified shutdown via onProgressDialogTerminate() + //-> required since it has our "this" pointer captured in lambda "notifyWindowTerminate"! + //-> nicely manages dialog lifetime + while (progressDlg) { - //notify about (logical) application main window => program won't quit, but stay on this dialog - setMainWindow(syncStatusFrame.getAsWindow()); - - //notify to syncStatusFrame that current process has ended - if (abortIsRequested()) - syncStatusFrame.processHasFinished(SyncProgressDialog::RESULT_ABORTED, errorLog); //enable okay and close events - else if (totalErrors > 0) - syncStatusFrame.processHasFinished(SyncProgressDialog::RESULT_FINISHED_WITH_ERROR, errorLog); - else if (totalWarnings > 0) - syncStatusFrame.processHasFinished(SyncProgressDialog::RESULT_FINISHED_WITH_WARNINGS, errorLog); - else - syncStatusFrame.processHasFinished(SyncProgressDialog::RESULT_FINISHED_WITH_SUCCESS, errorLog); + boost::this_thread::sleep(boost::posix_time::milliseconds(UI_UPDATE_INTERVAL)); + updateUiNow(); } - else - syncStatusFrame.closeWindowDirectly(); //syncStatusFrame is main window => program will quit directly } } + void BatchStatusHandler::initNewPhase(int objectsTotal, Int64 dataTotal, ProcessCallback::Phase phaseID) { StatusHandler::initNewPhase(objectsTotal, dataTotal, phaseID); - syncStatusFrame.initNewPhase(); //call after "StatusHandler::initNewPhase" + if (progressDlg) + progressDlg->initNewPhase(); //call after "StatusHandler::initNewPhase" } @@ -262,7 +278,8 @@ void BatchStatusHandler::updateProcessedData(int objectsDelta, Int64 dataDelta) { StatusHandler::updateProcessedData(objectsDelta, dataDelta); - syncStatusFrame.notifyProgressChange(); //noexcept + if (progressDlg) + progressDlg->notifyProgressChange(); //noexcept //note: this method should NOT throw in order to properly allow undoing setting of statistics! } @@ -285,11 +302,12 @@ void BatchStatusHandler::reportWarning(const std::wstring& warningMessage, bool& { case xmlAccess::ON_ERROR_POPUP: { - PauseTimers dummy(syncStatusFrame); + if (!progressDlg) abortThisProcess(); + PauseTimers dummy(*progressDlg); forceUiRefresh(); bool dontWarnAgain = false; - switch (showWarningDlg(syncStatusFrame.getAsWindow(), + switch (showWarningDlg(progressDlg->getAsWindow(), ReturnWarningDlg::BUTTON_IGNORE | ReturnWarningDlg::BUTTON_SWITCH | ReturnWarningDlg::BUTTON_CANCEL, warningMessage + L"\n\n" + _("Press \"Switch\" to resolve issues in FreeFileSync main dialog."), dontWarnAgain)) @@ -329,11 +347,12 @@ ProcessCallback::Response BatchStatusHandler::reportError(const std::wstring& er { case xmlAccess::ON_ERROR_POPUP: { - PauseTimers dummy(syncStatusFrame); + if (!progressDlg) abortThisProcess(); + PauseTimers dummy(*progressDlg); forceUiRefresh(); bool ignoreNextErrors = false; - switch (showErrorDlg(syncStatusFrame.getAsWindow(), + switch (showErrorDlg(progressDlg->getAsWindow(), ReturnErrorDlg::BUTTON_IGNORE | ReturnErrorDlg::BUTTON_RETRY | ReturnErrorDlg::BUTTON_CANCEL, errorMessage, &ignoreNextErrors)) { @@ -373,11 +392,12 @@ void BatchStatusHandler::reportFatalError(const std::wstring& errorMessage) { case xmlAccess::ON_ERROR_POPUP: { - PauseTimers dummy(syncStatusFrame); + if (!progressDlg) abortThisProcess(); + PauseTimers dummy(*progressDlg); forceUiRefresh(); bool ignoreNextErrors = false; - switch (showFatalErrorDlg(syncStatusFrame.getAsWindow(), + switch (showFatalErrorDlg(progressDlg->getAsWindow(), ReturnFatalErrorDlg::BUTTON_IGNORE | ReturnFatalErrorDlg::BUTTON_CANCEL, errorMessage, &ignoreNextErrors)) { @@ -405,12 +425,20 @@ void BatchStatusHandler::reportFatalError(const std::wstring& errorMessage) void BatchStatusHandler::forceUiRefresh() { - syncStatusFrame.updateGui(); + if (progressDlg) + progressDlg->updateGui(); } void BatchStatusHandler::abortThisProcess() { requestAbortion(); //just make sure... - throw BatchAbortProcess(); //abort can be triggered by syncStatusFrame + throw BatchAbortProcess(); //abort can be triggered by progressDlg +} + + +void BatchStatusHandler::onProgressDialogTerminate() +{ + //it's responsibility of "progressDlg" to call requestAbortion() when closing dialog + progressDlg = nullptr; } |