Skip to content

Commit

Permalink
[backport#16224 2/5] Make ThreadSafe{MessageBox|Question} bilingual
Browse files Browse the repository at this point in the history
Summary:
> This PR:
>
>  - makes GUI error messages bilingual: user's native language + untranslated (i.e. English)
>  - insures that only untranslated messages are written to the debug log file and to stderr (that is not the case on master).

Backport of Core [[bitcoin/bitcoin#16224 | PR16224]] - part 2 of 5
bitcoin/bitcoin@917ca93

Depends on D7985

Test Plan: `ninja && ninja check`

Reviewers: O1 Bitcoin ABC, #bitcoin_abc, deadalnix

Reviewed By: O1 Bitcoin ABC, #bitcoin_abc, deadalnix

Differential Revision: https://reviews.bitcoinabc.org/D7986
  • Loading branch information
hebasto authored and PiRK committed Oct 20, 2020
1 parent 4ca53cf commit 44c87af
Show file tree
Hide file tree
Showing 14 changed files with 101 additions and 90 deletions.
3 changes: 1 addition & 2 deletions src/httprpc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -405,8 +405,7 @@ static bool InitRPCAuthentication() {
// Same message as AbortNode.
uiInterface.ThreadSafeMessageBox(
_("Error: A fatal internal error occurred, see debug.log for "
"details")
.translated,
"details"),
"", CClientUIInterface::MSG_ERROR);
return false;
}
Expand Down
12 changes: 7 additions & 5 deletions src/httpserver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include <util/strencodings.h>
#include <util/system.h>
#include <util/threadnames.h>
#include <util/translation.h>

#include <event2/buffer.h>
#include <event2/bufferevent.h>
Expand Down Expand Up @@ -179,11 +180,12 @@ static bool InitHTTPAllowList() {
LookupSubNet(strAllow.c_str(), subnet);
if (!subnet.IsValid()) {
uiInterface.ThreadSafeMessageBox(
strprintf("Invalid -rpcallowip subnet specification: %s. "
"Valid are a single IP (e.g. 1.2.3.4), a "
"network/netmask (e.g. 1.2.3.4/255.255.255.0) or a "
"network/CIDR (e.g. 1.2.3.4/24).",
strAllow),
strprintf(
Untranslated("Invalid -rpcallowip subnet specification: "
"%s. Valid are a single IP (e.g. 1.2.3.4), a "
"network/netmask (e.g. 1.2.3.4/255.255.255.0) "
"or a network/CIDR (e.g. 1.2.3.4/24)."),
strAllow),
"", CClientUIInterface::MSG_ERROR);
return false;
}
Expand Down
6 changes: 4 additions & 2 deletions src/index/base.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <tinyformat.h>
#include <ui_interface.h>
#include <util/system.h>
#include <util/translation.h>
#include <validation.h>
#include <warnings.h>

Expand All @@ -25,8 +26,9 @@ static void FatalError(const char *fmt, const Args &... args) {
SetMiscWarning(strMessage);
LogPrintf("*** %s\n", strMessage);
uiInterface.ThreadSafeMessageBox(
"Error: A fatal internal error occurred, see debug.log for details", "",
CClientUIInterface::MSG_ERROR);
Untranslated("Error: A fatal internal error occurred, see debug.log "
"for details"),
"", CClientUIInterface::MSG_ERROR);
StartShutdown();
}

Expand Down
42 changes: 17 additions & 25 deletions src/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2395,7 +2395,7 @@ bool AppInitMain(Config &config, RPCServer &rpcServer,
bool fLoaded = false;
while (!fLoaded && !ShutdownRequested()) {
const bool fReset = fReindex;
std::string strLoadError;
bilingual_str strLoadError;

uiInterface.InitMessage(_("Loading block index...").translated);
do {
Expand Down Expand Up @@ -2437,7 +2437,7 @@ bool AppInitMain(Config &config, RPCServer &rpcServer,
if (ShutdownRequested()) {
break;
}
strLoadError = _("Error loading block database").translated;
strLoadError = _("Error loading block database");
break;
}

Expand All @@ -2458,8 +2458,7 @@ bool AppInitMain(Config &config, RPCServer &rpcServer,
strLoadError =
_("You need to rebuild the database using -reindex to "
"go back to unpruned mode. This will redownload the "
"entire blockchain")
.translated;
"entire blockchain");
break;
}

Expand All @@ -2470,8 +2469,7 @@ bool AppInitMain(Config &config, RPCServer &rpcServer,
// This is called again in ThreadImport after the reindex
// completes.
if (!fReindex && !LoadGenesisBlock(chainparams)) {
strLoadError =
_("Error initializing block database").translated;
strLoadError = _("Error initializing block database");
break;
}

Expand All @@ -2486,17 +2484,15 @@ bool AppInitMain(Config &config, RPCServer &rpcServer,
::ChainstateActive().CoinsErrorCatcher().AddReadErrCallback(
[]() {
uiInterface.ThreadSafeMessageBox(
_("Error reading from database, shutting down.")
.translated,
_("Error reading from database, shutting down."),
"", CClientUIInterface::MSG_ERROR);
});

// If necessary, upgrade from older database format.
// This is a no-op if we cleared the coinsviewdb with -reindex
// or -reindex-chainstate
if (!::ChainstateActive().CoinsDB().Upgrade()) {
strLoadError =
_("Error upgrading chainstate database").translated;
strLoadError = _("Error upgrading chainstate database");
break;
}

Expand All @@ -2505,8 +2501,7 @@ bool AppInitMain(Config &config, RPCServer &rpcServer,
if (!::ChainstateActive().ReplayBlocks(params)) {
strLoadError =
_("Unable to replay blocks. You will need to rebuild "
"the database using -reindex-chainstate.")
.translated;
"the database using -reindex-chainstate.");
break;
}

Expand All @@ -2521,8 +2516,7 @@ bool AppInitMain(Config &config, RPCServer &rpcServer,
// LoadChainTip initializes the chain based on CoinsTip()'s
// best block
if (!::ChainstateActive().LoadChainTip(chainparams)) {
strLoadError =
_("Error initializing block database").translated;
strLoadError = _("Error initializing block database");
break;
}
assert(::ChainActive().Tip() != nullptr);
Expand All @@ -2548,8 +2542,7 @@ bool AppInitMain(Config &config, RPCServer &rpcServer,
"to your computer's date and time being set "
"incorrectly. Only rebuild the block database if "
"you are sure that your computer's date and time "
"are correct")
.translated;
"are correct");
break;
}

Expand All @@ -2558,14 +2551,13 @@ bool AppInitMain(Config &config, RPCServer &rpcServer,
gArgs.GetArg("-checklevel", DEFAULT_CHECKLEVEL),
gArgs.GetArg("-checkblocks",
DEFAULT_CHECKBLOCKS))) {
strLoadError =
_("Corrupted block database detected").translated;
strLoadError = _("Corrupted block database detected");
break;
}
}
} catch (const std::exception &e) {
LogPrintf("%s\n", e.what());
strLoadError = _("Error opening block database").translated;
strLoadError = _("Error opening block database");
break;
}

Expand All @@ -2578,11 +2570,11 @@ bool AppInitMain(Config &config, RPCServer &rpcServer,
// first suggest a reindex
if (!fReset) {
bool fRet = uiInterface.ThreadSafeQuestion(
strLoadError + ".\n\n" +
_("Do you want to rebuild the block database now?")
.translated,
strLoadError + ".\nPlease restart with -reindex or "
"-reindex-chainstate to recover.",
strLoadError + Untranslated(".\n\n") +
_("Do you want to rebuild the block database now?"),
strLoadError.original +
".\nPlease restart with -reindex or "
"-reindex-chainstate to recover.",
"",
CClientUIInterface::MSG_ERROR |
CClientUIInterface::BTN_ABORT);
Expand All @@ -2594,7 +2586,7 @@ bool AppInitMain(Config &config, RPCServer &rpcServer,
return false;
}
} else {
return InitError(strLoadError);
return InitError(strLoadError.translated);
}
}
}
Expand Down
9 changes: 5 additions & 4 deletions src/interfaces/node.h
Original file line number Diff line number Diff line change
Expand Up @@ -228,14 +228,15 @@ class Node {

//! Register handler for message box messages.
using MessageBoxFn =
std::function<bool(const std::string &message,
std::function<bool(const bilingual_str &message,
const std::string &caption, unsigned int style)>;
virtual std::unique_ptr<Handler> handleMessageBox(MessageBoxFn fn) = 0;

//! Register handler for question messages.
using QuestionFn = std::function<bool(
const std::string &message, const std::string &non_interactive_message,
const std::string &caption, unsigned int style)>;
using QuestionFn =
std::function<bool(const bilingual_str &message,
const std::string &non_interactive_message,
const std::string &caption, unsigned int style)>;
virtual std::unique_ptr<Handler> handleQuestion(QuestionFn fn) = 0;

//! Register handler for progress messages.
Expand Down
40 changes: 18 additions & 22 deletions src/net.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2208,27 +2208,28 @@ void CConnman::ThreadMessageHandler() {
}
}

bool CConnman::BindListenPort(const CService &addrBind, std::string &strError,
bool CConnman::BindListenPort(const CService &addrBind, bilingual_str &strError,
NetPermissionFlags permissions) {
strError = "";
int nOne = 1;

// Create socket for listening for incoming connections
struct sockaddr_storage sockaddr;
socklen_t len = sizeof(sockaddr);
if (!addrBind.GetSockAddr((struct sockaddr *)&sockaddr, &len)) {
strError = strprintf("Error: Bind address family for %s not supported",
addrBind.ToString());
LogPrintf("%s\n", strError);
strError = strprintf(
Untranslated("Error: Bind address family for %s not supported"),
addrBind.ToString());
LogPrintf("%s\n", strError.original);
return false;
}

SOCKET hListenSocket = CreateSocket(addrBind);
if (hListenSocket == INVALID_SOCKET) {
strError = strprintf("Error: Couldn't open socket for incoming "
"connections (socket returned error %s)",
NetworkErrorString(WSAGetLastError()));
LogPrintf("%s\n", strError);
strError =
strprintf(Untranslated("Error: Couldn't open socket for incoming "
"connections (socket returned error %s)"),
NetworkErrorString(WSAGetLastError()));
LogPrintf("%s\n", strError.original);
return false;
}

Expand Down Expand Up @@ -2257,16 +2258,14 @@ bool CConnman::BindListenPort(const CService &addrBind, std::string &strError,
int nErr = WSAGetLastError();
if (nErr == WSAEADDRINUSE) {
strError = strprintf(_("Unable to bind to %s on this computer. %s "
"is probably already running.")
.translated,
"is probably already running."),
addrBind.ToString(), PACKAGE_NAME);
} else {
strError = strprintf(_("Unable to bind to %s on this computer "
"(bind returned error %s)")
.translated,
"(bind returned error %s)"),
addrBind.ToString(), NetworkErrorString(nErr));
}
LogPrintf("%s\n", strError);
LogPrintf("%s\n", strError.original);
CloseSocket(hListenSocket);
return false;
}
Expand All @@ -2275,10 +2274,9 @@ bool CConnman::BindListenPort(const CService &addrBind, std::string &strError,
// Listen for incoming connections
if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR) {
strError = strprintf(_("Error: Listening for incoming connections "
"failed (listen returned error %s)")
.translated,
"failed (listen returned error %s)"),
NetworkErrorString(WSAGetLastError()));
LogPrintf("%s\n", strError);
LogPrintf("%s\n", strError.original);
CloseSocket(hListenSocket);
return false;
}
Expand Down Expand Up @@ -2373,7 +2371,7 @@ bool CConnman::Bind(const CService &addr, unsigned int flags,
if (!(flags & BF_EXPLICIT) && !IsReachable(addr)) {
return false;
}
std::string strError;
bilingual_str strError;
if (!BindListenPort(addr, strError, permissions)) {
if ((flags & BF_REPORT_ERROR) && clientInterface) {
clientInterface->ThreadSafeMessageBox(
Expand Down Expand Up @@ -2427,8 +2425,7 @@ bool CConnman::Start(CScheduler &scheduler, const Options &connOptions) {
if (clientInterface) {
clientInterface->ThreadSafeMessageBox(
_("Failed to listen on any port. Use -listen=0 if you want "
"this.")
.translated,
"this."),
"", CClientUIInterface::MSG_ERROR);
}
return false;
Expand Down Expand Up @@ -2508,8 +2505,7 @@ bool CConnman::Start(CScheduler &scheduler, const Options &connOptions) {
if (clientInterface) {
clientInterface->ThreadSafeMessageBox(
_("Cannot provide specific connections and have addrman find "
"outgoing connections at the same.")
.translated,
"outgoing connections at the same."),
"", CClientUIInterface::MSG_ERROR);
}
return false;
Expand Down
3 changes: 2 additions & 1 deletion src/net.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ class BanMan;
class Config;
class CNode;
class CScheduler;
struct bilingual_str;

/** Default for -whitelistrelay. */
static const bool DEFAULT_WHITELISTRELAY = true;
Expand Down Expand Up @@ -363,7 +364,7 @@ class CConnman {
NetPermissionFlags m_permissions;
};

bool BindListenPort(const CService &bindAddr, std::string &strError,
bool BindListenPort(const CService &bindAddr, bilingual_str &strError,
NetPermissionFlags permissions);
bool Bind(const CService &addr, unsigned int flags,
NetPermissionFlags permissions);
Expand Down
18 changes: 9 additions & 9 deletions src/noui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@

#include <noui.h>

#include <logging.h>
#include <ui_interface.h>
#include <util/system.h>
#include <util/translation.h>

#include <boost/signals2/connection.hpp>
Expand All @@ -17,7 +17,7 @@ boost::signals2::connection noui_ThreadSafeMessageBoxConn;
boost::signals2::connection noui_ThreadSafeQuestionConn;
boost::signals2::connection noui_InitMessageConn;

bool noui_ThreadSafeMessageBox(const std::string &message,
bool noui_ThreadSafeMessageBox(const bilingual_str &message,
const std::string &caption, unsigned int style) {
bool fSecure = style & CClientUIInterface::SECURE;
style &= ~CClientUIInterface::SECURE;
Expand All @@ -43,17 +43,17 @@ bool noui_ThreadSafeMessageBox(const std::string &message,
}

if (!fSecure) {
LogPrintf("%s%s\n", strCaption, message);
LogPrintf("%s%s\n", strCaption, message.original);
}
tfm::format(std::cerr, "%s%s\n", strCaption.c_str(), message.c_str());
tfm::format(std::cerr, "%s%s\n", strCaption, message.original);
return false;
}

bool noui_ThreadSafeQuestion(
const std::string & /* ignored interactive message */,
const bilingual_str & /* ignored interactive message */,
const std::string &message, const std::string &caption,
unsigned int style) {
return noui_ThreadSafeMessageBox(message, caption, style);
return noui_ThreadSafeMessageBox(Untranslated(message), caption, style);
}

void noui_InitMessage(const std::string &message) {
Expand All @@ -68,15 +68,15 @@ void noui_connect() {
noui_InitMessageConn = uiInterface.InitMessage_connect(noui_InitMessage);
}

bool noui_ThreadSafeMessageBoxRedirect(const std::string &message,
bool noui_ThreadSafeMessageBoxRedirect(const bilingual_str &message,
const std::string &caption,
unsigned int style) {
LogPrintf("%s: %s\n", caption, message);
LogPrintf("%s: %s\n", caption, message.original);
return false;
}

bool noui_ThreadSafeQuestionRedirect(
const std::string & /* ignored interactive message */,
const bilingual_str & /* ignored interactive message */,
const std::string &message, const std::string &caption,
unsigned int style) {
LogPrintf("%s: %s\n", caption, message);
Expand Down
Loading

0 comments on commit 44c87af

Please sign in to comment.