-
Notifications
You must be signed in to change notification settings - Fork 38.3k
gui: Introduce bilingual GUI error messages #15340
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
src/ui_interface.h
Outdated
| bool InitErrorFormat(const char* fmt, const Args&... args) | ||
| { | ||
| std::string original_message = strprintf(fmt, args...); | ||
| std::string translated_message = strprintf(_(fmt), args...); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe make translate wouldn't pick those up any more.
ecd6197 to
0faa14c
Compare
|
This effectively removes all the translations as there is no |
|
The following sections might be updated with supplementary metadata relevant to reviewers and maintainers. ConflictsReviewers, this pull request conflicts with the following ones:
If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first. |
|
This would be much easier to review if |
0faa14c to
63b7018
Compare
Fixed. The main goal of this PR is to avoid printing localized messages to the debug log file and |
Rationale: |
|
I haven't looked at the code but printing error message always (additionally) in english seems to be a clever idea (especially with the faced complexity and immaturity of the UX). |
54c8d00 to
fb394a6
Compare
|
@MarcoFalke @laanwj it works with gettext now. @luke-jr your comment has been addressed. |
|
Rebased. |
src/init.cpp
Outdated
| if(!ECC_InitSanityCheck()) { | ||
| InitError("Elliptic curve cryptography sanity check failure. Aborting."); | ||
| if (!ECC_InitSanityCheck()) { | ||
| InitError(_("Elliptic curve cryptography sanity check failure. Aborting.", true)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand why this should be translated. This should never fail and if it fails, I bet you are better off with the english error message?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree, I feel we had this discussion already. Please don't translate extremely rare or technical errors.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
btw, this PR aims that a translated message:
- is written to debug log in English
- is printed to
stderrin English - is shown in GUI in both languages
Therefore, english error message is always available even for translated messages.
src/init.cpp
Outdated
|
|
||
| if (!Random_SanityCheck()) { | ||
| InitError("OS cryptographic RNG sanity check failure. Aborting."); | ||
| InitError(_("OS cryptographic RNG sanity check failure. Aborting.", true)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same for this one
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
src/ui_interface.cpp
Outdated
| } | ||
|
|
||
| ADD_SIGNALS_IMPL_WRAPPER(ThreadSafeMessageBox); | ||
| ADD_SIGNALS_IMPL_WRAPPER(ThreadSafeMessageBox2); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please use a better name than ThreadSafeMessageBox2. What makes this function different?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
btw, 2 in ThreadSafeMessageBox2 meant "bi-" in bilingual rather "second" :)
fb394a6 to
01781b4
Compare
|
@MarcoFalke @laanwj |
src/init.cpp
Outdated
|
|
||
| if (!SetupNetworking()) | ||
| return InitError("Initializing networking failed"); | ||
| return InitError(_("Initializing networking failed", true)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same here. This should never fail
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
01781b4 to
9a53d13
Compare
|
If the point is to make it easier to google error messages, wouldn't it be more efficient to add some kind of error code to the output? E.g. the example from the screenshot could look like this in the English version: and like this in the German version: This would also help searchability if the English error text changes between versions. Only drawback I suppose is that somebody would have to come up with all the error codes :-) |
|
I like the idea (so Concept ACK), no thoughts on the implementation. @flack Trying to assign numerical error codes in the face of parallel development seems tricky... but not impossible. The dual languages also helps in the common case that the user also reads English... since the translation may not be good or may not be clear (esp. even a native speaker of another language may have only seen various technical terms but a translator managed to use a rarely used word in the translated language). Error numbers don't have this benefit, so the dual language output would be useful independently of error numbers. |
|
@gmaxwell yes, it would require some coordination. But I suppose a linter can take care of most of the problems, esp. since the numbers don't have to be consecutive or follow any kind of logic really. It's true what you say about wonky translations. "Kürzungsmodus" from the screenshot is actually a case in point. It literally means "shortening mode". No way I would have guessed that this refers to pruning (or at least not on the first try). But otoh, if users have the UI set to e.g. German, then all they see are German terms, i.e. there's probably a checkbox labeled "Kürzungsmodus" somewhere and they might remember that they clicked that. Throwing the word "pruning" into the mix might just add to the confusion at this point, exactly because the meaning is different ("I selected shortening mode and now it's complaining about 'pruning' ?!?"). Anyhow, I get that my suggestion cannot be easily implemented in the short term, but how about making it a bit more clear that the two messages are actually referring to the same thing (instead of being one translated error and one untranslated error)? E.g. something like: "Original-Meldung" means "original message". Could also say "untranslated message" or something. |
I think we need to be careful here also to respect the translators. They are not developers and will not understand internal technical details in error messages. If an error message has more technical terms in it than the standard bitcoin and GUI ones such as window, wallet, block, transaction …. then it shouldn't be translated. Translators will get pissed at me for this or substitute some nonsense word. In both cases no one is better off. |
Still, you have to enable the user to make the connection between the error message and what they might have selected in the GUI settings. So e.g. if you don't translate "prune" in the error message, then you also shouldn't translate it in the rest of the GUI (or at least show the English term in brackets) |
|
prune is a grey area I guess. It doesn't go with the obvious bitcoin or computer words but it also isn't something like "glibc sanity check failed" which makes no sense to users nor translators whatsoever. So to be clear Im not against showing error messages in both languages, but this shouldn't a reason to translate things that would otherwise not be because the English message can be used to work around a terrible translation. |
9a53d13 to
539950b
Compare
|
Rebased. |
| Needs rebase |
539950b to
8aca2cf
Compare
|
@hebasto awesome! |
|
After the e2c8ba9 commit merged there is no straight way to pass function template I ask for advice @ryanofsky, @MarcoFalke, @jonasschnelli, @promag. |
maflcko
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Concept ACK
| std::string translated_str; | ||
| }; | ||
|
|
||
| inline bilingual_str _(const char* psz, bool translate) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the point of the bool argument, when it is always set to true at the call site? Should be called bool ignored or something like this?
enum class Tr{BI;};
inline bilingueal_str_(const char* psz, Tr ignored);|
|
||
| /** Show bilingual error message **/ | ||
| template <typename... Args> | ||
| bool InitError(const bilingual_str& fmt, const Args&... args) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd prefer if you removed the plain InitError, since it doesn't seem to be required.
Also, would be nice to add InitError to the linter ./test/lint/lint-format-strings.sh
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd prefer if you removed the plain InitError, since it doesn't seem to be required.
If I understand you correctly then what about #15340 (comment)?
Also see: fea324f
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I mean that InitError could take as first argument a string or bilingual string, so that the formatting always happens inside of InitError. Then add InitError to the linter.
|
Closing in favor of #16224 which provides a different approach and works with the |
18bd83b util: Cleanup translation.h (Hennadii Stepanov) e95e658 doc: Do not translate technical or extremely rare errors (Hennadii Stepanov) 7e923d4 Make InitError bilingual (Hennadii Stepanov) 917ca93 Make ThreadSafe{MessageBox|Question} bilingual (Hennadii Stepanov) 23b9fa2 gui: Add detailed text to BitcoinGUI::message (Hennadii Stepanov) Pull request description: This is an alternative to #15340 (it works with the `Chain` interface; see: #15340 (comment)). Refs: - #16218 (partial fix) - #15894 (comment) 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). If a translated string is unavailable only an English string appears to a user. Here are some **examples** (updated):   * `qt5ct: using qt5ct plugin` message is my local environment specific; please ignore it. --- Note for reviewers: `InitWarning()` is out of this PR scope. ACKs for top commit: Sjors: re-tACK 18bd83b MarcoFalke: ACK 18bd83b 🐦 Tree-SHA512: 3cc8ec44f84403e54b57d11714c86b0855ed90eb794b5472e432005073354b9e3f7b4e8e7bf347a4c21be47299dbc7170f2d0c4b80e308205ff09596e55a4f96
18bd83b util: Cleanup translation.h (Hennadii Stepanov) e95e658 doc: Do not translate technical or extremely rare errors (Hennadii Stepanov) 7e923d4 Make InitError bilingual (Hennadii Stepanov) 917ca93 Make ThreadSafe{MessageBox|Question} bilingual (Hennadii Stepanov) 23b9fa2 gui: Add detailed text to BitcoinGUI::message (Hennadii Stepanov) Pull request description: This is an alternative to bitcoin#15340 (it works with the `Chain` interface; see: bitcoin#15340 (comment)). Refs: - bitcoin#16218 (partial fix) - bitcoin#15894 (comment) 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). If a translated string is unavailable only an English string appears to a user. Here are some **examples** (updated):   * `qt5ct: using qt5ct plugin` message is my local environment specific; please ignore it. --- Note for reviewers: `InitWarning()` is out of this PR scope. ACKs for top commit: Sjors: re-tACK 18bd83b MarcoFalke: ACK 18bd83b 🐦 Tree-SHA512: 3cc8ec44f84403e54b57d11714c86b0855ed90eb794b5472e432005073354b9e3f7b4e8e7bf347a4c21be47299dbc7170f2d0c4b80e308205ff09596e55a4f96
Ref: #16218
This PR:
stderr(that is not the case on master).Note for reviewers:
InitWarning()is out of this PR scope.