1 #include "bitcoinamountfield.h"
2 #include "qvaluecombobox.h"
3 #include "bitcoinunits.h"
5 #include "guiconstants.h"
9 #include <QRegExpValidator>
10 #include <QHBoxLayout>
12 #include <QDoubleSpinBox>
14 #include <QApplication>
17 BitcoinAmountField::BitcoinAmountField(QWidget *parent):
18 QWidget(parent), amount(0), currentUnit(-1)
20 amount = new QDoubleSpinBox(this);
21 amount->setLocale(QLocale::c());
22 amount->setDecimals(8);
23 amount->installEventFilter(this);
24 amount->setMaximumWidth(170);
26 QHBoxLayout *layout = new QHBoxLayout(this);
27 layout->addWidget(amount);
28 unit = new QValueComboBox(this);
29 unit->setModel(new BitcoinUnits(this));
30 layout->addWidget(unit);
31 layout->addStretch(1);
32 layout->setContentsMargins(0,0,0,0);
36 setFocusPolicy(Qt::TabFocus);
37 setFocusProxy(amount);
39 // If one if the widgets changes, the combined content changes as well
40 connect(amount, SIGNAL(valueChanged(QString)), this, SIGNAL(textChanged()));
41 connect(unit, SIGNAL(currentIndexChanged(int)), this, SLOT(unitChanged(int)));
43 // Set default based on configuration
44 unitChanged(unit->currentIndex());
47 void BitcoinAmountField::setText(const QString &text)
52 amount->setValue(text.toDouble());
55 void BitcoinAmountField::clear()
58 unit->setCurrentIndex(0);
61 bool BitcoinAmountField::validate()
64 if (amount->value() == 0.0)
66 if (valid && !BitcoinUnits::parse(currentUnit, text(), 0))
74 void BitcoinAmountField::setValid(bool valid)
77 amount->setStyleSheet("");
79 amount->setStyleSheet(STYLE_INVALID);
82 QString BitcoinAmountField::text() const
84 if (amount->text().isEmpty())
87 return amount->text();
90 bool BitcoinAmountField::eventFilter(QObject *object, QEvent *event)
92 if (event->type() == QEvent::FocusIn)
94 // Clear invalid flag on focus
97 else if (event->type() == QEvent::KeyPress || event->type() == QEvent::KeyRelease)
99 QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
100 if (keyEvent->key() == Qt::Key_Comma)
102 // Translate a comma into a period
103 QKeyEvent periodKeyEvent(event->type(), Qt::Key_Period, keyEvent->modifiers(), ".", keyEvent->isAutoRepeat(), keyEvent->count());
104 qApp->sendEvent(object, &periodKeyEvent);
108 return QWidget::eventFilter(object, event);
111 QWidget *BitcoinAmountField::setupTabChain(QWidget *prev)
113 QWidget::setTabOrder(prev, amount);
117 qint64 BitcoinAmountField::value(bool *valid_out) const
120 bool valid = BitcoinUnits::parse(currentUnit, text(), &val_out);
128 void BitcoinAmountField::setValue(qint64 value)
130 setText(BitcoinUnits::format(currentUnit, value));
133 void BitcoinAmountField::unitChanged(int idx)
135 // Use description tooltip for current unit for the combobox
136 unit->setToolTip(unit->itemData(idx, Qt::ToolTipRole).toString());
138 // Determine new unit ID
139 int newUnit = unit->itemData(idx, BitcoinUnits::UnitRole).toInt();
141 // Parse current value and convert to new unit
143 qint64 currentValue = value(&valid);
145 currentUnit = newUnit;
147 // Set max length after retrieving the value, to prevent truncation
148 amount->setDecimals(BitcoinUnits::decimals(currentUnit));
149 amount->setMaximum(qPow(10, BitcoinUnits::amountDigits(currentUnit)) - qPow(10, -amount->decimals()));
153 // If value was valid, re-place it in the widget with the new unit
154 setValue(currentValue);
158 // If current value is invalid, just clear field
164 void BitcoinAmountField::setDisplayUnit(int newUnit)
166 unit->setValue(newUnit);