From 542d2ef8da50f141f86d27921579a1f998b81093 Mon Sep 17 00:00:00 2001 From: Megamouse Date: Tue, 7 Jan 2020 22:44:23 +0100 Subject: [PATCH] Qt: smoother batch package installation --- rpcs3/rpcs3qt/game_compatibility.cpp | 2 +- rpcs3/rpcs3qt/game_list_frame.cpp | 10 +-- rpcs3/rpcs3qt/main_window.cpp | 106 ++++++++++++++++----------- rpcs3/rpcs3qt/main_window.h | 2 +- rpcs3/rpcs3qt/progress_dialog.cpp | 8 +- rpcs3/rpcs3qt/progress_dialog.h | 2 +- rpcs3/rpcs3qt/update_manager.cpp | 2 +- 7 files changed, 79 insertions(+), 53 deletions(-) diff --git a/rpcs3/rpcs3qt/game_compatibility.cpp b/rpcs3/rpcs3qt/game_compatibility.cpp index e876c9c068..fdbe50e82a 100644 --- a/rpcs3/rpcs3qt/game_compatibility.cpp +++ b/rpcs3/rpcs3qt/game_compatibility.cpp @@ -130,7 +130,7 @@ void game_compatibility::RequestCompatibility(bool online) QNetworkReply* network_reply = m_network_access_manager->get(m_network_request); // Show Progress - m_progress_dialog = new progress_dialog(tr("Downloading Database"), tr(".Please wait."), tr("Abort"), 0, 100); + m_progress_dialog = new progress_dialog(tr("Downloading Database"), tr(".Please wait."), tr("Abort"), 0, 100, true); m_progress_dialog->show(); // Animate progress dialog a bit more diff --git a/rpcs3/rpcs3qt/game_list_frame.cpp b/rpcs3/rpcs3qt/game_list_frame.cpp index d8c6e7a266..2669d91d25 100644 --- a/rpcs3/rpcs3qt/game_list_frame.cpp +++ b/rpcs3/rpcs3qt/game_list_frame.cpp @@ -1373,7 +1373,7 @@ void game_list_frame::BatchCreatePPUCaches() return; } - progress_dialog* pdlg = new progress_dialog(tr("PPU Cache Batch Creation"), tr("Creating all PPU caches"), tr("Cancel"), 0, total, this); + progress_dialog* pdlg = new progress_dialog(tr("PPU Cache Batch Creation"), tr("Creating all PPU caches"), tr("Cancel"), 0, total, true, this); pdlg->setAutoClose(false); pdlg->setAutoReset(false); pdlg->show(); @@ -1418,7 +1418,7 @@ void game_list_frame::BatchRemovePPUCaches() return; } - progress_dialog* pdlg = new progress_dialog(tr("PPU Cache Batch Removal"), tr("Removing all PPU caches"), tr("Cancel"), 0, total, this); + progress_dialog* pdlg = new progress_dialog(tr("PPU Cache Batch Removal"), tr("Removing all PPU caches"), tr("Cancel"), 0, total, true, this); pdlg->setAutoClose(false); pdlg->setAutoReset(false); pdlg->show(); @@ -1503,7 +1503,7 @@ void game_list_frame::BatchRemoveCustomConfigurations() return; } - progress_dialog* pdlg = new progress_dialog(tr("Custom Configuration Batch Removal"), tr("Removing all custom configurations"), tr("Cancel"), 0, total, this); + progress_dialog* pdlg = new progress_dialog(tr("Custom Configuration Batch Removal"), tr("Removing all custom configurations"), tr("Cancel"), 0, total, true, this); pdlg->setAutoClose(false); pdlg->setAutoReset(false); pdlg->show(); @@ -1548,7 +1548,7 @@ void game_list_frame::BatchRemoveCustomPadConfigurations() return; } - progress_dialog* pdlg = new progress_dialog(tr("Custom Pad Configuration Batch Removal"), tr("Removing all custom pad configurations"), tr("Cancel"), 0, total, this); + progress_dialog* pdlg = new progress_dialog(tr("Custom Pad Configuration Batch Removal"), tr("Removing all custom pad configurations"), tr("Cancel"), 0, total, true, this); pdlg->setAutoClose(false); pdlg->setAutoReset(false); pdlg->show(); @@ -1590,7 +1590,7 @@ void game_list_frame::BatchRemoveShaderCaches() return; } - progress_dialog* pdlg = new progress_dialog(tr("Shader Cache Batch Removal"), tr("Removing all shader caches"), tr("Cancel"), 0, total, this); + progress_dialog* pdlg = new progress_dialog(tr("Shader Cache Batch Removal"), tr("Removing all shader caches"), tr("Cancel"), 0, total, true, this); pdlg->setAutoClose(false); pdlg->setAutoReset(false); pdlg->show(); diff --git a/rpcs3/rpcs3qt/main_window.cpp b/rpcs3/rpcs3qt/main_window.cpp index b8b0207aa0..bd6a2fc832 100644 --- a/rpcs3/rpcs3qt/main_window.cpp +++ b/rpcs3/rpcs3qt/main_window.cpp @@ -370,36 +370,34 @@ void main_window::BootRsxCapture(std::string path) } } -bool main_window::InstallPkg(QString filePath, bool show_confirm, bool show_success) +void main_window::InstallPackages(QStringList file_paths, bool show_confirm) { - if (filePath.isEmpty()) + if (file_paths.isEmpty()) { QString path_last_PKG = guiSettings->GetValue(gui::fd_install_pkg).toString(); - filePath = QFileDialog::getOpenFileName(this, tr("Select PKG To Install"), path_last_PKG, tr("PKG files (*.pkg);;All files (*.*)")); + const QString file_path = QFileDialog::getOpenFileName(this, tr("Select PKG To Install"), path_last_PKG, tr("PKG files (*.pkg);;All files (*.*)")); + + if (!file_path.isEmpty()) + { + file_paths.append(file_path); + } } else if (show_confirm) { - if (QMessageBox::question(this, tr("PKG Decrypter / Installer"), tr("Install package: %1?").arg(filePath), + if (QMessageBox::question(this, tr("PKG Decrypter / Installer"), tr("Install package: %1?").arg(file_paths.front()), QMessageBox::Yes | QMessageBox::No, QMessageBox::No) != QMessageBox::Yes) { - LOG_NOTICE(LOADER, "PKG: Cancelled installation from drop. File: %s", sstr(filePath)); - return false; + LOG_NOTICE(LOADER, "PKG: Cancelled installation from drop. File: %s", sstr(file_paths.front())); + return; } } - if (filePath.isEmpty()) + if (file_paths.isEmpty()) { - return false; + return; } - Emu.SetForceBoot(true); - Emu.Stop(); - - guiSettings->SetValue(gui::fd_install_pkg, QFileInfo(filePath).path()); - const std::string fileName = sstr(QFileInfo(filePath).fileName()); - const std::string path = sstr(filePath); - - progress_dialog pdlg(tr("RPCS3 Package Installer"), tr("Installing package ... please wait ..."), tr("Cancel"), 0, 1000, this); + progress_dialog pdlg(tr("RPCS3 Package Installer"), tr("Installing package ... please wait ..."), tr("Cancel"), 0, 1000, false, this); pdlg.show(); // Synchronization variable @@ -407,13 +405,30 @@ bool main_window::InstallPkg(QString filePath, bool show_confirm, bool show_succ bool cancelled = false; - // Run PKG unpacking asynchronously - named_thread worker("PKG Installer", [&] + for (int i = 0, count = file_paths.count(); i < count; i++) { - return pkg_install(path, progress); - }); + progress = 0.; + + pdlg.SetValue(0); + pdlg.setLabelText(tr("Installing package %0/%1 ... please wait ...").arg(i + 1).arg(count)); + pdlg.show(); + + Emu.SetForceBoot(true); + Emu.Stop(); + + const QString file_path = file_paths.at(i); + const QFileInfo file_info(file_path); + const std::string path = sstr(file_path); + const std::string file_name = sstr(file_info.fileName()); + + guiSettings->SetValue(gui::fd_install_pkg, file_info.path()); + + // Run PKG unpacking asynchronously + named_thread worker("PKG Installer", [path, &progress] + { + return pkg_install(path, progress); + }); - { // Wait for the completion while (std::this_thread::sleep_for(5ms), worker != thread_state::finished) { @@ -441,24 +456,33 @@ bool main_window::InstallPkg(QString filePath, bool show_confirm, bool show_succ pdlg.setHidden(true); pdlg.SignalFailure(); } - } - if (worker()) - { - m_gameListFrame->Refresh(true); - LOG_SUCCESS(GENERAL, "Successfully installed %s.", fileName); - if (show_success) + if (worker()) { - guiSettings->ShowInfoBox(tr("Success!"), tr("Successfully installed software from package(s)!"), gui::ib_pkg_success, this); + m_gameListFrame->Refresh(true); + LOG_SUCCESS(GENERAL, "Successfully installed %s.", file_name); + + if (i == (count - 1)) + { + guiSettings->ShowInfoBox(tr("Success!"), tr("Successfully installed software from package(s)!"), gui::ib_pkg_success, this); + } + } + else + { + if (!cancelled) + { + LOG_ERROR(GENERAL, "Failed to install %s.", file_name); + QMessageBox::critical(this, tr("Failure!"), tr("Failed to install software from package %1!").arg(file_path)); + } + return; + } + + // return if the thread was still running after cancel + if (cancelled) + { + return; } - return true; } - else if (!cancelled) - { - LOG_ERROR(GENERAL, "Failed to install %s.", fileName); - QMessageBox::critical(this, tr("Failure!"), tr("Failed to install software from package %1!").arg(filePath)); - } - return false; } void main_window::InstallPup(QString filePath) @@ -554,7 +578,7 @@ void main_window::InstallPup(QString filePath) return; } - progress_dialog pdlg(tr("RPCS3 Firmware Installer"), tr("Installing firmware version %1\nPlease wait...").arg(qstr(version_string)), tr("Cancel"), 0, static_cast(updatefilenames.size()), this); + progress_dialog pdlg(tr("RPCS3 Firmware Installer"), tr("Installing firmware version %1\nPlease wait...").arg(qstr(version_string)), tr("Cancel"), 0, static_cast(updatefilenames.size()), false, this); pdlg.show(); // Synchronization variable @@ -1203,7 +1227,7 @@ void main_window::CreateConnects() guiSettings->SetValue(gui::rg_freeze, checked); }); - connect(ui->bootInstallPkgAct, &QAction::triggered, [this] {InstallPkg(); }); + connect(ui->bootInstallPkgAct, &QAction::triggered, [this] {InstallPackages(); }); connect(ui->bootInstallPupAct, &QAction::triggered, [this] {InstallPup(); }); connect(ui->exitAct, &QAction::triggered, this, &QWidget::close); @@ -1899,18 +1923,16 @@ void main_window::dropEvent(QDropEvent* event) connect(&dlg, &QDialog::accepted, [this, &dlg]() { const QStringList paths = dlg.GetPathsToInstall(); - - for (int i = 0, count = paths.count(); i < count; i++) + if (!paths.isEmpty()) { - if (!InstallPkg(paths.at(i), false, i == count - 1)) - break; + InstallPackages(paths, false); } }); dlg.exec(); } else { - InstallPkg(dropPaths.front(), true); + InstallPackages(dropPaths, true); } break; case drop_type::drop_pup: // install the firmware diff --git a/rpcs3/rpcs3qt/main_window.h b/rpcs3/rpcs3qt/main_window.h index c66a525376..e81cf96c35 100644 --- a/rpcs3/rpcs3qt/main_window.h +++ b/rpcs3/rpcs3qt/main_window.h @@ -116,7 +116,7 @@ private: void CreateDockWindows(); void EnableMenus(bool enabled); void ShowTitleBars(bool show); - bool InstallPkg(QString filePath = "", bool show_confirm = true, bool show_success = true); + void InstallPackages(QStringList file_paths = QStringList(), bool show_confirm = true); void InstallPup(QString filePath = ""); int IsValidFile(const QMimeData& md, QStringList* dropPaths = nullptr); diff --git a/rpcs3/rpcs3qt/progress_dialog.cpp b/rpcs3/rpcs3qt/progress_dialog.cpp index 120765927b..ba28272974 100644 --- a/rpcs3/rpcs3qt/progress_dialog.cpp +++ b/rpcs3/rpcs3qt/progress_dialog.cpp @@ -2,14 +2,18 @@ #include -progress_dialog::progress_dialog(const QString &windowTitle, const QString &labelText, const QString &cancelButtonText, int minimum, int maximum, QWidget *parent, Qt::WindowFlags flags) +progress_dialog::progress_dialog(const QString &windowTitle, const QString &labelText, const QString &cancelButtonText, int minimum, int maximum, bool delete_on_close, QWidget *parent, Qt::WindowFlags flags) : QProgressDialog(labelText, cancelButtonText, minimum, maximum, parent, flags) { setWindowTitle(windowTitle); setFixedSize(QLabel("This is the very length of the progressdialog due to hidpi reasons.").sizeHint().width(), sizeHint().height()); setValue(0); setWindowModality(Qt::WindowModal); - connect(this, &QProgressDialog::canceled, this, &QProgressDialog::deleteLater); + + if (delete_on_close) + { + connect(this, &QProgressDialog::canceled, this, &QProgressDialog::deleteLater); + } #ifdef _WIN32 m_tb_button = std::make_unique(); diff --git a/rpcs3/rpcs3qt/progress_dialog.h b/rpcs3/rpcs3qt/progress_dialog.h index 395c9fc7b7..72ebbff8db 100644 --- a/rpcs3/rpcs3qt/progress_dialog.h +++ b/rpcs3/rpcs3qt/progress_dialog.h @@ -17,7 +17,7 @@ class progress_dialog : public QProgressDialog { public: - progress_dialog(const QString &windowTitle, const QString &labelText, const QString &cancelButtonText, int minimum, int maximum, QWidget *parent = Q_NULLPTR, Qt::WindowFlags flags = Qt::WindowFlags()); + progress_dialog(const QString &windowTitle, const QString &labelText, const QString &cancelButtonText, int minimum, int maximum, bool delete_on_close, QWidget *parent = Q_NULLPTR, Qt::WindowFlags flags = Qt::WindowFlags()); ~progress_dialog(); void SetValue(int progress); void SignalFailure(); diff --git a/rpcs3/rpcs3qt/update_manager.cpp b/rpcs3/rpcs3qt/update_manager.cpp index ee896242c5..70a31a9439 100644 --- a/rpcs3/rpcs3qt/update_manager.cpp +++ b/rpcs3/rpcs3qt/update_manager.cpp @@ -59,7 +59,7 @@ void update_manager::check_for_updates(bool automatic, QWidget* parent) const std::string request_url = m_update_url + rpcs3::get_commit_and_hash().second; QNetworkReply* reply_json = m_manager.get(QNetworkRequest(QUrl(QString::fromStdString(request_url)))); - m_progress_dialog = new progress_dialog(tr("Checking For Updates"), tr("Please wait..."), tr("Abort"), 0, 100, parent); + m_progress_dialog = new progress_dialog(tr("Checking For Updates"), tr("Please wait..."), tr("Abort"), 0, 100, true, parent); m_progress_dialog->setAutoClose(false); m_progress_dialog->setAutoReset(false); m_progress_dialog->show();