summaryrefslogtreecommitdiff
path: root/ui/gui_status_handler.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'ui/gui_status_handler.cpp')
-rw-r--r--ui/gui_status_handler.cpp479
1 files changed, 0 insertions, 479 deletions
diff --git a/ui/gui_status_handler.cpp b/ui/gui_status_handler.cpp
deleted file mode 100644
index f161b87b..00000000
--- a/ui/gui_status_handler.cpp
+++ /dev/null
@@ -1,479 +0,0 @@
-// **************************************************************************
-// * This file is part of the FreeFileSync project. It is distributed under *
-// * GNU General Public License: http://www.gnu.org/licenses/gpl.html *
-// * Copyright (C) Zenju (zenju AT gmx DOT de) - All Rights Reserved *
-// **************************************************************************
-
-#include "gui_status_handler.h"
-#include <zen/shell_execute.h>
-#include <wx/app.h>
-#include <wx/wupdlock.h>
-#include <wx+/bitmap_button.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;
-
-
-CompareStatusHandler::CompareStatusHandler(MainDialog& dlg) :
- mainDlg(dlg),
- ignoreErrors(false)
-{
- {
-#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
- mainDlg.auiMgr.GetPane(mainDlg.compareStatus->getAsWindow()).Show();
- mainDlg.auiMgr.Update();
- }
-
- mainDlg.Update(); //don't wait until idle event!
-
- //register keys
- mainDlg.Connect(wxEVT_CHAR_HOOK, wxKeyEventHandler(CompareStatusHandler::OnKeyPressed), nullptr, this);
- mainDlg.m_buttonCancel->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CompareStatusHandler::OnAbortCompare), nullptr, this);
-}
-
-
-CompareStatusHandler::~CompareStatusHandler()
-{
- //unregister keys
- mainDlg.Disconnect(wxEVT_CHAR_HOOK, wxKeyEventHandler(CompareStatusHandler::OnKeyPressed), nullptr, this);
- mainDlg.m_buttonCancel->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CompareStatusHandler::OnAbortCompare), nullptr, this);
-
- mainDlg.compareStatus->finalize();
- mainDlg.auiMgr.GetPane(mainDlg.compareStatus->getAsWindow()).Hide();
- mainDlg.auiMgr.Update();
-}
-
-
-void CompareStatusHandler::OnKeyPressed(wxKeyEvent& event)
-{
- const int keyCode = event.GetKeyCode();
- if (keyCode == WXK_ESCAPE)
- {
- wxCommandEvent dummy;
- OnAbortCompare(dummy);
- }
-
- event.Skip();
-}
-
-
-void CompareStatusHandler::initNewPhase(int objectsTotal, Int64 dataTotal, Phase phaseID)
-{
- StatusHandler::initNewPhase(objectsTotal, dataTotal, phaseID);
-
- switch (currentPhase())
- {
- case PHASE_NONE:
- case PHASE_SYNCHRONIZING:
- assert(false);
- case PHASE_SCANNING:
- break;
- case PHASE_COMPARING_CONTENT:
- {
-#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...
- }
- break;
- }
-}
-
-
-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 (showConfirmationDialog3(&mainDlg, DialogInfoType::ERROR2, PopupDialogCfg3().
- setDetailInstructions(errorMessage).
- setCheckBox(ignoreNextErrors, _("&Ignore subsequent errors"), ConfirmationButton3::DONT_DO_IT),
- _("&Ignore"), _("&Retry")))
- {
- case ConfirmationButton3::DO_IT: //ignore
- ignoreErrors = ignoreNextErrors;
- return ProcessCallback::IGNORE_ERROR;
-
- case ConfirmationButton3::DONT_DO_IT: //retry
- return ProcessCallback::RETRY;
-
- case ConfirmationButton3::CANCEL:
- abortThisProcess();
- break;
- }
-
- assert(false);
- return ProcessCallback::IGNORE_ERROR; //dummy return value
-}
-
-
-void CompareStatusHandler::reportFatalError(const std::wstring& errorMessage)
-{
- forceUiRefresh();
- showNotificationDialog(&mainDlg, DialogInfoType::ERROR2, PopupDialogCfg().setTitle(_("Serious Error")).setDetailInstructions(errorMessage));
-}
-
-
-void CompareStatusHandler::reportWarning(const std::wstring& warningMessage, bool& warningActive)
-{
- if (!warningActive || ignoreErrors) //if errors are ignored, then warnings should also
- return;
-
- forceUiRefresh();
-
- //show pop-up and ask user how to handle warning
- bool dontWarnAgain = false;
- switch (showConfirmationDialog(&mainDlg, DialogInfoType::WARNING,
- PopupDialogCfg().setDetailInstructions(warningMessage).
- setCheckBox(dontWarnAgain, _("&Don't show this warning again")),
- _("&Ignore")))
- {
- case ConfirmationButton::DO_IT:
- warningActive = !dontWarnAgain;
- break;
- case ConfirmationButton::CANCEL:
- abortThisProcess();
- break;
- }
-}
-
-
-void CompareStatusHandler::forceUiRefresh()
-{
- mainDlg.compareStatus->updateStatusPanelNow();
-}
-
-
-void CompareStatusHandler::OnAbortCompare(wxCommandEvent& event)
-{
- requestAbortion();
-}
-
-
-void CompareStatusHandler::abortThisProcess()
-{
- requestAbortion(); //just make sure...
- throw GuiAbortProcess();
-}
-
-//########################################################################################################
-
-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
-}
-
-
-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);
-
- //finalize error log
- std::wstring finalStatus;
- if (abortIsRequested())
- {
- finalStatus = _("Synchronization stopped");
- errorLog.logMsg(finalStatus, TYPE_ERROR);
- }
- else if (totalErrors > 0)
- {
- finalStatus = _("Synchronization completed with errors");
- errorLog.logMsg(finalStatus, TYPE_ERROR);
- }
- else if (totalWarnings > 0)
- {
- finalStatus = _("Synchronization completed with warnings");
- errorLog.logMsg(finalStatus, TYPE_WARNING); //give status code same warning priority as display category!
- }
- else
- {
- if (getObjectsTotal(PHASE_SYNCHRONIZING) == 0 && //we're past "initNewPhase(PHASE_SYNCHRONIZING)" at this point!
- getDataTotal (PHASE_SYNCHRONIZING) == 0)
- finalStatus = _("Nothing to synchronize"); //even if "ignored conflicts" occurred!
- else
- finalStatus = _("Synchronization completed successfully");
- errorLog.logMsg(finalStatus, TYPE_INFO);
- }
-
- const SummaryInfo summary =
- {
- jobName_, finalStatus,
- getObjectsCurrent(PHASE_SYNCHRONIZING), getDataCurrent(PHASE_SYNCHRONIZING),
- getObjectsTotal (PHASE_SYNCHRONIZING), getDataTotal (PHASE_SYNCHRONIZING),
- totalTime.Time() / 1000
- };
-
- try
- {
- saveToLastSyncsLog(summary, errorLog, lastSyncsLogFileSizeMax_); //throw FileError
- }
- catch (FileError&) {}
-
- if (progressDlg)
- {
- //notify to progressDlg that current process has ended
- if (showFinalResults)
- {
- 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();
-
- //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)
- {
- wxTheApp->Yield(); //*first* refresh GUI (removing flicker) before sleeping!
- boost::this_thread::sleep(boost::posix_time::milliseconds(UI_UPDATE_INTERVAL));
- }
- }
-}
-
-
-void SyncStatusHandler::initNewPhase(int objectsTotal, Int64 dataTotal, Phase phaseID)
-{
- assert(phaseID == PHASE_SYNCHRONIZING);
- StatusHandler::initNewPhase(objectsTotal, dataTotal, phaseID);
- if (progressDlg)
- progressDlg->initNewPhase(); //call after "StatusHandler::initNewPhase"
-}
-
-
-void SyncStatusHandler::updateProcessedData(int objectsDelta, Int64 dataDelta)
-{
- StatusHandler::updateProcessedData(objectsDelta, dataDelta);
- if (progressDlg)
- progressDlg->notifyProgressChange(); //noexcept
- //note: this method should NOT throw in order to properly allow undoing setting of statistics!
-}
-
-
-void SyncStatusHandler::reportInfo(const std::wstring& text)
-{
- StatusHandler::reportInfo(text);
- errorLog.logMsg(text, TYPE_INFO);
-}
-
-
-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); });
-
- switch (handleError_)
- {
- case ON_GUIERROR_POPUP:
- {
- if (!progressDlg) abortThisProcess();
- PauseTimers dummy(*progressDlg);
- forceUiRefresh();
-
- bool ignoreNextErrors = false;
- switch (showConfirmationDialog3(progressDlg->getWindowIfVisible(), DialogInfoType::ERROR2, PopupDialogCfg3().
- setDetailInstructions(errorMessage).
- setCheckBox(ignoreNextErrors, _("&Ignore subsequent errors"), ConfirmationButton3::DONT_DO_IT),
- _("&Ignore"), _("&Retry")))
- {
- case ConfirmationButton3::DO_IT: //ignore
- if (ignoreNextErrors) //falsify only
- handleError_ = ON_GUIERROR_IGNORE;
- return ProcessCallback::IGNORE_ERROR;
-
- case ConfirmationButton3::DONT_DO_IT: //retry
- guardWriteLog.dismiss();
- 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 ConfirmationButton3::CANCEL:
- abortThisProcess();
- break;
- }
- }
- break;
-
- case ON_GUIERROR_IGNORE:
- return ProcessCallback::IGNORE_ERROR;
- }
-
- assert(false);
- return ProcessCallback::IGNORE_ERROR; //dummy value
-}
-
-
-void SyncStatusHandler::reportFatalError(const std::wstring& errorMessage)
-{
- errorLog.logMsg(errorMessage, TYPE_FATAL_ERROR);
-
- switch (handleError_)
- {
- case ON_GUIERROR_POPUP:
- {
- if (!progressDlg) abortThisProcess();
- PauseTimers dummy(*progressDlg);
- forceUiRefresh();
-
- bool ignoreNextErrors = false;
- switch (showConfirmationDialog(progressDlg->getWindowIfVisible(), DialogInfoType::ERROR2,
- PopupDialogCfg().setTitle(_("Serious Error")).
- setDetailInstructions(errorMessage).
- setCheckBox(ignoreNextErrors, _("&Ignore subsequent errors")),
- _("&Ignore")))
- {
- case ConfirmationButton::DO_IT:
- if (ignoreNextErrors) //falsify only
- handleError_ = ON_GUIERROR_IGNORE;
- break;
- case ConfirmationButton::CANCEL:
- abortThisProcess();
- break;
- }
- }
- break;
-
- case ON_GUIERROR_IGNORE:
- break;
- }
-}
-
-
-void SyncStatusHandler::reportWarning(const std::wstring& warningMessage, bool& warningActive)
-{
- errorLog.logMsg(warningMessage, TYPE_WARNING);
-
- if (!warningActive)
- return;
-
- switch (handleError_)
- {
- case ON_GUIERROR_POPUP:
- {
- if (!progressDlg) abortThisProcess();
- PauseTimers dummy(*progressDlg);
- forceUiRefresh();
-
- bool dontWarnAgain = false;
- switch (showConfirmationDialog(progressDlg->getWindowIfVisible(), DialogInfoType::WARNING,
- PopupDialogCfg().setDetailInstructions(warningMessage).
- setCheckBox(dontWarnAgain, _("&Don't show this warning again")),
- _("&Ignore")))
- {
- case ConfirmationButton::DO_IT:
- warningActive = !dontWarnAgain;
- break;
- case ConfirmationButton::CANCEL:
- abortThisProcess();
- break;
- }
- }
- break;
-
- case ON_GUIERROR_IGNORE:
- break; //if errors are ignored, then warnings should be, too
- }
-}
-
-
-void SyncStatusHandler::forceUiRefresh()
-{
- if (progressDlg)
- progressDlg->updateGui();
-}
-
-
-void SyncStatusHandler::abortThisProcess()
-{
- requestAbortion(); //just make sure...
- throw GuiAbortProcess(); //abort can be triggered by progressDlg
-}
-
-
-void SyncStatusHandler::onProgressDialogTerminate()
-{
- //it's responsibility of "progressDlg" to call requestAbortion() when closing dialog
- progressDlg = nullptr;
-}
bgstack15