diff --git a/src/qt/forms/optionsdialog.ui b/src/qt/forms/optionsdialog.ui
index 240a7a7e9..fea759dee 100644
--- a/src/qt/forms/optionsdialog.ui
+++ b/src/qt/forms/optionsdialog.ui
@@ -1,900 +1,903 @@
OptionsDialog
0
0
560
440
Options
true
-
0
&Main
-
Automatically start %1 after logging in to the system.
&Start %1 on system login
-
Qt::Horizontal
40
5
-
-
Disables some advanced features but all blocks will still be fully validated. Reverting this setting requires re-downloading the entire blockchain. Actual disk usage may be somewhat higher.
Prune &block storage to
-
-
GB
Qt::PlainText
-
Qt::Horizontal
40
20
-
Reverting this setting requires re-downloading the entire blockchain.
Qt::PlainText
-
-
Size of &database cache
Qt::PlainText
databaseCache
-
-
MiB
Qt::PlainText
-
Qt::Horizontal
40
20
-
-
Number of script &verification threads
Qt::PlainText
threadsScriptVerif
-
(0 = auto, <0 = leave that many cores free)
-
Qt::Horizontal
40
20
-
Qt::Vertical
20
40
W&allet
-
Expert
-
Whether to show coin control features or not.
Enable coin &control features
-
If you disable the spending of unconfirmed change, the change from a transaction cannot be used until that transaction has at least one confirmation. This also affects how your balance is computed.
&Spend unconfirmed change
-
Qt::Vertical
20
40
&Network
-
Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled.
Map port using &UPnP
-
Accept connections from outside.
Allow incomin&g connections
-
Connect to the Bitcoin network through a SOCKS5 proxy.
&Connect through SOCKS5 proxy (default proxy):
-
-
Proxy &IP:
Qt::PlainText
proxyIp
-
140
0
140
16777215
IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)
-
&Port:
Qt::PlainText
proxyPort
-
55
0
55
16777215
Port of the proxy (e.g. 9050)
-
Qt::Horizontal
40
20
-
-
Used for reaching peers via:
Qt::PlainText
-
false
Shows if the supplied default SOCKS5 proxy is used to reach peers via this network type.
-
IPv4
Qt::PlainText
-
false
Shows if the supplied default SOCKS5 proxy is used to reach peers via this network type.
-
IPv6
Qt::PlainText
-
false
Shows if the supplied default SOCKS5 proxy is used to reach peers via this network type.
-
Tor
Qt::PlainText
-
Qt::Horizontal
40
20
-
Connect to the Bitcoin network through a separate SOCKS5 proxy for Tor hidden services.
Use separate SOCKS&5 proxy to reach peers via Tor hidden services:
-
-
Proxy &IP:
Qt::PlainText
proxyIpTor
-
140
0
140
16777215
IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)
-
&Port:
Qt::PlainText
proxyPortTor
-
55
0
55
16777215
Port of the proxy (e.g. 9050)
-
Qt::Horizontal
40
20
-
Qt::Vertical
20
40
&Window
-
Hide the icon from the system tray.
&Hide tray icon
-
Show only a tray icon after minimizing the window.
&Minimize to the tray instead of the taskbar
-
Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Exit in the menu.
M&inimize on close
-
Qt::Vertical
20
40
&Display
-
-
User Interface &language:
Qt::PlainText
lang
-
The user interface language can be set here. This setting will take effect after restarting %1.
-
-
&Unit to show amounts in:
Qt::PlainText
unit
-
Choose the default subdivision unit to show in the interface and when sending coins.
-
-
Third party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |.
&Third party transaction URLs
thirdPartyTxUrls
-
Third party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |.
+
+ https://example.com/tx/%s
+
-
Qt::Vertical
20
40
-
-
-
Options set in this dialog are overridden by the command line or in the configuration file:
Qt::PlainText
-
Qt::Horizontal
40
20
-
Qt::PlainText
true
-
-
-
Open the %1 configuration file from the working directory.
Open Configuration File
false
-
Reset all client options to default.
&Reset Options
false
-
Qt::Horizontal
40
48
-
200
0
75
true
Qt::PlainText
true
-
Qt::Horizontal
40
48
-
-
Qt::Vertical
20
40
-
-
&OK
false
true
-
&Cancel
false
QValidatedLineEdit
QLineEdit
QValueComboBox
QComboBox
diff --git a/src/qt/forms/sendcoinsentry.ui b/src/qt/forms/sendcoinsentry.ui
index 2b05825b0..acd1d660c 100644
--- a/src/qt/forms/sendcoinsentry.ui
+++ b/src/qt/forms/sendcoinsentry.ui
@@ -1,1284 +1,1287 @@
SendCoinsEntry
0
0
729
150
Qt::TabFocus
false
QFrame::NoFrame
8
4
12
8
-
Pay &To:
Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
payTo
-
0
-
The Bitcoin address to send the payment to
-
Choose previously used address
:/icons/address-book:/icons/address-book
22
22
Alt+A
-
Paste address from clipboard
:/icons/editpaste:/icons/editpaste
22
22
Alt+P
-
Remove this entry
:/icons/remove:/icons/remove
22
22
-
&Label:
Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
addAsLabel
-
Enter a label for this address to add it to the list of used addresses
+
+ Enter a label for this address to add it to your address book
+
-
A&mount:
Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
payAmount
-
-
The amount to send in the selected unit
-
The fee will be deducted from the amount being sent. The recipient will receive less bitcoins than you enter in the amount field. If multiple recipients are selected, the fee is split equally.
S&ubtract fee from amount
-
Use available balance
-
Message:
Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
-
Qt::PlainText
-
Qt::Horizontal
0
0
0
255
255
127
255
255
255
255
255
191
127
127
63
170
170
84
0
0
0
255
255
255
0
0
0
255
255
255
255
255
127
0
0
0
255
255
191
255
255
220
0
0
0
0
0
0
255
255
127
255
255
255
255
255
191
127
127
63
170
170
84
0
0
0
255
255
255
0
0
0
255
255
255
255
255
127
0
0
0
255
255
191
255
255
220
0
0
0
127
127
63
255
255
127
255
255
255
255
255
191
127
127
63
170
170
84
127
127
63
255
255
255
127
127
63
255
255
127
255
255
127
0
0
0
255
255
127
255
255
220
0
0
0
This is an unauthenticated payment request.
true
QFrame::NoFrame
12
-
Pay To:
Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
-
0
-
-
Remove this entry
:/icons/remove:/icons/remove
-
Memo:
Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
-
Qt::PlainText
-
A&mount:
Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
payAmount_is
-
false
0
0
0
140
232
119
230
255
224
185
243
171
70
116
59
93
155
79
0
0
0
155
255
147
0
0
0
119
255
233
140
232
119
0
0
0
197
243
187
125
194
122
255
255
220
0
0
0
0
0
0
140
232
119
230
255
224
185
243
171
70
116
59
93
155
79
0
0
0
155
255
147
0
0
0
119
255
233
140
232
119
0
0
0
197
243
187
125
194
122
255
255
220
0
0
0
70
116
59
140
232
119
230
255
224
185
243
171
70
116
59
93
155
79
70
116
59
155
255
147
70
116
59
140
232
119
140
232
119
0
0
0
140
232
119
125
194
122
255
255
220
0
0
0
This is an authenticated payment request.
true
QFrame::NoFrame
12
-
Pay To:
Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
-
0
-
Qt::PlainText
-
Remove this entry
:/icons/remove:/icons/remove
-
Memo:
Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
-
Qt::PlainText
-
A&mount:
Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
payAmount_s
-
false
QValidatedLineEdit
QLineEdit
BitcoinAmountField
QLineEdit
1
payTo
addressBookButton
pasteButton
deleteButton
addAsLabel
payAmount
payAmount_is
deleteButton_is
payAmount_s
deleteButton_s
diff --git a/src/qt/forms/signverifymessagedialog.ui b/src/qt/forms/signverifymessagedialog.ui
index 202edf27d..f42d19093 100644
--- a/src/qt/forms/signverifymessagedialog.ui
+++ b/src/qt/forms/signverifymessagedialog.ui
@@ -1,407 +1,410 @@
SignVerifyMessageDialog
0
0
700
380
Signatures - Sign / Verify a Message
true
-
0
&Sign Message
-
You can sign messages/agreements with your addresses to prove you can receive bitcoins sent to them. Be careful not to sign anything vague or random, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.
Qt::PlainText
true
-
0
-
The Bitcoin address to sign the message with
-
Choose previously used address
:/icons/address-book:/icons/address-book
Alt+A
false
-
Paste address from clipboard
:/icons/editpaste:/icons/editpaste
Alt+P
false
-
Enter the message you want to sign here
Enter the message you want to sign here
-
Signature
Qt::PlainText
-
0
-
+
+ Click "Sign Message" to generate signature
+
true
true
-
Copy the current signature to the system clipboard
:/icons/editcopy:/icons/editcopy
false
-
-
Sign the message to prove you own this Bitcoin address
Sign &Message
:/icons/edit:/icons/edit
false
-
Reset all sign message fields
Clear &All
:/icons/remove:/icons/remove
false
-
Qt::Horizontal
40
48
-
75
true
true
-
Qt::Horizontal
40
48
&Verify Message
-
Enter the receiver's address, message (ensure you copy line breaks, spaces, tabs, etc. exactly) and signature below to verify the message. Be careful not to read more into the signature than what is in the signed message itself, to avoid being tricked by a man-in-the-middle attack. Note that this only proves the signing party receives with the address, it cannot prove sendership of any transaction!
Qt::PlainText
Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop
true
-
0
-
The Bitcoin address the message was signed with
-
Choose previously used address
:/icons/address-book:/icons/address-book
Alt+A
false
-
The signed message to verify
The signed message to verify
-
The signature given when the message was signed
The signature given when the message was signed
-
-
Verify the message to ensure it was signed with the specified Bitcoin address
Verify &Message
:/icons/transaction_0:/icons/transaction_0
false
-
Reset all verify message fields
Clear &All
:/icons/remove:/icons/remove
false
-
Qt::Horizontal
40
48
-
75
true
true
-
Qt::Horizontal
40
48
QValidatedLineEdit
QLineEdit
diff --git a/src/qt/optionsdialog.cpp b/src/qt/optionsdialog.cpp
index 9da8d7cd7..53da01611 100644
--- a/src/qt/optionsdialog.cpp
+++ b/src/qt/optionsdialog.cpp
@@ -1,425 +1,423 @@
// Copyright (c) 2011-2016 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#if defined(HAVE_CONFIG_H)
#include
#endif
#include
#include
#include
#include
#include
#include
#include
#include
#include // for -dbcache defaults
#include // for DEFAULT_SCRIPTCHECK_THREADS and MAX_SCRIPTCHECK_THREADS
#include
#include
#include
#include
#include
#include
#include
OptionsDialog::OptionsDialog(QWidget *parent, bool enableWallet)
: QDialog(parent), ui(new Ui::OptionsDialog), model(nullptr),
mapper(nullptr) {
ui->setupUi(this);
/* Main elements init */
ui->databaseCache->setMinimum(nMinDbCache);
ui->databaseCache->setMaximum(nMaxDbCache);
ui->threadsScriptVerif->setMinimum(-GetNumCores());
ui->threadsScriptVerif->setMaximum(MAX_SCRIPTCHECK_THREADS);
ui->pruneWarning->setVisible(false);
ui->pruneWarning->setStyleSheet("QLabel { color: red; }");
ui->pruneSize->setEnabled(false);
connect(ui->prune, &QPushButton::toggled, ui->pruneSize,
&QWidget::setEnabled);
/* Network elements init */
#ifndef USE_UPNP
ui->mapPortUpnp->setEnabled(false);
#endif
ui->proxyIp->setEnabled(false);
ui->proxyPort->setEnabled(false);
ui->proxyPort->setValidator(new QIntValidator(1, 65535, this));
ui->proxyIpTor->setEnabled(false);
ui->proxyPortTor->setEnabled(false);
ui->proxyPortTor->setValidator(new QIntValidator(1, 65535, this));
connect(ui->connectSocks, &QPushButton::toggled, ui->proxyIp,
&QWidget::setEnabled);
connect(ui->connectSocks, &QPushButton::toggled, ui->proxyPort,
&QWidget::setEnabled);
connect(ui->connectSocks, &QPushButton::toggled, this,
&OptionsDialog::updateProxyValidationState);
connect(ui->connectSocksTor, &QPushButton::toggled, ui->proxyIpTor,
&QWidget::setEnabled);
connect(ui->connectSocksTor, &QPushButton::toggled, ui->proxyPortTor,
&QWidget::setEnabled);
connect(ui->connectSocksTor, &QPushButton::toggled, this,
&OptionsDialog::updateProxyValidationState);
/* Window elements init */
#ifdef Q_OS_MAC
/* remove Window tab on Mac */
ui->tabWidget->removeTab(ui->tabWidget->indexOf(ui->tabWindow));
/* hide launch at startup option on macOS */
ui->bitcoinAtStartup->setVisible(false);
ui->verticalLayout_Main->removeWidget(ui->bitcoinAtStartup);
ui->verticalLayout_Main->removeItem(ui->horizontalSpacer_0_Main);
#endif
/* remove Wallet tab in case of -disablewallet */
if (!enableWallet) {
ui->tabWidget->removeTab(ui->tabWidget->indexOf(ui->tabWallet));
}
/* Display elements init */
QDir translations(":translations");
ui->bitcoinAtStartup->setToolTip(
ui->bitcoinAtStartup->toolTip().arg(PACKAGE_NAME));
ui->bitcoinAtStartup->setText(
ui->bitcoinAtStartup->text().arg(PACKAGE_NAME));
ui->openBitcoinConfButton->setToolTip(
ui->openBitcoinConfButton->toolTip().arg(PACKAGE_NAME));
ui->lang->setToolTip(ui->lang->toolTip().arg(PACKAGE_NAME));
ui->lang->addItem(QString("(") + tr("default") + QString(")"),
QVariant(""));
for (const QString &langStr : translations.entryList()) {
QLocale locale(langStr);
/** check if the locale name consists of 2 parts (language_country) */
if (langStr.contains("_")) {
/** display language strings as "native language - native country
* (locale name)", e.g. "Deutsch - Deutschland (de)" */
ui->lang->addItem(locale.nativeLanguageName() + QString(" - ") +
locale.nativeCountryName() + QString(" (") +
langStr + QString(")"),
QVariant(langStr));
} else {
/** display language strings as "native language (locale name)",
* e.g. "Deutsch (de)" */
ui->lang->addItem(locale.nativeLanguageName() + QString(" (") +
langStr + QString(")"),
QVariant(langStr));
}
}
- ui->thirdPartyTxUrls->setPlaceholderText("https://example.com/tx/%s");
-
ui->unit->setModel(new BitcoinUnits(this));
/* Widget-to-option mapper */
mapper = new QDataWidgetMapper(this);
mapper->setSubmitPolicy(QDataWidgetMapper::ManualSubmit);
mapper->setOrientation(Qt::Vertical);
GUIUtil::ItemDelegate *delegate = new GUIUtil::ItemDelegate(mapper);
connect(delegate, &GUIUtil::ItemDelegate::keyEscapePressed, this,
&OptionsDialog::reject);
mapper->setItemDelegate(delegate);
/* setup/change UI elements when proxy IPs are invalid/valid */
ui->proxyIp->setCheckValidator(new ProxyAddressValidator(parent));
ui->proxyIpTor->setCheckValidator(new ProxyAddressValidator(parent));
connect(ui->proxyIp, &QValidatedLineEdit::validationDidChange, this,
&OptionsDialog::updateProxyValidationState);
connect(ui->proxyIpTor, &QValidatedLineEdit::validationDidChange, this,
&OptionsDialog::updateProxyValidationState);
connect(ui->proxyPort, &QLineEdit::textChanged, this,
&OptionsDialog::updateProxyValidationState);
connect(ui->proxyPortTor, &QLineEdit::textChanged, this,
&OptionsDialog::updateProxyValidationState);
if (!QSystemTrayIcon::isSystemTrayAvailable()) {
ui->hideTrayIcon->setChecked(true);
ui->hideTrayIcon->setEnabled(false);
ui->minimizeToTray->setChecked(false);
ui->minimizeToTray->setEnabled(false);
}
}
OptionsDialog::~OptionsDialog() {
delete ui;
}
void OptionsDialog::setModel(OptionsModel *_model) {
this->model = _model;
if (_model) {
/* check if client restart is needed and show persistent message */
if (_model->isRestartRequired()) {
showRestartWarning(true);
}
// Prune values are in GB to be consistent with intro.cpp
static constexpr uint64_t nMinDiskSpace =
(MIN_DISK_SPACE_FOR_BLOCK_FILES / GB_BYTES) +
(MIN_DISK_SPACE_FOR_BLOCK_FILES % GB_BYTES)
? 1
: 0;
ui->pruneSize->setRange(nMinDiskSpace, std::numeric_limits::max());
QString strLabel = _model->getOverriddenByCommandLine();
if (strLabel.isEmpty()) {
strLabel = tr("none");
}
ui->overriddenByCommandLineLabel->setText(strLabel);
mapper->setModel(_model);
setMapper();
mapper->toFirst();
updateDefaultProxyNets();
}
/* warn when one of the following settings changes by user action (placed
* here so init via mapper doesn't trigger them) */
/* Main */
connect(ui->prune, &QCheckBox::clicked, this,
&OptionsDialog::showRestartWarning);
connect(ui->prune, &QCheckBox::clicked, this,
&OptionsDialog::togglePruneWarning);
connect(ui->pruneSize,
static_cast(&QSpinBox::valueChanged), this,
&OptionsDialog::showRestartWarning);
connect(ui->databaseCache,
static_cast(&QSpinBox::valueChanged), this,
&OptionsDialog::showRestartWarning);
connect(ui->threadsScriptVerif,
static_cast(&QSpinBox::valueChanged), this,
&OptionsDialog::showRestartWarning);
/* Wallet */
connect(ui->spendZeroConfChange, &QCheckBox::clicked, this,
&OptionsDialog::showRestartWarning);
/* Network */
connect(ui->allowIncoming, &QCheckBox::clicked, this,
&OptionsDialog::showRestartWarning);
connect(ui->connectSocks, &QCheckBox::clicked, this,
&OptionsDialog::showRestartWarning);
connect(ui->connectSocksTor, &QCheckBox::clicked, this,
&OptionsDialog::showRestartWarning);
/* Display */
connect(
ui->lang,
static_cast(&QValueComboBox::valueChanged),
[this] { showRestartWarning(); });
connect(ui->thirdPartyTxUrls, &QLineEdit::textChanged,
[this] { showRestartWarning(); });
}
void OptionsDialog::setCurrentTab(OptionsDialog::Tab tab) {
QWidget *tab_widget = nullptr;
if (tab == OptionsDialog::Tab::TAB_NETWORK) {
tab_widget = ui->tabNetwork;
}
if (tab == OptionsDialog::Tab::TAB_MAIN) {
tab_widget = ui->tabMain;
}
if (tab_widget && ui->tabWidget->currentWidget() != tab_widget) {
ui->tabWidget->setCurrentWidget(tab_widget);
}
}
void OptionsDialog::setMapper() {
/* Main */
mapper->addMapping(ui->bitcoinAtStartup, OptionsModel::StartAtStartup);
mapper->addMapping(ui->threadsScriptVerif,
OptionsModel::ThreadsScriptVerif);
mapper->addMapping(ui->databaseCache, OptionsModel::DatabaseCache);
mapper->addMapping(ui->prune, OptionsModel::Prune);
mapper->addMapping(ui->pruneSize, OptionsModel::PruneSize);
/* Wallet */
mapper->addMapping(ui->spendZeroConfChange,
OptionsModel::SpendZeroConfChange);
mapper->addMapping(ui->coinControlFeatures,
OptionsModel::CoinControlFeatures);
/* Network */
mapper->addMapping(ui->mapPortUpnp, OptionsModel::MapPortUPnP);
mapper->addMapping(ui->allowIncoming, OptionsModel::Listen);
mapper->addMapping(ui->connectSocks, OptionsModel::ProxyUse);
mapper->addMapping(ui->proxyIp, OptionsModel::ProxyIP);
mapper->addMapping(ui->proxyPort, OptionsModel::ProxyPort);
mapper->addMapping(ui->connectSocksTor, OptionsModel::ProxyUseTor);
mapper->addMapping(ui->proxyIpTor, OptionsModel::ProxyIPTor);
mapper->addMapping(ui->proxyPortTor, OptionsModel::ProxyPortTor);
/* Window */
#ifndef Q_OS_MAC
if (QSystemTrayIcon::isSystemTrayAvailable()) {
mapper->addMapping(ui->hideTrayIcon, OptionsModel::HideTrayIcon);
mapper->addMapping(ui->minimizeToTray, OptionsModel::MinimizeToTray);
}
mapper->addMapping(ui->minimizeOnClose, OptionsModel::MinimizeOnClose);
#endif
/* Display */
mapper->addMapping(ui->lang, OptionsModel::Language);
mapper->addMapping(ui->unit, OptionsModel::DisplayUnit);
mapper->addMapping(ui->thirdPartyTxUrls, OptionsModel::ThirdPartyTxUrls);
}
void OptionsDialog::setOkButtonState(bool fState) {
ui->okButton->setEnabled(fState);
}
void OptionsDialog::on_resetButton_clicked() {
if (model) {
// confirmation dialog
QMessageBox::StandardButton btnRetVal = QMessageBox::question(
this, tr("Confirm options reset"),
tr("Client restart required to activate changes.") + "
" +
tr("Client will be shut down. Do you want to proceed?"),
QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Cancel);
if (btnRetVal == QMessageBox::Cancel) {
return;
}
/* reset all options and close GUI */
model->Reset();
QApplication::quit();
}
}
void OptionsDialog::on_openBitcoinConfButton_clicked() {
/* explain the purpose of the config file */
QMessageBox::information(
this, tr("Configuration options"),
tr("The configuration file is used to specify advanced user options "
"which override GUI settings. Additionally, any command-line "
"options will override this configuration file."));
/* show an error if there was some problem opening the file */
if (!GUIUtil::openBitcoinConf()) {
QMessageBox::critical(
this, tr("Error"),
tr("The configuration file could not be opened."));
}
}
void OptionsDialog::on_okButton_clicked() {
mapper->submit();
accept();
updateDefaultProxyNets();
}
void OptionsDialog::on_cancelButton_clicked() {
reject();
}
void OptionsDialog::on_hideTrayIcon_stateChanged(int fState) {
if (fState) {
ui->minimizeToTray->setChecked(false);
ui->minimizeToTray->setEnabled(false);
} else {
ui->minimizeToTray->setEnabled(true);
}
}
void OptionsDialog::togglePruneWarning(bool enabled) {
ui->pruneWarning->setVisible(!ui->pruneWarning->isVisible());
}
void OptionsDialog::showRestartWarning(bool fPersistent) {
ui->statusLabel->setStyleSheet("QLabel { color: red; }");
if (fPersistent) {
ui->statusLabel->setText(
tr("Client restart required to activate changes."));
} else {
ui->statusLabel->setText(
tr("This change would require a client restart."));
// clear non-persistent status label after 10 seconds
// TODO: should perhaps be a class attribute, if we extend the use of
// statusLabel
QTimer::singleShot(10000, this, &OptionsDialog::clearStatusLabel);
}
}
void OptionsDialog::clearStatusLabel() {
ui->statusLabel->clear();
if (model && model->isRestartRequired()) {
showRestartWarning(true);
}
}
void OptionsDialog::updateProxyValidationState() {
QValidatedLineEdit *pUiProxyIp = ui->proxyIp;
QValidatedLineEdit *otherProxyWidget =
(pUiProxyIp == ui->proxyIpTor) ? ui->proxyIp : ui->proxyIpTor;
if (pUiProxyIp->isValid() &&
(!ui->proxyPort->isEnabled() || ui->proxyPort->text().toInt() > 0) &&
(!ui->proxyPortTor->isEnabled() ||
ui->proxyPortTor->text().toInt() > 0)) {
// Only enable ok button if both proxys are valid
setOkButtonState(otherProxyWidget->isValid());
clearStatusLabel();
} else {
setOkButtonState(false);
ui->statusLabel->setStyleSheet("QLabel { color: red; }");
ui->statusLabel->setText(tr("The supplied proxy address is invalid."));
}
}
void OptionsDialog::updateDefaultProxyNets() {
proxyType proxy;
std::string strProxy;
QString strDefaultProxyGUI;
model->node().getProxy(NET_IPV4, proxy);
strProxy = proxy.proxy.ToStringIP() + ":" + proxy.proxy.ToStringPort();
strDefaultProxyGUI = ui->proxyIp->text() + ":" + ui->proxyPort->text();
(strProxy == strDefaultProxyGUI.toStdString())
? ui->proxyReachIPv4->setChecked(true)
: ui->proxyReachIPv4->setChecked(false);
model->node().getProxy(NET_IPV6, proxy);
strProxy = proxy.proxy.ToStringIP() + ":" + proxy.proxy.ToStringPort();
strDefaultProxyGUI = ui->proxyIp->text() + ":" + ui->proxyPort->text();
(strProxy == strDefaultProxyGUI.toStdString())
? ui->proxyReachIPv6->setChecked(true)
: ui->proxyReachIPv6->setChecked(false);
model->node().getProxy(NET_ONION, proxy);
strProxy = proxy.proxy.ToStringIP() + ":" + proxy.proxy.ToStringPort();
strDefaultProxyGUI = ui->proxyIp->text() + ":" + ui->proxyPort->text();
(strProxy == strDefaultProxyGUI.toStdString())
? ui->proxyReachTor->setChecked(true)
: ui->proxyReachTor->setChecked(false);
}
ProxyAddressValidator::ProxyAddressValidator(QObject *parent)
: QValidator(parent) {}
QValidator::State ProxyAddressValidator::validate(QString &input,
int &pos) const {
Q_UNUSED(pos);
// Validate the proxy
CService serv(
LookupNumeric(input.toStdString().c_str(), DEFAULT_GUI_PROXY_PORT));
proxyType addrProxy = proxyType(serv, true);
if (addrProxy.IsValid()) {
return QValidator::Acceptable;
}
return QValidator::Invalid;
}
diff --git a/src/qt/sendcoinsentry.cpp b/src/qt/sendcoinsentry.cpp
index 63aa9402c..b188c33d7 100644
--- a/src/qt/sendcoinsentry.cpp
+++ b/src/qt/sendcoinsentry.cpp
@@ -1,312 +1,310 @@
// Copyright (c) 2011-2016 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#if defined(HAVE_CONFIG_H)
#include
#endif
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
SendCoinsEntry::SendCoinsEntry(const PlatformStyle *_platformStyle,
WalletModel *_model, QWidget *parent)
: QStackedWidget(parent), ui(new Ui::SendCoinsEntry), model(_model),
platformStyle(_platformStyle) {
ui->setupUi(this);
ui->addressBookButton->setIcon(
platformStyle->SingleColorIcon(":/icons/address-book"));
ui->pasteButton->setIcon(
platformStyle->SingleColorIcon(":/icons/editpaste"));
ui->deleteButton->setIcon(platformStyle->SingleColorIcon(":/icons/remove"));
ui->deleteButton_is->setIcon(
platformStyle->SingleColorIcon(":/icons/remove"));
ui->deleteButton_s->setIcon(
platformStyle->SingleColorIcon(":/icons/remove"));
setCurrentWidget(ui->SendCoins);
if (platformStyle->getUseExtraSpacing()) {
ui->payToLayout->setSpacing(4);
}
- ui->addAsLabel->setPlaceholderText(
- tr("Enter a label for this address to add it to your address book"));
// normal bitcoin address field
GUIUtil::setupAddressWidget(ui->payTo, this);
// just a label for displaying bitcoin address(es)
ui->payTo_is->setFont(GUIUtil::fixedPitchFont());
// Connect signals
connect(ui->payAmount, &BitcoinAmountField::valueChanged, this,
&SendCoinsEntry::payAmountChanged);
connect(ui->checkboxSubtractFeeFromAmount, &QCheckBox::toggled, this,
&SendCoinsEntry::subtractFeeFromAmountChanged);
connect(ui->deleteButton, &QPushButton::clicked, this,
&SendCoinsEntry::deleteClicked);
connect(ui->deleteButton_is, &QPushButton::clicked, this,
&SendCoinsEntry::deleteClicked);
connect(ui->deleteButton_s, &QPushButton::clicked, this,
&SendCoinsEntry::deleteClicked);
connect(ui->useAvailableBalanceButton, &QPushButton::clicked, this,
&SendCoinsEntry::useAvailableBalanceClicked);
// Set the model properly.
setModel(model);
}
SendCoinsEntry::~SendCoinsEntry() {
delete ui;
}
void SendCoinsEntry::on_pasteButton_clicked() {
// Paste text from clipboard into recipient field
ui->payTo->setText(QApplication::clipboard()->text());
}
void SendCoinsEntry::on_addressBookButton_clicked() {
if (!model) {
return;
}
AddressBookPage dlg(platformStyle, AddressBookPage::ForSelection,
AddressBookPage::SendingTab, this);
dlg.setModel(model->getAddressTableModel());
if (dlg.exec()) {
ui->payTo->setText(dlg.getReturnValue());
ui->payAmount->setFocus();
}
}
void SendCoinsEntry::on_payTo_textChanged(const QString &address) {
updateLabel(address);
}
void SendCoinsEntry::setModel(WalletModel *_model) {
this->model = _model;
if (_model) {
ui->messageTextLabel->setToolTip(
tr("A message that was attached to the %1 URI which will be stored "
"with the transaction for your reference. Note: This message "
"will not be sent over the Bitcoin network.")
.arg(QString::fromStdString(
_model->getChainParams().CashAddrPrefix())));
}
if (_model && _model->getOptionsModel()) {
connect(_model->getOptionsModel(), &OptionsModel::displayUnitChanged,
this, &SendCoinsEntry::updateDisplayUnit);
}
clear();
}
void SendCoinsEntry::clear() {
// clear UI elements for normal payment
ui->payTo->clear();
ui->addAsLabel->clear();
ui->payAmount->clear();
ui->checkboxSubtractFeeFromAmount->setCheckState(Qt::Unchecked);
ui->messageTextLabel->clear();
ui->messageTextLabel->hide();
ui->messageLabel->hide();
// clear UI elements for unauthenticated payment request
ui->payTo_is->clear();
ui->memoTextLabel_is->clear();
ui->payAmount_is->clear();
// clear UI elements for authenticated payment request
ui->payTo_s->clear();
ui->memoTextLabel_s->clear();
ui->payAmount_s->clear();
// update the display unit, to not use the default ("BCH")
updateDisplayUnit();
}
void SendCoinsEntry::checkSubtractFeeFromAmount() {
ui->checkboxSubtractFeeFromAmount->setChecked(true);
}
void SendCoinsEntry::deleteClicked() {
Q_EMIT removeEntry(this);
}
void SendCoinsEntry::useAvailableBalanceClicked() {
Q_EMIT useAvailableBalance(this);
}
bool SendCoinsEntry::validate(interfaces::Node &node) {
if (!model) {
return false;
}
// Check input validity
bool retval = true;
#ifdef ENABLE_BIP70
// Skip checks for payment request
if (recipient.paymentRequest.IsInitialized()) {
return retval;
}
#endif
if (!model->validateAddress(ui->payTo->text())) {
ui->payTo->setValid(false);
retval = false;
}
if (!ui->payAmount->validate()) {
retval = false;
}
// Sending a zero amount is invalid
if (ui->payAmount->value(nullptr) <= Amount::zero()) {
ui->payAmount->setValid(false);
retval = false;
}
// Reject dust outputs:
if (retval &&
GUIUtil::isDust(node, ui->payTo->text(), ui->payAmount->value(),
model->getChainParams())) {
ui->payAmount->setValid(false);
retval = false;
}
return retval;
}
SendCoinsRecipient SendCoinsEntry::getValue() {
#ifdef ENABLE_BIP70
// Payment request
if (recipient.paymentRequest.IsInitialized()) {
return recipient;
}
#endif
// Normal payment
recipient.address = ui->payTo->text();
recipient.label = ui->addAsLabel->text();
recipient.amount = ui->payAmount->value();
recipient.message = ui->messageTextLabel->text();
recipient.fSubtractFeeFromAmount =
(ui->checkboxSubtractFeeFromAmount->checkState() == Qt::Checked);
return recipient;
}
QWidget *SendCoinsEntry::setupTabChain(QWidget *prev) {
QWidget::setTabOrder(prev, ui->payTo);
QWidget::setTabOrder(ui->payTo, ui->addAsLabel);
QWidget *w = ui->payAmount->setupTabChain(ui->addAsLabel);
QWidget::setTabOrder(w, ui->checkboxSubtractFeeFromAmount);
QWidget::setTabOrder(ui->checkboxSubtractFeeFromAmount,
ui->addressBookButton);
QWidget::setTabOrder(ui->addressBookButton, ui->pasteButton);
QWidget::setTabOrder(ui->pasteButton, ui->deleteButton);
return ui->deleteButton;
}
void SendCoinsEntry::setValue(const SendCoinsRecipient &value) {
recipient = value;
#ifdef ENABLE_BIP70
// payment request
if (recipient.paymentRequest.IsInitialized()) {
// unauthenticated
if (recipient.authenticatedMerchant.isEmpty()) {
ui->payTo_is->setText(recipient.address);
ui->memoTextLabel_is->setText(recipient.message);
ui->payAmount_is->setValue(recipient.amount);
ui->payAmount_is->setReadOnly(true);
setCurrentWidget(ui->SendCoins_UnauthenticatedPaymentRequest);
}
// authenticated
else {
ui->payTo_s->setText(recipient.authenticatedMerchant);
ui->memoTextLabel_s->setText(recipient.message);
ui->payAmount_s->setValue(recipient.amount);
ui->payAmount_s->setReadOnly(true);
setCurrentWidget(ui->SendCoins_AuthenticatedPaymentRequest);
}
}
// normal payment
else
#endif
{
// message
ui->messageTextLabel->setText(recipient.message);
ui->messageTextLabel->setVisible(!recipient.message.isEmpty());
ui->messageLabel->setVisible(!recipient.message.isEmpty());
ui->addAsLabel->clear();
// this may set a label from addressbook
ui->payTo->setText(recipient.address);
// if a label had been set from the addressbook, don't overwrite with an
// empty label
if (!recipient.label.isEmpty()) {
ui->addAsLabel->setText(recipient.label);
}
ui->payAmount->setValue(recipient.amount);
}
}
void SendCoinsEntry::setAddress(const QString &address) {
ui->payTo->setText(address);
ui->payAmount->setFocus();
}
void SendCoinsEntry::setAmount(const Amount amount) {
ui->payAmount->setValue(amount);
}
bool SendCoinsEntry::isClear() {
return ui->payTo->text().isEmpty() && ui->payTo_is->text().isEmpty() &&
ui->payTo_s->text().isEmpty();
}
void SendCoinsEntry::setFocus() {
ui->payTo->setFocus();
}
void SendCoinsEntry::updateDisplayUnit() {
if (model && model->getOptionsModel()) {
// Update payAmount with the current unit
ui->payAmount->setDisplayUnit(
model->getOptionsModel()->getDisplayUnit());
ui->payAmount_is->setDisplayUnit(
model->getOptionsModel()->getDisplayUnit());
ui->payAmount_s->setDisplayUnit(
model->getOptionsModel()->getDisplayUnit());
}
}
bool SendCoinsEntry::updateLabel(const QString &address) {
if (!model) {
return false;
}
// Fill in label from address book, if address has an associated label
QString associatedLabel =
model->getAddressTableModel()->labelForAddress(address);
if (!associatedLabel.isEmpty()) {
ui->addAsLabel->setText(associatedLabel);
return true;
}
return false;
}
diff --git a/src/qt/signverifymessagedialog.cpp b/src/qt/signverifymessagedialog.cpp
index eb7f20563..70f466aa1 100644
--- a/src/qt/signverifymessagedialog.cpp
+++ b/src/qt/signverifymessagedialog.cpp
@@ -1,279 +1,276 @@
// Copyright (c) 2011-2016 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include
#include
#include
#include
#include
#include
#include
#include // For MessageSign(), MessageVerify()
#include
#include
#include
SignVerifyMessageDialog::SignVerifyMessageDialog(
const PlatformStyle *_platformStyle, QWidget *parent)
: QDialog(parent), ui(new Ui::SignVerifyMessageDialog), model(nullptr),
platformStyle(_platformStyle) {
ui->setupUi(this);
ui->addressBookButton_SM->setIcon(
platformStyle->SingleColorIcon(":/icons/address-book"));
ui->pasteButton_SM->setIcon(
platformStyle->SingleColorIcon(":/icons/editpaste"));
ui->copySignatureButton_SM->setIcon(
platformStyle->SingleColorIcon(":/icons/editcopy"));
ui->signMessageButton_SM->setIcon(
platformStyle->SingleColorIcon(":/icons/edit"));
ui->clearButton_SM->setIcon(
platformStyle->SingleColorIcon(":/icons/remove"));
ui->addressBookButton_VM->setIcon(
platformStyle->SingleColorIcon(":/icons/address-book"));
ui->verifyMessageButton_VM->setIcon(
platformStyle->SingleColorIcon(":/icons/transaction_0"));
ui->clearButton_VM->setIcon(
platformStyle->SingleColorIcon(":/icons/remove"));
- ui->signatureOut_SM->setPlaceholderText(
- tr("Click \"Sign Message\" to generate signature"));
-
GUIUtil::setupAddressWidget(ui->addressIn_SM, this);
GUIUtil::setupAddressWidget(ui->addressIn_VM, this);
ui->addressIn_SM->installEventFilter(this);
ui->messageIn_SM->installEventFilter(this);
ui->signatureOut_SM->installEventFilter(this);
ui->addressIn_VM->installEventFilter(this);
ui->messageIn_VM->installEventFilter(this);
ui->signatureIn_VM->installEventFilter(this);
ui->signatureOut_SM->setFont(GUIUtil::fixedPitchFont());
ui->signatureIn_VM->setFont(GUIUtil::fixedPitchFont());
}
SignVerifyMessageDialog::~SignVerifyMessageDialog() {
delete ui;
}
void SignVerifyMessageDialog::setModel(WalletModel *_model) {
this->model = _model;
}
void SignVerifyMessageDialog::setAddress_SM(const QString &address) {
ui->addressIn_SM->setText(address);
ui->messageIn_SM->setFocus();
}
void SignVerifyMessageDialog::setAddress_VM(const QString &address) {
ui->addressIn_VM->setText(address);
ui->messageIn_VM->setFocus();
}
void SignVerifyMessageDialog::showTab_SM(bool fShow) {
ui->tabWidget->setCurrentIndex(0);
if (fShow) {
this->show();
}
}
void SignVerifyMessageDialog::showTab_VM(bool fShow) {
ui->tabWidget->setCurrentIndex(1);
if (fShow) {
this->show();
}
}
void SignVerifyMessageDialog::on_addressBookButton_SM_clicked() {
if (model && model->getAddressTableModel()) {
AddressBookPage dlg(platformStyle, AddressBookPage::ForSelection,
AddressBookPage::ReceivingTab, this);
dlg.setModel(model->getAddressTableModel());
if (dlg.exec()) {
setAddress_SM(dlg.getReturnValue());
}
}
}
void SignVerifyMessageDialog::on_pasteButton_SM_clicked() {
setAddress_SM(QApplication::clipboard()->text());
}
void SignVerifyMessageDialog::on_signMessageButton_SM_clicked() {
if (!model) {
return;
}
/* Clear old signature to ensure users don't get confused on error with an
* old signature displayed */
ui->signatureOut_SM->clear();
CTxDestination destination = DecodeDestination(
ui->addressIn_SM->text().toStdString(), model->getChainParams());
if (!IsValidDestination(destination)) {
ui->statusLabel_SM->setStyleSheet("QLabel { color: red; }");
ui->statusLabel_SM->setText(
tr("The entered address is invalid.") + QString(" ") +
tr("Please check the address and try again."));
return;
}
const PKHash *pkhash = boost::get(&destination);
if (!pkhash) {
ui->addressIn_SM->setValid(false);
ui->statusLabel_SM->setStyleSheet("QLabel { color: red; }");
ui->statusLabel_SM->setText(
tr("The entered address does not refer to a key.") + QString(" ") +
tr("Please check the address and try again."));
return;
}
WalletModel::UnlockContext ctx(model->requestUnlock());
if (!ctx.isValid()) {
ui->statusLabel_SM->setStyleSheet("QLabel { color: red; }");
ui->statusLabel_SM->setText(tr("Wallet unlock was cancelled."));
return;
}
const std::string &message =
ui->messageIn_SM->document()->toPlainText().toStdString();
std::string signature;
SigningResult res =
model->wallet().signMessage(message, *pkhash, signature);
QString error;
switch (res) {
case SigningResult::OK:
error = tr("No error");
break;
case SigningResult::PRIVATE_KEY_NOT_AVAILABLE:
error = tr("Private key for the entered address is not available.");
break;
case SigningResult::SIGNING_FAILED:
error = tr("Message signing failed.");
break;
// no default case, so the compiler can warn about missing cases
}
if (res != SigningResult::OK) {
ui->statusLabel_SM->setStyleSheet("QLabel { color: red; }");
ui->statusLabel_SM->setText(QString("") + error +
QString(""));
return;
}
ui->statusLabel_SM->setStyleSheet("QLabel { color: green; }");
ui->statusLabel_SM->setText(QString("") + tr("Message signed.") +
QString(""));
ui->signatureOut_SM->setText(QString::fromStdString(signature));
}
void SignVerifyMessageDialog::on_copySignatureButton_SM_clicked() {
GUIUtil::setClipboard(ui->signatureOut_SM->text());
}
void SignVerifyMessageDialog::on_clearButton_SM_clicked() {
ui->addressIn_SM->clear();
ui->messageIn_SM->clear();
ui->signatureOut_SM->clear();
ui->statusLabel_SM->clear();
ui->addressIn_SM->setFocus();
}
void SignVerifyMessageDialog::on_addressBookButton_VM_clicked() {
if (model && model->getAddressTableModel()) {
AddressBookPage dlg(platformStyle, AddressBookPage::ForSelection,
AddressBookPage::SendingTab, this);
dlg.setModel(model->getAddressTableModel());
if (dlg.exec()) {
setAddress_VM(dlg.getReturnValue());
}
}
}
void SignVerifyMessageDialog::on_verifyMessageButton_VM_clicked() {
const std::string &address = ui->addressIn_VM->text().toStdString();
const std::string &signature = ui->signatureIn_VM->text().toStdString();
const std::string &message =
ui->messageIn_VM->document()->toPlainText().toStdString();
const auto result =
MessageVerify(model->getChainParams(), address, signature, message);
if (result == MessageVerificationResult::OK) {
ui->statusLabel_VM->setStyleSheet("QLabel { color: green; }");
} else {
ui->statusLabel_VM->setStyleSheet("QLabel { color: red; }");
}
switch (result) {
case MessageVerificationResult::OK:
ui->statusLabel_VM->setText(QString("") +
tr("Message verified.") +
QString(""));
return;
case MessageVerificationResult::ERR_INVALID_ADDRESS:
ui->statusLabel_VM->setText(
tr("The entered address is invalid.") + QString(" ") +
tr("Please check the address and try again."));
return;
case MessageVerificationResult::ERR_ADDRESS_NO_KEY:
ui->addressIn_VM->setValid(false);
ui->statusLabel_VM->setText(
tr("The entered address does not refer to a key.") +
QString(" ") + tr("Please check the address and try again."));
return;
case MessageVerificationResult::ERR_MALFORMED_SIGNATURE:
ui->signatureIn_VM->setValid(false);
ui->statusLabel_VM->setText(
tr("The signature could not be decoded.") + QString(" ") +
tr("Please check the signature and try again."));
return;
case MessageVerificationResult::ERR_PUBKEY_NOT_RECOVERED:
ui->signatureIn_VM->setValid(false);
ui->statusLabel_VM->setText(
tr("The signature did not match the message digest.") +
QString(" ") + tr("Please check the signature and try again."));
return;
case MessageVerificationResult::ERR_NOT_SIGNED:
ui->statusLabel_VM->setText(QString("") +
tr("Message verification failed.") +
QString(""));
return;
}
}
void SignVerifyMessageDialog::on_clearButton_VM_clicked() {
ui->addressIn_VM->clear();
ui->signatureIn_VM->clear();
ui->messageIn_VM->clear();
ui->statusLabel_VM->clear();
ui->addressIn_VM->setFocus();
}
bool SignVerifyMessageDialog::eventFilter(QObject *object, QEvent *event) {
if (event->type() == QEvent::MouseButtonPress ||
event->type() == QEvent::FocusIn) {
if (ui->tabWidget->currentIndex() == 0) {
/* Clear status message on focus change */
ui->statusLabel_SM->clear();
/* Select generated signature */
if (object == ui->signatureOut_SM) {
ui->signatureOut_SM->selectAll();
return true;
}
} else if (ui->tabWidget->currentIndex() == 1) {
/* Clear status message on focus change */
ui->statusLabel_VM->clear();
}
}
return QDialog::eventFilter(object, event);
}