From 0fdae2adb8067594ee182c2d944fd07a9e7426ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Lam?= Date: Tue, 4 Jul 2017 17:38:25 +0200 Subject: [PATCH] UI: Refactor Wii update code This moves the progress dialog logic and the result dialog to separate functions that can easily be reused for disc updates. --- Source/Core/DolphinQt2/WiiUpdate.cpp | 141 ++++++++++++++++----------- Source/Core/DolphinWX/FrameTools.cpp | 86 ++++++++++------ 2 files changed, 136 insertions(+), 91 deletions(-) diff --git a/Source/Core/DolphinQt2/WiiUpdate.cpp b/Source/Core/DolphinQt2/WiiUpdate.cpp index 86200b21d1..b7e840f21e 100644 --- a/Source/Core/DolphinQt2/WiiUpdate.cpp +++ b/Source/Core/DolphinQt2/WiiUpdate.cpp @@ -22,66 +22,9 @@ namespace WiiUpdate { -void PerformOnlineUpdate(const std::string& region, QWidget* parent) +static void ShowResult(QWidget* parent, WiiUtils::UpdateResult result) { - const int confirm = QMessageBox::question( - parent, QObject::tr("Confirm"), - QObject::tr("Connect to the Internet and perform an online system update?")); - if (confirm != QMessageBox::Yes) - return; - - // Do not allow the user to close the dialog. Instead, wait until the update is finished - // or cancelled. - class UpdateProgressDialog final : public QProgressDialog - { - public: - using QProgressDialog::QProgressDialog; - - protected: - void reject() override {} - }; - - UpdateProgressDialog dialog{parent}; - dialog.setLabelText(QObject::tr("Preparing to update...\nThis can take a while.")); - dialog.setWindowTitle(QObject::tr("Updating")); - dialog.setWindowFlags(dialog.windowFlags() & ~Qt::WindowContextHelpButtonHint); - // QProgressDialog doesn't set its minimum size correctly. - dialog.setMinimumSize(360, 150); - - // QProgressDialog doesn't allow us to disable the cancel button when it's pressed, - // so we have to pass it our own push button. Note: the dialog takes ownership of it. - auto* cancel_button = new QPushButton(QObject::tr("&Cancel"), parent); - dialog.setCancelButton(cancel_button); - Common::Flag was_cancelled; - QObject::disconnect(&dialog, &QProgressDialog::canceled, &dialog, &QProgressDialog::cancel); - QObject::connect(&dialog, &QProgressDialog::canceled, [&] { - dialog.setLabelText(QObject::tr("Finishing the update...\nThis can take a while.")); - cancel_button->setEnabled(false); - was_cancelled.Set(); - }); - - std::future result = std::async(std::launch::async, [&] { - const WiiUtils::UpdateResult res = WiiUtils::DoOnlineUpdate( - [&](size_t processed, size_t total, u64 title_id) { - QueueOnObject(&dialog, [&dialog, &was_cancelled, processed, total, title_id]() { - if (was_cancelled.IsSet()) - return; - - dialog.setRange(0, static_cast(total)); - dialog.setValue(static_cast(processed)); - dialog.setLabelText(QObject::tr("Updating title %1...\nThis can take a while.") - .arg(title_id, 16, 16, QLatin1Char('0'))); - }); - return !was_cancelled.IsSet(); - }, - region); - QueueOnObject(&dialog, [&dialog] { dialog.close(); }); - return res; - }); - - dialog.exec(); - - switch (result.get()) + switch (result) { case WiiUtils::UpdateResult::Succeeded: QMessageBox::information(parent, QObject::tr("Update completed"), @@ -114,6 +57,86 @@ void PerformOnlineUpdate(const std::string& region, QWidget* parent) QObject::tr("The update has been cancelled. It is strongly recommended to " "finish it in order to avoid inconsistent system software versions.")); break; + case WiiUtils::UpdateResult::RegionMismatch: + QMessageBox::critical(parent, QObject::tr("Update failed"), + QObject::tr("The game's region does not match your console's. " + "To avoid issues with the system menu, it is not possible " + "to update the emulated console using this disc.")); + break; + case WiiUtils::UpdateResult::MissingUpdatePartition: + case WiiUtils::UpdateResult::DiscReadFailed: + QMessageBox::critical(parent, QObject::tr("Update failed"), + QObject::tr("The game disc does not contain any usable " + "update information.")); + break; } } + +template +static WiiUtils::UpdateResult ShowProgress(QWidget* parent, Callable function, Args&&... args) +{ + // Do not allow the user to close the dialog. Instead, wait until the update is finished + // or cancelled. + class UpdateProgressDialog final : public QProgressDialog + { + public: + using QProgressDialog::QProgressDialog; + + protected: + void reject() override {} + }; + + UpdateProgressDialog dialog{parent}; + dialog.setLabelText(QObject::tr("Preparing to update...\nThis can take a while.")); + dialog.setWindowTitle(QObject::tr("Updating")); + dialog.setWindowFlags(dialog.windowFlags() & ~Qt::WindowContextHelpButtonHint); + // QProgressDialog doesn't set its minimum size correctly. + dialog.setMinimumSize(360, 150); + + // QProgressDialog doesn't allow us to disable the cancel button when it's pressed, + // so we have to pass it our own push button. Note: the dialog takes ownership of it. + auto* cancel_button = new QPushButton(QObject::tr("&Cancel"), parent); + dialog.setCancelButton(cancel_button); + Common::Flag was_cancelled; + QObject::disconnect(&dialog, &QProgressDialog::canceled, &dialog, &QProgressDialog::cancel); + QObject::connect(&dialog, &QProgressDialog::canceled, [&] { + dialog.setLabelText(QObject::tr("Finishing the update...\nThis can take a while.")); + cancel_button->setEnabled(false); + was_cancelled.Set(); + }); + + std::future result = std::async(std::launch::async, [&] { + const WiiUtils::UpdateResult res = function( + [&](size_t processed, size_t total, u64 title_id) { + QueueOnObject(&dialog, [&dialog, &was_cancelled, processed, total, title_id] { + if (was_cancelled.IsSet()) + return; + + dialog.setRange(0, static_cast(total)); + dialog.setValue(static_cast(processed)); + dialog.setLabelText(QObject::tr("Updating title %1...\nThis can take a while.") + .arg(title_id, 16, 16, QLatin1Char('0'))); + }); + return !was_cancelled.IsSet(); + }, + std::forward(args)...); + QueueOnObject(&dialog, [&dialog] { dialog.close(); }); + return res; + }); + + dialog.exec(); + return result.get(); +} + +void PerformOnlineUpdate(const std::string& region, QWidget* parent) +{ + const int confirm = QMessageBox::question( + parent, QObject::tr("Confirm"), + QObject::tr("Connect to the Internet and perform an online system update?")); + if (confirm != QMessageBox::Yes) + return; + + const WiiUtils::UpdateResult result = ShowProgress(parent, WiiUtils::DoOnlineUpdate, region); + ShowResult(parent, result); +} } // namespace WiiUpdate diff --git a/Source/Core/DolphinWX/FrameTools.cpp b/Source/Core/DolphinWX/FrameTools.cpp index 787f5ae1c1..870cb6f28b 100644 --- a/Source/Core/DolphinWX/FrameTools.cpp +++ b/Source/Core/DolphinWX/FrameTools.cpp @@ -1320,39 +1320,9 @@ static std::string GetUpdateRegionFromIdm(int idm) } } -void CFrame::OnPerformOnlineWiiUpdate(wxCommandEvent& event) +static void ShowUpdateResult(WiiUtils::UpdateResult result) { - int confirm = wxMessageBox(_("Connect to the Internet and perform an online system update?"), - _("System Update"), wxYES_NO, this); - if (confirm != wxYES) - return; - - wxProgressDialog dialog(_("Updating"), _("Preparing to update...\nThis can take a while."), 1, - this, wxPD_APP_MODAL | wxPD_AUTO_HIDE | wxPD_SMOOTH | wxPD_CAN_ABORT); - - const std::string region = GetUpdateRegionFromIdm(event.GetId()); - std::future result = std::async(std::launch::async, [&] { - const WiiUtils::UpdateResult res = WiiUtils::DoOnlineUpdate( - [&](size_t processed, size_t total, u64 title_id) { - Core::QueueHostJob( - [&dialog, processed, total, title_id] { - dialog.SetRange(total); - dialog.Update(processed, wxString::Format(_("Updating title %016" PRIx64 "...\n" - "This can take a while."), - title_id)); - dialog.Fit(); - }, - true); - return !dialog.WasCancelled(); - }, - region); - Core::QueueHostJob([&dialog] { dialog.EndModal(0); }, true); - return res; - }); - - dialog.ShowModal(); - - switch (result.get()) + switch (result) { case WiiUtils::UpdateResult::Succeeded: wxMessageBox(_("The emulated Wii console has been updated."), _("Update completed"), @@ -1384,8 +1354,60 @@ void CFrame::OnPerformOnlineWiiUpdate(wxCommandEvent& event) "finish it in order to avoid inconsistent system software versions."), _("Update cancelled"), wxOK | wxICON_WARNING); break; + case WiiUtils::UpdateResult::RegionMismatch: + wxMessageBox(_("The game's region does not match your console's. " + "To avoid issues with the system menu, it is not possible to update " + "the emulated console using this disc."), + _("Update failed"), wxOK | wxICON_ERROR); + break; + case WiiUtils::UpdateResult::MissingUpdatePartition: + case WiiUtils::UpdateResult::DiscReadFailed: + wxMessageBox(_("The game disc does not contain any usable update information."), + _("Update failed"), wxOK | wxICON_ERROR); + break; } +} +template +static WiiUtils::UpdateResult ShowUpdateProgress(CFrame* frame, Callable function, Args&&... args) +{ + wxProgressDialog dialog(_("Updating"), _("Preparing to update...\nThis can take a while."), 1, + frame, wxPD_APP_MODAL | wxPD_AUTO_HIDE | wxPD_SMOOTH | wxPD_CAN_ABORT); + + std::future result = std::async(std::launch::async, [&] { + const WiiUtils::UpdateResult res = function( + [&](size_t processed, size_t total, u64 title_id) { + Core::QueueHostJob( + [&dialog, processed, total, title_id] { + dialog.SetRange(total); + dialog.Update(processed, wxString::Format(_("Updating title %016" PRIx64 "...\n" + "This can take a while."), + title_id)); + dialog.Fit(); + }, + true); + return !dialog.WasCancelled(); + }, + std::forward(args)...); + Core::QueueHostJob([&dialog] { dialog.EndModal(0); }, true); + return res; + }); + + dialog.ShowModal(); + return result.get(); +} + +void CFrame::OnPerformOnlineWiiUpdate(wxCommandEvent& event) +{ + int confirm = wxMessageBox(_("Connect to the Internet and perform an online system update?"), + _("System Update"), wxYES_NO, this); + if (confirm != wxYES) + return; + + const std::string region = GetUpdateRegionFromIdm(event.GetId()); + + const WiiUtils::UpdateResult result = ShowUpdateProgress(this, WiiUtils::DoOnlineUpdate, region); + ShowUpdateResult(result); UpdateLoadWiiMenuItem(); }