summaryrefslogtreecommitdiff
path: root/ui/gui_status_handler.cpp
diff options
context:
space:
mode:
authorDaniel Wilhelm <daniel@wili.li>2014-04-18 17:28:01 +0200
committerDaniel Wilhelm <daniel@wili.li>2014-04-18 17:28:01 +0200
commitfe9eb89ebc1b3c33cbac00a3fa095a14faef9113 (patch)
tree8a3bb620a9acb83fe0057061a86e8f2cb91a9fe1 /ui/gui_status_handler.cpp
parent5.21 (diff)
downloadFreeFileSync-fe9eb89ebc1b3c33cbac00a3fa095a14faef9113.tar.gz
FreeFileSync-fe9eb89ebc1b3c33cbac00a3fa095a14faef9113.tar.bz2
FreeFileSync-fe9eb89ebc1b3c33cbac00a3fa095a14faef9113.zip
5.22
Diffstat (limited to 'ui/gui_status_handler.cpp')
-rw-r--r--ui/gui_status_handler.cpp160
1 files changed, 100 insertions, 60 deletions
diff --git a/ui/gui_status_handler.cpp b/ui/gui_status_handler.cpp
index 0816f2f1..f161b87b 100644
--- a/ui/gui_status_handler.cpp
+++ b/ui/gui_status_handler.cpp
@@ -5,15 +5,16 @@
// **************************************************************************
#include "gui_status_handler.h"
+#include <zen/shell_execute.h>
+#include <wx/app.h>
#include <wx/wupdlock.h>
-#include <wx+/shell_execute.h>
#include <wx+/bitmap_button.h>
-#include <wx/app.h>
-#include "msg_popup.h"
+#include <wx+/popup_dlg.h>
#include "main_dlg.h"
#include "exec_finished_box.h"
#include "../lib/generate_logfile.h"
#include "../lib/resolve_path.h"
+#include "../lib/status_handler_impl.h"
using namespace zen;
using namespace xmlAccess;
@@ -24,7 +25,9 @@ CompareStatusHandler::CompareStatusHandler(MainDialog& dlg) :
ignoreErrors(false)
{
{
- wxWindowUpdateLocker dummy(&mainDlg); //avoid display distortion
+#ifdef ZEN_WIN
+ wxWindowUpdateLocker dummy(&mainDlg); //leads to GUI corruption problems on Linux/OS X!
+#endif
//display status panel during compare
mainDlg.compareStatus->init(*this); //clear old values before showing panel
@@ -78,7 +81,9 @@ void CompareStatusHandler::initNewPhase(int objectsTotal, Int64 dataTotal, Phase
break;
case PHASE_COMPARING_CONTENT:
{
- wxWindowUpdateLocker dummy(&mainDlg);
+#ifdef ZEN_WIN
+ wxWindowUpdateLocker dummy(&mainDlg); //leads to GUI corruption problems on Linux/OS X!
+#endif
mainDlg.compareStatus->switchToCompareBytewise();
mainDlg.Layout(); //show progress bar...
mainDlg.Refresh(); //remove distortion...
@@ -88,27 +93,32 @@ void CompareStatusHandler::initNewPhase(int objectsTotal, Int64 dataTotal, Phase
}
-ProcessCallback::Response CompareStatusHandler::reportError(const std::wstring& message)
+ProcessCallback::Response CompareStatusHandler::reportError(const std::wstring& errorMessage, size_t retryNumber)
{
+ //no need to implement auto-retry here: 1. user is watching 2. comparison is fast
+ //=> similar behavior like "ignoreErrors" which does not honor sync settings
+
if (ignoreErrors)
return ProcessCallback::IGNORE_ERROR;
forceUiRefresh();
bool ignoreNextErrors = false;
- switch (showErrorDlg(&mainDlg,
- ReturnErrorDlg::BUTTON_IGNORE | ReturnErrorDlg::BUTTON_RETRY | ReturnErrorDlg::BUTTON_CANCEL,
- message, &ignoreNextErrors))
+ switch (showConfirmationDialog3(&mainDlg, DialogInfoType::ERROR2, PopupDialogCfg3().
+ setDetailInstructions(errorMessage).
+ setCheckBox(ignoreNextErrors, _("&Ignore subsequent errors"), ConfirmationButton3::DONT_DO_IT),
+ _("&Ignore"), _("&Retry")))
{
- case ReturnErrorDlg::BUTTON_IGNORE:
+ case ConfirmationButton3::DO_IT: //ignore
ignoreErrors = ignoreNextErrors;
return ProcessCallback::IGNORE_ERROR;
- case ReturnErrorDlg::BUTTON_RETRY:
+ case ConfirmationButton3::DONT_DO_IT: //retry
return ProcessCallback::RETRY;
- case ReturnErrorDlg::BUTTON_CANCEL:
+ case ConfirmationButton3::CANCEL:
abortThisProcess();
+ break;
}
assert(false);
@@ -119,8 +129,7 @@ ProcessCallback::Response CompareStatusHandler::reportError(const std::wstring&
void CompareStatusHandler::reportFatalError(const std::wstring& errorMessage)
{
forceUiRefresh();
-
- showFatalErrorDlg(&mainDlg, ReturnFatalErrorDlg::BUTTON_CANCEL, errorMessage, nullptr);
+ showNotificationDialog(&mainDlg, DialogInfoType::ERROR2, PopupDialogCfg().setTitle(_("Serious Error")).setDetailInstructions(errorMessage));
}
@@ -133,17 +142,15 @@ void CompareStatusHandler::reportWarning(const std::wstring& warningMessage, boo
//show pop-up and ask user how to handle warning
bool dontWarnAgain = false;
- switch (showWarningDlg(&mainDlg,
- ReturnWarningDlg::BUTTON_IGNORE | ReturnWarningDlg::BUTTON_CANCEL,
- warningMessage, dontWarnAgain))
+ switch (showConfirmationDialog(&mainDlg, DialogInfoType::WARNING,
+ PopupDialogCfg().setDetailInstructions(warningMessage).
+ setCheckBox(dontWarnAgain, _("&Don't show this warning again")),
+ _("&Ignore")))
{
- case ReturnWarningDlg::BUTTON_IGNORE:
+ case ConfirmationButton::DO_IT:
warningActive = !dontWarnAgain;
break;
-
- case ReturnWarningDlg::BUTTON_SWITCH:
- assert(false);
- case ReturnWarningDlg::BUTTON_CANCEL:
+ case ConfirmationButton::CANCEL:
abortThisProcess();
break;
}
@@ -173,12 +180,16 @@ void CompareStatusHandler::abortThisProcess()
SyncStatusHandler::SyncStatusHandler(wxFrame* parentDlg,
size_t lastSyncsLogFileSizeMax,
OnGuiError handleError,
+ size_t automaticRetryCount,
+ size_t automaticRetryDelay,
const std::wstring& jobName,
const std::wstring& execWhenFinished,
std::vector<std::wstring>& execFinishedHistory) :
progressDlg(createProgressDialog(*this, [this] { this->onProgressDialogTerminate(); }, *this, parentDlg, true, jobName, execWhenFinished, execFinishedHistory)),
lastSyncsLogFileSizeMax_(lastSyncsLogFileSizeMax),
handleError_(handleError),
+ automaticRetryCount_(automaticRetryCount),
+ automaticRetryDelay_(automaticRetryDelay),
jobName_(jobName)
{
totalTime.Start(); //measure total time
@@ -187,6 +198,33 @@ SyncStatusHandler::SyncStatusHandler(wxFrame* parentDlg,
SyncStatusHandler::~SyncStatusHandler()
{
+ //------------ "on completion" command conceptually is part of the sync, not cleanup --------------------------------------
+
+ //decide whether to stay on status screen or exit immediately...
+ bool showFinalResults = true;
+
+ if (progressDlg)
+ {
+ //execute "on completion" command (even in case of ignored errors)
+ if (!abortIsRequested()) //if aborted (manually), we don't execute the command
+ {
+ const std::wstring finalCommand = progressDlg->getExecWhenFinishedCommand(); //final value (after possible user modification)
+ if (!finalCommand.empty())
+ {
+ if (isCloseProgressDlgCommand(finalCommand))
+ showFinalResults = false; //take precedence over current visibility status
+ else
+ try
+ {
+ tryReportingError([&] { shellExecute2(expandMacros(utfCvrtTo<Zstring>(finalCommand)), EXEC_TYPE_SYNC); }, //throw FileError, throw X?
+ *this);
+ }
+ catch (...) {}
+ }
+ }
+ }
+ //------------ end of sync: begin of cleanup --------------------------------------
+
const int totalErrors = errorLog.getItemCount(TYPE_ERROR | TYPE_FATAL_ERROR); //evaluate before finalizing log
const int totalWarnings = errorLog.getItemCount(TYPE_WARNING);
@@ -194,7 +232,7 @@ SyncStatusHandler::~SyncStatusHandler()
std::wstring finalStatus;
if (abortIsRequested())
{
- finalStatus = _("Synchronization aborted");
+ finalStatus = _("Synchronization stopped");
errorLog.logMsg(finalStatus, TYPE_ERROR);
}
else if (totalErrors > 0)
@@ -233,20 +271,6 @@ SyncStatusHandler::~SyncStatusHandler()
if (progressDlg)
{
- bool showFinalResults = true;
- //execute "on completion" command (even in case of ignored errors)
- if (!abortIsRequested()) //if aborted (manually), we don't execute the command
- {
- const std::wstring finalCommand = progressDlg->getExecWhenFinishedCommand(); //final value (after possible user modification)
- if (!finalCommand.empty())
- {
- if (isCloseProgressDlgCommand(finalCommand))
- showFinalResults = false; //take precedence over current visibility status
- else
- shellExecute(expandMacros(utfCvrtTo<Zstring>(finalCommand)));
- }
- }
-
//notify to progressDlg that current process has ended
if (showFinalResults)
{
@@ -299,8 +323,25 @@ void SyncStatusHandler::reportInfo(const std::wstring& text)
}
-ProcessCallback::Response SyncStatusHandler::reportError(const std::wstring& errorMessage)
+ProcessCallback::Response SyncStatusHandler::reportError(const std::wstring& errorMessage, size_t retryNumber)
{
+ //auto-retry
+ if (retryNumber < automaticRetryCount_)
+ {
+ errorLog.logMsg(errorMessage + L"\n=> " +
+ _P("Automatic retry in 1 second...", "Automatic retry in %x seconds...", automaticRetryDelay_), TYPE_INFO);
+ //delay
+ const int iterations = static_cast<int>(1000 * automaticRetryDelay_ / UI_UPDATE_INTERVAL); //always round down: don't allow for negative remaining time below
+ for (int i = 0; i < iterations; ++i)
+ {
+ reportStatus(_("Error") + L": " + _P("Automatic retry in 1 second...", "Automatic retry in %x seconds...",
+ (1000 * automaticRetryDelay_ - i * UI_UPDATE_INTERVAL + 999) / 1000)); //integer round up
+ boost::this_thread::sleep(boost::posix_time::milliseconds(UI_UPDATE_INTERVAL));
+ }
+ return ProcessCallback::RETRY;
+ }
+
+
//always, except for "retry":
zen::ScopeGuard guardWriteLog = zen::makeGuard([&] { errorLog.logMsg(errorMessage, TYPE_ERROR); });
@@ -313,22 +354,22 @@ ProcessCallback::Response SyncStatusHandler::reportError(const std::wstring& err
forceUiRefresh();
bool ignoreNextErrors = false;
- switch (showErrorDlg(progressDlg->getWindowIfVisible(),
- ReturnErrorDlg::BUTTON_IGNORE | ReturnErrorDlg::BUTTON_RETRY | ReturnErrorDlg::BUTTON_CANCEL,
- errorMessage,
- &ignoreNextErrors))
+ switch (showConfirmationDialog3(progressDlg->getWindowIfVisible(), DialogInfoType::ERROR2, PopupDialogCfg3().
+ setDetailInstructions(errorMessage).
+ setCheckBox(ignoreNextErrors, _("&Ignore subsequent errors"), ConfirmationButton3::DONT_DO_IT),
+ _("&Ignore"), _("&Retry")))
{
- case ReturnErrorDlg::BUTTON_IGNORE:
+ case ConfirmationButton3::DO_IT: //ignore
if (ignoreNextErrors) //falsify only
handleError_ = ON_GUIERROR_IGNORE;
return ProcessCallback::IGNORE_ERROR;
- case ReturnErrorDlg::BUTTON_RETRY:
+ case ConfirmationButton3::DONT_DO_IT: //retry
guardWriteLog.dismiss();
- errorLog.logMsg(_("Retrying operation after error:") + L" " + errorMessage, TYPE_INFO); //explain why there are duplicate "doing operation X" info messages in the log!
+ errorLog.logMsg(errorMessage + L"\n=> " + _("Retrying operation..."), TYPE_INFO); //explain why there are duplicate "doing operation X" info messages in the log!
return ProcessCallback::RETRY;
- case ReturnErrorDlg::BUTTON_CANCEL:
+ case ConfirmationButton3::CANCEL:
abortThisProcess();
break;
}
@@ -357,16 +398,17 @@ void SyncStatusHandler::reportFatalError(const std::wstring& errorMessage)
forceUiRefresh();
bool ignoreNextErrors = false;
- switch (showFatalErrorDlg(progressDlg->getWindowIfVisible(),
- ReturnFatalErrorDlg::BUTTON_IGNORE | ReturnFatalErrorDlg::BUTTON_CANCEL,
- errorMessage, &ignoreNextErrors))
+ switch (showConfirmationDialog(progressDlg->getWindowIfVisible(), DialogInfoType::ERROR2,
+ PopupDialogCfg().setTitle(_("Serious Error")).
+ setDetailInstructions(errorMessage).
+ setCheckBox(ignoreNextErrors, _("&Ignore subsequent errors")),
+ _("&Ignore")))
{
- case ReturnFatalErrorDlg::BUTTON_IGNORE:
+ case ConfirmationButton::DO_IT:
if (ignoreNextErrors) //falsify only
handleError_ = ON_GUIERROR_IGNORE;
break;
-
- case ReturnFatalErrorDlg::BUTTON_CANCEL:
+ case ConfirmationButton::CANCEL:
abortThisProcess();
break;
}
@@ -395,17 +437,15 @@ void SyncStatusHandler::reportWarning(const std::wstring& warningMessage, bool&
forceUiRefresh();
bool dontWarnAgain = false;
- switch (showWarningDlg(progressDlg->getWindowIfVisible(),
- ReturnWarningDlg::BUTTON_IGNORE | ReturnWarningDlg::BUTTON_CANCEL,
- warningMessage, dontWarnAgain))
+ switch (showConfirmationDialog(progressDlg->getWindowIfVisible(), DialogInfoType::WARNING,
+ PopupDialogCfg().setDetailInstructions(warningMessage).
+ setCheckBox(dontWarnAgain, _("&Don't show this warning again")),
+ _("&Ignore")))
{
- case ReturnWarningDlg::BUTTON_IGNORE: //no unhandled error situation!
+ case ConfirmationButton::DO_IT:
warningActive = !dontWarnAgain;
break;
-
- case ReturnWarningDlg::BUTTON_SWITCH:
- assert(false);
- case ReturnWarningDlg::BUTTON_CANCEL:
+ case ConfirmationButton::CANCEL:
abortThisProcess();
break;
}
bgstack15