Browse Source

[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
0.10
Philip Kaufmann 11 years ago committed by Wladimir J. van der Laan
parent
commit
c78bd93701
No known key found for this signature in database
GPG Key ID: 74810B012346C9A6
  1. 58
      src/qt/bitcoinaddressvalidator.cpp
  2. 22
      src/qt/bitcoinaddressvalidator.h
  3. 9
      src/qt/forms/editaddressdialog.ui
  4. 6
      src/qt/forms/signverifymessagedialog.ui
  5. 12
      src/qt/guiutil.cpp
  6. 3
      src/qt/guiutil.h
  7. 60
      src/qt/qvalidatedlineedit.cpp
  8. 7
      src/qt/qvalidatedlineedit.h
  9. 9
      src/qt/sendcoinsdialog.cpp
  10. 4
      src/qt/sendcoinsentry.cpp
  11. 5
      src/qt/signverifymessagedialog.cpp

58
src/qt/bitcoinaddressvalidator.cpp

@ -1,9 +1,11 @@ @@ -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 @@ @@ -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 @@ -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 @@ -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 @@ -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;
}

22
src/qt/bitcoinaddressvalidator.h

@ -1,4 +1,4 @@ @@ -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 @@ @@ -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

9
src/qt/forms/editaddressdialog.ui

@ -47,7 +47,7 @@ @@ -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 @@ @@ -67,6 +67,13 @@
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>QValidatedLineEdit</class>
<extends>QLineEdit</extends>
<header>qvalidatedlineedit.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections>
<connection>

6
src/qt/forms/signverifymessagedialog.ui

@ -47,9 +47,6 @@ @@ -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 @@ @@ -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>

12
src/qt/guiutil.cpp

@ -6,6 +6,7 @@ @@ -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() @@ -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)

3
src/qt/guiutil.h

@ -9,6 +9,7 @@ @@ -9,6 +9,7 @@
#include <QObject>
#include <QString>
class QValidatedLineEdit;
class SendCoinsRecipient;
QT_BEGIN_NAMESPACE
@ -32,7 +33,7 @@ namespace GUIUtil @@ -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

60
src/qt/qvalidatedlineedit.cpp

@ -4,10 +4,13 @@ @@ -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) @@ -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() @@ -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;
}

7
src/qt/qvalidatedlineedit.h

@ -15,20 +15,25 @@ class QValidatedLineEdit : public QLineEdit @@ -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

9
src/qt/sendcoinsdialog.cpp

@ -33,9 +33,8 @@ SendCoinsDialog::SendCoinsDialog(QWidget *parent) : @@ -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) : @@ -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) @@ -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) @@ -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) @@ -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

4
src/qt/sendcoinsentry.cpp

@ -28,9 +28,7 @@ SendCoinsEntry::SendCoinsEntry(QWidget *parent) : @@ -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() @@ -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;

5
src/qt/signverifymessagedialog.cpp

@ -26,11 +26,8 @@ SignVerifyMessageDialog::SignVerifyMessageDialog(QWidget *parent) : @@ -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() @@ -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() @@ -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;

Loading…
Cancel
Save