From 107372df595a9e2d06d0040eec8795e758c936c7 Mon Sep 17 00:00:00 2001 From: crueter Date: Sat, 18 Oct 2025 13:54:36 -0400 Subject: [PATCH] [qt] fix translations Linguist strongly dislikes lookup tables of this sort due to the fact that it looks for tr(), qsTr(), etc. when determining what strings need translations. To fix this, we can create a "fake" tr function that gets Linguist to recognize the strings while keeping them constexpr; then, the Lookup function can translate them at runtime. Signed-off-by: crueter --- src/frontend_common/firmware_manager.h | 21 +-------- src/qt_common/CMakeLists.txt | 2 - src/qt_common/externals/cpmfile.json | 3 +- src/qt_common/qt_string_lookup.h | 63 +++++++++++++++++++++----- src/qt_common/util/content.cpp | 34 ++++++++------ src/qt_common/util/content.h | 26 ++++++----- 6 files changed, 87 insertions(+), 62 deletions(-) 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..246590410c 100644 --- a/src/qt_common/CMakeLists.txt +++ b/src/qt_common/CMakeLists.txt @@ -66,8 +66,6 @@ target_compile_definitions(qt_common PUBLIC add_subdirectory(externals) -find_package(frozen REQUIRED) - 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..86d7603aad 100644 --- a/src/qt_common/qt_string_lookup.h +++ b/src/qt_common/qt_string_lookup.h @@ -4,15 +4,20 @@ #pragma once #include -#include -#include -#include -#include +#include "frozen/map.h" +#include "frozen/string.h" +#include namespace QtCommon::StringLookup { Q_NAMESPACE +// fake tr to make linguist happy +constexpr const frozen::string tr(const char *data) +{ + return frozen::string{data}; +} + // TODO(crueter): QML interface enum StringKey { SavesTooltip, @@ -20,19 +25,53 @@ enum StringKey { UserNandTooltip, SysNandTooltip, ModsTooltip, + + // Key install results + KeyInstallSuccess, + KeyInstallInvalidDir, + KeyInstallErrorFailedCopy, + KeyInstallErrorWrongFilename, + KeyInstallErrorFailedInit, + + // Firmware install results + FwInstallSuccess, + FwInstallNoOp, + FwInstallNoNCAs, + FwInstallFailedDelete, + FwInstallFailedCopy, + FwInstallFailedCorrupted, }; -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, tr("Contains game save data. DO NOT REMOVE UNLESS YOU KNOW WHAT YOU'RE DOING!")}, + {ShadersTooltip, tr("Contains Vulkan and OpenGL pipeline caches. Generally safe to remove.")}, + {UserNandTooltip, tr("Contains updates and DLC for games.")}, + {SysNandTooltip, tr("Contains firmware and applet data.")}, + {ModsTooltip, tr("Contains game mods, patches, and cheats.")}, + + // Key install results + {KeyInstallSuccess, tr("Decryption Keys were successfully installed")}, + {KeyInstallInvalidDir, tr("Unable to read key directory, aborting")}, + {KeyInstallErrorFailedCopy, tr("One or more keys failed to copy.")}, + {KeyInstallErrorWrongFilename, tr("Verify your keys file has a .keys extension and try again.")}, + {KeyInstallErrorFailedInit, + tr("Decryption Keys failed to initialize. Check that your dumping tools are up to date and " + "re-dump keys.")}, + + // fw install + {FwInstallSuccess, tr("Successfully installed firmware version %1")}, + {FwInstallNoOp, tr("")}, + {FwInstallNoNCAs, tr("Unable to locate potential firmware NCA files")}, + {FwInstallFailedDelete, tr("Failed to delete one or more firmware files.")}, + {FwInstallFailedCopy, tr("One or more firmware files failed to copy into NAND.")}, + {FwInstallFailedCorrupted, + tr("Firmware installation cancelled, firmware may be in a bad state or corrupted. Restart " + "Eden or re-install firmware.")}, }; 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..a47f8a0720 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 { @@ -68,7 +68,7 @@ void InstallFirmware(const QString& location, bool recursive) const auto ShowMessage = [&]() { QtCommon::Frontend::ShowMessage(icon, tr(failedTitle), - tr(GetFirmwareInstallResultString(result))); + GetFirmwareInstallResultString(result)); }; LOG_INFO(Frontend, "Installing firmware from {}", location.toStdString()); @@ -188,10 +188,10 @@ 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(rootObject, + tr(successTitle), + GetFirmwareInstallResultString(result).arg( + QString::fromStdString(display_version))); } QString UnzipFirmwareToTmp(const QString& location) @@ -277,14 +277,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; } } @@ -415,7 +414,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 +500,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..bbb014e9cb 100644 --- a/src/qt_common/util/content.h +++ b/src/qt_common/util/content.h @@ -7,21 +7,14 @@ #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, @@ -31,9 +24,20 @@ enum class FirmwareInstallResult { FailedCorrupted, }; -inline constexpr const char *GetFirmwareInstallResultString(FirmwareInstallResult result) +inline const QString GetFirmwareInstallResultString(FirmwareInstallResult 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) { - return FIRMWARE_RESULTS.at(static_cast(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);