From f193c57a63d8e66835873ff05ef8028fa87b427f Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Mon, 20 Jun 2011 21:31:42 +0200 Subject: [PATCH] introduce bitcoin amount field with split amount/decimals, to protect against mistakes (https://forum.bitcoin.org/index.php?topic=19168.0) --- bitcoin-qt.pro | 6 ++- src/qt/bitcoinamountfield.cpp | 67 +++++++++++++++++++++++++++++++++ src/qt/bitcoinamountfield.h | 33 ++++++++++++++++ src/qt/forms/sendcoinsdialog.ui | 39 +++++++++++-------- src/qt/optionsdialog.cpp | 8 ++-- src/qt/sendcoinsdialog.cpp | 1 - 6 files changed, 130 insertions(+), 24 deletions(-) create mode 100644 src/qt/bitcoinamountfield.cpp create mode 100644 src/qt/bitcoinamountfield.h diff --git a/bitcoin-qt.pro b/bitcoin-qt.pro index 27703592..501695bd 100644 --- a/bitcoin-qt.pro +++ b/bitcoin-qt.pro @@ -68,7 +68,8 @@ HEADERS += src/qt/bitcoingui.h \ src/qt/monitoreddatamapper.h \ src/externui.h \ src/qt/transactiondesc.h \ - src/qt/transactiondescdialog.h + src/qt/transactiondescdialog.h \ + src/qt/bitcoinamountfield.h SOURCES += src/qt/bitcoin.cpp src/qt/bitcoingui.cpp \ src/qt/transactiontablemodel.cpp \ src/qt/addresstablemodel.cpp \ @@ -98,7 +99,8 @@ SOURCES += src/qt/bitcoin.cpp src/qt/bitcoingui.cpp \ src/qt/monitoreddatamapper.cpp \ src/qt/transactiondesc.cpp \ src/qt/transactiondescdialog.cpp \ - src/qt/bitcoinstrings.cpp + src/qt/bitcoinstrings.cpp \ + src/qt/bitcoinamountfield.cpp RESOURCES += \ src/qt/bitcoin.qrc diff --git a/src/qt/bitcoinamountfield.cpp b/src/qt/bitcoinamountfield.cpp new file mode 100644 index 00000000..e475441f --- /dev/null +++ b/src/qt/bitcoinamountfield.cpp @@ -0,0 +1,67 @@ +#include "bitcoinamountfield.h" + +#include +#include +#include +#include +#include + +BitcoinAmountField::BitcoinAmountField(QWidget *parent): + QWidget(parent), amount(0), decimals(0) +{ + amount = new QLineEdit(this); + amount->setValidator(new QRegExpValidator(QRegExp("[0-9]+"), this)); + amount->setAlignment(Qt::AlignRight|Qt::AlignVCenter); + amount->installEventFilter(this); + amount->setMaximumWidth(80); + decimals = new QLineEdit(this); + decimals->setValidator(new QRegExpValidator(QRegExp("[0-9]+"), this)); + decimals->setMaxLength(8); + decimals->setAlignment(Qt::AlignLeft|Qt::AlignVCenter); + decimals->setMaximumWidth(75); + + QHBoxLayout *layout = new QHBoxLayout(this); + layout->setSpacing(0); + layout->addWidget(amount); + layout->addWidget(new QLabel(QString("."))); + layout->addWidget(decimals); + layout->addStretch(1); + + setFocusPolicy(Qt::TabFocus); + setLayout(layout); + setFocusProxy(amount); + + // If one if the widgets changes, the combined content changes as well + connect(amount, SIGNAL(textChanged(QString)), this, SIGNAL(textChanged())); + connect(decimals, SIGNAL(textChanged(QString)), this, SIGNAL(textChanged())); +} + +void BitcoinAmountField::setText(const QString &text) +{ + const QStringList parts = text.split(QString(".")); + if(parts.size() == 2) + { + amount->setText(parts[0]); + decimals->setText(parts[1]); + } +} + +QString BitcoinAmountField::text() const +{ + return amount->text() + QString(".") + decimals->text(); +} + +// Intercept '.' and ',' keys, if pressed focus a specified widget +bool BitcoinAmountField::eventFilter(QObject *object, QEvent *event) +{ + Q_UNUSED(object); + if(event->type() == QEvent::KeyPress) + { + QKeyEvent *keyEvent = static_cast(event); + if(keyEvent->key() == Qt::Key_Period || keyEvent->key() == Qt::Key_Comma) + { + decimals->setFocus(); + } + } + return false; +} diff --git a/src/qt/bitcoinamountfield.h b/src/qt/bitcoinamountfield.h new file mode 100644 index 00000000..2171578e --- /dev/null +++ b/src/qt/bitcoinamountfield.h @@ -0,0 +1,33 @@ +#ifndef BITCOINFIELD_H +#define BITCOINFIELD_H + +#include + +QT_BEGIN_NAMESPACE +class QLineEdit; +QT_END_NAMESPACE + +class BitcoinAmountField: public QWidget +{ + Q_OBJECT + Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged USER true); +public: + explicit BitcoinAmountField(QWidget *parent = 0); + + void setText(const QString &text); + QString text() const; + +signals: + void textChanged(); + +protected: + // Intercept '.' and ',' keys, if pressed focus a specified widget + bool eventFilter(QObject *object, QEvent *event); + +private: + QLineEdit *amount; + QLineEdit *decimals; +}; + + +#endif // BITCOINFIELD_H diff --git a/src/qt/forms/sendcoinsdialog.ui b/src/qt/forms/sendcoinsdialog.ui index 595b7f40..3aaec1b5 100644 --- a/src/qt/forms/sendcoinsdialog.ui +++ b/src/qt/forms/sendcoinsdialog.ui @@ -52,22 +52,6 @@ - - - - - 145 - 16777215 - - - - Amount of bitcoins to send (e.g. 0.05) - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - @@ -106,6 +90,13 @@ + + + + Qt::TabFocus + + + @@ -173,6 +164,22 @@ + + + BitcoinAmountField + QWidget +
bitcoinamountfield.h
+ 1 +
+
+ + payTo + payAmount + pasteButton + addressBookButton + sendButton + buttonBox + diff --git a/src/qt/optionsdialog.cpp b/src/qt/optionsdialog.cpp index 1bf123b2..1b5b2fef 100644 --- a/src/qt/optionsdialog.cpp +++ b/src/qt/optionsdialog.cpp @@ -1,5 +1,6 @@ #include "optionsdialog.h" #include "optionsmodel.h" +#include "bitcoinamountfield.h" #include "monitoreddatamapper.h" #include "guiutil.h" @@ -31,7 +32,7 @@ private: QCheckBox *connect_socks4; QLineEdit *proxy_ip; QLineEdit *proxy_port; - QLineEdit *fee_edit; + BitcoinAmountField *fee_edit; signals: @@ -195,12 +196,9 @@ MainOptionsPage::MainOptionsPage(QWidget *parent): fee_hbox->addSpacing(18); QLabel *fee_label = new QLabel(tr("Pay transaction &fee")); fee_hbox->addWidget(fee_label); - fee_edit = new QLineEdit(); - fee_edit->setMaximumWidth(100); + fee_edit = new BitcoinAmountField(); fee_edit->setToolTip(tr("Optional transaction fee per KB that helps make sure your transactions are processed quickly. Most transactions are 1KB. Fee 0.01 recommended.")); - GUIUtil::setupAmountWidget(fee_edit, this); - fee_label->setBuddy(fee_edit); fee_hbox->addWidget(fee_edit); fee_hbox->addStretch(1); diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp index 01072c42..5f9ee18a 100644 --- a/src/qt/sendcoinsdialog.cpp +++ b/src/qt/sendcoinsdialog.cpp @@ -23,7 +23,6 @@ SendCoinsDialog::SendCoinsDialog(QWidget *parent, const QString &address) : ui->setupUi(this); GUIUtil::setupAddressWidget(ui->payTo, this); - GUIUtil::setupAmountWidget(ui->payAmount, this); // Set initial send-to address if provided if(!address.isEmpty())