]> Git Repo - VerusCoin.git/blame - src/qt/bitcoinamountfield.cpp
Remove translation for -help-debug options
[VerusCoin.git] / src / qt / bitcoinamountfield.cpp
CommitLineData
f914f1a7 1// Copyright (c) 2011-2014 The Bitcoin Core developers
78253fcb 2// Distributed under the MIT software license, see the accompanying
e592d43f
WL
3// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4
f193c57a 5#include "bitcoinamountfield.h"
32af5266 6
e285ffcd 7#include "bitcoinunits.h"
527137e3 8#include "guiconstants.h"
51ed9ec9 9#include "qvaluecombobox.h"
527137e3 10
84ef729a 11#include <QApplication>
91cce173 12#include <QAbstractSpinBox>
f193c57a
WL
13#include <QHBoxLayout>
14#include <QKeyEvent>
91cce173 15#include <QLineEdit>
f193c57a 16
91cce173
WL
17/** QSpinBox that uses fixed-point numbers internally and uses our own
18 * formatting/parsing functions.
19 */
20class AmountSpinBox: public QAbstractSpinBox
70074029 21{
91cce173 22 Q_OBJECT
0fd9e2bf 23
70074029
RB
24public:
25 explicit AmountSpinBox(QWidget *parent):
91cce173
WL
26 QAbstractSpinBox(parent),
27 currentUnit(BitcoinUnits::BTC),
28 singleStep(100000) // satoshis
70074029 29 {
91cce173
WL
30 setAlignment(Qt::AlignRight);
31
32 connect(lineEdit(), SIGNAL(textEdited(QString)), this, SIGNAL(valueChanged()));
33 }
34
35 QValidator::State validate(QString &text, int &pos) const
36 {
37 if(text.isEmpty())
38 return QValidator::Intermediate;
39 bool valid = false;
40 parse(text, &valid);
41 /* Make sure we return Intermediate so that fixup() is called on defocus */
42 return valid ? QValidator::Intermediate : QValidator::Invalid;
43 }
44
45 void fixup(QString &input) const
46 {
47 bool valid = false;
a372168e 48 CAmount val = parse(input, &valid);
91cce173
WL
49 if(valid)
50 {
51 input = BitcoinUnits::format(currentUnit, val, false, BitcoinUnits::separatorAlways);
52 lineEdit()->setText(input);
53 }
70074029 54 }
91cce173 55
a372168e 56 CAmount value(bool *valid_out=0) const
70074029 57 {
91cce173
WL
58 return parse(text(), valid_out);
59 }
60
a372168e 61 void setValue(const CAmount& value)
91cce173
WL
62 {
63 lineEdit()->setText(BitcoinUnits::format(currentUnit, value, false, BitcoinUnits::separatorAlways));
64 emit valueChanged();
65 }
66
67 void stepBy(int steps)
68 {
69 bool valid = false;
a372168e 70 CAmount val = value(&valid);
91cce173 71 val = val + steps * singleStep;
a372168e 72 val = qMin(qMax(val, CAmount(0)), BitcoinUnits::maxMoney());
91cce173
WL
73 setValue(val);
74 }
75
91cce173
WL
76 void setDisplayUnit(int unit)
77 {
78 bool valid = false;
a372168e 79 CAmount val = value(&valid);
91cce173
WL
80
81 currentUnit = unit;
82
83 if(valid)
84 setValue(val);
70074029 85 else
91cce173 86 clear();
70074029 87 }
91cce173 88
a372168e 89 void setSingleStep(const CAmount& step)
70074029 90 {
91cce173
WL
91 singleStep = step;
92 }
93
94 QSize minimumSizeHint() const
95 {
96 if(cachedMinimumSizeHint.isEmpty())
97 {
98 ensurePolished();
99
100 const QFontMetrics fm(fontMetrics());
101 int h = lineEdit()->minimumSizeHint().height();
102 int w = fm.width(BitcoinUnits::format(BitcoinUnits::BTC, BitcoinUnits::maxMoney(), false, BitcoinUnits::separatorAlways));
103 w += 2; // cursor blinking space
104
105 QStyleOptionSpinBox opt;
106 initStyleOption(&opt);
107 QSize hint(w, h);
108 QSize extra(35, 6);
109 opt.rect.setSize(hint + extra);
110 extra += hint - style()->subControlRect(QStyle::CC_SpinBox, &opt,
111 QStyle::SC_SpinBoxEditField, this).size();
112 // get closer to final result by repeating the calculation
113 opt.rect.setSize(hint + extra);
114 extra += hint - style()->subControlRect(QStyle::CC_SpinBox, &opt,
115 QStyle::SC_SpinBoxEditField, this).size();
116 hint += extra;
7335ca1a 117 hint.setHeight(h);
91cce173
WL
118
119 opt.rect = rect();
120
121 cachedMinimumSizeHint = style()->sizeFromContents(QStyle::CT_SpinBox, &opt, hint, this)
122 .expandedTo(QApplication::globalStrut());
123 }
124 return cachedMinimumSizeHint;
125 }
0fd9e2bf 126
91cce173
WL
127private:
128 int currentUnit;
a372168e 129 CAmount singleStep;
91cce173
WL
130 mutable QSize cachedMinimumSizeHint;
131
132 /**
133 * Parse a string into a number of base monetary units and
134 * return validity.
135 * @note Must return 0 if !valid.
136 */
a372168e 137 CAmount parse(const QString &text, bool *valid_out=0) const
91cce173 138 {
a372168e 139 CAmount val = 0;
91cce173
WL
140 bool valid = BitcoinUnits::parse(currentUnit, text, &val);
141 if(valid)
142 {
143 if(val < 0 || val > BitcoinUnits::maxMoney())
144 valid = false;
145 }
146 if(valid_out)
147 *valid_out = valid;
148 return valid ? val : 0;
70074029 149 }
91cce173
WL
150
151protected:
152 bool event(QEvent *event)
70074029 153 {
91cce173
WL
154 if (event->type() == QEvent::KeyPress || event->type() == QEvent::KeyRelease)
155 {
156 QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
157 if (keyEvent->key() == Qt::Key_Comma)
158 {
159 // Translate a comma into a period
160 QKeyEvent periodKeyEvent(event->type(), Qt::Key_Period, keyEvent->modifiers(), ".", keyEvent->isAutoRepeat(), keyEvent->count());
161 return QAbstractSpinBox::event(&periodKeyEvent);
162 }
163 }
164 return QAbstractSpinBox::event(event);
70074029 165 }
91cce173 166
0fd9e2bf
PK
167 StepEnabled stepEnabled() const
168 {
0fd9e2bf
PK
169 if (isReadOnly()) // Disable steps when AmountSpinBox is read-only
170 return StepNone;
80dd50cc 171 if (text().isEmpty()) // Allow step-up with empty field
0fd9e2bf 172 return StepUpEnabled;
80dd50cc
PK
173
174 StepEnabled rv = 0;
0fd9e2bf
PK
175 bool valid = false;
176 CAmount val = value(&valid);
177 if(valid)
178 {
179 if(val > 0)
180 rv |= StepDownEnabled;
181 if(val < BitcoinUnits::maxMoney())
182 rv |= StepUpEnabled;
183 }
184 return rv;
185 }
186
91cce173
WL
187signals:
188 void valueChanged();
70074029
RB
189};
190
91cce173
WL
191#include "bitcoinamountfield.moc"
192
6c1bf199
PK
193BitcoinAmountField::BitcoinAmountField(QWidget *parent) :
194 QWidget(parent),
91cce173 195 amount(0)
f193c57a 196{
70074029 197 amount = new AmountSpinBox(this);
527137e3 198 amount->setLocale(QLocale::c());
f193c57a 199 amount->installEventFilter(this);
527137e3 200 amount->setMaximumWidth(170);
f193c57a
WL
201
202 QHBoxLayout *layout = new QHBoxLayout(this);
f193c57a 203 layout->addWidget(amount);
ee014e5b 204 unit = new QValueComboBox(this);
587e5285
WL
205 unit->setModel(new BitcoinUnits(this));
206 layout->addWidget(unit);
f193c57a 207 layout->addStretch(1);
84114e34 208 layout->setContentsMargins(0,0,0,0);
f193c57a 209
f193c57a 210 setLayout(layout);
a5e6d723
WL
211
212 setFocusPolicy(Qt::TabFocus);
f193c57a
WL
213 setFocusProxy(amount);
214
215 // If one if the widgets changes, the combined content changes as well
91cce173 216 connect(amount, SIGNAL(valueChanged()), this, SIGNAL(valueChanged()));
587e5285
WL
217 connect(unit, SIGNAL(currentIndexChanged(int)), this, SLOT(unitChanged(int)));
218
b0849613 219 // Set default based on configuration
587e5285 220 unitChanged(unit->currentIndex());
f193c57a
WL
221}
222
73cd5e52
WL
223void BitcoinAmountField::clear()
224{
225 amount->clear();
83c8d678 226 unit->setCurrentIndex(0);
73cd5e52
WL
227}
228
c1c9d5b4
CL
229void BitcoinAmountField::setEnabled(bool fEnabled)
230{
231 amount->setEnabled(fEnabled);
232 unit->setEnabled(fEnabled);
233}
234
a5e6d723
WL
235bool BitcoinAmountField::validate()
236{
91cce173
WL
237 bool valid = false;
238 value(&valid);
527137e3 239 setValid(valid);
a5e6d723
WL
240 return valid;
241}
242
587e5285
WL
243void BitcoinAmountField::setValid(bool valid)
244{
527137e3 245 if (valid)
246 amount->setStyleSheet("");
247 else
248 amount->setStyleSheet(STYLE_INVALID);
587e5285
WL
249}
250
f193c57a
WL
251bool BitcoinAmountField::eventFilter(QObject *object, QEvent *event)
252{
527137e3 253 if (event->type() == QEvent::FocusIn)
254 {
255 // Clear invalid flag on focus
256 setValid(true);
257 }
527137e3 258 return QWidget::eventFilter(object, event);
f193c57a 259}
a5e6d723
WL
260
261QWidget *BitcoinAmountField::setupTabChain(QWidget *prev)
262{
263 QWidget::setTabOrder(prev, amount);
69d03bc6
WL
264 QWidget::setTabOrder(amount, unit);
265 return unit;
a5e6d723 266}
587e5285 267
a372168e 268CAmount BitcoinAmountField::value(bool *valid_out) const
587e5285 269{
91cce173 270 return amount->value(valid_out);
587e5285
WL
271}
272
a372168e 273void BitcoinAmountField::setValue(const CAmount& value)
587e5285 274{
91cce173 275 amount->setValue(value);
587e5285
WL
276}
277
75fa27ea 278void BitcoinAmountField::setReadOnly(bool fReadOnly)
a41d5fe0 279{
75fa27ea 280 amount->setReadOnly(fReadOnly);
a41d5fe0
GA
281}
282
587e5285
WL
283void BitcoinAmountField::unitChanged(int idx)
284{
285 // Use description tooltip for current unit for the combobox
286 unit->setToolTip(unit->itemData(idx, Qt::ToolTipRole).toString());
287
288 // Determine new unit ID
289 int newUnit = unit->itemData(idx, BitcoinUnits::UnitRole).toInt();
290
91cce173 291 amount->setDisplayUnit(newUnit);
ee014e5b 292}
587e5285 293
ee014e5b
WL
294void BitcoinAmountField::setDisplayUnit(int newUnit)
295{
296 unit->setValue(newUnit);
587e5285 297}
b9201482 298
a372168e 299void BitcoinAmountField::setSingleStep(const CAmount& step)
b9201482 300{
91cce173 301 amount->setSingleStep(step);
b9201482 302}
This page took 0.195753 seconds and 4 git commands to generate.