aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilip Kaufmann <phil.kaufmann@t-online.de>2013-11-20 15:56:51 +0100
committerWladimir J. van der Laan <laanwj@gmail.com>2014-01-29 14:15:55 +0100
commitc78bd937017212c89c1c7aab07399cec5b6b3bdd (patch)
tree92129bb63c2b9bbb724c3a2b4ad643710484e3ea
parentaab8fc58c6e6dc6e0a104170bd2aa10dc1af5dea (diff)
[Qt] extend validate line edit and btc address validator
- remove btc address length from address validator - add an optional btc address check in validated line edit that defaults to off and is used in GUIUtil::setupAddressWidget() - an isAcceptable() check is added to validated line edit on focus out which only kicks in, when a validator is used with that widget - remove an isAcceptable() check from sendcoinsentry.cpp - remove obsolete attributes from ui files, which are set by calling GUIUtil::setupAddressWidget() - move some more things to GUIUtil::setupAddressWidget() and remove them from normal code e.g. placeholder text
-rw-r--r--src/qt/bitcoinaddressvalidator.cpp58
-rw-r--r--src/qt/bitcoinaddressvalidator.h22
-rw-r--r--src/qt/forms/editaddressdialog.ui9
-rw-r--r--src/qt/forms/signverifymessagedialog.ui6
-rw-r--r--src/qt/guiutil.cpp12
-rw-r--r--src/qt/guiutil.h3
-rw-r--r--src/qt/qvalidatedlineedit.cpp60
-rw-r--r--src/qt/qvalidatedlineedit.h7
-rw-r--r--src/qt/sendcoinsdialog.cpp9
-rw-r--r--src/qt/sendcoinsentry.cpp4
-rw-r--r--src/qt/signverifymessagedialog.cpp5
11 files changed, 140 insertions, 55 deletions
diff --git a/src/qt/bitcoinaddressvalidator.cpp b/src/qt/bitcoinaddressvalidator.cpp
index 604f24192b..293cc168b9 100644
--- a/src/qt/bitcoinaddressvalidator.cpp
+++ b/src/qt/bitcoinaddressvalidator.cpp
@@ -1,9 +1,11 @@
-// Copyright (c) 2011-2013 The Bitcoin developers
+// Copyright (c) 2011-2014 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "bitcoinaddressvalidator.h"
+#include "base58.h"
+
/* Base58 characters are:
"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
@@ -11,21 +13,23 @@
- All numbers except for '0'
- All upper-case letters except for 'I' and 'O'
- All lower-case letters except for 'l'
-
- User friendly Base58 input can map
- - 'l' and 'I' to '1'
- - '0' and 'O' to 'o'
*/
-BitcoinAddressValidator::BitcoinAddressValidator(QObject *parent) :
+BitcoinAddressEntryValidator::BitcoinAddressEntryValidator(QObject *parent) :
QValidator(parent)
{
}
-QValidator::State BitcoinAddressValidator::validate(QString &input, int &pos) const
+QValidator::State BitcoinAddressEntryValidator::validate(QString &input, int &pos) const
{
+ Q_UNUSED(pos);
+
+ // Empty address is "intermediate" input
+ if (input.isEmpty())
+ return QValidator::Intermediate;
+
// Correction
- for(int idx=0; idx<input.size();)
+ for (int idx = 0; idx < input.size();)
{
bool removeChar = false;
QChar ch = input.at(idx);
@@ -42,11 +46,13 @@ QValidator::State BitcoinAddressValidator::validate(QString &input, int &pos) co
default:
break;
}
+
// Remove whitespace
- if(ch.isSpace())
+ if (ch.isSpace())
removeChar = true;
+
// To next character
- if(removeChar)
+ if (removeChar)
input.remove(idx, 1);
else
++idx;
@@ -54,14 +60,14 @@ QValidator::State BitcoinAddressValidator::validate(QString &input, int &pos) co
// Validation
QValidator::State state = QValidator::Acceptable;
- for(int idx=0; idx<input.size(); ++idx)
+ for (int idx = 0; idx < input.size(); ++idx)
{
int ch = input.at(idx).unicode();
- if(((ch >= '0' && ch<='9') ||
- (ch >= 'a' && ch<='z') ||
- (ch >= 'A' && ch<='Z')) &&
- ch != 'l' && ch != 'I' && ch != '0' && ch != 'O')
+ if (((ch >= '0' && ch<='9') ||
+ (ch >= 'a' && ch<='z') ||
+ (ch >= 'A' && ch<='Z')) &&
+ ch != 'l' && ch != 'I' && ch != '0' && ch != 'O')
{
// Alphanumeric and not a 'forbidden' character
}
@@ -71,11 +77,21 @@ QValidator::State BitcoinAddressValidator::validate(QString &input, int &pos) co
}
}
- // Empty address is "intermediate" input
- if(input.isEmpty())
- {
- state = QValidator::Intermediate;
- }
-
return state;
}
+
+BitcoinAddressCheckValidator::BitcoinAddressCheckValidator(QObject *parent) :
+ QValidator(parent)
+{
+}
+
+QValidator::State BitcoinAddressCheckValidator::validate(QString &input, int &pos) const
+{
+ Q_UNUSED(pos);
+ // Validate the passed Bitcoin address
+ CBitcoinAddress addr(input.toStdString());
+ if (addr.IsValid())
+ return QValidator::Acceptable;
+
+ return QValidator::Invalid;
+}
diff --git a/src/qt/bitcoinaddressvalidator.h b/src/qt/bitcoinaddressvalidator.h
index 91d248abd1..0fb779f7d8 100644
--- a/src/qt/bitcoinaddressvalidator.h
+++ b/src/qt/bitcoinaddressvalidator.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011-2013 The Bitcoin developers
+// Copyright (c) 2011-2014 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
@@ -7,19 +7,29 @@
#include <QValidator>
-/** Base58 entry widget validator.
- Corrects near-miss characters and refuses characters that are not part of base58.
+/** Base58 entry widget validator, checks for valid characters and
+ * removes some whitespace.
*/
-class BitcoinAddressValidator : public QValidator
+class BitcoinAddressEntryValidator : public QValidator
{
Q_OBJECT
public:
- explicit BitcoinAddressValidator(QObject *parent = 0);
+ explicit BitcoinAddressEntryValidator(QObject *parent);
State validate(QString &input, int &pos) const;
+};
+
+/** Bitcoin address widget validator, checks for a valid bitcoin address.
+ */
+class BitcoinAddressCheckValidator : public QValidator
+{
+ Q_OBJECT
+
+public:
+ explicit BitcoinAddressCheckValidator(QObject *parent);
- static const int MaxAddressLength = 35;
+ State validate(QString &input, int &pos) const;
};
#endif // BITCOINADDRESSVALIDATOR_H
diff --git a/src/qt/forms/editaddressdialog.ui b/src/qt/forms/editaddressdialog.ui
index 915b3679a1..c1aea36338 100644
--- a/src/qt/forms/editaddressdialog.ui
+++ b/src/qt/forms/editaddressdialog.ui
@@ -47,7 +47,7 @@
</widget>
</item>
<item row="1" column="1">
- <widget class="QLineEdit" name="addressEdit">
+ <widget class="QValidatedLineEdit" name="addressEdit">
<property name="toolTip">
<string>The address associated with this address list entry. This can only be modified for sending addresses.</string>
</property>
@@ -67,6 +67,13 @@
</item>
</layout>
</widget>
+ <customwidgets>
+ <customwidget>
+ <class>QValidatedLineEdit</class>
+ <extends>QLineEdit</extends>
+ <header>qvalidatedlineedit.h</header>
+ </customwidget>
+ </customwidgets>
<resources/>
<connections>
<connection>
diff --git a/src/qt/forms/signverifymessagedialog.ui b/src/qt/forms/signverifymessagedialog.ui
index 989522bb58..aa271b4f2a 100644
--- a/src/qt/forms/signverifymessagedialog.ui
+++ b/src/qt/forms/signverifymessagedialog.ui
@@ -47,9 +47,6 @@
<property name="toolTip">
<string>The address to sign the message with (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)</string>
</property>
- <property name="maxLength">
- <number>34</number>
- </property>
</widget>
</item>
<item>
@@ -260,9 +257,6 @@
<property name="toolTip">
<string>The address the message was signed with (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)</string>
</property>
- <property name="maxLength">
- <number>34</number>
- </property>
</widget>
</item>
<item>
diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp
index 5c3ba05b06..7e1831f037 100644
--- a/src/qt/guiutil.cpp
+++ b/src/qt/guiutil.cpp
@@ -6,6 +6,7 @@
#include "bitcoinaddressvalidator.h"
#include "bitcoinunits.h"
+#include "qvalidatedlineedit.h"
#include "walletmodel.h"
#include "core.h"
@@ -72,11 +73,16 @@ QFont bitcoinAddressFont()
return font;
}
-void setupAddressWidget(QLineEdit *widget, QWidget *parent)
+void setupAddressWidget(QValidatedLineEdit *widget, QWidget *parent)
{
- widget->setMaxLength(BitcoinAddressValidator::MaxAddressLength);
- widget->setValidator(new BitcoinAddressValidator(parent));
+ parent->setFocusProxy(widget);
+
widget->setFont(bitcoinAddressFont());
+#if QT_VERSION >= 0x040700
+ widget->setPlaceholderText(QObject::tr("Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)"));
+#endif
+ widget->setValidator(new BitcoinAddressEntryValidator(parent));
+ widget->setCheckValidator(new BitcoinAddressCheckValidator(parent));
}
void setupAmountWidget(QLineEdit *widget, QWidget *parent)
diff --git a/src/qt/guiutil.h b/src/qt/guiutil.h
index c894850a91..52124ff20a 100644
--- a/src/qt/guiutil.h
+++ b/src/qt/guiutil.h
@@ -9,6 +9,7 @@
#include <QObject>
#include <QString>
+class QValidatedLineEdit;
class SendCoinsRecipient;
QT_BEGIN_NAMESPACE
@@ -32,7 +33,7 @@ namespace GUIUtil
QFont bitcoinAddressFont();
// Set up widgets for address and amounts
- void setupAddressWidget(QLineEdit *widget, QWidget *parent);
+ void setupAddressWidget(QValidatedLineEdit *widget, QWidget *parent);
void setupAmountWidget(QLineEdit *widget, QWidget *parent);
// Parse "bitcoin:" URI into recipient object, return true on successful parsing
diff --git a/src/qt/qvalidatedlineedit.cpp b/src/qt/qvalidatedlineedit.cpp
index 1e7596c9c1..c2567835c9 100644
--- a/src/qt/qvalidatedlineedit.cpp
+++ b/src/qt/qvalidatedlineedit.cpp
@@ -4,10 +4,13 @@
#include "qvalidatedlineedit.h"
+#include "bitcoinaddressvalidator.h"
#include "guiconstants.h"
QValidatedLineEdit::QValidatedLineEdit(QWidget *parent) :
- QLineEdit(parent), valid(true)
+ QLineEdit(parent),
+ valid(true),
+ checkValidator(0)
{
connect(this, SIGNAL(textChanged(QString)), this, SLOT(markValid()));
}
@@ -34,11 +37,20 @@ void QValidatedLineEdit::focusInEvent(QFocusEvent *evt)
{
// Clear invalid flag on focus
setValid(true);
+
QLineEdit::focusInEvent(evt);
}
+void QValidatedLineEdit::focusOutEvent(QFocusEvent *evt)
+{
+ checkValidity();
+
+ QLineEdit::focusOutEvent(evt);
+}
+
void QValidatedLineEdit::markValid()
{
+ // As long as a user is typing ensure we display state as valid
setValid(true);
}
@@ -47,3 +59,49 @@ void QValidatedLineEdit::clear()
setValid(true);
QLineEdit::clear();
}
+
+void QValidatedLineEdit::setEnabled(bool enabled)
+{
+ if (!enabled)
+ {
+ // A disabled QValidatedLineEdit should be marked valid
+ setValid(true);
+ }
+ else
+ {
+ // Recheck validity when QValidatedLineEdit gets enabled
+ checkValidity();
+ }
+
+ QLineEdit::setEnabled(enabled);
+}
+
+void QValidatedLineEdit::checkValidity()
+{
+ if (text().isEmpty())
+ {
+ setValid(true);
+ }
+ else if (hasAcceptableInput())
+ {
+ setValid(true);
+
+ // Check contents on focus out
+ if (checkValidator)
+ {
+ QString address = text();
+ int pos = 0;
+ if (checkValidator->validate(address, pos) == QValidator::Acceptable)
+ setValid(true);
+ else
+ setValid(false);
+ }
+ }
+ else
+ setValid(false);
+}
+
+void QValidatedLineEdit::setCheckValidator(const QValidator *v)
+{
+ checkValidator = v;
+}
diff --git a/src/qt/qvalidatedlineedit.h b/src/qt/qvalidatedlineedit.h
index 53ef04e4a0..c2a4817e65 100644
--- a/src/qt/qvalidatedlineedit.h
+++ b/src/qt/qvalidatedlineedit.h
@@ -15,20 +15,25 @@ class QValidatedLineEdit : public QLineEdit
Q_OBJECT
public:
- explicit QValidatedLineEdit(QWidget *parent = 0);
+ explicit QValidatedLineEdit(QWidget *parent);
void clear();
+ void setCheckValidator(const QValidator *v);
protected:
void focusInEvent(QFocusEvent *evt);
+ void focusOutEvent(QFocusEvent *evt);
private:
bool valid;
+ const QValidator *checkValidator;
public slots:
void setValid(bool valid);
+ void setEnabled(bool enabled);
private slots:
void markValid();
+ void checkValidity();
};
#endif // QVALIDATEDLINEEDIT_H
diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp
index b15f005646..e2d7dc9bd3 100644
--- a/src/qt/sendcoinsdialog.cpp
+++ b/src/qt/sendcoinsdialog.cpp
@@ -33,9 +33,8 @@ SendCoinsDialog::SendCoinsDialog(QWidget *parent) :
ui->clearButton->setIcon(QIcon());
ui->sendButton->setIcon(QIcon());
#endif
-#if QT_VERSION >= 0x040700
- ui->lineEditCoinControlChange->setPlaceholderText(tr("Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)"));
-#endif
+
+ GUIUtil::setupAddressWidget(ui->lineEditCoinControlChange, this);
addEntry();
@@ -43,7 +42,6 @@ SendCoinsDialog::SendCoinsDialog(QWidget *parent) :
connect(ui->clearButton, SIGNAL(clicked()), this, SLOT(clear()));
// Coin Control
- ui->lineEditCoinControlChange->setFont(GUIUtil::bitcoinAddressFont());
connect(ui->pushButtonCoinControl, SIGNAL(clicked()), this, SLOT(coinControlButtonClicked()));
connect(ui->checkBoxCoinControlChange, SIGNAL(stateChanged(int)), this, SLOT(coinControlChangeChecked(int)));
connect(ui->lineEditCoinControlChange, SIGNAL(textEdited(const QString &)), this, SLOT(coinControlChangeEdited(const QString &)));
@@ -536,7 +534,6 @@ void SendCoinsDialog::coinControlChangeChecked(int state)
if (state == Qt::Unchecked)
{
CoinControlDialog::coinControl->destChange = CNoDestination();
- ui->lineEditCoinControlChange->setValid(true);
ui->labelCoinControlChangeLabel->clear();
}
else
@@ -563,7 +560,6 @@ void SendCoinsDialog::coinControlChangeEdited(const QString& text)
}
else if (!addr.IsValid()) // Invalid address
{
- ui->lineEditCoinControlChange->setValid(false);
ui->labelCoinControlChangeLabel->setText(tr("Warning: Invalid Bitcoin address"));
}
else // Valid address
@@ -573,7 +569,6 @@ void SendCoinsDialog::coinControlChangeEdited(const QString& text)
addr.GetKeyID(keyid);
if (!model->getPubKey(keyid, pubkey)) // Unknown change address
{
- ui->lineEditCoinControlChange->setValid(false);
ui->labelCoinControlChangeLabel->setText(tr("Warning: Unknown change address"));
}
else // Known change address
diff --git a/src/qt/sendcoinsentry.cpp b/src/qt/sendcoinsentry.cpp
index b4e74b078c..ad8dd7b732 100644
--- a/src/qt/sendcoinsentry.cpp
+++ b/src/qt/sendcoinsentry.cpp
@@ -28,9 +28,7 @@ SendCoinsEntry::SendCoinsEntry(QWidget *parent) :
#endif
#if QT_VERSION >= 0x040700
ui->addAsLabel->setPlaceholderText(tr("Enter a label for this address to add it to your address book"));
- ui->payTo->setPlaceholderText(tr("Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)"));
#endif
- setFocusProxy(ui->payTo);
// normal bitcoin address field
GUIUtil::setupAddressWidget(ui->payTo, this);
@@ -121,7 +119,7 @@ bool SendCoinsEntry::validate()
if (recipient.paymentRequest.IsInitialized())
return retval;
- if (!ui->payTo->hasAcceptableInput() || !model->validateAddress(ui->payTo->text()))
+ if (!model->validateAddress(ui->payTo->text()))
{
ui->payTo->setValid(false);
retval = false;
diff --git a/src/qt/signverifymessagedialog.cpp b/src/qt/signverifymessagedialog.cpp
index e319f5075a..3e56412c7c 100644
--- a/src/qt/signverifymessagedialog.cpp
+++ b/src/qt/signverifymessagedialog.cpp
@@ -26,11 +26,8 @@ SignVerifyMessageDialog::SignVerifyMessageDialog(QWidget *parent) :
ui->setupUi(this);
#if QT_VERSION >= 0x040700
- ui->addressIn_SM->setPlaceholderText(tr("Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)"));
ui->signatureOut_SM->setPlaceholderText(tr("Click \"Sign Message\" to generate signature"));
-
ui->addressIn_VM->setPlaceholderText(tr("Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)"));
- ui->signatureIn_VM->setPlaceholderText(tr("Enter Bitcoin signature"));
#endif
GUIUtil::setupAddressWidget(ui->addressIn_SM, this);
@@ -112,7 +109,6 @@ void SignVerifyMessageDialog::on_signMessageButton_SM_clicked()
CBitcoinAddress addr(ui->addressIn_SM->text().toStdString());
if (!addr.IsValid())
{
- ui->addressIn_SM->setValid(false);
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;
@@ -193,7 +189,6 @@ void SignVerifyMessageDialog::on_verifyMessageButton_VM_clicked()
CBitcoinAddress addr(ui->addressIn_VM->text().toStdString());
if (!addr.IsValid())
{
- ui->addressIn_VM->setValid(false);
ui->statusLabel_VM->setStyleSheet("QLabel { color: red; }");
ui->statusLabel_VM->setText(tr("The entered address is invalid.") + QString(" ") + tr("Please check the address and try again."));
return;