diff --git a/src/frontend_common/firmware_manager.h b/src/frontend_common/firmware_manager.h index 23fce59eb3..40814a11f8 100644 --- a/src/frontend_common/firmware_manager.h +++ b/src/frontend_common/firmware_manager.h @@ -15,21 +15,12 @@ #include #include +#include "core/hle/result.h" #include "core/hle/service/set/settings_types.h" #include "core/hle/service/set/system_settings_server.h" -#include "core/hle/result.h" namespace FirmwareManager { -static constexpr std::array KEY_INSTALL_RESULT_STRINGS = { - "Decryption Keys were successfully installed", - "Unable to read key directory, aborting", - "One or more keys failed to copy.", - "Verify your keys file has a .keys extension and try again.", - "Decryption Keys failed to initialize. Check that your dumping tools are up to date and " - "re-dump keys.", -}; - static constexpr std::array FIRMWARE_REQUIRED_GAMES = { 0x0100152000022000ULL, // MK8DX }; @@ -50,16 +41,6 @@ enum KeyInstallResult { */ KeyInstallResult InstallKeys(std::string location, std::string expected_extension); -/** - * \brief Get a string representation of a result from InstallKeys. - * \param result The result code. - * \return A string representation of the passed result code. - */ -inline constexpr const char *GetKeyInstallResultString(KeyInstallResult result) -{ - return KEY_INSTALL_RESULT_STRINGS.at(static_cast(result)); -} - /** * \brief Check if the specified program requires firmware to run properly. * It is the responsibility of the frontend to properly expose this to the user. diff --git a/src/qt_common/CMakeLists.txt b/src/qt_common/CMakeLists.txt index 3fe990d7f2..e80fde24e0 100644 --- a/src/qt_common/CMakeLists.txt +++ b/src/qt_common/CMakeLists.txt @@ -66,7 +66,8 @@ target_compile_definitions(qt_common PUBLIC add_subdirectory(externals) -find_package(frozen REQUIRED) +# pass targets +find_package(frozen) target_link_libraries(qt_common PRIVATE core Qt6::Core Qt6::Concurrent SimpleIni::SimpleIni QuaZip::QuaZip) target_link_libraries(qt_common PUBLIC frozen::frozen-headers) diff --git a/src/qt_common/externals/cpmfile.json b/src/qt_common/externals/cpmfile.json index 0b464b95b2..3b8cec0def 100644 --- a/src/qt_common/externals/cpmfile.json +++ b/src/qt_common/externals/cpmfile.json @@ -13,7 +13,6 @@ "package": "frozen", "repo": "serge-sans-paille/frozen", "sha": "61dce5ae18", - "hash": "1ae3d073e659c1f24b2cdd76379c90d6af9e06bc707d285a4fafce05f7a4c9e592ff208c94a9ae0f0d07620b3c6cec191f126b03d70ad4dfa496a86ed5658a6d", - "bundled": true + "hash": "1ae3d073e659c1f24b2cdd76379c90d6af9e06bc707d285a4fafce05f7a4c9e592ff208c94a9ae0f0d07620b3c6cec191f126b03d70ad4dfa496a86ed5658a6d" } } diff --git a/src/qt_common/qt_string_lookup.h b/src/qt_common/qt_string_lookup.h index de6acac8a1..7756bcdaf2 100644 --- a/src/qt_common/qt_string_lookup.h +++ b/src/qt_common/qt_string_lookup.h @@ -3,11 +3,10 @@ #pragma once +#include #include -#include -#include -#include -#include +#include "frozen/map.h" +#include "frozen/string.h" namespace QtCommon::StringLookup { @@ -20,19 +19,85 @@ enum StringKey { UserNandTooltip, SysNandTooltip, ModsTooltip, + + // Key install results + KeyInstallSuccess, + KeyInstallInvalidDir, + KeyInstallErrorFailedCopy, + KeyInstallErrorWrongFilename, + KeyInstallErrorFailedInit, + + // Firmware install results + FwInstallSuccess, + FwInstallNoNCAs, + FwInstallFailedDelete, + FwInstallFailedCopy, + FwInstallFailedCorrupted, + + // user data migrator + MigrationPromptPrefix, + MigrationPrompt, + MigrationTooltipClearShader, + MigrationTooltipKeepOld, + MigrationTooltipClearOld, + MigrationTooltipLinkOld, + }; -static constexpr const frozen::unordered_map strings = { - {SavesTooltip, "Contains game save data. DO NOT REMOVE UNLESS YOU KNOW WHAT YOU'RE DOING!"}, - {ShadersTooltip, "Contains Vulkan and OpenGL pipeline caches. Generally safe to remove."}, - {UserNandTooltip, "Contains updates and DLC for games."}, - {SysNandTooltip, "Contains firmware and applet data."}, - {ModsTooltip, "Contains game mods, patches, and cheats."}, +static const frozen::map strings = { + {SavesTooltip, + QT_TR_NOOP("Contains game save data. DO NOT REMOVE UNLESS YOU KNOW WHAT YOU'RE DOING!")}, + {ShadersTooltip, + QT_TR_NOOP("Contains Vulkan and OpenGL pipeline caches. Generally safe to remove.")}, + {UserNandTooltip, QT_TR_NOOP("Contains updates and DLC for games.")}, + {SysNandTooltip, QT_TR_NOOP("Contains firmware and applet data.")}, + {ModsTooltip, QT_TR_NOOP("Contains game mods, patches, and cheats.")}, + + // Key install + {KeyInstallSuccess, QT_TR_NOOP("Decryption Keys were successfully installed")}, + {KeyInstallInvalidDir, QT_TR_NOOP("Unable to read key directory, aborting")}, + {KeyInstallErrorFailedCopy, QT_TR_NOOP("One or more keys failed to copy.")}, + {KeyInstallErrorWrongFilename, + QT_TR_NOOP("Verify your keys file has a .keys extension and try again.")}, + {KeyInstallErrorFailedInit, + QT_TR_NOOP( + "Decryption Keys failed to initialize. Check that your dumping tools are up to date and " + "re-dump keys.")}, + + // fw install + {FwInstallSuccess, QT_TR_NOOP("Successfully installed firmware version %1")}, + {FwInstallNoNCAs, QT_TR_NOOP("Unable to locate potential firmware NCA files")}, + {FwInstallFailedDelete, QT_TR_NOOP("Failed to delete one or more firmware files.")}, + {FwInstallFailedCopy, QT_TR_NOOP("One or more firmware files failed to copy into NAND.")}, + {FwInstallFailedCorrupted, + QT_TR_NOOP( + "Firmware installation cancelled, firmware may be in a bad state or corrupted. Restart " + "Eden or re-install firmware.")}, + + // migrator + {MigrationPromptPrefix, QT_TR_NOOP("Eden has detected user data for the following emulators:")}, + {MigrationPrompt, + QT_TR_NOOP("Would you like to migrate your data for use in Eden?\n" + "Select the corresponding button to migrate data from that emulator.\n" + "This may take a while.")}, + {MigrationTooltipClearShader, + QT_TR_NOOP("Clearing shader cache is recommended for all " + "users.\nDo not uncheck unless you know what " + "you're doing.")}, + {MigrationTooltipKeepOld, + QT_TR_NOOP("Keeps the old data directory. This is recommended if you aren't\n" + "space-constrained and want to keep separate data for the old emulator.")}, + {MigrationTooltipClearOld, + QT_TR_NOOP("Deletes the old data directory.\nThis is recommended on " + "devices with space constraints.")}, + {MigrationTooltipLinkOld, + QT_TR_NOOP("Creates a filesystem link between the old directory and Eden directory.\n" + "This is recommended if you want to share data between emulators.")}, }; static inline const QString Lookup(StringKey key) { - return QString::fromStdString(strings.at(key).data()); + return QObject::tr(strings.at(key).data()); } -} +} // namespace QtCommon::StringLookup diff --git a/src/qt_common/util/content.cpp b/src/qt_common/util/content.cpp index b42bdd8421..f7487ac36f 100644 --- a/src/qt_common/util/content.cpp +++ b/src/qt_common/util/content.cpp @@ -10,15 +10,15 @@ #include "frontend_common/data_manager.h" #include "frontend_common/firmware_manager.h" -#include "qt_common/qt_common.h" #include "compress.h" -#include "qt_common/abstract/qt_progress_dialog.h" #include "qt_common/abstract/qt_frontend_util.h" +#include "qt_common/abstract/qt_progress_dialog.h" +#include "qt_common/qt_common.h" #include +#include #include #include -#include namespace QtCommon::Content { @@ -60,15 +60,15 @@ void InstallFirmware(const QString& location, bool recursive) return progress.wasCanceled(); }; - static constexpr const char* failedTitle = "Firmware Install Failed"; - static constexpr const char* successTitle = "Firmware Install Succeeded"; + QString failedTitle = tr("Firmware Install Failed"); + QString successTitle = tr("Firmware Install Succeeded"); QMessageBox::Icon icon; FirmwareInstallResult result; const auto ShowMessage = [&]() { QtCommon::Frontend::ShowMessage(icon, - tr(failedTitle), - tr(GetFirmwareInstallResultString(result))); + failedTitle, + GetFirmwareInstallResultString(result)); }; LOG_INFO(Frontend, "Installing firmware from {}", location.toStdString()); @@ -188,10 +188,9 @@ void InstallFirmware(const QString& location, bool recursive) const std::string display_version(firmware_data.display_version.data()); result = FirmwareInstallResult::Success; - QtCommon::Frontend::Information( - rootObject, - tr(successTitle), - tr(GetFirmwareInstallResultString(result)).arg(QString::fromStdString(display_version))); + QtCommon::Frontend::Information(successTitle, + GetFirmwareInstallResultString(result).arg( + QString::fromStdString(display_version))); } QString UnzipFirmwareToTmp(const QString& location) @@ -277,14 +276,13 @@ void InstallKeys() system->GetFileSystemController().CreateFactories(*QtCommon::vfs); + const QString resMsg = GetKeyInstallResultString(result); switch (result) { case FirmwareManager::KeyInstallResult::Success: - QtCommon::Frontend::Information(tr("Decryption Keys install succeeded"), - tr("Decryption Keys were successfully installed")); + QtCommon::Frontend::Information(tr("Decryption Keys install succeeded"), resMsg); break; default: - QtCommon::Frontend::Critical(tr("Decryption Keys install failed"), - tr(FirmwareManager::GetKeyInstallResultString(result))); + QtCommon::Frontend::Critical(tr("Decryption Keys install failed"), resMsg); break; } } @@ -296,7 +294,7 @@ void VerifyInstalledContents() tr("Cancel"), 0, 100, - QtCommon::rootObject); + rootObject); progress.setWindowModality(Qt::WindowModal); progress.setMinimumDuration(100); progress.setAutoClose(false); @@ -415,7 +413,9 @@ void ExportDataDir(FrontendCommon::DataManager::DataDir data_dir, QGuiApplication::processEvents(); auto progress_callback = [=](size_t total_size, size_t processed_size) { - QMetaObject::invokeMethod(progress, "setValue", Qt::DirectConnection, + QMetaObject::invokeMethod(progress, + "setValue", + Qt::DirectConnection, Q_ARG(int, static_cast((processed_size * 100) / total_size))); return !progress->wasCanceled(); }; @@ -499,8 +499,11 @@ void ImportDataDir(FrontendCommon::DataManager::DataDir data_dir, QObject::connect(delete_watcher, &QFutureWatcher::finished, rootObject, [=]() { auto progress_callback = [=](size_t total_size, size_t processed_size) { - QMetaObject::invokeMethod(progress, "setValue", Qt::DirectConnection, - Q_ARG(int, static_cast((processed_size * 100) / total_size))); + QMetaObject::invokeMethod(progress, + "setValue", + Qt::DirectConnection, + Q_ARG(int, + static_cast((processed_size * 100) / total_size))); return !progress->wasCanceled(); }; diff --git a/src/qt_common/util/content.h b/src/qt_common/util/content.h index 29d45d5766..d1384546e1 100644 --- a/src/qt_common/util/content.h +++ b/src/qt_common/util/content.h @@ -7,33 +7,36 @@ #include #include "common/common_types.h" #include "frontend_common/data_manager.h" +#include "frontend_common/firmware_manager.h" +#include "qt_common/qt_string_lookup.h" namespace QtCommon::Content { // bool CheckGameFirmware(u64 program_id, QObject *parent); -static constexpr std::array FIRMWARE_RESULTS - = {"Successfully installed firmware version %1", - "", - "Unable to locate potential firmware NCA files", - "Failed to delete one or more firmware files.", - "One or more firmware files failed to copy into NAND.", - "Firmware installation cancelled, firmware may be in a bad state or corrupted." - "Restart Eden or re-install firmware."}; - enum class FirmwareInstallResult { Success, - NoOp, NoNCAs, FailedDelete, FailedCopy, FailedCorrupted, }; -inline constexpr const char *GetFirmwareInstallResultString(FirmwareInstallResult result) +inline const QString GetFirmwareInstallResultString(FirmwareInstallResult result) { - return FIRMWARE_RESULTS.at(static_cast(result)); + return QtCommon::StringLookup::Lookup(static_cast((int) result + (int) QtCommon::StringLookup::FwInstallSuccess)); +} + +/** + * \brief Get a string representation of a result from InstallKeys. + * \param result The result code. + * \return A string representation of the passed result code. + */ +inline const QString GetKeyInstallResultString(FirmwareManager::KeyInstallResult result) +{ + // this can probably be made into a common function of sorts + return QtCommon::StringLookup::Lookup(static_cast((int) result + (int) QtCommon::StringLookup::KeyInstallSuccess)); } void InstallFirmware(const QString &location, bool recursive); diff --git a/src/qt_common/util/game.cpp b/src/qt_common/util/game.cpp index 62bfd8acd3..04434c714f 100644 --- a/src/qt_common/util/game.cpp +++ b/src/qt_common/util/game.cpp @@ -8,9 +8,9 @@ #include "core/file_sys/savedata_factory.h" #include "core/hle/service/am/am_types.h" #include "frontend_common/content_manager.h" -#include "qt_common/qt_common.h" -#include "qt_common/config/uisettings.h" #include "qt_common/abstract/qt_frontend_util.h" +#include "qt_common/config/uisettings.h" +#include "qt_common/qt_common.h" #include "yuzu/util/util.h" #include @@ -166,7 +166,8 @@ bool MakeShortcutIcoPath(const u64 program_id, void OpenEdenFolder(const Common::FS::EdenPath& path) { - QDesktopServices::openUrl(QUrl::fromLocalFile(QString::fromStdString(Common::FS::GetEdenPathString(path)))); + QDesktopServices::openUrl( + QUrl::fromLocalFile(QString::fromStdString(Common::FS::GetEdenPathString(path)))); } void OpenRootDataFolder() @@ -181,7 +182,8 @@ void OpenNANDFolder() void OpenSaveFolder() { - const auto path = Common::FS::GetEdenPath(Common::FS::EdenPath::NANDDir) / "user/save/0000000000000000"; + const auto path = Common::FS::GetEdenPath(Common::FS::EdenPath::NANDDir) + / "user/save/0000000000000000"; QDesktopServices::openUrl(QUrl::fromLocalFile(QString::fromStdString(path.string()))); } @@ -220,12 +222,11 @@ void RemoveBaseContent(u64 program_id, InstalledEntryType type) const auto res = ContentManager::RemoveBaseContent(system->GetFileSystemController(), program_id); if (res) { - QtCommon::Frontend::Information(rootObject, - tr("Successfully Removed"), + QtCommon::Frontend::Information(tr("Successfully Removed"), tr("Successfully removed the installed base game.")); } else { QtCommon::Frontend::Warning( - rootObject, + GetGameListErrorRemoving(type), tr("The base game is not installed in the NAND and cannot be removed.")); } @@ -235,12 +236,10 @@ void RemoveUpdateContent(u64 program_id, InstalledEntryType type) { const auto res = ContentManager::RemoveUpdate(system->GetFileSystemController(), program_id); if (res) { - QtCommon::Frontend::Information(rootObject, - tr("Successfully Removed"), + QtCommon::Frontend::Information(tr("Successfully Removed"), tr("Successfully removed the installed update.")); } else { - QtCommon::Frontend::Warning(rootObject, - GetGameListErrorRemoving(type), + QtCommon::Frontend::Warning(GetGameListErrorRemoving(type), tr("There is no update installed for this title.")); } } @@ -249,14 +248,12 @@ void RemoveAddOnContent(u64 program_id, InstalledEntryType type) { const size_t count = ContentManager::RemoveAllDLC(*system, program_id); if (count == 0) { - QtCommon::Frontend::Warning(rootObject, - GetGameListErrorRemoving(type), + QtCommon::Frontend::Warning(GetGameListErrorRemoving(type), tr("There are no DLCs installed for this title.")); return; } - QtCommon::Frontend::Information(rootObject, - tr("Successfully Removed"), + QtCommon::Frontend::Information(tr("Successfully Removed"), tr("Successfully removed %1 installed DLC.").arg(count)); } @@ -279,18 +276,15 @@ void RemoveTransferableShaderCache(u64 program_id, GameListRemoveTarget target) const auto target_file = shader_cache_folder_path / target_file_name; if (!Common::FS::Exists(target_file)) { - QtCommon::Frontend::Warning(rootObject, - tr("Error Removing Transferable Shader Cache"), + QtCommon::Frontend::Warning(tr("Error Removing Transferable Shader Cache"), tr("A shader cache for this title does not exist.")); return; } if (Common::FS::RemoveFile(target_file)) { - QtCommon::Frontend::Information(rootObject, - tr("Successfully Removed"), + QtCommon::Frontend::Information(tr("Successfully Removed"), tr("Successfully removed the transferable shader cache.")); } else { - QtCommon::Frontend::Warning(rootObject, - tr("Error Removing Transferable Shader Cache"), + QtCommon::Frontend::Warning(tr("Error Removing Transferable Shader Cache"), tr("Failed to remove the transferable shader cache.")); } } @@ -307,8 +301,7 @@ void RemoveVulkanDriverPipelineCache(u64 program_id) return; } if (!Common::FS::RemoveFile(target_file)) { - QtCommon::Frontend::Warning(rootObject, - tr("Error Removing Vulkan Driver Pipeline Cache"), + QtCommon::Frontend::Warning(tr("Error Removing Vulkan Driver Pipeline Cache"), tr("Failed to remove the driver pipeline cache.")); } } @@ -319,18 +312,16 @@ void RemoveAllTransferableShaderCaches(u64 program_id) const auto program_shader_cache_dir = shader_cache_dir / fmt::format("{:016x}", program_id); if (!Common::FS::Exists(program_shader_cache_dir)) { - QtCommon::Frontend::Warning(rootObject, - tr("Error Removing Transferable Shader Caches"), + QtCommon::Frontend::Warning(tr("Error Removing Transferable Shader Caches"), tr("A shader cache for this title does not exist.")); return; } if (Common::FS::RemoveDirRecursively(program_shader_cache_dir)) { - QtCommon::Frontend::Information(rootObject, - tr("Successfully Removed"), + QtCommon::Frontend::Information(tr("Successfully Removed"), tr("Successfully removed the transferable shader caches.")); } else { QtCommon::Frontend::Warning( - rootObject, + tr("Error Removing Transferable Shader Caches"), tr("Failed to remove the transferable shader cache directory.")); } @@ -339,27 +330,23 @@ void RemoveAllTransferableShaderCaches(u64 program_id) void RemoveCustomConfiguration(u64 program_id, const std::string& game_path) { const auto file_path = std::filesystem::path(Common::FS::ToU8String(game_path)); - const auto config_file_name = program_id == 0 - ? Common::FS::PathToUTF8String(file_path.filename()) - .append(".ini") - : fmt::format("{:016X}.ini", program_id); + const auto config_file_name + = program_id == 0 ? Common::FS::PathToUTF8String(file_path.filename()).append(".ini") + : fmt::format("{:016X}.ini", program_id); const auto custom_config_file_path = Common::FS::GetEdenPath(Common::FS::EdenPath::ConfigDir) / "custom" / config_file_name; if (!Common::FS::Exists(custom_config_file_path)) { - QtCommon::Frontend::Warning(rootObject, - tr("Error Removing Custom Configuration"), + QtCommon::Frontend::Warning(tr("Error Removing Custom Configuration"), tr("A custom configuration for this title does not exist.")); return; } if (Common::FS::RemoveFile(custom_config_file_path)) { - QtCommon::Frontend::Information(rootObject, - tr("Successfully Removed"), + QtCommon::Frontend::Information(tr("Successfully Removed"), tr("Successfully removed the custom game configuration.")); } else { - QtCommon::Frontend::Warning(rootObject, - tr("Error Removing Custom Configuration"), + QtCommon::Frontend::Warning(tr("Error Removing Custom Configuration"), tr("Failed to remove the custom game configuration.")); } } @@ -392,18 +379,23 @@ void ResetMetadata(bool show_message) if (!Common::FS::Exists(Common::FS::GetEdenPath(Common::FS::EdenPath::CacheDir) / "game_list/")) { - if (show_message) QtCommon::Frontend::Warning(rootObject, title, tr("The metadata cache is already empty.")); + if (show_message) + QtCommon::Frontend::Warning(rootObject, + title, + tr("The metadata cache is already empty.")); } else if (Common::FS::RemoveDirRecursively( Common::FS::GetEdenPath(Common::FS::EdenPath::CacheDir) / "game_list")) { - if (show_message) QtCommon::Frontend::Information(rootObject, - title, - tr("The operation completed successfully.")); + if (show_message) + QtCommon::Frontend::Information(rootObject, + title, + tr("The operation completed successfully.")); UISettings::values.is_game_list_reload_pending.exchange(true); } else { - if (show_message) QtCommon::Frontend::Warning( - rootObject, - title, - tr("The metadata cache couldn't be deleted. It might be in use or non-existent.")); + if (show_message) + QtCommon::Frontend::Warning( + + title, + tr("The metadata cache couldn't be deleted. It might be in use or non-existent.")); } } @@ -446,7 +438,7 @@ inline constexpr bool CreateShortcutMessagesGUI(ShortcutMessages imsg, const QSt void CreateShortcut(const std::string& game_path, const u64 program_id, const std::string& game_title_, - const ShortcutTarget &target, + const ShortcutTarget& target, std::string arguments_, const bool needs_title) { @@ -458,16 +450,18 @@ void CreateShortcut(const std::string& game_path, if (!std::filesystem::exists(shortcut_path)) { CreateShortcutMessagesGUI(ShortcutMessages::Failed, - QString::fromStdString(shortcut_path.generic_string())); + QString::fromStdString(shortcut_path.generic_string())); LOG_ERROR(Frontend, "Invalid shortcut target {}", shortcut_path.generic_string()); return; } - const FileSys::PatchManager pm{program_id, QtCommon::system->GetFileSystemController(), + const FileSys::PatchManager pm{program_id, + QtCommon::system->GetFileSystemController(), QtCommon::system->GetContentProvider()}; const auto control = pm.GetControlMetadata(); - const auto loader = - Loader::GetLoader(*QtCommon::system, QtCommon::vfs->OpenFile(game_path, FileSys::OpenMode::Read)); + const auto loader = Loader::GetLoader(*QtCommon::system, + QtCommon::vfs->OpenFile(game_path, + FileSys::OpenMode::Read)); std::string game_title{game_title_}; @@ -498,8 +492,8 @@ void CreateShortcut(const std::string& game_path, LOG_WARNING(Frontend, "Could not read icon from {:s}", game_path); } - QImage icon_data = - QImage::fromData(icon_image_file.data(), static_cast(icon_image_file.size())); + QImage icon_data = QImage::fromData(icon_image_file.data(), + static_cast(icon_image_file.size())); std::filesystem::path out_icon_path; if (QtCommon::Game::MakeShortcutIcoPath(program_id, game_title, out_icon_path)) { if (!SaveIconToFile(out_icon_path, icon_data)) { @@ -532,33 +526,39 @@ void CreateShortcut(const std::string& game_path, const std::string categories = "Game;Emulator;Qt;"; const std::string keywords = "Switch;Nintendo;"; - if (QtCommon::Game::CreateShortcutLink(shortcut_path, comment, out_icon_path, command, - arguments, categories, keywords, game_title)) { - CreateShortcutMessagesGUI(ShortcutMessages::Success, - qgame_title); + if (QtCommon::Game::CreateShortcutLink(shortcut_path, + comment, + out_icon_path, + command, + arguments, + categories, + keywords, + game_title)) { + CreateShortcutMessagesGUI(ShortcutMessages::Success, qgame_title); return; } - CreateShortcutMessagesGUI(ShortcutMessages::Failed, - qgame_title); + CreateShortcutMessagesGUI(ShortcutMessages::Failed, qgame_title); } // TODO: You want this to be constexpr? Well too bad, clang19 doesn't believe this is a string literal -std::string GetShortcutPath(ShortcutTarget target) { +std::string GetShortcutPath(ShortcutTarget target) +{ { std::string shortcut_path{}; if (target == ShortcutTarget::Desktop) { - shortcut_path = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation) - .toStdString(); + shortcut_path + = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation).toStdString(); } else if (target == ShortcutTarget::Applications) { - shortcut_path = QStandardPaths::writableLocation(QStandardPaths::ApplicationsLocation) - .toStdString(); + shortcut_path + = QStandardPaths::writableLocation(QStandardPaths::ApplicationsLocation).toStdString(); } return shortcut_path; } } -void CreateHomeMenuShortcut(ShortcutTarget target) { +void CreateHomeMenuShortcut(ShortcutTarget target) +{ constexpr u64 QLaunchId = static_cast(Service::AM::AppletProgramId::QLaunch); auto bis_system = QtCommon::system->GetFileSystemController().GetSystemNANDContents(); if (!bis_system) { diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index 4f9dd4f9cd..4478734547 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp @@ -406,7 +406,7 @@ GMainWindow::GMainWindow(bool has_broken_vulkan) #define MIGRATE_DIR(type) \ std::string type##path = Common::FS::GetEdenPathString(Common::FS::EdenPath::type##Dir); \ if (type##path.starts_with(user_data_migrator.selected_emu.get_user_dir())) { \ - boost::replace_all(type##path, user_data_migrator.selected_emu.lower_name(), "eden"); \ + boost::replace_all(type##path, user_data_migrator.selected_emu.lower_name().toStdString(), "eden"); \ Common::FS::SetEdenPath(Common::FS::EdenPath::type##Dir, type##path); \ } diff --git a/src/yuzu/migration_worker.cpp b/src/yuzu/migration_worker.cpp index 95f205ec0c..b39bd22584 100644 --- a/src/yuzu/migration_worker.cpp +++ b/src/yuzu/migration_worker.cpp @@ -24,14 +24,14 @@ void MigrationWorker::process() namespace fs = std::filesystem; constexpr auto copy_options = fs::copy_options::update_existing | fs::copy_options::recursive; - const fs::path legacy_user_dir = selected_legacy_emu.get_user_dir(); + const fs::path legacy_user_dir = selected_legacy_emu.get_user_dir(); const fs::path legacy_config_dir = selected_legacy_emu.get_config_dir(); - const fs::path legacy_cache_dir = selected_legacy_emu.get_cache_dir(); + const fs::path legacy_cache_dir = selected_legacy_emu.get_cache_dir(); // TODO(crueter): Make these constexpr since they're defaulted - const fs::path eden_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::EdenDir); + const fs::path eden_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::EdenDir); const fs::path config_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::ConfigDir); - const fs::path cache_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::CacheDir); + const fs::path cache_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::CacheDir); const fs::path shader_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::ShaderDir); try { @@ -68,7 +68,7 @@ void MigrationWorker::process() success_text.append(tr("\n\nNote that your configuration and data will be shared with %1.\n" "If this is not desirable, delete the following files:\n%2\n%3\n%4") - .arg(tr(selected_legacy_emu.name), + .arg(selected_legacy_emu.name(), QString::fromStdString(eden_dir.string()), QString::fromStdString(config_dir.string()), QString::fromStdString(cache_dir.string()))); diff --git a/src/yuzu/migration_worker.h b/src/yuzu/migration_worker.h index 4d678e7751..5f9e400db0 100644 --- a/src/yuzu/migration_worker.h +++ b/src/yuzu/migration_worker.h @@ -10,7 +10,7 @@ using namespace Common::FS; typedef struct Emulator { - const char *name; + const char *m_name; LegacyPath e_user_dir; LegacyPath e_config_dir; @@ -28,23 +28,19 @@ typedef struct Emulator { return Common::FS::GetLegacyPath(e_cache_dir).string(); } - const std::string lower_name() const { - std::string lower_name{name}; - std::transform(lower_name.begin(), lower_name.end(), lower_name.begin(), - [](unsigned char c){ return std::tolower(c); }); + const QString name() const { return QObject::tr(m_name); + } - return lower_name; + const QString lower_name() const { return name().toLower(); } } Emulator; -#define EMU(name) Emulator{#name, name##Dir, name##ConfigDir, name##CacheDir} static constexpr std::array legacy_emus = { - EMU(Citron), - EMU(Sudachi), - EMU(Suyu), - EMU(Yuzu), + Emulator{QT_TR_NOOP("Citron"), CitronDir, CitronConfigDir, CitronCacheDir}, + Emulator{QT_TR_NOOP("Sudachi"), SudachiDir, SudachiConfigDir, SudachiCacheDir}, + Emulator{QT_TR_NOOP("Suyu"), SuyuDir, SuyuConfigDir, SuyuCacheDir}, + Emulator{QT_TR_NOOP("Yuzu"), YuzuDir, YuzuConfigDir, YuzuCacheDir}, }; -#undef EMU class MigrationWorker : public QObject { diff --git a/src/yuzu/user_data_migration.cpp b/src/yuzu/user_data_migration.cpp index 22cf1a188c..a0243ec882 100644 --- a/src/yuzu/user_data_migration.cpp +++ b/src/yuzu/user_data_migration.cpp @@ -11,12 +11,13 @@ #include #include #include "common/fs/path_util.h" -#include "../yuzu/migration_dialog.h" +#include "qt_common/qt_string_lookup.h" +#include "yuzu/migration_dialog.h" // Needs to be included at the end due to https://bugreports.qt.io/browse/QTBUG-73263 -#include #include #include +#include #include #include #include @@ -41,30 +42,19 @@ void UserDataMigrator::ShowMigrationPrompt(QMainWindow *main_window) namespace fs = std::filesystem; // define strings here for easy access - static constexpr const char *prompt_prefix_text - = "Eden has detected user data for the following emulators:"; - static constexpr const char *migration_prompt_message - = "Would you like to migrate your data for use in Eden?\n" - "Select the corresponding button to migrate data from that emulator.\n" - "This may take a while."; - - static constexpr const char *clear_shader_tooltip - = "Clearing shader cache is recommended for all " - "users.\nDo not uncheck unless you know what " - "you're doing."; - - static constexpr const char *keep_old_data_tooltip - = "Keeps the old data directory. This is recommended if you aren't\n" - "space-constrained and want to keep separate data for the old emulator."; - - static constexpr const char *clear_old_data_tooltip - = "Deletes the old data directory.\nThis is recommended on " - "devices with space constraints."; - - static constexpr const char *link_old_dir_tooltip - = "Creates a filesystem link between the old directory and Eden directory.\n" - "This is recommended if you want to share data between emulators."; + QString prompt_prefix_text = QtCommon::StringLookup::Lookup( + QtCommon::StringLookup::MigrationPromptPrefix); + QString migration_prompt_message = QtCommon::StringLookup::Lookup( + QtCommon::StringLookup::MigrationPrompt); + QString clear_shader_tooltip = QtCommon::StringLookup::Lookup( + QtCommon::StringLookup::MigrationTooltipClearShader); + QString keep_old_data_tooltip = QtCommon::StringLookup::Lookup( + QtCommon::StringLookup::MigrationTooltipKeepOld); + QString clear_old_data_tooltip = QtCommon::StringLookup::Lookup( + QtCommon::StringLookup::MigrationTooltipClearOld); + QString link_old_dir_tooltip = QtCommon::StringLookup::Lookup( + QtCommon::StringLookup::MigrationTooltipLinkOld); // actual migration code @@ -78,12 +68,12 @@ void UserDataMigrator::ShowMigrationPrompt(QMainWindow *main_window) #define BUTTON(clazz, name, text, tooltip, checkState) \ clazz *name = new clazz(&migration_prompt); \ - name->setText(QObject::tr(text)); \ - name->setToolTip(QObject::tr(tooltip)); \ + name->setText(text); \ + name->setToolTip(tooltip); \ name->setChecked(checkState); \ migration_prompt.addBox(name); - BUTTON(QCheckBox, clear_shaders, "Clear Shader Cache", clear_shader_tooltip, true) + BUTTON(QCheckBox, clear_shaders, QObject::tr("Clear Shader Cache"), clear_shader_tooltip, true) u32 id = 0; @@ -91,9 +81,9 @@ void UserDataMigrator::ShowMigrationPrompt(QMainWindow *main_window) BUTTON(QRadioButton, name, text, tooltip, checkState) \ group->addButton(name, ++id); - RADIO(keep_old, "Keep Old Data", keep_old_data_tooltip, true) - RADIO(clear_old, "Clear Old Data", clear_old_data_tooltip, false) - RADIO(link_old, "Link Old Directory", link_old_dir_tooltip, false) + RADIO(keep_old, QObject::tr("Keep Old Data"), keep_old_data_tooltip, true) + RADIO(clear_old, QObject::tr("Clear Old Data"), clear_old_data_tooltip, false) + RADIO(link_old, QObject::tr("Link Old Directory"), link_old_dir_tooltip, false) #undef RADIO #undef BUTTON @@ -111,20 +101,20 @@ void UserDataMigrator::ShowMigrationPrompt(QMainWindow *main_window) // makes my life easier qRegisterMetaType(); - QString prompt_text = QObject::tr(prompt_prefix_text); + QString prompt_text = prompt_prefix_text; // natural language processing is a nightmare for (const Emulator &emu : found) { - prompt_text.append(QStringLiteral("\n- %1").arg(QObject::tr(emu.name))); + prompt_text = prompt_text % QStringLiteral("\n ") % emu.name(); - QAbstractButton *button = migration_prompt.addButton(QObject::tr(emu.name)); + QAbstractButton *button = migration_prompt.addButton(emu.name()); // This is cursed, but it's actually the most efficient way by a mile button->setProperty("emulator", QVariant::fromValue(emu)); } prompt_text.append(QObject::tr("\n\n")); - prompt_text.append(QObject::tr(migration_prompt_message)); + prompt_text = prompt_text % QStringLiteral("\n\n") % migration_prompt_message; migration_prompt.setText(prompt_text); migration_prompt.addButton(QObject::tr("No"), true); @@ -191,16 +181,19 @@ void UserDataMigrator::MigrateUserData(QMainWindow *main_window, thread->connect(thread, &QThread::started, worker, &MigrationWorker::process); - thread->connect(worker, &MigrationWorker::finished, progress, [=, this](const QString &success_text, const std::string &path) { - progress->close(); - QMessageBox::information(main_window, - QObject::tr("Migration"), - success_text, - QMessageBox::Ok); + thread->connect(worker, + &MigrationWorker::finished, + progress, + [=, this](const QString &success_text, const std::string &path) { + progress->close(); + QMessageBox::information(main_window, + QObject::tr("Migration"), + success_text, + QMessageBox::Ok); - migrated = true; - thread->quit(); - }); + migrated = true; + thread->quit(); + }); thread->connect(worker, &MigrationWorker::finished, worker, &QObject::deleteLater); thread->connect(thread, &QThread::finished, thread, &QObject::deleteLater);