mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-03-09 15:37:00 -04:00

Step for buttons 'up' and 'down' - 0.001. With BTC and mBTC all ok, but 0.001 uBTC is lower than minimal value (satoshi) User should press 10 times on 'up' button to get 0.01 uBTC
169 lines
4.3 KiB
C++
169 lines
4.3 KiB
C++
#include "bitcoinamountfield.h"
|
|
|
|
#include "qvaluecombobox.h"
|
|
#include "bitcoinunits.h"
|
|
#include "guiconstants.h"
|
|
|
|
#include <QHBoxLayout>
|
|
#include <QKeyEvent>
|
|
#include <QDoubleSpinBox>
|
|
#include <QApplication>
|
|
#include <qmath.h> // for qPow()
|
|
|
|
BitcoinAmountField::BitcoinAmountField(QWidget *parent):
|
|
QWidget(parent), amount(0), currentUnit(-1)
|
|
{
|
|
amount = new QDoubleSpinBox(this);
|
|
amount->setLocale(QLocale::c());
|
|
amount->setDecimals(8);
|
|
amount->installEventFilter(this);
|
|
amount->setMaximumWidth(170);
|
|
amount->setSingleStep(0.001);
|
|
|
|
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(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(text.toDouble());
|
|
}
|
|
|
|
void BitcoinAmountField::clear()
|
|
{
|
|
amount->clear();
|
|
unit->setCurrentIndex(0);
|
|
}
|
|
|
|
bool BitcoinAmountField::validate()
|
|
{
|
|
bool valid = true;
|
|
if (amount->value() == 0.0)
|
|
valid = false;
|
|
if (valid && !BitcoinUnits::parse(currentUnit, text(), 0))
|
|
valid = false;
|
|
|
|
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());
|
|
qApp->sendEvent(object, &periodKeyEvent);
|
|
return true;
|
|
}
|
|
}
|
|
return QWidget::eventFilter(object, event);
|
|
}
|
|
|
|
QWidget *BitcoinAmountField::setupTabChain(QWidget *prev)
|
|
{
|
|
QWidget::setTabOrder(prev, amount);
|
|
return amount;
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
void BitcoinAmountField::setValue(qint64 value)
|
|
{
|
|
setText(BitcoinUnits::format(currentUnit, value));
|
|
}
|
|
|
|
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()));
|
|
|
|
if(currentUnit == BitcoinUnits::uBTC)
|
|
amount->setSingleStep(0.01);
|
|
else
|
|
amount->setSingleStep(0.001);
|
|
|
|
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);
|
|
}
|
|
|
|
void BitcoinAmountField::setDisplayUnit(int newUnit)
|
|
{
|
|
unit->setValue(newUnit);
|
|
}
|