From c82dc4de2ece758ec537f8382fcb71c3ff35099f Mon Sep 17 00:00:00 2001 From: Megamouse Date: Tue, 28 Apr 2026 10:01:19 +0200 Subject: [PATCH] cli: allow headless installs --- rpcs3/rpcs3.cpp | 14 +- rpcs3/rpcs3qt/gui_application.cpp | 3 +- rpcs3/rpcs3qt/main_window.cpp | 314 ++++++++++++++++++++---------- rpcs3/rpcs3qt/main_window.h | 12 +- 4 files changed, 228 insertions(+), 115 deletions(-) diff --git a/rpcs3/rpcs3.cpp b/rpcs3/rpcs3.cpp index 9db7ab6da4..810318fa58 100644 --- a/rpcs3/rpcs3.cpp +++ b/rpcs3/rpcs3.cpp @@ -1159,11 +1159,11 @@ int run_rpcs3(int argc, char** argv) } else if (parser.isSet(arg_installfw)) { - gui_app->m_main_window->InstallPup(parser.value(installfw_option)); + main_window::InstallPup(gui_app->m_main_window, parser.value(installfw_option)); } else { - gui_app->m_main_window->InstallPackages({parser.value(installpkg_option)}); + main_window::InstallPackages(gui_app->m_main_window, {parser.value(installpkg_option)}); } } else @@ -1173,7 +1173,15 @@ int run_rpcs3(int argc, char** argv) } else { - report_fatal_error("Cannot perform installation in headless mode!"); + if (parser.isSet(arg_installfw)) + { + main_window::InstallPup(nullptr, parser.value(installfw_option)); + } + + if (parser.isSet(arg_installpkg)) + { + main_window::InstallPackages(nullptr, {parser.value(installpkg_option)}); + } } } diff --git a/rpcs3/rpcs3qt/gui_application.cpp b/rpcs3/rpcs3qt/gui_application.cpp index 756dbe18ed..54dade609a 100644 --- a/rpcs3/rpcs3qt/gui_application.cpp +++ b/rpcs3/rpcs3qt/gui_application.cpp @@ -830,14 +830,13 @@ void gui_application::InitializeCallbacks() { callbacks.on_install_pkgs = [this](const std::vector& pkgs) { - ensure(m_main_window); ensure(!pkgs.empty()); QStringList pkg_list; for (const std::string& pkg : pkgs) { pkg_list << QString::fromStdString(pkg); } - return m_main_window->InstallPackages(pkg_list, true); + return main_window::InstallPackages(m_main_window, pkg_list, true); }; } diff --git a/rpcs3/rpcs3qt/main_window.cpp b/rpcs3/rpcs3qt/main_window.cpp index a78acc7964..62809ce4c2 100644 --- a/rpcs3/rpcs3qt/main_window.cpp +++ b/rpcs3/rpcs3qt/main_window.cpp @@ -356,7 +356,7 @@ void main_window::OnMissingFw() connect(mb, &QDialog::accepted, this, [this]() { - QTimer::singleShot(1, [this](){ InstallPup(); }); // singleShot to avoid a Qt bug that causes a deletion of the sender during long slots. + QTimer::singleShot(1, [this](){ InstallPup(this); }); // singleShot to avoid a Qt bug that causes a deletion of the sender during long slots. }); } @@ -864,15 +864,21 @@ bool main_window::InstallFileInExData(const std::string& extension, const QStrin return to.commit(); } -bool main_window::InstallPackages(QStringList file_paths, bool from_boot) +bool main_window::InstallPackages(main_window* mw, QStringList file_paths, bool from_boot) { if (file_paths.isEmpty()) { + if (!mw) + { + gui_log.error("PKG: no filepaths selected"); + return false; + } + ensure(!from_boot); // If this function was called without a path, ask the user for files to install. - const QString path_last_pkg = m_gui_settings->GetValue(gui::fd_install_pkg).toString(); - const QStringList paths = QFileDialog::getOpenFileNames(this, tr("Select packages and/or rap files to install"), + const QString path_last_pkg = mw->m_gui_settings->GetValue(gui::fd_install_pkg).toString(); + const QStringList paths = QFileDialog::getOpenFileNames(mw, tr("Select packages and/or rap files to install"), path_last_pkg, tr("All relevant (*.pkg *.PKG *.rap *.RAP *.edat *.EDAT);;Package files (*.pkg *.PKG);;Rap files (*.rap *.RAP);;Edat files (*.edat *.EDAT);;All files (*.*)")); if (paths.isEmpty()) @@ -882,7 +888,7 @@ bool main_window::InstallPackages(QStringList file_paths, bool from_boot) file_paths.append(paths); const QFileInfo file_info(file_paths[0]); - m_gui_settings->SetValue(gui::fd_install_pkg, file_info.path()); + mw->m_gui_settings->SetValue(gui::fd_install_pkg, file_info.path()); } if (file_paths.count() == 1) @@ -903,7 +909,7 @@ bool main_window::InstallPackages(QStringList file_paths, bool from_boot) return true; } - return InstallPackages(dir_file_paths, from_boot); + return InstallPackages(mw, dir_file_paths, from_boot); } } @@ -932,7 +938,7 @@ bool main_window::InstallPackages(QStringList file_paths, bool from_boot) if (!from_boot) { - if (!m_gui_settings->GetBootConfirmation(this)) + if (mw && !mw->m_gui_settings->GetBootConfirmation(mw)) { // Last chance to cancel the operation return true; @@ -947,10 +953,10 @@ bool main_window::InstallPackages(QStringList file_paths, bool from_boot) install_filetype("edat"); } - if (installed_rap_and_edat_count > 0) + if (mw && installed_rap_and_edat_count > 0) { // Refresh game list since we probably unlocked some games now. - m_game_list_frame->Refresh(true); + mw->m_game_list_frame->Refresh(true); } // Find remaining package files @@ -963,19 +969,26 @@ bool main_window::InstallPackages(QStringList file_paths, bool from_boot) if (from_boot) { - return HandlePackageInstallation(file_paths, true); + return HandlePackageInstallation(mw, file_paths, true); } // Handle further installations with a timeout. Otherwise the source explorer instance is not usable during the following file processing. - QTimer::singleShot(0, [this, paths = std::move(file_paths)]() + if (mw) { - HandlePackageInstallation(paths, false); - }); + QTimer::singleShot(0, [mw, paths = std::move(file_paths)]() + { + HandlePackageInstallation(mw, paths, false); + }); + } + else + { + return HandlePackageInstallation(nullptr, file_paths, false); + } return true; } -bool main_window::HandlePackageInstallation(QStringList file_paths, bool from_boot) +bool main_window::HandlePackageInstallation(main_window* mw, QStringList file_paths, bool from_boot) { if (file_paths.empty()) { @@ -987,33 +1000,52 @@ bool main_window::HandlePackageInstallation(QStringList file_paths, bool from_bo bool precompile_caches = false; bool canceled = false; - const game_compatibility* compat = m_game_list_frame ? m_game_list_frame->GetGameCompatibility() : nullptr; - - // Let the user choose the packages to install and select the order in which they shall be installed. - pkg_install_dialog dlg(file_paths, from_boot, compat, this); - connect(&dlg, &QDialog::finished, this, [&](int result) + if (mw) { - if (result != QDialog::Accepted) + // Let the user choose the packages to install and select the order in which they shall be installed. + const game_compatibility* compat = (mw && mw->m_game_list_frame) ? mw->m_game_list_frame->GetGameCompatibility() : nullptr; + + pkg_install_dialog dlg(file_paths, from_boot, compat, mw); + connect(&dlg, &QDialog::finished, mw, [&](int result) { - canceled = true; - return; + if (result != QDialog::Accepted) + { + canceled = true; + return; + } + + packages = dlg.get_paths_to_install(); + precompile_caches = dlg.precompile_caches(); + + if (dlg.create_desktop_shortcuts()) + shortcut_locations.insert(gui::utils::shortcut_location::desktop); + + if (dlg.create_app_shortcut()) + shortcut_locations.insert(gui::utils::shortcut_location::applications); + + if (dlg.create_steam_shortcut()) + shortcut_locations.insert(gui::utils::shortcut_location::steam); + }); + dlg.exec(); + } + else + { + game_compatibility compat(nullptr); + compat.RequestCompatibility(); + + for (const QString& path : file_paths) + { + compat::package_info info = game_compatibility::GetPkgInfo(path, &compat); + if (!info.is_valid) + { + gui_log.error("Cannot install invalid package: '%s'", info.path); + continue; + } + packages.push_back(std::move(info)); } + } - packages = dlg.get_paths_to_install(); - precompile_caches = dlg.precompile_caches(); - - if (dlg.create_desktop_shortcuts()) - shortcut_locations.insert(gui::utils::shortcut_location::desktop); - - if (dlg.create_app_shortcut()) - shortcut_locations.insert(gui::utils::shortcut_location::applications); - - if (dlg.create_steam_shortcut()) - shortcut_locations.insert(gui::utils::shortcut_location::steam); - }); - dlg.exec(); - - if (canceled) + if (canceled || packages.empty()) { // return "true" if installation of optional packages (requested by some games at first boot) is skipped return from_boot; @@ -1021,7 +1053,7 @@ bool main_window::HandlePackageInstallation(QStringList file_paths, bool from_bo if (!from_boot) { - if (!m_gui_settings->GetBootConfirmation(this)) + if (mw && !mw->m_gui_settings->GetBootConfirmation(mw)) { return true; } @@ -1036,9 +1068,14 @@ bool main_window::HandlePackageInstallation(QStringList file_paths, bool from_bo } gui_log.notice("About to install packages:\n%s", fmt::merge(path_vec, "\n")); - progress_dialog pdlg(tr("RPCS3 Package Installer"), tr("Installing package, please wait..."), tr("Cancel"), 0, 1000, false, this); - pdlg.setAutoClose(false); - pdlg.show(); + std::unique_ptr pdlg; + + if (mw) + { + pdlg = std::make_unique(tr("RPCS3 Package Installer"), tr("Installing package, please wait..."), tr("Cancel"), 0, 1000, false, mw); + pdlg->setAutoClose(false); + pdlg->show(); + } package_install_result result = {}; @@ -1087,7 +1124,10 @@ bool main_window::HandlePackageInstallation(QStringList file_paths, bool from_bo return result.error == package_install_result::error_type::no_error; }); - pdlg.show(); + if (pdlg) + { + pdlg->show(); + } // Wait for the completion int reader_it = 0; @@ -1101,7 +1141,7 @@ bool main_window::HandlePackageInstallation(QStringList file_paths, bool from_bo return true; } - if (pdlg.wasCanceled()) + if (pdlg && pdlg->wasCanceled()) { cancelled = true; @@ -1115,16 +1155,21 @@ bool main_window::HandlePackageInstallation(QStringList file_paths, bool from_bo } // Update progress window - const int progress = readers[reader_it].get_progress(pdlg.maximum()); - pdlg.SetValue(progress); + const int progress_max = pdlg ? pdlg->maximum() : 100; + const int progress = readers[reader_it].get_progress(progress_max); - if (set_text != reader_it) + if (pdlg) { - pdlg.setLabelText(tr("Installing package (%0/%1), please wait...\n\n%2").arg(reader_it + 1).arg(readers_size).arg(get_app_info(packages[reader_it]))); - set_text = reader_it; + pdlg->SetValue(progress); + + if (set_text != reader_it) + { + pdlg->setLabelText(tr("Installing package (%0/%1), please wait...\n\n%2").arg(reader_it + 1).arg(readers_size).arg(get_app_info(packages[reader_it]))); + set_text = reader_it; + } } - if (progress == pdlg.maximum()) + if (progress == progress_max) { reader_it++; } @@ -1137,7 +1182,10 @@ bool main_window::HandlePackageInstallation(QStringList file_paths, bool from_bo if (success) { - pdlg.SetValue(pdlg.maximum()); + if (pdlg) + { + pdlg->SetValue(pdlg->maximum()); + } const u64 start_time = get_system_time(); @@ -1189,9 +1237,9 @@ bool main_window::HandlePackageInstallation(QStringList file_paths, bool from_bo // Need to test here due to potential std::move later const bool installed_a_whole_package_without_new_software = bootable_paths_installed.empty() && !cancelled; - if (!bootable_paths_installed.empty()) + if (mw && !bootable_paths_installed.empty()) { - m_game_list_frame->AddRefreshedSlot([this, shortcut_locations, precompile_caches, paths = std::move(bootable_paths_installed)](std::set& claimed_paths) mutable + mw->m_game_list_frame->AddRefreshedSlot([mw, shortcut_locations, precompile_caches, paths = std::move(bootable_paths_installed)](std::set& claimed_paths) mutable { // Try to claim operations on ID for (auto it = paths.begin(); it != paths.end();) @@ -1209,29 +1257,39 @@ bool main_window::HandlePackageInstallation(QStringList file_paths, bool from_bo } } - CreateShortCuts(paths, shortcut_locations); + mw->CreateShortCuts(paths, shortcut_locations); if (precompile_caches) { - PrecompileCachesFromInstalledPackages(paths); + mw->PrecompileCachesFromInstalledPackages(paths); } }); } - m_game_list_frame->Refresh(true); + if (mw) + { + mw->m_game_list_frame->Refresh(true); + } std::this_thread::sleep_for(std::chrono::microseconds(100'000 - std::min(100'000, get_system_time() - start_time))); - pdlg.hide(); - if (installed_a_whole_package_without_new_software) + if (pdlg) { - m_gui_settings->ShowInfoBox(tr("Success!"), tr("Successfully installed software from package(s)!"), gui::ib_pkg_success, this); + pdlg->hide(); + } + + if (mw && installed_a_whole_package_without_new_software) + { + mw->m_gui_settings->ShowInfoBox(tr("Success!"), tr("Successfully installed software from package(s)!"), gui::ib_pkg_success, mw); } } else { - pdlg.hide(); - pdlg.SignalFailure(); + if (pdlg) + { + pdlg->hide(); + pdlg->SignalFailure(); + } if (!cancelled) { @@ -1260,30 +1318,42 @@ bool main_window::HandlePackageInstallation(QStringList file_paths, bool from_bo if (result.error == package_install_result::error_type::app_version) { gui_log.error("Cannot install %s.", package->path); + + if (!mw) + { + return success; + } + const bool has_expected = !result.version.expected.empty(); const bool has_found = !result.version.found.empty(); if (has_expected && has_found) { - QMessageBox::warning(this, tr("Warning!"), tr("Package cannot be installed on top of the current data.\nUpdate is for version %1, but you have version %2.\n\nTried to install: %3") + QMessageBox::warning(mw, tr("Warning!"), tr("Package cannot be installed on top of the current data.\nUpdate is for version %1, but you have version %2.\n\nTried to install: %3") .arg(QString::fromStdString(result.version.expected)).arg(QString::fromStdString(result.version.found)).arg(package->path)); } else if (has_expected) { - QMessageBox::warning(this, tr("Warning!"), tr("Package cannot be installed on top of the current data.\nUpdate is for version %1, but you don't have any data installed.\n\nTried to install: %2") + QMessageBox::warning(mw, tr("Warning!"), tr("Package cannot be installed on top of the current data.\nUpdate is for version %1, but you don't have any data installed.\n\nTried to install: %2") .arg(QString::fromStdString(result.version.expected)).arg(package->path)); } else { // probably unreachable const QString found = has_found ? tr("version %1").arg(QString::fromStdString(result.version.found)) : tr("no data installed"); - QMessageBox::warning(this, tr("Warning!"), tr("Package cannot be installed on top of the current data.\nUpdate is for unknown version, but you have version %1.\n\nTried to install: %2") + QMessageBox::warning(mw, tr("Warning!"), tr("Package cannot be installed on top of the current data.\nUpdate is for unknown version, but you have version %1.\n\nTried to install: %2") .arg(QString::fromStdString(result.version.expected)).arg(found).arg(package->path)); } } else { gui_log.error("Failed to install %s.", package->path); - QMessageBox::critical(this, tr("Failure!"), tr("Failed to install software from package:\n%1!" + + if (!mw) + { + return success; + } + + QMessageBox::critical(mw, tr("Failure!"), tr("Failed to install software from package:\n%1!" "\nThis is very likely caused by external interference from a faulty anti-virus software." "\nPlease add RPCS3 to your anti-virus\' whitelist or use better anti-virus software.").arg(package->path)); } @@ -1312,16 +1382,22 @@ void main_window::ExtractMSELF() } } -void main_window::InstallPup(QString file_path) +void main_window::InstallPup(main_window* mw, QString file_path) { if (file_path.isEmpty()) { - const QString path_last_pup = m_gui_settings->GetValue(gui::fd_install_pup).toString(); - file_path = QFileDialog::getOpenFileName(this, tr("Select PS3UPDAT.PUP To Install"), path_last_pup, tr("PS3 update file (PS3UPDAT.PUP);;All pup files (*.pup *.PUP);;All files (*.*)")); + if (!mw) + { + gui_log.error("Firmware: Cancelled installation. Filepath empty"); + return; + } + + const QString path_last_pup = mw->m_gui_settings->GetValue(gui::fd_install_pup).toString(); + file_path = QFileDialog::getOpenFileName(mw, tr("Select PS3UPDAT.PUP To Install"), path_last_pup, tr("PS3 update file (PS3UPDAT.PUP);;All pup files (*.pup *.PUP);;All files (*.*)")); } - else + else if (mw) { - if (QMessageBox::question(this, tr("RPCS3 Firmware Installer"), tr("Install firmware: %1?").arg(file_path), + if (QMessageBox::question(mw, tr("RPCS3 Firmware Installer"), tr("Install firmware: %1?").arg(file_path), QMessageBox::Yes | QMessageBox::No, QMessageBox::No) != QMessageBox::Yes) { gui_log.notice("Firmware: Cancelled installation from drop. File: %s", file_path); @@ -1331,11 +1407,18 @@ void main_window::InstallPup(QString file_path) if (!file_path.isEmpty()) { - // Handle the actual installation with a timeout. Otherwise the source explorer instance is not usable during the following file processing. - QTimer::singleShot(0, [this, file_path]() + if (mw) { - HandlePupInstallation(file_path); - }); + // Handle the actual installation with a timeout. Otherwise the source explorer instance is not usable during the following file processing. + QTimer::singleShot(0, [mw, file_path]() + { + HandlePupInstallation(mw, file_path); + }); + } + else + { + HandlePupInstallation(nullptr, file_path); + } } } @@ -1353,7 +1436,7 @@ void main_window::ExtractPup() if (!dir.isEmpty()) { - HandlePupInstallation(file_path, dir); + HandlePupInstallation(this, file_path, dir); } } @@ -1427,13 +1510,15 @@ void main_window::ExtractTar() } } -void main_window::HandlePupInstallation(const QString& file_path, const QString& dir_path) +void main_window::HandlePupInstallation(main_window* mw, const QString& file_path, const QString& dir_path) { - const auto critical = [this](QString str) + const auto critical = [mw](QString str) { - Emu.CallFromMainThread([this, str = std::move(str)]() + if (!mw) return; + + Emu.CallFromMainThread([mw, str = std::move(str)]() { - QMessageBox::critical(this, tr("Firmware Installation Failed"), str); + QMessageBox::critical(mw, tr("Firmware Installation Failed"), str); }, nullptr, false); }; @@ -1444,14 +1529,17 @@ void main_window::HandlePupInstallation(const QString& file_path, const QString& return; } - if (!m_gui_settings->GetBootConfirmation(this)) + if (mw && !mw->m_gui_settings->GetBootConfirmation(mw)) { return; } - Emu.GracefulShutdown(false); + if (mw) + { + Emu.GracefulShutdown(false); - m_gui_settings->SetValue(gui::fd_install_pup, QFileInfo(file_path).path()); + mw->m_gui_settings->SetValue(gui::fd_install_pup, QFileInfo(file_path).path()); + } const std::string path = file_path.toStdString(); @@ -1506,7 +1594,8 @@ void main_window::HandlePupInstallation(const QString& file_path, const QString& critical(tr("Firmware installation failed: The provided file's contents are corrupted.")); return; } - case pup_error::ok: break; + case pup_error::ok: + break; } fs::file update_files_f = pup.get_file(0x300); @@ -1595,8 +1684,8 @@ void main_window::HandlePupInstallation(const QString& file_path, const QString& return; } - if (version_string < cur_version && - QMessageBox::question(this, tr("RPCS3 Firmware Installer"), tr("Old firmware detected.\nThe newest firmware version is %1 and you are trying to install version %2\nContinue installation?").arg(QString::fromUtf8(cur_version.data(), ::size32(cur_version)), QString::fromStdString(version_string)), + if (version_string < cur_version && mw && + QMessageBox::question(mw, tr("RPCS3 Firmware Installer"), tr("Old firmware detected.\nThe newest firmware version is %1 and you are trying to install version %2\nContinue installation?").arg(QString::fromUtf8(cur_version.data(), ::size32(cur_version)), QString::fromStdString(version_string)), QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes) == QMessageBox::No) { return; @@ -1606,7 +1695,7 @@ void main_window::HandlePupInstallation(const QString& file_path, const QString& { gui_log.warning("Reinstalling firmware: old=%s, new=%s", installed, version_string); - if (QMessageBox::question(this, tr("RPCS3 Firmware Installer"), tr("Firmware of version %1 has already been installed.\nOverwrite current installation with version %2?").arg(QString::fromStdString(installed), QString::fromStdString(version_string)), + if (mw && QMessageBox::question(mw, tr("RPCS3 Firmware Installer"), tr("Firmware of version %1 has already been installed.\nOverwrite current installation with version %2?").arg(QString::fromStdString(installed), QString::fromStdString(version_string)), QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes) == QMessageBox::No) { gui_log.warning("Reinstallation of firmware aborted."); @@ -1614,11 +1703,16 @@ void main_window::HandlePupInstallation(const QString& file_path, const QString& } } - // Remove possibly PS3 fonts from database - QFontDatabase::removeAllApplicationFonts(); + std::unique_ptr pdlg; - progress_dialog pdlg(tr("RPCS3 Firmware Installer"), tr("Installing firmware version %1\nPlease wait...").arg(QString::fromStdString(version_string)), tr("Cancel"), 0, static_cast(update_filenames.size()), false, this); - pdlg.show(); + if (mw) + { + // Remove possibly PS3 fonts from database + QFontDatabase::removeAllApplicationFonts(); + + pdlg = std::make_unique(tr("RPCS3 Firmware Installer"), tr("Installing firmware version %1\nPlease wait...").arg(QString::fromStdString(version_string)), tr("Cancel"), 0, static_cast(update_filenames.size()), false, mw); + pdlg->show(); + } // Used by tar_object::extract() as destination directory vfs::mount("/dev_flash", g_cfg_vfs.get_dev_flash()); @@ -1685,14 +1779,18 @@ void main_window::HandlePupInstallation(const QString& file_path, const QString& return true; } - if (pdlg.wasCanceled()) + if (pdlg) { - progress = -1; - return true; + if (pdlg->wasCanceled()) + { + progress = -1; + return true; + } + + // Update progress window + pdlg->SetValue(static_cast(value)); } - // Update progress window - pdlg.SetValue(static_cast(value)); return false; }); @@ -1704,24 +1802,32 @@ void main_window::HandlePupInstallation(const QString& file_path, const QString& if (progress == update_filenames.size()) { - pdlg.SetValue(pdlg.maximum()); + if (pdlg) + { + pdlg->SetValue(pdlg->maximum()); + } std::this_thread::sleep_for(100ms); } // Update with newly installed PS3 fonts - Q_EMIT RequestGlobalStylesheetChange(); + if (mw) + { + Q_EMIT mw->RequestGlobalStylesheetChange(); + } // Unmount Emu.Init(); if (progress == update_filenames.size()) { - ui->bootVSHAct->setEnabled(fs::is_file(g_cfg_vfs.get_dev_flash() + "/vsh/module/vsh.self")); - gui_log.success("Successfully installed PS3 firmware version %s.", version_string); - m_gui_settings->ShowInfoBox(tr("Success!"), tr("Successfully installed PS3 firmware and LLE Modules!"), gui::ib_pup_success, this); - CreateFirmwareCache(); + if (mw) + { + mw->ui->bootVSHAct->setEnabled(fs::is_file(g_cfg_vfs.get_dev_flash() + "/vsh/module/vsh.self")); + mw->m_gui_settings->ShowInfoBox(tr("Success!"), tr("Successfully installed PS3 firmware and LLE Modules!"), gui::ib_pup_success, mw); + mw->CreateFirmwareCache(); + } } } @@ -2714,8 +2820,8 @@ void main_window::CreateConnects() m_gui_settings->SetValue(gui::rs_freeze, checked); }); - connect(ui->bootInstallPkgAct, &QAction::triggered, this, [this] {InstallPackages(); }); - connect(ui->bootInstallPupAct, &QAction::triggered, this, [this] {InstallPup(); }); + connect(ui->bootInstallPkgAct, &QAction::triggered, this, [this] {InstallPackages(this); }); + connect(ui->bootInstallPupAct, &QAction::triggered, this, [this] {InstallPup(this); }); connect(this, &main_window::NotifyWindowCloseEvent, this, [this](bool closed) { @@ -4200,12 +4306,12 @@ void main_window::dropEvent(QDropEvent* event) } case drop_type::drop_rap_edat_pkg: // install the packages { - InstallPackages(drop_paths); + InstallPackages(this, drop_paths); break; } case drop_type::drop_pup: // install the firmware { - InstallPup(drop_paths.first()); + InstallPup(this, drop_paths.first()); break; } case drop_type::drop_psf: // Display PARAM.SFO content diff --git a/rpcs3/rpcs3qt/main_window.h b/rpcs3/rpcs3qt/main_window.h index b1dc4847d1..0dcf48200d 100644 --- a/rpcs3/rpcs3qt/main_window.h +++ b/rpcs3/rpcs3qt/main_window.h @@ -75,8 +75,8 @@ public: bool Init(bool with_cli_boot); QIcon GetAppIcon() const; void OnMissingFw(); - bool InstallPackages(QStringList file_paths = {}, bool from_boot = false); - void InstallPup(QString file_path = ""); + static bool InstallPackages(main_window* mw, QStringList file_paths = {}, bool from_boot = false); + static void InstallPup(main_window* mw, QString file_path = ""); Q_SIGNALS: void RequestLanguageChange(const QString& language); @@ -142,12 +142,12 @@ private: void PrecompileCachesFromInstalledPackages(const std::map& bootable_paths); void ShowOptionalGamePreparations(const QString& title, const QString& message, std::map game_path); - static bool InstallFileInExData(const std::string& extension, const QString& path, const std::string& filename); - - bool HandlePackageInstallation(QStringList file_paths, bool from_boot); void CreateShortCuts(const std::map& paths, std::set locations); - void HandlePupInstallation(const QString& file_path, const QString& dir_path = ""); + static bool InstallFileInExData(const std::string& extension, const QString& path, const std::string& filename); + static bool HandlePackageInstallation(main_window* mw, QStringList file_paths, bool from_boot); + static void HandlePupInstallation(main_window* mw, const QString& file_path, const QString& dir_path = ""); + void ExtractPup(); void ExtractTar();