1 #include "bitcoinamountfield.h"
2 #include "qvalidatedlineedit.h"
3 #include "bitcoinunits.h"
7 #include <QRegExpValidator>
12 BitcoinAmountField::BitcoinAmountField(QWidget *parent):
13 QWidget(parent), amount(0), decimals(0), currentUnit(-1)
15 amount = new QValidatedLineEdit(this);
16 amount->setValidator(new QRegExpValidator(QRegExp("[0-9]*"), this));
17 amount->setAlignment(Qt::AlignRight|Qt::AlignVCenter);
18 amount->installEventFilter(this);
19 amount->setMaximumWidth(100);
20 decimals = new QValidatedLineEdit(this);
21 decimals->setValidator(new QRegExpValidator(QRegExp("[0-9]+"), this));
22 decimals->setAlignment(Qt::AlignLeft|Qt::AlignVCenter);
23 decimals->setMaximumWidth(75);
25 QHBoxLayout *layout = new QHBoxLayout(this);
26 layout->setSpacing(0);
27 layout->addWidget(amount);
28 layout->addWidget(new QLabel(QString(".")));
29 layout->addWidget(decimals);
30 unit = new QComboBox(this);
31 unit->setModel(new BitcoinUnits(this));
32 layout->addWidget(unit);
33 layout->addStretch(1);
34 layout->setContentsMargins(0,0,0,0);
38 setFocusPolicy(Qt::TabFocus);
39 setFocusProxy(amount);
41 // If one if the widgets changes, the combined content changes as well
42 connect(amount, SIGNAL(textChanged(QString)), this, SIGNAL(textChanged()));
43 connect(decimals, SIGNAL(textChanged(QString)), this, SIGNAL(textChanged()));
44 connect(unit, SIGNAL(currentIndexChanged(int)), this, SLOT(unitChanged(int)));
46 // TODO: set default based on configuration
47 unitChanged(unit->currentIndex());
50 void BitcoinAmountField::setText(const QString &text)
52 const QStringList parts = text.split(QString("."));
55 amount->setText(parts[0]);
56 decimals->setText(parts[1]);
60 amount->setText(QString());
61 decimals->setText(QString());
65 void BitcoinAmountField::clear()
71 bool BitcoinAmountField::validate()
74 if(decimals->text().isEmpty())
76 decimals->setValid(false);
79 if(!BitcoinUnits::parse(BitcoinUnits::BTC, text(), 0))
88 void BitcoinAmountField::setValid(bool valid)
90 amount->setValid(valid);
91 decimals->setValid(valid);
94 QString BitcoinAmountField::text() const
96 if(decimals->text().isEmpty() && amount->text().isEmpty())
100 return amount->text() + QString(".") + decimals->text();
103 // Intercept '.' and ',' keys, if pressed focus a specified widget
104 bool BitcoinAmountField::eventFilter(QObject *object, QEvent *event)
107 if(event->type() == QEvent::KeyPress)
109 QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
110 if(keyEvent->key() == Qt::Key_Period || keyEvent->key() == Qt::Key_Comma)
112 decimals->setFocus();
113 decimals->selectAll();
119 QWidget *BitcoinAmountField::setupTabChain(QWidget *prev)
121 QWidget::setTabOrder(prev, amount);
122 QWidget::setTabOrder(amount, decimals);
126 qint64 BitcoinAmountField::value(bool *valid_out) const
129 bool valid = BitcoinUnits::parse(currentUnit, text(), &val_out);
137 void BitcoinAmountField::setValue(qint64 value)
139 setText(BitcoinUnits::format(currentUnit, value));
142 void BitcoinAmountField::unitChanged(int idx)
144 // Use description tooltip for current unit for the combobox
145 unit->setToolTip(unit->itemData(idx, Qt::ToolTipRole).toString());
147 // Determine new unit ID
148 int newUnit = unit->itemData(idx, BitcoinUnits::UnitRole).toInt();
150 // Parse current value and convert to new unit
152 qint64 currentValue = value(&valid);
154 currentUnit = newUnit;
156 // Set max length after retrieving the value, to prevent truncation
157 amount->setMaxLength(BitcoinUnits::amountDigits(currentUnit));
158 decimals->setMaxLength(BitcoinUnits::decimals(currentUnit));
162 setValue(currentValue);
166 // If current value is invalid, just clear field