summaryrefslogtreecommitdiff
path: root/ui/batch_status_handler.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'ui/batch_status_handler.cpp')
-rw-r--r--ui/batch_status_handler.cpp128
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;
}
bgstack15