Feathercoin  0.5.0
P2P Digital Currency
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros
bitcoinamountfield.cpp
Go to the documentation of this file.
1 #include "bitcoinamountfield.h"
2 
3 #include "qvaluecombobox.h"
4 #include "bitcoinunits.h"
5 #include "guiconstants.h"
6 
7 #include <QHBoxLayout>
8 #include <QKeyEvent>
9 #include <QDoubleSpinBox>
10 #include <QApplication>
11 #include <qmath.h> // for qPow()
12 
14  QWidget(parent), amount(0), currentUnit(-1)
15 {
16  amount = new QDoubleSpinBox(this);
17  amount->setLocale(QLocale::c());
18  amount->setDecimals(8);
19  amount->installEventFilter(this);
20  amount->setMaximumWidth(170);
21  amount->setSingleStep(0.001);
22 
23  QHBoxLayout *layout = new QHBoxLayout(this);
24  layout->addWidget(amount);
25  unit = new QValueComboBox(this);
26  unit->setModel(new BitcoinUnits(this));
27  layout->addWidget(unit);
28  layout->addStretch(1);
29  layout->setContentsMargins(0,0,0,0);
30 
31  setLayout(layout);
32 
33  setFocusPolicy(Qt::TabFocus);
34  setFocusProxy(amount);
35 
36  // If one if the widgets changes, the combined content changes as well
37  connect(amount, SIGNAL(valueChanged(QString)), this, SIGNAL(textChanged()));
38  connect(unit, SIGNAL(currentIndexChanged(int)), this, SLOT(unitChanged(int)));
39 
40  // Set default based on configuration
41  unitChanged(unit->currentIndex());
42 }
43 
44 void BitcoinAmountField::setText(const QString &text)
45 {
46  if (text.isEmpty())
47  amount->clear();
48  else
49  amount->setValue(text.toDouble());
50 }
51 
53 {
54  amount->clear();
55  unit->setCurrentIndex(0);
56 }
57 
59 {
60  bool valid = true;
61  if (amount->value() == 0.0)
62  valid = false;
63  if (valid && !BitcoinUnits::parse(currentUnit, text(), 0))
64  valid = false;
65 
66  setValid(valid);
67 
68  return valid;
69 }
70 
72 {
73  if (valid)
74  amount->setStyleSheet("");
75  else
76  amount->setStyleSheet(STYLE_INVALID);
77 }
78 
79 QString BitcoinAmountField::text() const
80 {
81  if (amount->text().isEmpty())
82  return QString();
83  else
84  return amount->text();
85 }
86 
87 bool BitcoinAmountField::eventFilter(QObject *object, QEvent *event)
88 {
89  if (event->type() == QEvent::FocusIn)
90  {
91  // Clear invalid flag on focus
92  setValid(true);
93  }
94  else if (event->type() == QEvent::KeyPress || event->type() == QEvent::KeyRelease)
95  {
96  QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
97  if (keyEvent->key() == Qt::Key_Comma)
98  {
99  // Translate a comma into a period
100  QKeyEvent periodKeyEvent(event->type(), Qt::Key_Period, keyEvent->modifiers(), ".", keyEvent->isAutoRepeat(), keyEvent->count());
101  QApplication::sendEvent(object, &periodKeyEvent);
102  return true;
103  }
104  }
105  return QWidget::eventFilter(object, event);
106 }
107 
109 {
110  QWidget::setTabOrder(prev, amount);
111  return amount;
112 }
113 
114 qint64 BitcoinAmountField::value(bool *valid_out) const
115 {
116  qint64 val_out = 0;
117  bool valid = BitcoinUnits::parse(currentUnit, text(), &val_out);
118  if(valid_out)
119  {
120  *valid_out = valid;
121  }
122  return val_out;
123 }
124 
126 {
128 }
129 
131 {
132  // Use description tooltip for current unit for the combobox
133  unit->setToolTip(unit->itemData(idx, Qt::ToolTipRole).toString());
134 
135  // Determine new unit ID
136  int newUnit = unit->itemData(idx, BitcoinUnits::UnitRole).toInt();
137 
138  // Parse current value and convert to new unit
139  bool valid = false;
140  qint64 currentValue = value(&valid);
141 
142  currentUnit = newUnit;
143 
144  // Set max length after retrieving the value, to prevent truncation
146  amount->setMaximum(qPow(10, BitcoinUnits::amountDigits(currentUnit)) - qPow(10, -amount->decimals()));
147 
149  amount->setSingleStep(0.01);
150  else
151  amount->setSingleStep(0.001);
152 
153  if(valid)
154  {
155  // If value was valid, re-place it in the widget with the new unit
156  setValue(currentValue);
157  }
158  else
159  {
160  // If current value is invalid, just clear field
161  setText("");
162  }
163  setValid(true);
164 }
165 
167 {
168  unit->setValue(newUnit);
169 }
LRUHandle * prev
Definition: cache.cc:30
bool validate()
Perform input validation, mark field as invalid if entered value is not valid.
Bitcoin unit definitions.
Definition: bitcoinunits.h:10
std::string * value
Definition: version_set.cc:270
QDoubleSpinBox * amount
QWidget * setupTabChain(QWidget *prev)
Qt messes up the tab chain by default in some cases (issue https://bugreports.qt-project.org/browse/QTBUG-10907), in these cases we have to set it up manually.
bool eventFilter(QObject *object, QEvent *event)
Intercept focus-in event and ',' key presses.
QString text() const
BitcoinAmountField(QWidget *parent=0)
#define STYLE_INVALID
Definition: guiconstants.h:14
Unit identifier.
Definition: bitcoinunits.h:58
QValueComboBox * unit
void setValue(const QVariant &value)
void clear()
Make field empty and ready for new input.
static int amountDigits(int unit)
Number of amount digits (to represent max number of coins)
static bool parse(int unit, const QString &value, qint64 *val_out)
Parse string to coin amount.
void setValid(bool valid)
Mark current value as invalid in UI.
void setText(const QString &text)
void setDisplayUnit(int unit)
Change unit used to display amount.
void setValue(qint64 value)
static QString format(int unit, qint64 amount, bool plussign=false)
Format as string.
static int decimals(int unit)
Number of decimals left.