Update CMakeLists.txt - play with openssl
[novacoin.git] / src / qt / bitcoinamountfield.cpp
1 #include "bitcoinamountfield.h"
2 #include "qvaluecombobox.h"
3 #include "bitcoinunits.h"
4
5 #include "guiconstants.h"
6
7 #include <QLabel>
8 #include <QLineEdit>
9 #include <QRegExpValidator>
10 #include <QHBoxLayout>
11 #include <QKeyEvent>
12 #include <QDoubleSpinBox>
13 #include <QComboBox>
14 #include <QApplication>
15 #include <qmath.h>
16
17 BitcoinAmountField::BitcoinAmountField(QWidget *parent):
18         QWidget(parent), amount(0), currentUnit(-1)
19 {
20     amount = new QDoubleSpinBox(this);
21     amount->setLocale(QLocale::c());
22     amount->setDecimals(8);
23     amount->installEventFilter(this);
24     amount->setMaximumWidth(240);
25     amount->setSingleStep(0.001);
26
27     QHBoxLayout *layout = new QHBoxLayout(this);
28     layout->addWidget(amount);
29     unit = new QValueComboBox(this);
30     unit->setModel(new BitcoinUnits(this));
31     layout->addWidget(unit);
32     layout->addStretch(1);
33     layout->setContentsMargins(0,0,0,0);
34
35     setLayout(layout);
36
37     setFocusPolicy(Qt::TabFocus);
38     setFocusProxy(amount);
39
40     // If one if the widgets changes, the combined content changes as well
41     connect(amount, SIGNAL(valueChanged(QString)), this, SIGNAL(textChanged()));
42     connect(unit, SIGNAL(currentIndexChanged(int)), this, SLOT(unitChanged(int)));
43
44     // Set default based on configuration
45     unitChanged(unit->currentIndex());
46 }
47
48 void BitcoinAmountField::setText(const QString &text)
49 {
50     if (text.isEmpty())
51         amount->clear();
52     else
53         amount->setValue(text.toDouble());
54 }
55
56 void BitcoinAmountField::clear()
57 {
58     amount->clear();
59     unit->setCurrentIndex(0);
60 }
61
62 bool BitcoinAmountField::validate()
63 {
64     bool valid = true;
65     if (amount->value() == 0.0)
66         valid = false;
67     if (valid && !BitcoinUnits::parse(currentUnit, text(), 0))
68         valid = false;
69
70     setValid(valid);
71
72     return valid;
73 }
74
75 void BitcoinAmountField::setValid(bool valid)
76 {
77     if (valid)
78         amount->setStyleSheet("");
79     else
80         amount->setStyleSheet(STYLE_INVALID);
81 }
82
83 QString BitcoinAmountField::text() const
84 {
85     if (amount->text().isEmpty())
86         return QString();
87     else
88         return amount->text();
89 }
90
91 bool BitcoinAmountField::eventFilter(QObject *object, QEvent *event)
92 {
93     if (event->type() == QEvent::FocusIn)
94     {
95         // Clear invalid flag on focus
96         setValid(true);
97     }
98     else if (event->type() == QEvent::KeyPress || event->type() == QEvent::KeyRelease)
99     {
100         QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
101         if (keyEvent->key() == Qt::Key_Comma)
102         {
103             // Translate a comma into a period
104             QKeyEvent periodKeyEvent(event->type(), Qt::Key_Period, keyEvent->modifiers(), ".", keyEvent->isAutoRepeat(), keyEvent->count());
105             qApp->sendEvent(object, &periodKeyEvent);
106             return true;
107         }
108     }
109     return QWidget::eventFilter(object, event);
110 }
111
112 QWidget *BitcoinAmountField::setupTabChain(QWidget *prev)
113 {
114     QWidget::setTabOrder(prev, amount);
115     return amount;
116 }
117
118 qint64 BitcoinAmountField::value(bool *valid_out) const
119 {
120     qint64 val_out = 0;
121     bool valid = BitcoinUnits::parse(currentUnit, text(), &val_out);
122     if(valid_out)
123     {
124         *valid_out = valid;
125     }
126     return val_out;
127 }
128
129 void BitcoinAmountField::setValue(qint64 value)
130 {
131     setText(BitcoinUnits::format(currentUnit, value));
132 }
133
134 void BitcoinAmountField::unitChanged(int idx)
135 {
136     // Use description tooltip for current unit for the combobox
137     unit->setToolTip(unit->itemData(idx, Qt::ToolTipRole).toString());
138
139     // Determine new unit ID
140     int newUnit = unit->itemData(idx, BitcoinUnits::UnitRole).toInt();
141
142     // Parse current value and convert to new unit
143     bool valid = false;
144     qint64 currentValue = value(&valid);
145
146     currentUnit = newUnit;
147
148     // Set max length after retrieving the value, to prevent truncation
149     amount->setDecimals(BitcoinUnits::decimals(currentUnit));
150     amount->setMaximum(qPow(10, BitcoinUnits::amountDigits(currentUnit)) - qPow(10, -amount->decimals()));
151
152     if(valid)
153     {
154         // If value was valid, re-place it in the widget with the new unit
155         setValue(currentValue);
156     }
157     else
158     {
159         // If current value is invalid, just clear field
160         setText("");
161     }
162     setValid(true);
163 }
164
165 void BitcoinAmountField::setDisplayUnit(int newUnit)
166 {
167     unit->setValue(newUnit);
168 }