1 #include "bitcoinamountfield.h"
2 #include "qvalidatedlineedit.h"
3 #include "qvaluecombobox.h"
4 #include "bitcoinunits.h"
8 #include <QRegExpValidator>
13 BitcoinAmountField::BitcoinAmountField(QWidget *parent):
14 QWidget(parent), amount(0), decimals(0), currentUnit(-1)
16 amount = new QValidatedLineEdit(this);
17 amount->setValidator(new QRegExpValidator(QRegExp("[0-9]*"), this));
18 amount->setAlignment(Qt::AlignRight|Qt::AlignVCenter);
19 amount->installEventFilter(this);
20 amount->setMaximumWidth(75);
21 decimals = new QValidatedLineEdit(this);
22 decimals->setValidator(new QRegExpValidator(QRegExp("[0-9]+"), this));
23 decimals->setAlignment(Qt::AlignLeft|Qt::AlignVCenter);
24 decimals->setMaximumWidth(75);
26 QHBoxLayout *layout = new QHBoxLayout(this);
27 layout->setSpacing(0);
28 layout->addWidget(amount);
29 layout->addWidget(new QLabel(QString("<b>.</b>")));
30 layout->addWidget(decimals);
31 unit = new QValueComboBox(this);
32 unit->setModel(new BitcoinUnits(this));
33 layout->addWidget(unit);
34 layout->addStretch(1);
35 layout->setContentsMargins(0,0,0,0);
39 setFocusPolicy(Qt::TabFocus);
40 setFocusProxy(amount);
42 // If one if the widgets changes, the combined content changes as well
43 connect(amount, SIGNAL(textChanged(QString)), this, SIGNAL(textChanged()));
44 connect(decimals, SIGNAL(textChanged(QString)), this, SIGNAL(textChanged()));
45 connect(unit, SIGNAL(currentIndexChanged(int)), this, SLOT(unitChanged(int)));
47 // Set default based on configuration
48 unitChanged(unit->currentIndex());
51 void BitcoinAmountField::setText(const QString &text)
53 const QStringList parts = text.split(QString("."));
56 amount->setText(parts[0]);
57 decimals->setText(parts[1]);
61 amount->setText(QString());
62 decimals->setText(QString());
66 void BitcoinAmountField::clear()
70 unit->setCurrentIndex(0);
73 bool BitcoinAmountField::validate()
76 if(decimals->text().isEmpty())
78 decimals->setValid(false);
81 if(!BitcoinUnits::parse(currentUnit, text(), 0))
90 void BitcoinAmountField::setValid(bool valid)
92 amount->setValid(valid);
93 decimals->setValid(valid);
96 QString BitcoinAmountField::text() const
98 if(decimals->text().isEmpty() && amount->text().isEmpty())
102 return amount->text() + QString(".") + decimals->text();
105 // Intercept '.' and ',' keys, if pressed focus a specified widget
106 bool BitcoinAmountField::eventFilter(QObject *object, QEvent *event)
109 if(event->type() == QEvent::KeyPress)
111 QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
112 if(keyEvent->key() == Qt::Key_Period || keyEvent->key() == Qt::Key_Comma)
114 decimals->setFocus();
115 decimals->selectAll();
121 QWidget *BitcoinAmountField::setupTabChain(QWidget *prev)
123 QWidget::setTabOrder(prev, amount);
124 QWidget::setTabOrder(amount, decimals);
128 qint64 BitcoinAmountField::value(bool *valid_out) const
131 bool valid = BitcoinUnits::parse(currentUnit, text(), &val_out);
139 void BitcoinAmountField::setValue(qint64 value)
141 setText(BitcoinUnits::format(currentUnit, value));
144 void BitcoinAmountField::unitChanged(int idx)
146 // Use description tooltip for current unit for the combobox
147 unit->setToolTip(unit->itemData(idx, Qt::ToolTipRole).toString());
149 // Determine new unit ID
150 int newUnit = unit->itemData(idx, BitcoinUnits::UnitRole).toInt();
152 // Parse current value and convert to new unit
154 qint64 currentValue = value(&valid);
156 currentUnit = newUnit;
158 // Set max length after retrieving the value, to prevent truncation
159 amount->setMaxLength(BitcoinUnits::amountDigits(currentUnit));
160 decimals->setMaxLength(BitcoinUnits::decimals(currentUnit));
164 setValue(currentValue);
168 // If current value is invalid, just clear field
174 void BitcoinAmountField::setDisplayUnit(int newUnit)
176 unit->setValue(newUnit);