diff --git a/src/init.cpp b/src/init.cpp --- a/src/init.cpp +++ b/src/init.cpp @@ -1694,9 +1694,9 @@ // Warn if unrecognized section name are present in the config file. for (const auto §ion : 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())) { @@ -1798,9 +1798,9 @@ [](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)); } } } @@ -1809,9 +1809,8 @@ // 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)); } } @@ -2104,9 +2103,9 @@ 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", diff --git a/src/interfaces/chain.h b/src/interfaces/chain.h --- a/src/interfaces/chain.h +++ b/src/interfaces/chain.h @@ -257,7 +257,7 @@ 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/interfaces/chain.cpp b/src/interfaces/chain.cpp --- a/src/interfaces/chain.cpp +++ b/src/interfaces/chain.cpp @@ -395,7 +395,7 @@ void initMessage(const std::string &message) override { ::uiInterface.InitMessage(message); } - void initWarning(const std::string &message) override { + void initWarning(const bilingual_str &message) override { InitWarning(message); } void initError(const bilingual_str &message) override { diff --git a/src/qt/walletcontroller.cpp b/src/qt/walletcontroller.cpp --- a/src/qt/walletcontroller.cpp +++ b/src/qt/walletcontroller.cpp @@ -248,9 +248,10 @@ 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) { @@ -291,9 +292,10 @@ 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) { diff --git a/src/ui_interface.h b/src/ui_interface.h --- a/src/ui_interface.h +++ b/src/ui_interface.h @@ -140,8 +140,7 @@ }; /** 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/ui_interface.cpp b/src/ui_interface.cpp --- a/src/ui_interface.cpp +++ b/src/ui_interface.cpp @@ -96,7 +96,6 @@ return false; } -void InitWarning(const std::string &str) { - uiInterface.ThreadSafeMessageBox(Untranslated(str), "", - CClientUIInterface::MSG_WARNING); +void InitWarning(const bilingual_str &str) { + uiInterface.ThreadSafeMessageBox(str, "", CClientUIInterface::MSG_WARNING); } diff --git a/src/util/string.h b/src/util/string.h --- a/src/util/string.h +++ b/src/util/string.h @@ -28,10 +28,10 @@ * @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) { - std::string ret; +template +auto Join(const std::vector &list, const BaseType &separator, + UnaryOp unary_op) -> decltype(unary_op(list.at(0))) { + decltype(unary_op(list.at(0))) ret; for (size_t i = 0; i < list.size(); ++i) { if (i > 0) { ret += separator; @@ -41,9 +41,15 @@ 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); } /** diff --git a/src/util/translation.h b/src/util/translation.h --- a/src/util/translation.h +++ b/src/util/translation.h @@ -17,26 +17,23 @@ 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) { - return bilingual_str{lhs.original + rhs.original, - lhs.translated + rhs.translated}; +inline bilingual_str operator+(bilingual_str lhs, const bilingual_str &rhs) { + lhs += rhs; + return lhs; } /** 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/load.cpp b/src/wallet/load.cpp --- a/src/wallet/load.cpp +++ b/src/wallet/load.cpp @@ -64,7 +64,7 @@ bool verify_success = CWallet::Verify(chainParams, chain, location, error_string, warnings); if (!warnings.empty()) { - chain.initWarning(Join(warnings, "\n", OpTranslated)); + chain.initWarning(Join(warnings, Untranslated("\n"))); } if (!verify_success) { chain.initError(error_string); @@ -83,7 +83,7 @@ std::shared_ptr pwallet = CWallet::CreateWalletFromFile( chainParams, chain, WalletLocation(walletFile), error, warnings); if (!warnings.empty()) { - chain.initWarning(Join(warnings, "\n", OpTranslated)); + chain.initWarning(Join(warnings, Untranslated("\n"))); } if (!pwallet) { chain.initError(error); diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -3212,7 +3212,7 @@ 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; } @@ -3384,7 +3384,7 @@ 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; }