Skip to content

Commit 64879f4

Browse files
committed
Merge bitcoin-core/gui#771: Avoid error-prone leading whitespace in translatable strings
856325f lint: Add `lint-qt-translation.py` (Hennadii Stepanov) 294a018 qt: Avoid error prone leading spaces in translatable strings (Hennadii Stepanov) d8298e7 qt, refactor: Drop superfluous type conversions (Hennadii Stepanov) Pull request description: While working on the GUI translation via Transifex web interface, I found it error-prone to have leading whitespace in translatable strings. This is because it is very easy to unintentionally drop them in translations unnoticed. Fixed all current cases. Added a linter to prevent similar cases in the future. ACKs for top commit: furszy: utACK 856325f Tree-SHA512: b1ca5effb2db6649e1e99382de79acf3a9f81cc9dad434db5623338489e597897e8addd60c1ab3dcc7506ae62753a7a4ad5a41d7a865f8fcdf94348b54baa7e7
2 parents afa081a + 856325f commit 64879f4

6 files changed

+36
-11
lines changed

src/qt/psbtoperationsdialog.cpp

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -167,19 +167,20 @@ void PSBTOperationsDialog::saveTransaction() {
167167
}
168168

169169
void PSBTOperationsDialog::updateTransactionDisplay() {
170-
m_ui->transactionDescription->setText(QString::fromStdString(renderTransaction(m_transaction_data)));
170+
m_ui->transactionDescription->setText(renderTransaction(m_transaction_data));
171171
showTransactionStatus(m_transaction_data);
172172
}
173173

174-
std::string PSBTOperationsDialog::renderTransaction(const PartiallySignedTransaction &psbtx)
174+
QString PSBTOperationsDialog::renderTransaction(const PartiallySignedTransaction &psbtx)
175175
{
176-
QString tx_description = "";
176+
QString tx_description;
177+
QLatin1String bullet_point(" * ");
177178
CAmount totalAmount = 0;
178179
for (const CTxOut& out : psbtx.tx->vout) {
179180
CTxDestination address;
180181
ExtractDestination(out.scriptPubKey, address);
181182
totalAmount += out.nValue;
182-
tx_description.append(tr(" * Sends %1 to %2")
183+
tx_description.append(bullet_point).append(tr("Sends %1 to %2")
183184
.arg(BitcoinUnits::formatWithUnit(BitcoinUnit::BTC, out.nValue))
184185
.arg(QString::fromStdString(EncodeDestination(address))));
185186
// Check if the address is one of ours
@@ -188,7 +189,7 @@ std::string PSBTOperationsDialog::renderTransaction(const PartiallySignedTransac
188189
}
189190

190191
PSBTAnalysis analysis = AnalyzePSBT(psbtx);
191-
tx_description.append(" * ");
192+
tx_description.append(bullet_point);
192193
if (!*analysis.fee) {
193194
// This happens if the transaction is missing input UTXO information.
194195
tx_description.append(tr("Unable to calculate transaction fee or total transaction amount."));
@@ -217,7 +218,7 @@ std::string PSBTOperationsDialog::renderTransaction(const PartiallySignedTransac
217218
tx_description.append(tr("Transaction has %1 unsigned inputs.").arg(QString::number(num_unsigned)));
218219
}
219220

220-
return tx_description.toStdString();
221+
return tx_description;
221222
}
222223

223224
void PSBTOperationsDialog::showStatus(const QString &msg, StatusLevel level) {

src/qt/psbtoperationsdialog.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#define BITCOIN_QT_PSBTOPERATIONSDIALOG_H
77

88
#include <QDialog>
9+
#include <QString>
910

1011
#include <psbt.h>
1112
#include <qt/clientmodel.h>
@@ -46,7 +47,7 @@ public Q_SLOTS:
4647

4748
size_t couldSignInputs(const PartiallySignedTransaction &psbtx);
4849
void updateTransactionDisplay();
49-
std::string renderTransaction(const PartiallySignedTransaction &psbtx);
50+
QString renderTransaction(const PartiallySignedTransaction &psbtx);
5051
void showStatus(const QString &msg, StatusLevel level);
5152
void showTransactionStatus(const PartiallySignedTransaction &psbtx);
5253
};

src/qt/sendcoinsdialog.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,7 @@ bool SendCoinsDialog::PrepareSendText(QString& question_string, QString& informa
302302
// generate amount string with wallet name in case of multiwallet
303303
QString amount = BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), rcp.amount);
304304
if (model->isMultiwallet()) {
305-
amount.append(tr(" from wallet '%1'").arg(GUIUtil::HtmlEscape(model->getWalletName())));
305+
amount = tr("%1 from wallet '%2'").arg(amount, GUIUtil::HtmlEscape(model->getWalletName()));
306306
}
307307

308308
// generate address string

src/qt/transactiondesc.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -323,7 +323,7 @@ QString TransactionDesc::toHTML(interfaces::Node& node, interfaces::Wallet& wall
323323
if (!GetPaymentRequestMerchant(r.second, merchant)) {
324324
merchant.clear();
325325
} else {
326-
merchant += tr(" (Certificate was not verified)");
326+
merchant = tr("%1 (Certificate was not verified)").arg(merchant);
327327
}
328328
if (!merchant.isNull()) {
329329
strHTML += "<b>" + tr("Merchant") + ":</b> " + GUIUtil::HtmlEscape(merchant) + "<br>";

src/qt/walletcontroller.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -472,10 +472,10 @@ void MigrateWalletActivity::migrate(WalletModel* wallet_model)
472472
if (res) {
473473
m_success_message = tr("The wallet '%1' was migrated successfully.").arg(GUIUtil::HtmlEscape(res->wallet->getWalletName()));
474474
if (res->watchonly_wallet_name) {
475-
m_success_message += tr(" Watchonly scripts have been migrated to a new wallet named '%1'.").arg(GUIUtil::HtmlEscape(res->watchonly_wallet_name.value()));
475+
m_success_message += QChar(' ') + tr("Watchonly scripts have been migrated to a new wallet named '%1'.").arg(GUIUtil::HtmlEscape(res->watchonly_wallet_name.value()));
476476
}
477477
if (res->solvables_wallet_name) {
478-
m_success_message += tr(" Solvable but not watched scripts have been migrated to a new wallet named '%1'.").arg(GUIUtil::HtmlEscape(res->solvables_wallet_name.value()));
478+
m_success_message += QChar(' ') + tr("Solvable but not watched scripts have been migrated to a new wallet named '%1'.").arg(GUIUtil::HtmlEscape(res->solvables_wallet_name.value()));
479479
}
480480
m_wallet_model = m_wallet_controller->getOrCreateWallet(std::move(res->wallet));
481481
} else {

test/lint/lint-qt-translation.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#!/usr/bin/env python3
2+
#
3+
# Copyright (c) 2023-present The Bitcoin Core developers
4+
# Distributed under the MIT software license, see the accompanying
5+
# file COPYING or https://opensource.org/license/mit/.
6+
#
7+
# Check for leading whitespaces in the translatable strings.
8+
9+
import subprocess
10+
import sys
11+
12+
13+
def main():
14+
tr_strings = subprocess.run(['git', 'grep', '-e', 'tr("[[:space:]]', '--', 'src/qt'], stdout=subprocess.PIPE, text=True).stdout
15+
16+
if tr_strings.strip():
17+
print("Avoid leading whitespaces in:")
18+
print(tr_strings)
19+
sys.exit(1)
20+
21+
22+
if __name__ == "__main__":
23+
main()

0 commit comments

Comments
 (0)