Page MenuHomePhabricator

No OneTemporary

diff --git a/src/Makefile.qt.include b/src/Makefile.qt.include
index 75b7b683dd..2772bc753a 100644
--- a/src/Makefile.qt.include
+++ b/src/Makefile.qt.include
@@ -1,417 +1,418 @@
bin_PROGRAMS += qt/bitcoin-qt
noinst_LIBRARIES += qt/libbitcoinqt.a
# bitcoin qt core #
QT_TS = \
qt/locale/bitcoin_ach.ts \
qt/locale/bitcoin_af_ZA.ts \
qt/locale/bitcoin_ar.ts \
qt/locale/bitcoin_be_BY.ts \
qt/locale/bitcoin_bg.ts \
qt/locale/bitcoin_bs.ts \
qt/locale/bitcoin_ca_ES.ts \
qt/locale/bitcoin_ca.ts \
qt/locale/bitcoin_ca@valencia.ts \
qt/locale/bitcoin_cmn.ts \
qt/locale/bitcoin_cs.ts \
qt/locale/bitcoin_cy.ts \
qt/locale/bitcoin_da.ts \
qt/locale/bitcoin_de.ts \
qt/locale/bitcoin_el_GR.ts \
qt/locale/bitcoin_en.ts \
qt/locale/bitcoin_eo.ts \
qt/locale/bitcoin_es_CL.ts \
qt/locale/bitcoin_es_DO.ts \
qt/locale/bitcoin_es_MX.ts \
qt/locale/bitcoin_es.ts \
qt/locale/bitcoin_es_UY.ts \
qt/locale/bitcoin_et.ts \
qt/locale/bitcoin_eu_ES.ts \
qt/locale/bitcoin_fa_IR.ts \
qt/locale/bitcoin_fa.ts \
qt/locale/bitcoin_fi.ts \
qt/locale/bitcoin_fr_CA.ts \
qt/locale/bitcoin_fr.ts \
qt/locale/bitcoin_gl.ts \
qt/locale/bitcoin_gu_IN.ts \
qt/locale/bitcoin_he.ts \
qt/locale/bitcoin_hi_IN.ts \
qt/locale/bitcoin_hr.ts \
qt/locale/bitcoin_hu.ts \
qt/locale/bitcoin_id_ID.ts \
qt/locale/bitcoin_it.ts \
qt/locale/bitcoin_ja.ts \
qt/locale/bitcoin_ka.ts \
qt/locale/bitcoin_kk_KZ.ts \
qt/locale/bitcoin_ko_KR.ts \
qt/locale/bitcoin_ky.ts \
qt/locale/bitcoin_la.ts \
qt/locale/bitcoin_lt.ts \
qt/locale/bitcoin_lv_LV.ts \
qt/locale/bitcoin_mn.ts \
qt/locale/bitcoin_ms_MY.ts \
qt/locale/bitcoin_nb.ts \
qt/locale/bitcoin_nl.ts \
qt/locale/bitcoin_pam.ts \
qt/locale/bitcoin_pl.ts \
qt/locale/bitcoin_pt_BR.ts \
qt/locale/bitcoin_pt_PT.ts \
qt/locale/bitcoin_ro_RO.ts \
qt/locale/bitcoin_ru.ts \
qt/locale/bitcoin_sah.ts \
qt/locale/bitcoin_sk.ts \
qt/locale/bitcoin_sl_SI.ts \
qt/locale/bitcoin_sq.ts \
qt/locale/bitcoin_sr.ts \
qt/locale/bitcoin_sv.ts \
qt/locale/bitcoin_th_TH.ts \
qt/locale/bitcoin_tr.ts \
qt/locale/bitcoin_uk.ts \
qt/locale/bitcoin_ur_PK.ts \
qt/locale/bitcoin_uz@Cyrl.ts \
qt/locale/bitcoin_vi.ts \
qt/locale/bitcoin_vi_VN.ts \
qt/locale/bitcoin_zh_CN.ts \
qt/locale/bitcoin_zh_HK.ts \
qt/locale/bitcoin_zh_TW.ts
QT_FORMS_UI = \
qt/forms/addressbookpage.ui \
qt/forms/askpassphrasedialog.ui \
qt/forms/coincontroldialog.ui \
qt/forms/editaddressdialog.ui \
qt/forms/helpmessagedialog.ui \
qt/forms/intro.ui \
qt/forms/openuridialog.ui \
qt/forms/optionsdialog.ui \
qt/forms/overviewpage.ui \
qt/forms/receivecoinsdialog.ui \
qt/forms/receiverequestdialog.ui \
qt/forms/rpcconsole.ui \
qt/forms/sendcoinsdialog.ui \
qt/forms/sendcoinsentry.ui \
qt/forms/signverifymessagedialog.ui \
qt/forms/transactiondescdialog.ui
QT_MOC_CPP = \
qt/moc_addressbookpage.cpp \
qt/moc_addresstablemodel.cpp \
qt/moc_askpassphrasedialog.cpp \
qt/moc_bitcoinaddressvalidator.cpp \
qt/moc_bitcoinamountfield.cpp \
qt/moc_bitcoingui.cpp \
qt/moc_bitcoinunits.cpp \
qt/moc_clientmodel.cpp \
qt/moc_coincontroldialog.cpp \
qt/moc_coincontroltreewidget.cpp \
qt/moc_csvmodelwriter.cpp \
qt/moc_editaddressdialog.cpp \
qt/moc_guiutil.cpp \
qt/moc_intro.cpp \
qt/moc_macdockiconhandler.cpp \
qt/moc_macnotificationhandler.cpp \
qt/moc_monitoreddatamapper.cpp \
qt/moc_notificator.cpp \
qt/moc_openuridialog.cpp \
qt/moc_optionsdialog.cpp \
qt/moc_optionsmodel.cpp \
qt/moc_overviewpage.cpp \
qt/moc_peertablemodel.cpp \
qt/moc_paymentserver.cpp \
qt/moc_qvalidatedlineedit.cpp \
qt/moc_qvaluecombobox.cpp \
qt/moc_receivecoinsdialog.cpp \
qt/moc_receiverequestdialog.cpp \
qt/moc_recentrequeststablemodel.cpp \
qt/moc_rpcconsole.cpp \
qt/moc_sendcoinsdialog.cpp \
qt/moc_sendcoinsentry.cpp \
qt/moc_signverifymessagedialog.cpp \
qt/moc_splashscreen.cpp \
qt/moc_trafficgraphwidget.cpp \
qt/moc_transactiondesc.cpp \
qt/moc_transactiondescdialog.cpp \
qt/moc_transactionfilterproxy.cpp \
qt/moc_transactiontablemodel.cpp \
qt/moc_transactionview.cpp \
qt/moc_utilitydialog.cpp \
qt/moc_walletframe.cpp \
qt/moc_walletmodel.cpp \
qt/moc_walletview.cpp
BITCOIN_MM = \
qt/macdockiconhandler.mm \
qt/macnotificationhandler.mm
QT_MOC = \
qt/bitcoin.moc \
+ qt/bitcoinamountfield.moc \
qt/intro.moc \
qt/overviewpage.moc \
qt/rpcconsole.moc
QT_QRC_CPP = qt/qrc_bitcoin.cpp
QT_QRC = qt/bitcoin.qrc
QT_QRC_LOCALE_CPP = qt/qrc_bitcoin_locale.cpp
QT_QRC_LOCALE = qt/bitcoin_locale.qrc
PROTOBUF_CC = qt/paymentrequest.pb.cc
PROTOBUF_H = qt/paymentrequest.pb.h
PROTOBUF_PROTO = qt/paymentrequest.proto
BITCOIN_QT_H = \
qt/addressbookpage.h \
qt/addresstablemodel.h \
qt/askpassphrasedialog.h \
qt/bitcoinaddressvalidator.h \
qt/bitcoinamountfield.h \
qt/bitcoingui.h \
qt/bitcoinunits.h \
qt/clientmodel.h \
qt/coincontroldialog.h \
qt/coincontroltreewidget.h \
qt/csvmodelwriter.h \
qt/editaddressdialog.h \
qt/guiconstants.h \
qt/guiutil.h \
qt/intro.h \
qt/macdockiconhandler.h \
qt/macnotificationhandler.h \
qt/monitoreddatamapper.h \
qt/notificator.h \
qt/openuridialog.h \
qt/optionsdialog.h \
qt/optionsmodel.h \
qt/overviewpage.h \
qt/paymentrequestplus.h \
qt/paymentserver.h \
qt/peertablemodel.h \
qt/qvalidatedlineedit.h \
qt/qvaluecombobox.h \
qt/receivecoinsdialog.h \
qt/receiverequestdialog.h \
qt/recentrequeststablemodel.h \
qt/rpcconsole.h \
qt/sendcoinsdialog.h \
qt/sendcoinsentry.h \
qt/signverifymessagedialog.h \
qt/splashscreen.h \
qt/trafficgraphwidget.h \
qt/transactiondesc.h \
qt/transactiondescdialog.h \
qt/transactionfilterproxy.h \
qt/transactionrecord.h \
qt/transactiontablemodel.h \
qt/transactionview.h \
qt/utilitydialog.h \
qt/walletframe.h \
qt/walletmodel.h \
qt/walletmodeltransaction.h \
qt/walletview.h \
qt/winshutdownmonitor.h
RES_ICONS = \
qt/res/icons/add.png \
qt/res/icons/address-book.png \
qt/res/icons/bitcoin.ico \
qt/res/icons/bitcoin.png \
qt/res/icons/bitcoin_testnet.ico \
qt/res/icons/bitcoin_testnet.png \
qt/res/icons/clock1.png \
qt/res/icons/clock2.png \
qt/res/icons/clock3.png \
qt/res/icons/clock4.png \
qt/res/icons/clock5.png \
qt/res/icons/configure.png \
qt/res/icons/connect0_16.png \
qt/res/icons/connect1_16.png \
qt/res/icons/connect2_16.png \
qt/res/icons/connect3_16.png \
qt/res/icons/connect4_16.png \
qt/res/icons/debugwindow.png \
qt/res/icons/edit.png \
qt/res/icons/editcopy.png \
qt/res/icons/editpaste.png \
qt/res/icons/export.png \
qt/res/icons/filesave.png \
qt/res/icons/history.png \
qt/res/icons/key.png \
qt/res/icons/lock_closed.png \
qt/res/icons/lock_open.png \
qt/res/icons/overview.png \
qt/res/icons/qrcode.png \
qt/res/icons/quit.png \
qt/res/icons/receive.png \
qt/res/icons/remove.png \
qt/res/icons/send.png \
qt/res/icons/synced.png \
qt/res/icons/toolbar.png \
qt/res/icons/toolbar_testnet.png \
qt/res/icons/transaction0.png \
qt/res/icons/transaction2.png \
qt/res/icons/transaction_conflicted.png \
qt/res/icons/tx_inout.png \
qt/res/icons/tx_input.png \
qt/res/icons/tx_output.png \
qt/res/icons/tx_mined.png \
qt/res/icons/unit_btc.png \
qt/res/icons/unit_mbtc.png \
qt/res/icons/unit_ubtc.png
BITCOIN_QT_CPP = \
qt/bitcoinaddressvalidator.cpp \
qt/bitcoinamountfield.cpp \
qt/bitcoingui.cpp \
qt/bitcoinunits.cpp \
qt/clientmodel.cpp \
qt/csvmodelwriter.cpp \
qt/guiutil.cpp \
qt/intro.cpp \
qt/monitoreddatamapper.cpp \
qt/notificator.cpp \
qt/optionsdialog.cpp \
qt/optionsmodel.cpp \
qt/peertablemodel.cpp \
qt/qvalidatedlineedit.cpp \
qt/qvaluecombobox.cpp \
qt/rpcconsole.cpp \
qt/splashscreen.cpp \
qt/trafficgraphwidget.cpp \
qt/utilitydialog.cpp \
qt/winshutdownmonitor.cpp
if ENABLE_WALLET
BITCOIN_QT_CPP += \
qt/addressbookpage.cpp \
qt/addresstablemodel.cpp \
qt/askpassphrasedialog.cpp \
qt/coincontroldialog.cpp \
qt/coincontroltreewidget.cpp \
qt/editaddressdialog.cpp \
qt/openuridialog.cpp \
qt/overviewpage.cpp \
qt/paymentrequestplus.cpp \
qt/paymentserver.cpp \
qt/receivecoinsdialog.cpp \
qt/receiverequestdialog.cpp \
qt/recentrequeststablemodel.cpp \
qt/sendcoinsdialog.cpp \
qt/sendcoinsentry.cpp \
qt/signverifymessagedialog.cpp \
qt/transactiondesc.cpp \
qt/transactiondescdialog.cpp \
qt/transactionfilterproxy.cpp \
qt/transactionrecord.cpp \
qt/transactiontablemodel.cpp \
qt/transactionview.cpp \
qt/walletframe.cpp \
qt/walletmodel.cpp \
qt/walletmodeltransaction.cpp \
qt/walletview.cpp
endif
RES_IMAGES = \
qt/res/images/about.png \
qt/res/images/splash.png \
qt/res/images/splash_testnet.png
RES_MOVIES = $(wildcard qt/res/movies/spinner-*.png)
BITCOIN_RC = qt/res/bitcoin-qt-res.rc
BITCOIN_QT_INCLUDES = -I$(builddir)/qt -I$(srcdir)/qt -I$(srcdir)/qt/forms \
-I$(builddir)/qt/forms
qt_libbitcoinqt_a_CPPFLAGS = $(BITCOIN_INCLUDES) $(BITCOIN_QT_INCLUDES) \
$(QT_INCLUDES) $(QT_DBUS_INCLUDES) $(PROTOBUF_CFLAGS) $(QR_CFLAGS)
qt_libbitcoinqt_a_SOURCES = $(BITCOIN_QT_CPP) $(BITCOIN_QT_H) $(QT_FORMS_UI) \
$(QT_QRC) $(QT_QRC_LOCALE) $(QT_TS) $(PROTOBUF_PROTO) $(RES_ICONS) $(RES_IMAGES) $(RES_MOVIES)
nodist_qt_libbitcoinqt_a_SOURCES = $(QT_MOC_CPP) $(QT_MOC) $(PROTOBUF_CC) \
$(PROTOBUF_H) $(QT_QRC_CPP) $(QT_QRC_LOCALE_CPP)
# forms/foo.h -> forms/ui_foo.h
QT_FORMS_H=$(join $(dir $(QT_FORMS_UI)),$(addprefix ui_, $(notdir $(QT_FORMS_UI:.ui=.h))))
# Most files will depend on the forms and moc files as includes. Generate them
# before anything else.
$(QT_MOC): $(QT_FORMS_H)
$(qt_libbitcoinqt_a_OBJECTS) $(qt_bitcoin_qt_OBJECTS) : | $(QT_MOC)
#Generating these with a half-written protobuf header leads to wacky results.
#This makes sure it's done.
$(QT_MOC): $(PROTOBUF_H)
$(QT_MOC_CPP): $(PROTOBUF_H)
# bitcoin-qt binary #
qt_bitcoin_qt_CPPFLAGS = $(BITCOIN_INCLUDES) $(BITCOIN_QT_INCLUDES) \
$(QT_INCLUDES) $(PROTOBUF_CFLAGS) $(QR_CFLAGS)
qt_bitcoin_qt_SOURCES = qt/bitcoin.cpp
if TARGET_DARWIN
qt_bitcoin_qt_SOURCES += $(BITCOIN_MM)
endif
if TARGET_WINDOWS
qt_bitcoin_qt_SOURCES += $(BITCOIN_RC)
endif
qt_bitcoin_qt_LDADD = qt/libbitcoinqt.a $(LIBBITCOIN_SERVER)
if ENABLE_WALLET
qt_bitcoin_qt_LDADD += $(LIBBITCOIN_WALLET)
endif
qt_bitcoin_qt_LDADD += $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CRYPTO) $(LIBLEVELDB) $(LIBMEMENV) \
$(BOOST_LIBS) $(QT_LIBS) $(QT_DBUS_LIBS) $(QR_LIBS) $(PROTOBUF_LIBS) $(BDB_LIBS)
if USE_LIBSECP256K1
qt_bitcoin_qt_LDADD += secp256k1/libsecp256k1.la
endif
qt_bitcoin_qt_LDFLAGS = $(AM_LDFLAGS) $(QT_LDFLAGS)
#locale/foo.ts -> locale/foo.qm
QT_QM=$(QT_TS:.ts=.qm)
.SECONDARY: $(QT_QM)
qt/bitcoinstrings.cpp: $(libbitcoin_server_a_SOURCES) $(libbitcoin_wallet_a_SOURCES)
@test -n $(XGETTEXT) || echo "xgettext is required for updating translations"
$(AM_V_GEN) cd $(srcdir); XGETTEXT=$(XGETTEXT) ../share/qt/extract_strings_qt.py $^
translate: qt/bitcoinstrings.cpp $(QT_FORMS_UI) $(QT_FORMS_UI) $(BITCOIN_QT_CPP) $(BITCOIN_QT_H) $(BITCOIN_MM)
@test -n $(LUPDATE) || echo "lupdate is required for updating translations"
$(AM_V_GEN) QT_SELECT=$(QT_SELECT) $(LUPDATE) $^ -locations relative -no-obsolete -ts qt/locale/bitcoin_en.ts
$(QT_QRC_LOCALE_CPP): $(QT_QRC_LOCALE) $(QT_QM)
@test -f $(RCC)
@test -f $(@D)/$(<F) || cp -f $< $(@D)
$(AM_V_GEN) QT_SELECT=$(QT_SELECT) $(RCC) -name bitcoin_locale $(@D)/$(<F) | \
$(SED) -e '/^\*\*.*Created:/d' -e '/^\*\*.*by:/d' > $@
$(QT_QRC_CPP): $(QT_QRC) $(QT_FORMS_H) $(RES_ICONS) $(RES_IMAGES) $(RES_MOVIES) $(PROTOBUF_H)
@test -f $(RCC)
$(AM_V_GEN) QT_SELECT=$(QT_SELECT) $(RCC) -name bitcoin $< | \
$(SED) -e '/^\*\*.*Created:/d' -e '/^\*\*.*by:/d' > $@
CLEAN_QT = $(nodist_qt_libbitcoinqt_a_SOURCES) $(QT_QM) $(QT_FORMS_H) qt/*.gcda qt/*.gcno
CLEANFILES += $(CLEAN_QT)
bitcoin_qt_clean: FORCE
rm -f $(CLEAN_QT) $(qt_libbitcoinqt_a_OBJECTS) $(qt_bitcoin_qt_OBJECTS) qt/bitcoin-qt$(EXEEXT) $(LIBBITCOINQT)
bitcoin_qt : qt/bitcoin-qt$(EXEEXT)
ui_%.h: %.ui
@test -f $(UIC)
@$(MKDIR_P) $(@D)
$(AM_V_GEN) QT_SELECT=$(QT_SELECT) $(UIC) -o $@ $< || (echo "Error creating $@"; false)
%.moc: %.cpp
$(AM_V_GEN) QT_SELECT=$(QT_SELECT) $(MOC) $(QT_INCLUDES) $(MOC_DEFS) $< | \
$(SED) -e '/^\*\*.*Created:/d' -e '/^\*\*.*by:/d' > $@
moc_%.cpp: %.h
$(AM_V_GEN) QT_SELECT=$(QT_SELECT) $(MOC) $(QT_INCLUDES) $(MOC_DEFS) $< | \
$(SED) -e '/^\*\*.*Created:/d' -e '/^\*\*.*by:/d' > $@
%.qm: %.ts
@test -f $(LRELEASE)
@$(MKDIR_P) $(@D)
$(AM_V_GEN) QT_SELECT=$(QT_SELECT) $(LRELEASE) -silent $< -qm $@
diff --git a/src/qt/bitcoinamountfield.cpp b/src/qt/bitcoinamountfield.cpp
index e047c278b7..6466039013 100644
--- a/src/qt/bitcoinamountfield.cpp
+++ b/src/qt/bitcoinamountfield.cpp
@@ -1,231 +1,291 @@
// 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 "bitcoinamountfield.h"
#include "bitcoinunits.h"
#include "guiconstants.h"
#include "qvaluecombobox.h"
#include <QApplication>
-#include <QDoubleSpinBox>
+#include <QAbstractSpinBox>
#include <QHBoxLayout>
#include <QKeyEvent>
-#include <qmath.h> // for qPow()
+#include <QLineEdit>
-// QDoubleSpinBox that shows SI-style thin space thousands separators
-class AmountSpinBox: public QDoubleSpinBox
+/** QSpinBox that uses fixed-point numbers internally and uses our own
+ * formatting/parsing functions.
+ */
+class AmountSpinBox: public QAbstractSpinBox
{
+ Q_OBJECT
public:
explicit AmountSpinBox(QWidget *parent):
- QDoubleSpinBox(parent)
+ QAbstractSpinBox(parent),
+ currentUnit(BitcoinUnits::BTC),
+ singleStep(100000) // satoshis
{
+ setAlignment(Qt::AlignRight);
+
+ connect(lineEdit(), SIGNAL(textEdited(QString)), this, SIGNAL(valueChanged()));
+ }
+
+ QValidator::State validate(QString &text, int &pos) const
+ {
+ if(text.isEmpty())
+ return QValidator::Intermediate;
+ bool valid = false;
+ parse(text, &valid);
+ /* Make sure we return Intermediate so that fixup() is called on defocus */
+ return valid ? QValidator::Intermediate : QValidator::Invalid;
+ }
+
+ void fixup(QString &input) const
+ {
+ bool valid = false;
+ qint64 val = parse(input, &valid);
+ if(valid)
+ {
+ input = BitcoinUnits::format(currentUnit, val, false, BitcoinUnits::separatorAlways);
+ lineEdit()->setText(input);
+ }
}
- QString textFromValue(double value) const
+
+ qint64 value(bool *valid_out=0) const
{
- QStringList parts = QDoubleSpinBox::textFromValue(value).split(".");
- QString quotient_str = parts[0];
- QString remainder_str;
- if(parts.size() > 1)
- remainder_str = parts[1];
-
- // Code duplication between here and BitcoinUnits::format
- // TODO: Figure out how to share this code
- QChar thin_sp(THIN_SP_CP);
- int q_size = quotient_str.size();
- if (q_size > 4)
- for (int i = 3; i < q_size; i += 3)
- quotient_str.insert(q_size - i, thin_sp);
-
- int r_size = remainder_str.size();
- if (r_size > 4)
- for (int i = 3, adj = 0; i < r_size; i += 3, adj++)
- remainder_str.insert(i + adj, thin_sp);
-
- if(remainder_str.isEmpty())
- return quotient_str;
+ return parse(text(), valid_out);
+ }
+
+ void setValue(qint64 value)
+ {
+ lineEdit()->setText(BitcoinUnits::format(currentUnit, value, false, BitcoinUnits::separatorAlways));
+ emit valueChanged();
+ }
+
+ void stepBy(int steps)
+ {
+ bool valid = false;
+ qint64 val = value(&valid);
+ val = val + steps * singleStep;
+ val = qMin(qMax(val, Q_INT64_C(0)), BitcoinUnits::maxMoney());
+ setValue(val);
+ }
+
+ StepEnabled stepEnabled() const
+ {
+ StepEnabled rv = 0;
+ if(text().isEmpty()) // Allow step-up with empty field
+ return StepUpEnabled;
+ bool valid = false;
+ qint64 val = value(&valid);
+ if(valid)
+ {
+ if(val > 0)
+ rv |= StepDownEnabled;
+ if(val < BitcoinUnits::maxMoney())
+ rv |= StepUpEnabled;
+ }
+ return rv;
+ }
+
+ void setDisplayUnit(int unit)
+ {
+ bool valid = false;
+ qint64 val = value(&valid);
+
+ currentUnit = unit;
+
+ if(valid)
+ setValue(val);
else
- return quotient_str + QString(".") + remainder_str;
+ clear();
}
- QValidator::State validate (QString &text, int &pos) const
+
+ void setSingleStep(qint64 step)
{
- QString s(BitcoinUnits::removeSpaces(text));
- return QDoubleSpinBox::validate(s, pos);
+ singleStep = step;
+ }
+
+ QSize minimumSizeHint() const
+ {
+ if(cachedMinimumSizeHint.isEmpty())
+ {
+ ensurePolished();
+
+ const QFontMetrics fm(fontMetrics());
+ int h = lineEdit()->minimumSizeHint().height();
+ int w = fm.width(BitcoinUnits::format(BitcoinUnits::BTC, BitcoinUnits::maxMoney(), false, BitcoinUnits::separatorAlways));
+ w += 2; // cursor blinking space
+
+ QStyleOptionSpinBox opt;
+ initStyleOption(&opt);
+ QSize hint(w, h);
+ QSize extra(35, 6);
+ opt.rect.setSize(hint + extra);
+ extra += hint - style()->subControlRect(QStyle::CC_SpinBox, &opt,
+ QStyle::SC_SpinBoxEditField, this).size();
+ // get closer to final result by repeating the calculation
+ opt.rect.setSize(hint + extra);
+ extra += hint - style()->subControlRect(QStyle::CC_SpinBox, &opt,
+ QStyle::SC_SpinBoxEditField, this).size();
+ hint += extra;
+
+ opt.rect = rect();
+
+ cachedMinimumSizeHint = style()->sizeFromContents(QStyle::CT_SpinBox, &opt, hint, this)
+ .expandedTo(QApplication::globalStrut());
+ }
+ return cachedMinimumSizeHint;
+ }
+private:
+ int currentUnit;
+ qint64 singleStep;
+ mutable QSize cachedMinimumSizeHint;
+
+ /**
+ * Parse a string into a number of base monetary units and
+ * return validity.
+ * @note Must return 0 if !valid.
+ */
+ qint64 parse(const QString &text, bool *valid_out=0) const
+ {
+ qint64 val = 0;
+ bool valid = BitcoinUnits::parse(currentUnit, text, &val);
+ if(valid)
+ {
+ if(val < 0 || val > BitcoinUnits::maxMoney())
+ valid = false;
+ }
+ if(valid_out)
+ *valid_out = valid;
+ return valid ? val : 0;
}
- double valueFromText(const QString& text) const
+
+protected:
+ bool event(QEvent *event)
{
- return QDoubleSpinBox::valueFromText(BitcoinUnits::removeSpaces(text));
+ if (event->type() == QEvent::KeyPress || event->type() == QEvent::KeyRelease)
+ {
+ QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
+ if (keyEvent->key() == Qt::Key_Comma)
+ {
+ // Translate a comma into a period
+ QKeyEvent periodKeyEvent(event->type(), Qt::Key_Period, keyEvent->modifiers(), ".", keyEvent->isAutoRepeat(), keyEvent->count());
+ return QAbstractSpinBox::event(&periodKeyEvent);
+ }
+ }
+ return QAbstractSpinBox::event(event);
}
+
+signals:
+ void valueChanged();
};
+#include "bitcoinamountfield.moc"
+
BitcoinAmountField::BitcoinAmountField(QWidget *parent) :
QWidget(parent),
- amount(0),
- currentUnit(-1)
+ amount(0)
{
- nSingleStep = 100000; // satoshis
-
amount = new AmountSpinBox(this);
amount->setLocale(QLocale::c());
amount->installEventFilter(this);
amount->setMaximumWidth(170);
QHBoxLayout *layout = new QHBoxLayout(this);
layout->addWidget(amount);
unit = new QValueComboBox(this);
unit->setModel(new BitcoinUnits(this));
layout->addWidget(unit);
layout->addStretch(1);
layout->setContentsMargins(0,0,0,0);
setLayout(layout);
setFocusPolicy(Qt::TabFocus);
setFocusProxy(amount);
// If one if the widgets changes, the combined content changes as well
- connect(amount, SIGNAL(valueChanged(QString)), this, SIGNAL(textChanged()));
+ connect(amount, SIGNAL(valueChanged()), this, SIGNAL(valueChanged()));
connect(unit, SIGNAL(currentIndexChanged(int)), this, SLOT(unitChanged(int)));
// Set default based on configuration
unitChanged(unit->currentIndex());
}
-void BitcoinAmountField::setText(const QString &text)
-{
- if (text.isEmpty())
- amount->clear();
- else
- amount->setValue(BitcoinUnits::removeSpaces(text).toDouble());
-}
-
void BitcoinAmountField::clear()
{
amount->clear();
unit->setCurrentIndex(0);
}
bool BitcoinAmountField::validate()
{
- bool valid = true;
- if (amount->value() == 0.0)
- valid = false;
- else if (!BitcoinUnits::parse(currentUnit, text(), 0))
- valid = false;
- else if (amount->value() > BitcoinUnits::maxAmount(currentUnit))
- valid = false;
-
+ bool valid = false;
+ value(&valid);
setValid(valid);
-
return valid;
}
void BitcoinAmountField::setValid(bool valid)
{
if (valid)
amount->setStyleSheet("");
else
amount->setStyleSheet(STYLE_INVALID);
}
-QString BitcoinAmountField::text() const
-{
- if (amount->text().isEmpty())
- return QString();
- else
- return amount->text();
-}
-
bool BitcoinAmountField::eventFilter(QObject *object, QEvent *event)
{
if (event->type() == QEvent::FocusIn)
{
// Clear invalid flag on focus
setValid(true);
}
- else if (event->type() == QEvent::KeyPress || event->type() == QEvent::KeyRelease)
- {
- QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
- if (keyEvent->key() == Qt::Key_Comma)
- {
- // Translate a comma into a period
- QKeyEvent periodKeyEvent(event->type(), Qt::Key_Period, keyEvent->modifiers(), ".", keyEvent->isAutoRepeat(), keyEvent->count());
- QApplication::sendEvent(object, &periodKeyEvent);
- return true;
- }
- }
return QWidget::eventFilter(object, event);
}
QWidget *BitcoinAmountField::setupTabChain(QWidget *prev)
{
QWidget::setTabOrder(prev, amount);
QWidget::setTabOrder(amount, unit);
return unit;
}
qint64 BitcoinAmountField::value(bool *valid_out) const
{
- qint64 val_out = 0;
- bool valid = BitcoinUnits::parse(currentUnit, text(), &val_out);
- if (valid_out)
- {
- *valid_out = valid;
- }
- return val_out;
+ return amount->value(valid_out);
}
void BitcoinAmountField::setValue(qint64 value)
{
- setText(BitcoinUnits::format(currentUnit, value));
+ amount->setValue(value);
}
void BitcoinAmountField::setReadOnly(bool fReadOnly)
{
amount->setReadOnly(fReadOnly);
unit->setEnabled(!fReadOnly);
}
void BitcoinAmountField::unitChanged(int idx)
{
// Use description tooltip for current unit for the combobox
unit->setToolTip(unit->itemData(idx, Qt::ToolTipRole).toString());
// Determine new unit ID
int newUnit = unit->itemData(idx, BitcoinUnits::UnitRole).toInt();
- // Parse current value and convert to new unit
- bool valid = false;
- qint64 currentValue = value(&valid);
-
- currentUnit = newUnit;
-
- // Set max length after retrieving the value, to prevent truncation
- amount->setDecimals(BitcoinUnits::decimals(currentUnit));
- amount->setMaximum(qPow(10, BitcoinUnits::amountDigits(currentUnit)) - qPow(10, -amount->decimals()));
- amount->setSingleStep((double)nSingleStep / (double)BitcoinUnits::factor(currentUnit));
-
- if (valid)
- {
- // If value was valid, re-place it in the widget with the new unit
- setValue(currentValue);
- }
- else
- {
- // If current value is invalid, just clear field
- setText("");
- }
- setValid(true);
+ amount->setDisplayUnit(newUnit);
}
void BitcoinAmountField::setDisplayUnit(int newUnit)
{
unit->setValue(newUnit);
}
void BitcoinAmountField::setSingleStep(qint64 step)
{
- nSingleStep = step;
- unitChanged(unit->currentIndex());
+ amount->setSingleStep(step);
}
diff --git a/src/qt/bitcoinamountfield.h b/src/qt/bitcoinamountfield.h
index 521a9ed561..c713f5d687 100644
--- a/src/qt/bitcoinamountfield.h
+++ b/src/qt/bitcoinamountfield.h
@@ -1,72 +1,68 @@
// Copyright (c) 2011-2013 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOINAMOUNTFIELD_H
#define BITCOINAMOUNTFIELD_H
#include <QWidget>
QT_BEGIN_NAMESPACE
-class QDoubleSpinBox;
class QValueComboBox;
QT_END_NAMESPACE
+class AmountSpinBox;
+
/** Widget for entering bitcoin amounts.
*/
class BitcoinAmountField: public QWidget
{
Q_OBJECT
- Q_PROPERTY(qint64 value READ value WRITE setValue NOTIFY textChanged USER true)
+ Q_PROPERTY(qint64 value READ value WRITE setValue NOTIFY valueChanged USER true)
public:
explicit BitcoinAmountField(QWidget *parent = 0);
qint64 value(bool *valid=0) const;
void setValue(qint64 value);
/** Set single step in satoshis **/
void setSingleStep(qint64 step);
/** Make read-only **/
void setReadOnly(bool fReadOnly);
/** Mark current value as invalid in UI. */
void setValid(bool valid);
/** Perform input validation, mark field as invalid if entered value is not valid. */
bool validate();
/** Change unit used to display amount. */
void setDisplayUnit(int unit);
/** Make field empty and ready for new input. */
void clear();
/** Qt messes up the tab chain by default in some cases (issue https://bugreports.qt-project.org/browse/QTBUG-10907),
in these cases we have to set it up manually.
*/
QWidget *setupTabChain(QWidget *prev);
signals:
- void textChanged();
+ void valueChanged();
protected:
/** Intercept focus-in event and ',' key presses */
bool eventFilter(QObject *object, QEvent *event);
private:
- QDoubleSpinBox *amount;
+ AmountSpinBox *amount;
QValueComboBox *unit;
- int currentUnit;
- qint64 nSingleStep;
-
- void setText(const QString &text);
- QString text() const;
private slots:
void unitChanged(int idx);
};
#endif // BITCOINAMOUNTFIELD_H
diff --git a/src/qt/bitcoinunits.cpp b/src/qt/bitcoinunits.cpp
index 21aed235cf..0435ebc5dc 100644
--- a/src/qt/bitcoinunits.cpp
+++ b/src/qt/bitcoinunits.cpp
@@ -1,252 +1,259 @@
// Copyright (c) 2011-2013 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 "bitcoinunits.h"
+#include "core.h"
+
#include <QStringList>
BitcoinUnits::BitcoinUnits(QObject *parent):
QAbstractListModel(parent),
unitlist(availableUnits())
{
}
QList<BitcoinUnits::Unit> BitcoinUnits::availableUnits()
{
QList<BitcoinUnits::Unit> unitlist;
unitlist.append(BTC);
unitlist.append(mBTC);
unitlist.append(uBTC);
return unitlist;
}
bool BitcoinUnits::valid(int unit)
{
switch(unit)
{
case BTC:
case mBTC:
case uBTC:
return true;
default:
return false;
}
}
QString BitcoinUnits::id(int unit)
{
switch(unit)
{
case BTC: return QString("btc");
case mBTC: return QString("mbtc");
case uBTC: return QString("ubtc");
default: return QString("???");
}
}
QString BitcoinUnits::name(int unit)
{
switch(unit)
{
case BTC: return QString("BTC");
case mBTC: return QString("mBTC");
case uBTC: return QString::fromUtf8("μBTC");
default: return QString("???");
}
}
QString BitcoinUnits::description(int unit)
{
switch(unit)
{
case BTC: return QString("Bitcoins");
case mBTC: return QString("Milli-Bitcoins (1 / 1" THIN_SP_UTF8 "000)");
case uBTC: return QString("Micro-Bitcoins (1 / 1" THIN_SP_UTF8 "000" THIN_SP_UTF8 "000)");
default: return QString("???");
}
}
qint64 BitcoinUnits::factor(int unit)
{
switch(unit)
{
case BTC: return 100000000;
case mBTC: return 100000;
case uBTC: return 100;
default: return 100000000;
}
}
qint64 BitcoinUnits::maxAmount(int unit)
{
switch(unit)
{
case BTC: return Q_INT64_C(21000000);
case mBTC: return Q_INT64_C(21000000000);
case uBTC: return Q_INT64_C(21000000000000);
default: return 0;
}
}
int BitcoinUnits::amountDigits(int unit)
{
switch(unit)
{
case BTC: return 8; // 21,000,000 (# digits, without commas)
case mBTC: return 11; // 21,000,000,000
case uBTC: return 14; // 21,000,000,000,000
default: return 0;
}
}
int BitcoinUnits::decimals(int unit)
{
switch(unit)
{
case BTC: return 8;
case mBTC: return 5;
case uBTC: return 2;
default: return 0;
}
}
QString BitcoinUnits::format(int unit, qint64 n, bool fPlus, SeparatorStyle separators)
{
// Note: not using straight sprintf here because we do NOT want
// localized number formatting.
if(!valid(unit))
return QString(); // Refuse to format invalid unit
qint64 coin = factor(unit);
int num_decimals = decimals(unit);
qint64 n_abs = (n > 0 ? n : -n);
qint64 quotient = n_abs / coin;
qint64 remainder = n_abs % coin;
QString quotient_str = QString::number(quotient);
QString remainder_str = QString::number(remainder).rightJustified(num_decimals, '0');
// Use SI-stule separators as these are locale indendent and can't be
// confused with the decimal marker. Rule is to use a thin space every
// three digits on *both* sides of the decimal point - but only if there
// are five or more digits
QChar thin_sp(THIN_SP_CP);
int q_size = quotient_str.size();
if (separators == separatorAlways || (separators == separatorStandard && q_size > 4))
for (int i = 3; i < q_size; i += 3)
quotient_str.insert(q_size - i, thin_sp);
int r_size = remainder_str.size();
if (separators == separatorAlways || (separators == separatorStandard && r_size > 4))
for (int i = 3, adj = 0; i < r_size ; i += 3, adj++)
remainder_str.insert(i + adj, thin_sp);
if (n < 0)
quotient_str.insert(0, '-');
else if (fPlus && n > 0)
quotient_str.insert(0, '+');
return quotient_str + QString(".") + remainder_str;
}
// TODO: Review all remaining calls to BitcoinUnits::formatWithUnit to
// TODO: determine whether the output is used in a plain text context
// TODO: or an HTML context (and replace with
// TODO: BtcoinUnits::formatHtmlWithUnit in the latter case). Hopefully
// TODO: there aren't instances where the result could be used in
// TODO: either context.
// NOTE: Using formatWithUnit in an HTML context risks wrapping
// quantities at the thousands separator. More subtly, it also results
// in a standard space rather than a thin space, due to a bug in Qt's
// XML whitespace canonicalisation
//
// Please take care to use formatHtmlWithUnit instead, when
// appropriate.
QString BitcoinUnits::formatWithUnit(int unit, qint64 amount, bool plussign, SeparatorStyle separators)
{
return format(unit, amount, plussign, separators) + QString(" ") + name(unit);
}
QString BitcoinUnits::formatHtmlWithUnit(int unit, qint64 amount, bool plussign, SeparatorStyle separators)
{
QString str(formatWithUnit(unit, amount, plussign, separators));
str.replace(QChar(THIN_SP_CP), QString(THIN_SP_HTML));
return QString("<span style='white-space: nowrap;'>%1</span>").arg(str);
}
bool BitcoinUnits::parse(int unit, const QString &value, qint64 *val_out)
{
if(!valid(unit) || value.isEmpty())
return false; // Refuse to parse invalid unit or empty string
int num_decimals = decimals(unit);
// Ignore spaces and thin spaces when parsing
QStringList parts = removeSpaces(value).split(".");
if(parts.size() > 2)
{
return false; // More than one dot
}
QString whole = parts[0];
QString decimals;
if(parts.size() > 1)
{
decimals = parts[1];
}
if(decimals.size() > num_decimals)
{
return false; // Exceeds max precision
}
bool ok = false;
QString str = whole + decimals.leftJustified(num_decimals, '0');
if(str.size() > 18)
{
return false; // Longer numbers will exceed 63 bits
}
qint64 retvalue = str.toLongLong(&ok);
if(val_out)
{
*val_out = retvalue;
}
return ok;
}
QString BitcoinUnits::getAmountColumnTitle(int unit)
{
QString amountTitle = QObject::tr("Amount");
if (BitcoinUnits::valid(unit))
{
amountTitle += " ("+BitcoinUnits::name(unit) + ")";
}
return amountTitle;
}
int BitcoinUnits::rowCount(const QModelIndex &parent) const
{
Q_UNUSED(parent);
return unitlist.size();
}
QVariant BitcoinUnits::data(const QModelIndex &index, int role) const
{
int row = index.row();
if(row >= 0 && row < unitlist.size())
{
Unit unit = unitlist.at(row);
switch(role)
{
case Qt::EditRole:
case Qt::DisplayRole:
return QVariant(name(unit));
case Qt::ToolTipRole:
return QVariant(description(unit));
case UnitRole:
return QVariant(static_cast<int>(unit));
}
}
return QVariant();
}
+
+qint64 BitcoinUnits::maxMoney()
+{
+ return MAX_MONEY;
+}
diff --git a/src/qt/bitcoinunits.h b/src/qt/bitcoinunits.h
index 7fa24c8542..944b4ec530 100644
--- a/src/qt/bitcoinunits.h
+++ b/src/qt/bitcoinunits.h
@@ -1,128 +1,131 @@
// Copyright (c) 2011-2013 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOINUNITS_H
#define BITCOINUNITS_H
#include <QAbstractListModel>
#include <QString>
// U+2009 THIN SPACE = UTF-8 E2 80 89
#define REAL_THIN_SP_CP 0x2009
#define REAL_THIN_SP_UTF8 "\xE2\x80\x89"
#define REAL_THIN_SP_HTML "&thinsp;"
// U+200A HAIR SPACE = UTF-8 E2 80 8A
#define HAIR_SP_CP 0x200A
#define HAIR_SP_UTF8 "\xE2\x80\x8A"
#define HAIR_SP_HTML "&#8202;"
// U+2006 SIX-PER-EM SPACE = UTF-8 E2 80 86
#define SIXPEREM_SP_CP 0x2006
#define SIXPEREM_SP_UTF8 "\xE2\x80\x86"
#define SIXPEREM_SP_HTML "&#8198;"
// U+2007 FIGURE SPACE = UTF-8 E2 80 87
#define FIGURE_SP_CP 0x2007
#define FIGURE_SP_UTF8 "\xE2\x80\x87"
#define FIGURE_SP_HTML "&#8199;"
// QMessageBox seems to have a bug whereby it doesn't display thin/hair spaces
// correctly. Workaround is to display a space in a small font. If you
// change this, please test that it doesn't cause the parent span to start
// wrapping.
#define HTML_HACK_SP "<span style='white-space: nowrap; font-size: 6pt'> </span>"
// Define THIN_SP_* variables to be our preferred type of thin space
#define THIN_SP_CP REAL_THIN_SP_CP
#define THIN_SP_UTF8 REAL_THIN_SP_UTF8
#define THIN_SP_HTML HTML_HACK_SP
/** Bitcoin unit definitions. Encapsulates parsing and formatting
and serves as list model for drop-down selection boxes.
*/
class BitcoinUnits: public QAbstractListModel
{
Q_OBJECT
public:
explicit BitcoinUnits(QObject *parent);
/** Bitcoin units.
@note Source: https://en.bitcoin.it/wiki/Units . Please add only sensible ones
*/
enum Unit
{
BTC,
mBTC,
uBTC
};
enum SeparatorStyle
{
separatorNever,
separatorStandard,
separatorAlways
};
//! @name Static API
//! Unit conversion and formatting
///@{
//! Get list of units, for drop-down box
static QList<Unit> availableUnits();
//! Is unit ID valid?
static bool valid(int unit);
//! Identifier, e.g. for image names
static QString id(int unit);
//! Short name
static QString name(int unit);
//! Longer description
static QString description(int unit);
//! Number of Satoshis (1e-8) per unit
static qint64 factor(int unit);
//! Max amount per unit
static qint64 maxAmount(int unit);
//! Number of amount digits (to represent max number of coins)
static int amountDigits(int unit);
//! Number of decimals left
static int decimals(int unit);
//! Format as string
static QString format(int unit, qint64 amount, bool plussign=false, SeparatorStyle separators=separatorStandard);
//! Format as string (with unit)
static QString formatWithUnit(int unit, qint64 amount, bool plussign=false, SeparatorStyle separators=separatorStandard);
static QString formatHtmlWithUnit(int unit, qint64 amount, bool plussign=false, SeparatorStyle separators=separatorStandard);
//! Parse string to coin amount
static bool parse(int unit, const QString &value, qint64 *val_out);
//! Gets title for amount column including current display unit if optionsModel reference available */
static QString getAmountColumnTitle(int unit);
///@}
//! @name AbstractListModel implementation
//! List model for unit drop-down selection box.
///@{
enum RoleIndex {
/** Unit identifier */
UnitRole = Qt::UserRole
};
int rowCount(const QModelIndex &parent) const;
QVariant data(const QModelIndex &index, int role) const;
///@}
static QString removeSpaces(QString text)
{
text.remove(' ');
text.remove(QChar(THIN_SP_CP));
#if (THIN_SP_CP != REAL_THIN_SP_CP)
text.remove(QChar(REAL_THIN_SP_CP));
#endif
return text;
}
+ //! Return maximum number of base units (Satoshis)
+ static qint64 maxMoney();
+
private:
QList<BitcoinUnits::Unit> unitlist;
};
typedef BitcoinUnits::Unit BitcoinUnit;
#endif // BITCOINUNITS_H
diff --git a/src/qt/sendcoinsentry.cpp b/src/qt/sendcoinsentry.cpp
index e0f56f8cd2..3c0b8881ff 100644
--- a/src/qt/sendcoinsentry.cpp
+++ b/src/qt/sendcoinsentry.cpp
@@ -1,247 +1,254 @@
// Copyright (c) 2011-2013 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 "sendcoinsentry.h"
#include "ui_sendcoinsentry.h"
#include "addressbookpage.h"
#include "addresstablemodel.h"
#include "guiutil.h"
#include "optionsmodel.h"
#include "walletmodel.h"
#include <QApplication>
#include <QClipboard>
SendCoinsEntry::SendCoinsEntry(QWidget *parent) :
QStackedWidget(parent),
ui(new Ui::SendCoinsEntry),
model(0)
{
ui->setupUi(this);
setCurrentWidget(ui->SendCoins);
#ifdef Q_OS_MAC
ui->payToLayout->setSpacing(4);
#endif
#if QT_VERSION >= 0x040700
ui->addAsLabel->setPlaceholderText(tr("Enter a label for this address to add it to your address book"));
#endif
// normal bitcoin address field
GUIUtil::setupAddressWidget(ui->payTo, this);
// just a label for displaying bitcoin address(es)
ui->payTo_is->setFont(GUIUtil::bitcoinAddressFont());
}
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(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 && model->getOptionsModel())
connect(model->getOptionsModel(), SIGNAL(displayUnitChanged(int)), this, SLOT(updateDisplayUnit()));
- connect(ui->payAmount, SIGNAL(textChanged()), this, SIGNAL(payAmountChanged()));
+ connect(ui->payAmount, SIGNAL(valueChanged()), this, SIGNAL(payAmountChanged()));
connect(ui->deleteButton, SIGNAL(clicked()), this, SLOT(deleteClicked()));
connect(ui->deleteButton_is, SIGNAL(clicked()), this, SLOT(deleteClicked()));
connect(ui->deleteButton_s, SIGNAL(clicked()), this, SLOT(deleteClicked()));
clear();
}
void SendCoinsEntry::clear()
{
// clear UI elements for normal payment
ui->payTo->clear();
ui->addAsLabel->clear();
ui->payAmount->clear();
ui->messageTextLabel->clear();
ui->messageTextLabel->hide();
ui->messageLabel->hide();
// clear UI elements for insecure payment request
ui->payTo_is->clear();
ui->memoTextLabel_is->clear();
ui->payAmount_is->clear();
// clear UI elements for secure payment request
ui->payTo_s->clear();
ui->memoTextLabel_s->clear();
ui->payAmount_s->clear();
// update the display unit, to not use the default ("BTC")
updateDisplayUnit();
}
void SendCoinsEntry::deleteClicked()
{
emit removeEntry(this);
}
bool SendCoinsEntry::validate()
{
if (!model)
return false;
// Check input validity
bool retval = true;
// Skip checks for payment request
if (recipient.paymentRequest.IsInitialized())
return retval;
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(0) <= 0)
+ {
+ ui->payAmount->setValid(false);
+ retval = false;
+ }
+
// Reject dust outputs:
if (retval && GUIUtil::isDust(ui->payTo->text(), ui->payAmount->value())) {
ui->payAmount->setValid(false);
retval = false;
}
return retval;
}
SendCoinsRecipient SendCoinsEntry::getValue()
{
// Payment request
if (recipient.paymentRequest.IsInitialized())
return recipient;
// Normal payment
recipient.address = ui->payTo->text();
recipient.label = ui->addAsLabel->text();
recipient.amount = ui->payAmount->value();
recipient.message = ui->messageTextLabel->text();
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->addressBookButton);
QWidget::setTabOrder(ui->addressBookButton, ui->pasteButton);
QWidget::setTabOrder(ui->pasteButton, ui->deleteButton);
return ui->deleteButton;
}
void SendCoinsEntry::setValue(const SendCoinsRecipient &value)
{
recipient = value;
if (recipient.paymentRequest.IsInitialized()) // payment request
{
if (recipient.authenticatedMerchant.isEmpty()) // insecure
{
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_InsecurePaymentRequest);
}
else // secure
{
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_SecurePaymentRequest);
}
}
else // normal payment
{
// message
ui->messageTextLabel->setText(recipient.message);
ui->messageTextLabel->setVisible(!recipient.message.isEmpty());
ui->messageLabel->setVisible(!recipient.message.isEmpty());
ui->addAsLabel->clear();
ui->payTo->setText(recipient.address); // this may set a label from addressbook
if (!recipient.label.isEmpty()) // if a label had been set from the addressbook, dont overwrite with an empty label
ui->addAsLabel->setText(recipient.label);
ui->payAmount->setValue(recipient.amount);
}
}
void SendCoinsEntry::setAddress(const QString &address)
{
ui->payTo->setText(address);
ui->payAmount->setFocus();
}
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;
}

File Metadata

Mime Type
text/x-diff
Expires
Thu, May 22, 00:13 (1 d, 1 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
5866194
Default Alt Text
(46 KB)

Event Timeline