mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-03-13 07:14:49 +00:00
PKG: Ask to user if he wants to install game shortcut on PKG installation
This commit is contained in:
parent
b7d80ab335
commit
0d126afb1f
@ -858,6 +858,12 @@ bool package_reader::extract_data(atomic_t<double>& sync)
|
||||
else
|
||||
{
|
||||
pkg_log.notice("Created file %s", path);
|
||||
|
||||
if (name == "USRDIR/EBOOT.BIN" && entry.file_size > 4)
|
||||
{
|
||||
// Expose the creation of a bootable file
|
||||
m_bootable_file_path = path;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -312,6 +312,11 @@ public:
|
||||
bool extract_data(atomic_t<double>& sync);
|
||||
psf::registry get_psf() const { return m_psf; }
|
||||
|
||||
std::string try_get_bootable_file_path_if_created_new() const
|
||||
{
|
||||
return m_bootable_file_path;
|
||||
}
|
||||
|
||||
private:
|
||||
bool read_header();
|
||||
bool read_metadata();
|
||||
@ -334,4 +339,7 @@ private:
|
||||
PKGHeader m_header{};
|
||||
PKGMetaData m_metadata{};
|
||||
psf::registry m_psf{};
|
||||
|
||||
// Expose bootable file installed (if installed such)
|
||||
std::string m_bootable_file_path;
|
||||
};
|
||||
|
@ -1021,7 +1021,7 @@ void game_list_frame::ShowContextMenu(const QPoint &pos)
|
||||
const std::string target_cli_args = fmt::format("--no-gui \"%s\"", gameinfo->info.path);
|
||||
const std::string target_icon_dir = fmt::format("%sIcons/game_icons/%s/", fs::get_config_dir(), gameinfo->info.serial);
|
||||
|
||||
if (gui::utils::create_shortcut(gameinfo->info.name, target_cli_args, gameinfo->info.name, gameinfo->info.icon_path, target_icon_dir, is_desktop_shortcut))
|
||||
if (gui::utils::create_shortcut(gameinfo->info.name, target_cli_args, gameinfo->info.name, gameinfo->info.icon_path, target_icon_dir, is_desktop_shortcut ? gui::utils::shortcut_location::desktop : gui::utils::shortcut_location::rpcs3_shortcuts))
|
||||
{
|
||||
game_list_log.success("Created %s shortcut for %s", is_desktop_shortcut ? "desktop" : "application menu", sstr(qstr(gameinfo->info.name).simplified()));
|
||||
QMessageBox::information(this, tr("Success!"), tr("Successfully created a shortcut."));
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include "input_dialog.h"
|
||||
#include "camera_settings_dialog.h"
|
||||
#include "ipc_settings_dialog.h"
|
||||
#include "shortcut_utils.h"
|
||||
|
||||
#include <thread>
|
||||
#include <charconv>
|
||||
@ -40,6 +41,8 @@
|
||||
#include <QMessageBox>
|
||||
#include <QFileDialog>
|
||||
#include <QFontDatabase>
|
||||
#include <QBuffer>
|
||||
#include <QTemporaryFile>
|
||||
|
||||
#include "rpcs3_version.h"
|
||||
#include "Emu/IdManager.h"
|
||||
@ -846,6 +849,7 @@ void main_window::HandlePackageInstallation(QStringList file_paths)
|
||||
package_error error = package_error::no_error;
|
||||
|
||||
bool cancelled = false;
|
||||
std::map<std::string, QString> bootable_paths_installed; // -> title
|
||||
|
||||
for (usz i = 0, count = packages.size(); i < count; i++)
|
||||
{
|
||||
@ -882,15 +886,21 @@ void main_window::HandlePackageInstallation(QStringList file_paths)
|
||||
const std::string path = sstr(package.path);
|
||||
const std::string file_name = sstr(file_info.fileName());
|
||||
|
||||
std::string bootable_path;
|
||||
|
||||
// Run PKG unpacking asynchronously
|
||||
named_thread worker("PKG Installer", [path, &progress, &error]
|
||||
named_thread worker("PKG Installer", [path, &progress, &error, &bootable_path]
|
||||
{
|
||||
package_reader reader(path);
|
||||
error = reader.check_target_app_version();
|
||||
|
||||
if (error == package_error::no_error)
|
||||
{
|
||||
return reader.extract_data(progress);
|
||||
if (reader.extract_data(progress))
|
||||
{
|
||||
bootable_path = reader.try_get_bootable_file_path_if_created_new();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
@ -922,7 +932,7 @@ void main_window::HandlePackageInstallation(QStringList file_paths)
|
||||
}
|
||||
else
|
||||
{
|
||||
pdlg.setHidden(true);
|
||||
pdlg.hide();
|
||||
pdlg.SignalFailure();
|
||||
}
|
||||
|
||||
@ -931,9 +941,132 @@ void main_window::HandlePackageInstallation(QStringList file_paths)
|
||||
m_game_list_frame->Refresh(true);
|
||||
gui_log.success("Successfully installed %s (title_id=%s, title=%s, version=%s).", file_name, sstr(package.title_id), sstr(package.title), sstr(package.version));
|
||||
|
||||
if (!bootable_path.empty())
|
||||
{
|
||||
bootable_paths_installed[bootable_path] = package.title;
|
||||
}
|
||||
|
||||
if (i == (count - 1))
|
||||
{
|
||||
m_gui_settings->ShowInfoBox(tr("Success!"), tr("Successfully installed software from package(s)!"), gui::ib_pkg_success, this);
|
||||
pdlg.hide();
|
||||
|
||||
bool create_desktop_shortcuts = false;
|
||||
bool create_app_shortcut = false;
|
||||
|
||||
if (bootable_paths_installed.empty())
|
||||
{
|
||||
m_gui_settings->ShowInfoBox(tr("Success!"), tr("Successfully installed software from package(s)!"), gui::ib_pkg_success, this);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto dlg = new QDialog(this);
|
||||
dlg->setWindowTitle(tr("Success!"));
|
||||
|
||||
QVBoxLayout* vlayout = new QVBoxLayout(dlg);
|
||||
|
||||
QCheckBox* desk_check = new QCheckBox(tr("Add desktop shortcut(s)"));
|
||||
#ifdef _WIN32
|
||||
QCheckBox* quick_check = new QCheckBox(tr("Add Start menu shortcut(s)"));
|
||||
#elif defined(__APPLE__)
|
||||
QCheckBox* quick_check = new QCheckBox(tr("Add dock shortcut(s)"));
|
||||
#else
|
||||
QCheckBox* quick_check = new QCheckBox(tr("Add launcher shortcut(s)"));
|
||||
#endif
|
||||
QLabel* label = new QLabel(tr("Successfully installed software from package(s)!\nWould you like to install shortcuts to the installed software? (%1 new software detected)\n\n").arg(bootable_paths_installed.size()), dlg);
|
||||
|
||||
vlayout->addWidget(label);
|
||||
vlayout->addStretch(10);
|
||||
vlayout->addWidget(desk_check);
|
||||
vlayout->addStretch(3);
|
||||
vlayout->addWidget(quick_check);
|
||||
vlayout->addStretch(3);
|
||||
|
||||
QDialogButtonBox* btn_box = new QDialogButtonBox(QDialogButtonBox::Ok);
|
||||
|
||||
vlayout->addWidget(btn_box);
|
||||
dlg->setLayout(vlayout);
|
||||
|
||||
connect(btn_box, &QDialogButtonBox::accepted, this, [&]()
|
||||
{
|
||||
create_desktop_shortcuts = desk_check->isChecked();
|
||||
create_app_shortcut = quick_check->isChecked();
|
||||
dlg->accept();
|
||||
});
|
||||
|
||||
dlg->setAttribute(Qt::WA_DeleteOnClose);
|
||||
dlg->exec();
|
||||
}
|
||||
|
||||
for (const auto& [boot_path, title] : bootable_paths_installed)
|
||||
{
|
||||
if (std::string game_dir = fs::get_parent_dir(boot_path, 2); fs::is_dir(game_dir) && fs::is_file(boot_path))
|
||||
{
|
||||
const std::string target_cli_args = fmt::format("--no-gui \"%%RPCS3_GAMEID%%:%s\"", game_dir.substr(game_dir.find_last_of(fs::delim) + 1));
|
||||
const std::string std_title_id = sstr(package.title_id);
|
||||
const std::string target_icon_dir = fmt::format("%sIcons/game_icons/%s/", fs::get_config_dir(), std_title_id);
|
||||
|
||||
// Copy the icon used by rpcs3 to a file
|
||||
QTemporaryFile tmp_file(QDir::tempPath() + "/tempFile");
|
||||
if (!tmp_file.open())
|
||||
{
|
||||
gui_log.error("Failed to create icon for '%s'", sstr(title.simplified()));
|
||||
continue;
|
||||
}
|
||||
|
||||
const QIcon icon = gui::utils::get_app_icon_from_path(rpcs3::utils::get_sfo_dir_from_game_path(boot_path + "/../../"), std_title_id);
|
||||
QPixmap pix = icon.pixmap(icon.actualSize(QSize(1000, 1000)));
|
||||
QByteArray bytes;
|
||||
QBuffer buffer(&bytes);
|
||||
buffer.open(QIODevice::ReadWrite);
|
||||
pix.save(&buffer, "PNG");
|
||||
tmp_file.write(bytes.data(), bytes.size());
|
||||
|
||||
std::string icon_path = sstr(tmp_file.fileName());
|
||||
#ifdef _WIN32
|
||||
if (gui::utils::create_shortcut(sstr(title), target_cli_args, sstr(title), icon_path, target_icon_dir, gui::utils::shortcut_location::rpcs3_shortcuts))
|
||||
{
|
||||
gui_log.success("Created a shortcut for '%s' at '%s/games/shortcuts/'", sstr(title.simplified()), fs::get_config_dir());
|
||||
}
|
||||
#endif
|
||||
|
||||
struct install_shortcut_info
|
||||
{
|
||||
std::string type;
|
||||
gui::utils::shortcut_location location;
|
||||
bool to_install;
|
||||
};
|
||||
|
||||
std::initializer_list<install_shortcut_info> installing_locations =
|
||||
{
|
||||
{"desktop", gui::utils::shortcut_location::desktop, create_desktop_shortcuts},
|
||||
#ifdef _WIN32
|
||||
{"Start menu", gui::utils::shortcut_location::applications, create_app_shortcut},
|
||||
#elif defined(__APPLE__)
|
||||
{"dock", gui::utils::shortcut_location::applications, create_app_shortcut},
|
||||
#else
|
||||
{"launcher", gui::utils::shortcut_location::applications, create_app_shortcut},
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
for (const auto& loc : installing_locations)
|
||||
{
|
||||
if (!loc.to_install)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (gui::utils::create_shortcut(sstr(title), target_cli_args, sstr(title), icon_path, target_icon_dir, loc.location))
|
||||
{
|
||||
gui_log.success("Created %s shortcut for %s", loc.type, sstr(title.simplified()));
|
||||
}
|
||||
else
|
||||
{
|
||||
gui_log.error("Failed to create %s shortcut for %s", loc.type, sstr(title.simplified()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -66,7 +66,7 @@ namespace gui::utils
|
||||
[[maybe_unused]] const std::string& description,
|
||||
[[maybe_unused]] const std::string& src_icon_path,
|
||||
[[maybe_unused]] const std::string& target_icon_dir,
|
||||
bool is_desktop_shortcut)
|
||||
shortcut_location location)
|
||||
{
|
||||
if (name.empty())
|
||||
{
|
||||
@ -84,14 +84,21 @@ namespace gui::utils
|
||||
|
||||
std::string link_path;
|
||||
|
||||
if (is_desktop_shortcut)
|
||||
if (location == shortcut_location::desktop)
|
||||
{
|
||||
link_path = QStandardPaths::writableLocation(QStandardPaths::StandardLocation::DesktopLocation).toStdString();
|
||||
}
|
||||
else
|
||||
else if (location == shortcut_location::applications)
|
||||
{
|
||||
link_path = QStandardPaths::writableLocation(QStandardPaths::StandardLocation::ApplicationsLocation).toStdString();
|
||||
}
|
||||
#ifdef _WIN32
|
||||
else if (location == shortcut_location::rpcs3_shortcuts)
|
||||
{
|
||||
link_path = fs::get_config_dir() + "/games/shortcuts/";
|
||||
fs::create_dir(link_path);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!fs::is_dir(link_path))
|
||||
{
|
||||
@ -99,7 +106,7 @@ namespace gui::utils
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!is_desktop_shortcut)
|
||||
if (location == shortcut_location::applications)
|
||||
{
|
||||
link_path += "/RPCS3";
|
||||
|
||||
@ -197,7 +204,7 @@ namespace gui::utils
|
||||
res = pPersistFile->Save(w_link_file.c_str(), TRUE);
|
||||
if (FAILED(res))
|
||||
{
|
||||
if (is_desktop_shortcut)
|
||||
if (location == shortcut_location::desktop)
|
||||
{
|
||||
return cleanup(false, fmt::format("Saving file to desktop failed (%s)", str_error(res)));
|
||||
}
|
||||
@ -348,7 +355,7 @@ namespace gui::utils
|
||||
}
|
||||
shortcut_file.close();
|
||||
|
||||
if (is_desktop_shortcut)
|
||||
if (location == shortcut_location::desktop)
|
||||
{
|
||||
if (chmod(link_path.c_str(), S_IRWXU) != 0) // enables user to execute file
|
||||
{
|
||||
|
@ -2,10 +2,19 @@
|
||||
|
||||
namespace gui::utils
|
||||
{
|
||||
enum shortcut_location
|
||||
{
|
||||
desktop,
|
||||
applications,
|
||||
#ifdef _WIN32
|
||||
rpcs3_shortcuts,
|
||||
#endif
|
||||
};
|
||||
|
||||
bool create_shortcut(const std::string& name,
|
||||
const std::string& target_cli_args,
|
||||
const std::string& description,
|
||||
const std::string& src_icon_path,
|
||||
const std::string& target_icon_dir,
|
||||
bool is_desktop_shortcut);
|
||||
shortcut_location shortcut_location);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user