Qt: smoother batch package installation

This commit is contained in:
Megamouse 2020-01-07 22:44:23 +01:00
parent be2d225d96
commit 542d2ef8da
7 changed files with 79 additions and 53 deletions

View file

@ -130,7 +130,7 @@ void game_compatibility::RequestCompatibility(bool online)
QNetworkReply* network_reply = m_network_access_manager->get(m_network_request); QNetworkReply* network_reply = m_network_access_manager->get(m_network_request);
// Show Progress // 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(); m_progress_dialog->show();
// Animate progress dialog a bit more // Animate progress dialog a bit more

View file

@ -1373,7 +1373,7 @@ void game_list_frame::BatchCreatePPUCaches()
return; 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->setAutoClose(false);
pdlg->setAutoReset(false); pdlg->setAutoReset(false);
pdlg->show(); pdlg->show();
@ -1418,7 +1418,7 @@ void game_list_frame::BatchRemovePPUCaches()
return; 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->setAutoClose(false);
pdlg->setAutoReset(false); pdlg->setAutoReset(false);
pdlg->show(); pdlg->show();
@ -1503,7 +1503,7 @@ void game_list_frame::BatchRemoveCustomConfigurations()
return; 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->setAutoClose(false);
pdlg->setAutoReset(false); pdlg->setAutoReset(false);
pdlg->show(); pdlg->show();
@ -1548,7 +1548,7 @@ void game_list_frame::BatchRemoveCustomPadConfigurations()
return; 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->setAutoClose(false);
pdlg->setAutoReset(false); pdlg->setAutoReset(false);
pdlg->show(); pdlg->show();
@ -1590,7 +1590,7 @@ void game_list_frame::BatchRemoveShaderCaches()
return; 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->setAutoClose(false);
pdlg->setAutoReset(false); pdlg->setAutoReset(false);
pdlg->show(); pdlg->show();

View file

@ -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(); 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) 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) QMessageBox::Yes | QMessageBox::No, QMessageBox::No) != QMessageBox::Yes)
{ {
LOG_NOTICE(LOADER, "PKG: Cancelled installation from drop. File: %s", sstr(filePath)); LOG_NOTICE(LOADER, "PKG: Cancelled installation from drop. File: %s", sstr(file_paths.front()));
return false; return;
} }
} }
if (filePath.isEmpty()) if (file_paths.isEmpty())
{ {
return false; return;
} }
Emu.SetForceBoot(true); progress_dialog pdlg(tr("RPCS3 Package Installer"), tr("Installing package ... please wait ..."), tr("Cancel"), 0, 1000, false, this);
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);
pdlg.show(); pdlg.show();
// Synchronization variable // Synchronization variable
@ -407,13 +405,30 @@ bool main_window::InstallPkg(QString filePath, bool show_confirm, bool show_succ
bool cancelled = false; bool cancelled = false;
// Run PKG unpacking asynchronously for (int i = 0, count = file_paths.count(); i < count; i++)
named_thread worker("PKG Installer", [&]
{ {
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 // Wait for the completion
while (std::this_thread::sleep_for(5ms), worker != thread_state::finished) 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.setHidden(true);
pdlg.SignalFailure(); pdlg.SignalFailure();
} }
}
if (worker()) if (worker())
{
m_gameListFrame->Refresh(true);
LOG_SUCCESS(GENERAL, "Successfully installed %s.", fileName);
if (show_success)
{ {
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) void main_window::InstallPup(QString filePath)
@ -554,7 +578,7 @@ void main_window::InstallPup(QString filePath)
return; return;
} }
progress_dialog pdlg(tr("RPCS3 Firmware Installer"), tr("Installing firmware version %1\nPlease wait...").arg(qstr(version_string)), tr("Cancel"), 0, static_cast<int>(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<int>(updatefilenames.size()), false, this);
pdlg.show(); pdlg.show();
// Synchronization variable // Synchronization variable
@ -1203,7 +1227,7 @@ void main_window::CreateConnects()
guiSettings->SetValue(gui::rg_freeze, checked); 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->bootInstallPupAct, &QAction::triggered, [this] {InstallPup(); });
connect(ui->exitAct, &QAction::triggered, this, &QWidget::close); connect(ui->exitAct, &QAction::triggered, this, &QWidget::close);
@ -1899,18 +1923,16 @@ void main_window::dropEvent(QDropEvent* event)
connect(&dlg, &QDialog::accepted, [this, &dlg]() connect(&dlg, &QDialog::accepted, [this, &dlg]()
{ {
const QStringList paths = dlg.GetPathsToInstall(); const QStringList paths = dlg.GetPathsToInstall();
if (!paths.isEmpty())
for (int i = 0, count = paths.count(); i < count; i++)
{ {
if (!InstallPkg(paths.at(i), false, i == count - 1)) InstallPackages(paths, false);
break;
} }
}); });
dlg.exec(); dlg.exec();
} }
else else
{ {
InstallPkg(dropPaths.front(), true); InstallPackages(dropPaths, true);
} }
break; break;
case drop_type::drop_pup: // install the firmware case drop_type::drop_pup: // install the firmware

View file

@ -116,7 +116,7 @@ private:
void CreateDockWindows(); void CreateDockWindows();
void EnableMenus(bool enabled); void EnableMenus(bool enabled);
void ShowTitleBars(bool show); 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 = ""); void InstallPup(QString filePath = "");
int IsValidFile(const QMimeData& md, QStringList* dropPaths = nullptr); int IsValidFile(const QMimeData& md, QStringList* dropPaths = nullptr);

View file

@ -2,14 +2,18 @@
#include <QLabel> #include <QLabel>
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) : QProgressDialog(labelText, cancelButtonText, minimum, maximum, parent, flags)
{ {
setWindowTitle(windowTitle); setWindowTitle(windowTitle);
setFixedSize(QLabel("This is the very length of the progressdialog due to hidpi reasons.").sizeHint().width(), sizeHint().height()); setFixedSize(QLabel("This is the very length of the progressdialog due to hidpi reasons.").sizeHint().width(), sizeHint().height());
setValue(0); setValue(0);
setWindowModality(Qt::WindowModal); setWindowModality(Qt::WindowModal);
connect(this, &QProgressDialog::canceled, this, &QProgressDialog::deleteLater);
if (delete_on_close)
{
connect(this, &QProgressDialog::canceled, this, &QProgressDialog::deleteLater);
}
#ifdef _WIN32 #ifdef _WIN32
m_tb_button = std::make_unique<QWinTaskbarButton>(); m_tb_button = std::make_unique<QWinTaskbarButton>();

View file

@ -17,7 +17,7 @@
class progress_dialog : public QProgressDialog class progress_dialog : public QProgressDialog
{ {
public: 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(); ~progress_dialog();
void SetValue(int progress); void SetValue(int progress);
void SignalFailure(); void SignalFailure();

View file

@ -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; 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)))); 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->setAutoClose(false);
m_progress_dialog->setAutoReset(false); m_progress_dialog->setAutoReset(false);
m_progress_dialog->show(); m_progress_dialog->show();