From fe05dd0611cfc2929a7fdec04ca5948bccf0233b Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Sat, 9 May 2020 14:43:00 +0300 Subject: [PATCH 1/4] util: Enhance bilingual_str --- src/util/translation.h | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/util/translation.h b/src/util/translation.h index 45595405e..dd6056016 100644 --- a/src/util/translation.h +++ b/src/util/translation.h @@ -16,13 +16,19 @@ struct bilingual_str { std::string original; std::string translated; + + bilingual_str& operator+=(const bilingual_str& rhs) + { + original += rhs.original; + translated += rhs.translated; + return *this; + } }; -inline bilingual_str operator+(const bilingual_str& lhs, const bilingual_str& rhs) +inline bilingual_str operator+(bilingual_str lhs, const bilingual_str& rhs) { - return bilingual_str{ - lhs.original + rhs.original, - lhs.translated + rhs.translated}; + lhs += rhs; + return lhs; } /** Mark a bilingual_str as untranslated */ From 4c9b9a4882e68835f16a52f1f0657efe47e589b5 Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Sat, 9 May 2020 14:45:47 +0300 Subject: [PATCH 2/4] util: Enhance Join() --- src/util/string.h | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/util/string.h b/src/util/string.h index b8e2a0623..cdb41630c 100644 --- a/src/util/string.h +++ b/src/util/string.h @@ -30,10 +30,11 @@ NODISCARD inline std::string TrimString(const std::string& str, const std::strin * @param separator The separator * @param unary_op Apply this operator to each item in the list */ -template -std::string Join(const std::vector& list, const std::string& separator, UnaryOp unary_op) +template +auto Join(const std::vector& list, const BaseType& separator, UnaryOp unary_op) + -> decltype(unary_op(list.at(0))) { - std::string ret; + decltype(unary_op(list.at(0))) ret; for (size_t i = 0; i < list.size(); ++i) { if (i > 0) ret += separator; ret += unary_op(list.at(i)); @@ -41,9 +42,16 @@ std::string Join(const std::vector& list, const std::string& separator, Unary return ret; } +template +T Join(const std::vector& list, const T& separator) +{ + return Join(list, separator, [](const T& i) { return i; }); +} + +// Explicit overload needed for c_str arguments, which would otherwise cause a substitution failure in the template above. inline std::string Join(const std::vector& list, const std::string& separator) { - return Join(list, separator, [](const std::string& i) { return i; }); + return Join(list, separator); } /** From da16f95c3fecf4ee1e9a1dc4333b0b92cd981afd Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Sat, 9 May 2020 14:46:01 +0300 Subject: [PATCH 3/4] gui: Do not translate InitWarning messages in debug.log --- src/init.cpp | 10 +++++----- src/interfaces/chain.cpp | 2 +- src/interfaces/chain.h | 2 +- src/ui_interface.cpp | 4 ++-- src/ui_interface.h | 3 +-- src/wallet/load.cpp | 4 ++-- 6 files changed, 12 insertions(+), 13 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index 221cab15f..0851abe8a 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -971,7 +971,7 @@ bool AppInitParameterInteraction() // Warn if unrecognized section name are present in the config file. for (const auto& section : gArgs.GetUnrecognizedSections()) { - InitWarning(strprintf("%s:%i " + _("Section [%s] is not recognized.").translated, section.m_file, section.m_line, section.m_name)); + InitWarning(strprintf(Untranslated("%s:%i ") + _("Section [%s] is not recognized."), section.m_file, section.m_line, section.m_name)); } if (!fs::is_directory(GetBlocksDir())) { @@ -1027,7 +1027,7 @@ bool AppInitParameterInteraction() nMaxConnections = std::min(nFD - MIN_CORE_FILEDESCRIPTORS - MAX_ADDNODE_CONNECTIONS, nMaxConnections); if (nMaxConnections < nUserMaxConnections) - InitWarning(strprintf(_("Reducing -maxconnections from %d to %d, because of system limitations.").translated, nUserMaxConnections, nMaxConnections)); + InitWarning(strprintf(_("Reducing -maxconnections from %d to %d, because of system limitations."), nUserMaxConnections, nMaxConnections)); // ********************************************************* Step 3: parameter-to-internal-flags if (gArgs.IsArgSet("-debug")) { @@ -1038,7 +1038,7 @@ bool AppInitParameterInteraction() [](std::string cat){return cat == "0" || cat == "none";})) { for (const auto& cat : categories) { if (!LogInstance().EnableCategory(cat)) { - InitWarning(strprintf(_("Unsupported logging category %s=%s.").translated, "-debug", cat)); + InitWarning(strprintf(_("Unsupported logging category %s=%s."), "-debug", cat)); } } } @@ -1047,7 +1047,7 @@ bool AppInitParameterInteraction() // Now remove the logging categories which were explicitly excluded for (const std::string& cat : gArgs.GetArgs("-debugexclude")) { if (!LogInstance().DisableCategory(cat)) { - InitWarning(strprintf(_("Unsupported logging category %s=%s.").translated, "-debugexclude", cat)); + InitWarning(strprintf(_("Unsupported logging category %s=%s."), "-debugexclude", cat)); } } @@ -1260,7 +1260,7 @@ bool AppInitMain(NodeContext& node) LogPrintf("Config file: %s\n", config_file_path.string()); } else if (gArgs.IsArgSet("-conf")) { // Warn if no conf file exists at path provided by user - InitWarning(strprintf(_("The specified config file %s does not exist\n").translated, config_file_path.string())); + InitWarning(strprintf(_("The specified config file %s does not exist\n"), config_file_path.string())); } else { // Not categorizing as "Warning" because it's the default behavior LogPrintf("Config file: %s (not found, skipping)\n", config_file_path.string()); diff --git a/src/interfaces/chain.cpp b/src/interfaces/chain.cpp index 515a2ba1b..1f6e59ab3 100644 --- a/src/interfaces/chain.cpp +++ b/src/interfaces/chain.cpp @@ -344,7 +344,7 @@ public: bool shutdownRequested() override { return ShutdownRequested(); } int64_t getAdjustedTime() override { return GetAdjustedTime(); } void initMessage(const std::string& message) override { ::uiInterface.InitMessage(message); } - void initWarning(const std::string& message) override { InitWarning(message); } + void initWarning(const bilingual_str& message) override { InitWarning(message); } void initError(const bilingual_str& message) override { InitError(message); } void showProgress(const std::string& title, int progress, bool resume_possible) override { diff --git a/src/interfaces/chain.h b/src/interfaces/chain.h index 77b315b19..7dfc77db7 100644 --- a/src/interfaces/chain.h +++ b/src/interfaces/chain.h @@ -225,7 +225,7 @@ public: virtual void initMessage(const std::string& message) = 0; //! Send init warning. - virtual void initWarning(const std::string& message) = 0; + virtual void initWarning(const bilingual_str& message) = 0; //! Send init error. virtual void initError(const bilingual_str& message) = 0; diff --git a/src/ui_interface.cpp b/src/ui_interface.cpp index 9cfde9502..bb41154af 100644 --- a/src/ui_interface.cpp +++ b/src/ui_interface.cpp @@ -59,7 +59,7 @@ bool InitError(const bilingual_str& str) return false; } -void InitWarning(const std::string& str) +void InitWarning(const bilingual_str& str) { - uiInterface.ThreadSafeMessageBox(Untranslated(str), "", CClientUIInterface::MSG_WARNING); + uiInterface.ThreadSafeMessageBox(str, "", CClientUIInterface::MSG_WARNING); } diff --git a/src/ui_interface.h b/src/ui_interface.h index 132866cc5..9c49451e8 100644 --- a/src/ui_interface.h +++ b/src/ui_interface.h @@ -120,8 +120,7 @@ public: }; /** Show warning message **/ -// TODO: InitWarning() should take a bilingual_str parameter. -void InitWarning(const std::string& str); +void InitWarning(const bilingual_str& str); /** Show error message **/ bool InitError(const bilingual_str& str); diff --git a/src/wallet/load.cpp b/src/wallet/load.cpp index 45841b2ae..16f3699d3 100644 --- a/src/wallet/load.cpp +++ b/src/wallet/load.cpp @@ -56,7 +56,7 @@ bool VerifyWallets(interfaces::Chain& chain, const std::vector& wal bilingual_str error_string; std::vector warnings; bool verify_success = CWallet::Verify(chain, location, salvage_wallet, error_string, warnings); - if (!warnings.empty()) chain.initWarning(Join(warnings, "\n", OpTranslated)); + if (!warnings.empty()) chain.initWarning(Join(warnings, Untranslated("\n"))); if (!verify_success) { chain.initError(error_string); return false; @@ -73,7 +73,7 @@ bool LoadWallets(interfaces::Chain& chain, const std::vector& walle bilingual_str error; std::vector warnings; std::shared_ptr pwallet = CWallet::CreateWalletFromFile(chain, WalletLocation(walletFile), error, warnings); - if (!warnings.empty()) chain.initWarning(Join(warnings, "\n", OpTranslated)); + if (!warnings.empty()) chain.initWarning(Join(warnings, Untranslated("\n"))); if (!pwallet) { chain.initError(error); return false; From 78be8d97d3d750fcfbbe509a72639b7b30b7bd18 Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Sun, 10 May 2020 21:28:29 +0300 Subject: [PATCH 4/4] util: Drop OpOriginal() and OpTranslated() The current implementation of the Join() allows do not use OpOriginal() and OpTranslated() unary operators at all. --- src/qt/walletcontroller.cpp | 4 ++-- src/util/translation.h | 4 ---- src/wallet/rpcwallet.cpp | 4 ++-- 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/src/qt/walletcontroller.cpp b/src/qt/walletcontroller.cpp index 7cde3ca30..20f2ef5b5 100644 --- a/src/qt/walletcontroller.cpp +++ b/src/qt/walletcontroller.cpp @@ -248,7 +248,7 @@ void CreateWalletActivity::finish() if (!m_error_message.original.empty()) { QMessageBox::critical(m_parent_widget, tr("Create wallet failed"), QString::fromStdString(m_error_message.translated)); } else if (!m_warning_message.empty()) { - QMessageBox::warning(m_parent_widget, tr("Create wallet warning"), QString::fromStdString(Join(m_warning_message, "\n", OpTranslated))); + QMessageBox::warning(m_parent_widget, tr("Create wallet warning"), QString::fromStdString(Join(m_warning_message, Untranslated("\n")).translated)); } if (m_wallet_model) Q_EMIT created(m_wallet_model); @@ -289,7 +289,7 @@ void OpenWalletActivity::finish() if (!m_error_message.original.empty()) { QMessageBox::critical(m_parent_widget, tr("Open wallet failed"), QString::fromStdString(m_error_message.translated)); } else if (!m_warning_message.empty()) { - QMessageBox::warning(m_parent_widget, tr("Open wallet warning"), QString::fromStdString(Join(m_warning_message, "\n", OpTranslated))); + QMessageBox::warning(m_parent_widget, tr("Open wallet warning"), QString::fromStdString(Join(m_warning_message, Untranslated("\n")).translated)); } if (m_wallet_model) Q_EMIT opened(m_wallet_model); diff --git a/src/util/translation.h b/src/util/translation.h index dd6056016..268bcf30a 100644 --- a/src/util/translation.h +++ b/src/util/translation.h @@ -33,10 +33,6 @@ inline bilingual_str operator+(bilingual_str lhs, const bilingual_str& rhs) /** Mark a bilingual_str as untranslated */ inline bilingual_str Untranslated(std::string original) { return {original, original}; } -/** Unary operator to return the original */ -inline std::string OpOriginal(const bilingual_str& b) { return b.original; } -/** Unary operator to return the translation */ -inline std::string OpTranslated(const bilingual_str& b) { return b.translated; } namespace tinyformat { template diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index dda00f1fe..c36d22b4e 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -2597,7 +2597,7 @@ static UniValue loadwallet(const JSONRPCRequest& request) UniValue obj(UniValue::VOBJ); obj.pushKV("name", wallet->GetName()); - obj.pushKV("warning", Join(warnings, "\n", OpOriginal)); + obj.pushKV("warning", Join(warnings, Untranslated("\n")).original); return obj; } @@ -2737,7 +2737,7 @@ static UniValue createwallet(const JSONRPCRequest& request) UniValue obj(UniValue::VOBJ); obj.pushKV("name", wallet->GetName()); - obj.pushKV("warning", Join(warnings, "\n", OpOriginal)); + obj.pushKV("warning", Join(warnings, Untranslated("\n")).original); return obj; }