From 64cff74861dba7264badfa114c120dd380722318 Mon Sep 17 00:00:00 2001 From: Megamouse Date: Fri, 9 Dec 2022 17:54:45 +0100 Subject: [PATCH] Qt: simplify shortcut creation --- rpcs3/rpcs3qt/game_list_frame.cpp | 148 +++++++++++++++++++----------- rpcs3/rpcs3qt/game_list_frame.h | 5 +- rpcs3/rpcs3qt/main_window.cpp | 88 +++++------------- 3 files changed, 120 insertions(+), 121 deletions(-) diff --git a/rpcs3/rpcs3qt/game_list_frame.cpp b/rpcs3/rpcs3qt/game_list_frame.cpp index 43aa53d482..9a0c112d9b 100644 --- a/rpcs3/rpcs3qt/game_list_frame.cpp +++ b/rpcs3/rpcs3qt/game_list_frame.cpp @@ -1,6 +1,5 @@ #include "game_list_frame.h" #include "qt_utils.h" -#include "shortcut_utils.h" #include "settings_dialog.h" #include "pad_settings_dialog.h" #include "table_item_delegate.h" @@ -895,6 +894,98 @@ void game_list_frame::ItemSelectionChangedSlot() Q_EMIT NotifyGameSelection(game); } +void game_list_frame::CreateShortcuts(const game_info& gameinfo, std::vector locations) +{ + if (locations.empty()) + { + game_list_log.error("Failed to create shortcuts for %s. No locations selected.", sstr(qstr(gameinfo->info.name).simplified())); + return; + } + + std::string gameid_token_value; + + if (gameinfo->info.category == "DG" && !fs::is_file(rpcs3::utils::get_hdd0_dir() + "/game/" + gameinfo->info.serial + "/USRDIR/EBOOT.BIN")) + { + const usz ps3_game_dir_pos = fs::get_parent_dir(gameinfo->info.path).size(); + std::string relative_boot_dir = gameinfo->info.path.substr(ps3_game_dir_pos); + + if (usz char_pos = relative_boot_dir.find_first_not_of(fs::delim); char_pos != umax) + { + relative_boot_dir = relative_boot_dir.substr(char_pos); + } + else + { + relative_boot_dir.clear(); + } + + if (!relative_boot_dir.empty()) + { + if (relative_boot_dir != "PS3_GAME") + { + gameid_token_value = gameinfo->info.serial + "/" + relative_boot_dir; + } + else + { + gameid_token_value = gameinfo->info.serial; + } + } + } + else + { + gameid_token_value = gameinfo->info.serial; + } + + const std::string target_cli_args = fmt::format("--no-gui \"%%RPCS3_GAMEID%%:%s\"", gameid_token_value); + const std::string target_icon_dir = fmt::format("%sIcons/game_icons/%s/", fs::get_config_dir(), gameinfo->info.serial); + + if (!fs::create_path(target_icon_dir)) + { + game_list_log.error("Failed to create shortcut path %s (%s)", sstr(qstr(gameinfo->info.name).simplified()), target_icon_dir, fs::g_tls_error); + return; + } + + bool success = true; + + for (const gui::utils::shortcut_location& location : locations) + { + std::string destination; + + switch (location) + { + case gui::utils::shortcut_location::desktop: + destination = "desktop"; + break; + case gui::utils::shortcut_location::applications: + destination = "application menu"; + break; +#ifdef _WIN32 + case gui::utils::shortcut_location::rpcs3_shortcuts: + destination = "/games/shortcuts/"; + break; +#endif + } + + if (!gameid_token_value.empty() && gui::utils::create_shortcut(gameinfo->info.name, target_cli_args, gameinfo->info.name, gameinfo->info.icon_path, target_icon_dir, location)) + { + game_list_log.success("Created %s shortcut for %s", destination, sstr(qstr(gameinfo->info.name).simplified())); + } + else + { + game_list_log.error("Failed to create %s shortcut for %s", destination, sstr(qstr(gameinfo->info.name).simplified())); + success = false; + } + } + + if (success) + { + QMessageBox::information(this, tr("Success!"), tr("Successfully created shortcut(s).")); + } + else + { + QMessageBox::warning(this, tr("Warning!"), tr("Failed to create shortcut(s)!")); + } +} + void game_list_frame::ShowContextMenu(const QPoint &pos) { QPoint global_pos; @@ -1016,58 +1107,9 @@ void game_list_frame::ShowContextMenu(const QPoint &pos) menu.addSeparator(); - const auto on_shortcut = [this, gameinfo](bool is_desktop_shortcut) - { - std::string gameid_token_value; - - if (gameinfo->info.category == "DG" && !fs::is_file(rpcs3::utils::get_hdd0_dir() + "/game/" + gameinfo->info.serial + "/USRDIR/EBOOT.BIN")) - { - const usz ps3_game_dir_pos = fs::get_parent_dir(gameinfo->info.path).size(); - std::string relative_boot_dir = gameinfo->info.path.substr(ps3_game_dir_pos); - - if (usz char_pos = relative_boot_dir.find_first_not_of(fs::delim); char_pos != umax) - { - relative_boot_dir = relative_boot_dir.substr(char_pos); - } - else - { - relative_boot_dir.clear(); - } - - if (!relative_boot_dir.empty()) - { - if (relative_boot_dir != "PS3_GAME") - { - gameid_token_value = gameinfo->info.serial + "/" + relative_boot_dir; - } - else - { - gameid_token_value = gameinfo->info.serial; - } - } - } - else - { - gameid_token_value = gameinfo->info.serial; - } - - const std::string target_cli_args = fmt::format("--no-gui \"%%RPCS3_GAMEID%%:%s\"", gameid_token_value); - const std::string target_icon_dir = fmt::format("%sIcons/game_icons/%s/", fs::get_config_dir(), gameinfo->info.serial); - - if (!gameid_token_value.empty() && 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::applications)) - { - 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.")); - } - else - { - game_list_log.error("Failed to create %s shortcut for %s", is_desktop_shortcut ? "desktop" : "application menu", sstr(qstr(gameinfo->info.name).simplified())); - QMessageBox::warning(this, tr("Warning!"), tr("Failed to create a shortcut!")); - } - }; QMenu* shortcut_menu = menu.addMenu(tr("&Create Shortcut")); QAction* create_desktop_shortcut = shortcut_menu->addAction(tr("&Create Desktop Shortcut")); - connect(create_desktop_shortcut, &QAction::triggered, this, [this, gameinfo, on_shortcut](){ on_shortcut(true); }); + connect(create_desktop_shortcut, &QAction::triggered, this, [this, gameinfo](){ CreateShortcuts(gameinfo, { gui::utils::shortcut_location::desktop }); }); #ifdef _WIN32 QAction* create_start_menu_shortcut = shortcut_menu->addAction(tr("&Create Start Menu Shortcut")); #elif defined(__APPLE__) @@ -1075,7 +1117,7 @@ void game_list_frame::ShowContextMenu(const QPoint &pos) #else QAction* create_start_menu_shortcut = shortcut_menu->addAction(tr("&Create Application Menu Shortcut")); #endif - connect(create_start_menu_shortcut, &QAction::triggered, this, [this, gameinfo, on_shortcut](){ on_shortcut(false); }); + connect(create_start_menu_shortcut, &QAction::triggered, this, [this, gameinfo](){ CreateShortcuts(gameinfo, { gui::utils::shortcut_location::applications }); }); menu.addSeparator(); @@ -2795,7 +2837,7 @@ void game_list_frame::SetPlayHoverGifs(bool play) } } -QList game_list_frame::GetGameInfo() const +const QList& game_list_frame::GetGameInfo() const { return m_game_data; } diff --git a/rpcs3/rpcs3qt/game_list_frame.h b/rpcs3/rpcs3qt/game_list_frame.h index 3dd1f93d8f..ae79658dcf 100644 --- a/rpcs3/rpcs3qt/game_list_frame.h +++ b/rpcs3/rpcs3qt/game_list_frame.h @@ -3,6 +3,7 @@ #include "game_list.h" #include "custom_dock_widget.h" #include "gui_save.h" +#include "shortcut_utils.h" #include "Utilities/lockless.h" #include "Emu/System.h" @@ -56,11 +57,13 @@ public: game_compatibility* GetGameCompatibility() const { return m_game_compat; } - QList GetGameInfo() const; + const QList& GetGameInfo() const; // Returns the visible version string in the game list static std::string GetGameVersion(const game_info& game); + void CreateShortcuts(const game_info& gameinfo, std::vector locations); + public Q_SLOTS: void BatchCreatePPUCaches(); void BatchRemovePPUCaches(); diff --git a/rpcs3/rpcs3qt/main_window.cpp b/rpcs3/rpcs3qt/main_window.cpp index a5bed6163d..4eaec06b80 100644 --- a/rpcs3/rpcs3qt/main_window.cpp +++ b/rpcs3/rpcs3qt/main_window.cpp @@ -849,7 +849,7 @@ void main_window::HandlePackageInstallation(QStringList file_paths) package_error error = package_error::no_error; bool cancelled = false; - std::map bootable_paths_installed; // -> title + std::map bootable_paths_installed; // -> title id for (usz i = 0, count = packages.size(); i < count; i++) { @@ -943,7 +943,7 @@ void main_window::HandlePackageInstallation(QStringList file_paths) if (!bootable_path.empty()) { - bootable_paths_installed[bootable_path] = package.title; + bootable_paths_installed[bootable_path] = package.title_id; } if (i == (count - 1)) @@ -997,73 +997,27 @@ void main_window::HandlePackageInstallation(QStringList file_paths) dlg->exec(); } - for (const auto& [boot_path, title] : bootable_paths_installed) + std::vector locations; +#ifdef _WIN32 + locations.push_back(gui::utils::shortcut_location::rpcs3_shortcuts); +#endif + if (create_desktop_shortcuts) { - if (std::string game_dir = fs::get_parent_dir(boot_path, 2); fs::is_dir(game_dir) && fs::is_file(boot_path)) + locations.push_back(gui::utils::shortcut_location::desktop); + } + if (create_app_shortcut) + { + locations.push_back(gui::utils::shortcut_location::applications); + } + + for (const auto& [boot_path, title_id] : bootable_paths_installed) + { + for (const game_info& gameinfo : m_game_list_frame->GetGameInfo()) { - 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()) + if (gameinfo && gameinfo->info.bootable && gameinfo->info.serial == sstr(title_id) && boot_path.starts_with(gameinfo->info.path)) { - 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 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())); - } + m_game_list_frame->CreateShortcuts(gameinfo, locations); + break; } } } @@ -2378,7 +2332,7 @@ void main_window::CreateConnects() std::unordered_map> games; if (m_game_list_frame) { - for (const auto& game : m_game_list_frame->GetGameInfo()) + for (const game_info& game : m_game_list_frame->GetGameInfo()) { if (game) {