1 #include "bitcoinamountfield.h"
2 #include "qvaluecombobox.h"
3 #include "bitcoinunits.h"
5 #include "guiconstants.h"
10 #include <QRegExpValidator>
11 #include <QHBoxLayout>
13 #include <QDoubleSpinBox>
15 #include <QApplication>
18 BitcoinAmountField::BitcoinAmountField(QWidget *parent):
19 QWidget(parent), amount(0), currentUnit(-1)
21 amount = new QDoubleSpinBox(this);
22 amount->setLocale(QLocale::c());
23 amount->setDecimals(8);
24 amount->installEventFilter(this);
25 amount->setMaximumWidth(170);
27 QHBoxLayout *layout = new QHBoxLayout(this);
28 layout->addWidget(amount);
29 unit = new QValueComboBox(this);
30 unit->setModel(new BitcoinUnits(this));
31 layout->addWidget(unit);
32 layout->addStretch(1);
33 layout->setContentsMargins(0,0,0,0);
37 setFocusPolicy(Qt::TabFocus);
38 setFocusProxy(amount);
40 // If one if the widgets changes, the combined content changes as well
41 connect(amount, SIGNAL(valueChanged(QString)), this, SIGNAL(textChanged()));
42 connect(unit, SIGNAL(currentIndexChanged(int)), this, SLOT(unitChanged(int)));
44 // Set default based on configuration
45 unitChanged(unit->currentIndex());
48 void BitcoinAmountField::setText(const QString &text)
53 amount->setValue(text.toDouble());
56 void BitcoinAmountField::clear()
59 unit->setCurrentIndex(0);
62 bool BitcoinAmountField::validate()
65 if (amount->value() == 0.0)
67 if (valid && !BitcoinUnits::parse(currentUnit, text(), 0))
75 void BitcoinAmountField::setValid(bool valid)
78 amount->setStyleSheet("");
80 amount->setStyleSheet(STYLE_INVALID);
83 QString BitcoinAmountField::text() const
85 if (amount->text().isEmpty())
88 return amount->text();
91 bool BitcoinAmountField::eventFilter(QObject *object, QEvent *event)
93 if (event->type() == QEvent::FocusIn)
95 // Clear invalid flag on focus
98 else if (event->type() == QEvent::KeyPress || event->type() == QEvent::KeyRelease)
100 QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
101 if (keyEvent->key() == Qt::Key_Comma)
103 // Translate a comma into a period
104 QKeyEvent periodKeyEvent(event->type(), Qt::Key_Period, keyEvent->modifiers(), ".", keyEvent->isAutoRepeat(), keyEvent->count());
105 qApp->sendEvent(object, &periodKeyEvent);
109 return QWidget::eventFilter(object, event);
112 QWidget *BitcoinAmountField::setupTabChain(QWidget *prev)
114 QWidget::setTabOrder(prev, amount);
118 qint64 BitcoinAmountField::value(bool *valid_out) const
121 bool valid = BitcoinUnits::parse(currentUnit, text(), &val_out);
129 void BitcoinAmountField::setValue(qint64 value)
131 setText(BitcoinUnits::format(currentUnit, value));
134 void BitcoinAmountField::unitChanged(int idx)
136 // Use description tooltip for current unit for the combobox
137 unit->setToolTip(unit->itemData(idx, Qt::ToolTipRole).toString());
139 // Determine new unit ID
140 int newUnit = unit->itemData(idx, BitcoinUnits::UnitRole).toInt();
142 // Parse current value and convert to new unit
144 qint64 currentValue = value(&valid);
146 currentUnit = newUnit;
148 // Set max length after retrieving the value, to prevent truncation
149 amount->setDecimals(BitcoinUnits::decimals(currentUnit));
150 amount->setMaximum(qPow(10, BitcoinUnits::amountDigits(currentUnit)) - qPow(10, -amount->decimals()));
154 // If value was valid, re-place it in the widget with the new unit
155 setValue(currentValue);
159 // If current value is invalid, just clear field
165 void BitcoinAmountField::setDisplayUnit(int newUnit)
167 unit->setValue(newUnit);