source: trunk/src/gui/widgets/qspinbox.cpp@ 324

Last change on this file since 324 was 2, checked in by Dmitry A. Kuminov, 16 years ago

Initially imported qt-all-opensource-src-4.5.1 from Trolltech.

File size: 43.6 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** Contact: Qt Software Information ([email protected])
5**
6** This file is part of the QtGui module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial Usage
10** Licensees holding valid Qt Commercial licenses may use this file in
11** accordance with the Qt Commercial License Agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and Nokia.
14**
15** GNU Lesser General Public License Usage
16** Alternatively, this file may be used under the terms of the GNU Lesser
17** General Public License version 2.1 as published by the Free Software
18** Foundation and appearing in the file LICENSE.LGPL included in the
19** packaging of this file. Please review the following information to
20** ensure the GNU Lesser General Public License version 2.1 requirements
21** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
22**
23** In addition, as a special exception, Nokia gives you certain
24** additional rights. These rights are described in the Nokia Qt LGPL
25** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
26** package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you are unsure which license is appropriate for your use, please
37** contact the sales department at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include <private/qabstractspinbox_p.h>
43#include <qspinbox.h>
44
45#ifndef QT_NO_SPINBOX
46
47#include <qlineedit.h>
48#include <qlocale.h>
49#include <qvalidator.h>
50#include <qdebug.h>
51
52#include <math.h>
53
54QT_BEGIN_NAMESPACE
55
56//#define QSPINBOX_QSBDEBUG
57#ifdef QSPINBOX_QSBDEBUG
58# define QSBDEBUG qDebug
59#else
60# define QSBDEBUG if (false) qDebug
61#endif
62
63static bool isIntermediateValueHelper(qint64 num, qint64 minimum, qint64 maximum, qint64 *match = 0);
64
65class QSpinBoxPrivate : public QAbstractSpinBoxPrivate
66{
67 Q_DECLARE_PUBLIC(QSpinBox)
68public:
69 QSpinBoxPrivate(QWidget *parent = 0);
70 void emitSignals(EmitPolicy ep, const QVariant &);
71
72 virtual QVariant valueFromText(const QString &n) const;
73 virtual QString textFromValue(const QVariant &n) const;
74 QVariant validateAndInterpret(QString &input, int &pos,
75 QValidator::State &state) const;
76 bool isIntermediateValue(const QString &str) const;
77 QChar thousand;
78
79 inline void init() {
80 setLayoutItemMargins(QStyle::SE_SpinBoxLayoutItem);
81 }
82};
83
84class QDoubleSpinBoxPrivate : public QAbstractSpinBoxPrivate
85{
86 Q_DECLARE_PUBLIC(QDoubleSpinBox)
87public:
88 QDoubleSpinBoxPrivate(QWidget *parent = 0);
89 void emitSignals(EmitPolicy ep, const QVariant &);
90 bool isIntermediateValue(const QString &str) const;
91
92 virtual QVariant valueFromText(const QString &n) const;
93 virtual QString textFromValue(const QVariant &n) const;
94 QVariant validateAndInterpret(QString &input, int &pos,
95 QValidator::State &state) const;
96 double round(double input) const;
97 // variables
98 int decimals;
99 QChar delimiter, thousand;
100};
101
102
103/*!
104 \class QSpinBox
105 \brief The QSpinBox class provides a spin box widget.
106
107 \ingroup basicwidgets
108 \mainclass
109
110 QSpinBox is designed to handle integers and discrete sets of
111 values (e.g., month names); use QDoubleSpinBox for floating point
112 values.
113
114 QSpinBox allows the user to choose a value by clicking the up/down
115 buttons or pressing up/down on the keyboard to increase/decrease
116 the value currently displayed. The user can also type the value in
117 manually. The spin box supports integer values but can be extended to
118 use different strings with validate(), textFromValue() and valueFromText().
119
120 Every time the value changes QSpinBox emits the valueChanged()
121 signals. The current value can be fetched with value() and set
122 with setValue().
123
124 Clicking the up/down buttons or using the keyboard accelerator's
125 up and down arrows will increase or decrease the current value in
126 steps of size singleStep(). If you want to change this behaviour you
127 can reimplement the virtual function stepBy(). The minimum and
128 maximum value and the step size can be set using one of the
129 constructors, and can be changed later with setMinimum(),
130 setMaximum() and setSingleStep().
131
132 Most spin boxes are directional, but QSpinBox can also operate as
133 a circular spin box, i.e. if the range is 0-99 and the current
134 value is 99, clicking "up" will give 0 if wrapping() is set to
135 true. Use setWrapping() if you want circular behavior.
136
137 The displayed value can be prepended and appended with arbitrary
138 strings indicating, for example, currency or the unit of
139 measurement. See setPrefix() and setSuffix(). The text in the spin
140 box is retrieved with text() (which includes any prefix() and
141 suffix()), or with cleanText() (which has no prefix(), no suffix()
142 and no leading or trailing whitespace).
143
144 It is often desirable to give the user a special (often default)
145 choice in addition to the range of numeric values. See
146 setSpecialValueText() for how to do this with QSpinBox.
147
148 \table 100%
149 \row \o \inlineimage windowsxp-spinbox.png Screenshot of a Windows XP spin box
150 \o A spin box shown in the \l{Windows XP Style Widget Gallery}{Windows XP widget style}.
151 \row \o \inlineimage plastique-spinbox.png Screenshot of a Plastique spin box
152 \o A spin box shown in the \l{Plastique Style Widget Gallery}{Plastique widget style}.
153 \row \o \inlineimage macintosh-spinbox.png Screenshot of a Macintosh spin box
154 \o A spin box shown in the \l{Macintosh Style Widget Gallery}{Macintosh widget style}.
155 \endtable
156
157 \section1 Subclassing QSpinBox
158
159 If using prefix(), suffix(), and specialValueText() don't provide
160 enough control, you subclass QSpinBox and reimplement
161 valueFromText() and textFromValue(). For example, here's the code
162 for a custom spin box that allows the user to enter icon sizes
163 (e.g., "32 x 32"):
164
165 \snippet examples/widgets/icons/iconsizespinbox.cpp 1
166 \codeline
167 \snippet examples/widgets/icons/iconsizespinbox.cpp 2
168
169 See the \l{widgets/icons}{Icons} example for the full source
170 code.
171
172 \sa QDoubleSpinBox, QDateTimeEdit, QSlider, {Spin Boxes Example}
173*/
174
175/*!
176 \fn void QSpinBox::valueChanged(int i)
177
178 This signal is emitted whenever the spin box's value is changed.
179 The new value's integer value is passed in \a i.
180*/
181
182/*!
183 \fn void QSpinBox::valueChanged(const QString &text)
184
185 \overload
186
187 The new value is passed literally in \a text with no prefix() or
188 suffix().
189*/
190
191/*!
192 Constructs a spin box with 0 as minimum value and 99 as maximum value, a
193 step value of 1. The value is initially set to 0. It is parented to \a
194 parent.
195
196 \sa setMinimum(), setMaximum(), setSingleStep()
197*/
198
199QSpinBox::QSpinBox(QWidget *parent)
200 : QAbstractSpinBox(*new QSpinBoxPrivate(parent), parent)
201{
202 Q_D(QSpinBox);
203 d->init();
204}
205
206#ifdef QT3_SUPPORT
207/*!
208 Use one of the constructors that doesn't take the \a name
209 argument and then use setObjectName() instead.
210*/
211QSpinBox::QSpinBox(QWidget *parent, const char *name)
212 : QAbstractSpinBox(*new QSpinBoxPrivate(parent), parent)
213{
214 Q_D(QSpinBox);
215 setObjectName(QString::fromAscii(name));
216 d->init();
217}
218
219/*!
220 Use one of the constructors that doesn't take the \a name
221 argument and then use setObjectName() instead.
222*/
223QSpinBox::QSpinBox(int minimum, int maximum, int step, QWidget *parent, const char *name)
224 : QAbstractSpinBox(*new QSpinBoxPrivate(parent), parent)
225{
226 Q_D(QSpinBox);
227 d->minimum = QVariant(qMin<int>(minimum, maximum));
228 d->maximum = QVariant(qMax<int>(minimum, maximum));
229 d->singleStep = QVariant(step);
230 setObjectName(QString::fromAscii(name));
231 d->init();
232}
233
234#endif
235
236/*!
237 \property QSpinBox::value
238 \brief the value of the spin box
239
240 setValue() will emit valueChanged() if the new value is different
241 from the old one.
242*/
243
244int QSpinBox::value() const
245{
246 Q_D(const QSpinBox);
247 return d->value.toInt();
248}
249
250void QSpinBox::setValue(int value)
251{
252 Q_D(QSpinBox);
253 d->setValue(QVariant(value), EmitIfChanged);
254}
255
256/*!
257 \property QSpinBox::prefix
258 \brief the spin box's prefix
259
260 The prefix is prepended to the start of the displayed value.
261 Typical use is to display a unit of measurement or a currency
262 symbol. For example:
263
264 \snippet doc/src/snippets/code/src_gui_widgets_qspinbox.cpp 0
265
266 To turn off the prefix display, set this property to an empty
267 string. The default is no prefix. The prefix is not displayed when
268 value() == minimum() and specialValueText() is set.
269
270 If no prefix is set, prefix() returns an empty string.
271
272 \sa suffix(), setSuffix(), specialValueText(), setSpecialValueText()
273*/
274
275QString QSpinBox::prefix() const
276{
277 Q_D(const QSpinBox);
278 return d->prefix;
279}
280
281void QSpinBox::setPrefix(const QString &prefix)
282{
283 Q_D(QSpinBox);
284
285 d->prefix = prefix;
286 d->updateEdit();
287}
288
289/*!
290 \property QSpinBox::suffix
291 \brief the suffix of the spin box
292
293 The suffix is appended to the end of the displayed value. Typical
294 use is to display a unit of measurement or a currency symbol. For
295 example:
296
297 \snippet doc/src/snippets/code/src_gui_widgets_qspinbox.cpp 1
298
299 To turn off the suffix display, set this property to an empty
300 string. The default is no suffix. The suffix is not displayed for
301 the minimum() if specialValueText() is set.
302
303 If no suffix is set, suffix() returns an empty string.
304
305 \sa prefix(), setPrefix(), specialValueText(), setSpecialValueText()
306*/
307
308QString QSpinBox::suffix() const
309{
310 Q_D(const QSpinBox);
311
312 return d->suffix;
313}
314
315void QSpinBox::setSuffix(const QString &suffix)
316{
317 Q_D(QSpinBox);
318
319 d->suffix = suffix;
320 d->updateEdit();
321}
322
323/*!
324 \property QSpinBox::cleanText
325
326 \brief the text of the spin box excluding any prefix, suffix,
327 or leading or trailing whitespace.
328
329 \sa text, QSpinBox::prefix, QSpinBox::suffix
330*/
331
332QString QSpinBox::cleanText() const
333{
334 Q_D(const QSpinBox);
335
336 return d->stripped(d->edit->displayText());
337}
338
339
340/*!
341 \property QSpinBox::singleStep
342 \brief the step value
343
344 When the user uses the arrows to change the spin box's value the
345 value will be incremented/decremented by the amount of the
346 singleStep. The default value is 1. Setting a singleStep value of
347 less than 0 does nothing.
348*/
349
350int QSpinBox::singleStep() const
351{
352 Q_D(const QSpinBox);
353
354 return d->singleStep.toInt();
355}
356
357void QSpinBox::setSingleStep(int value)
358{
359 Q_D(QSpinBox);
360 if (value >= 0) {
361 d->singleStep = QVariant(value);
362 d->updateEdit();
363 }
364}
365
366/*!
367 \property QSpinBox::minimum
368
369 \brief the minimum value of the spin box
370
371 When setting this property the \l maximum is adjusted
372 if necessary to ensure that the range remains valid.
373
374 The default minimum value is 0.
375
376 \sa setRange() specialValueText
377*/
378
379int QSpinBox::minimum() const
380{
381 Q_D(const QSpinBox);
382
383 return d->minimum.toInt();
384}
385
386void QSpinBox::setMinimum(int minimum)
387{
388 Q_D(QSpinBox);
389 const QVariant m(minimum);
390 d->setRange(m, (d->variantCompare(d->maximum, m) > 0 ? d->maximum : m));
391}
392
393/*!
394 \property QSpinBox::maximum
395
396 \brief the maximum value of the spin box
397
398 When setting this property the \l minimum is adjusted
399 if necessary, to ensure that the range remains valid.
400
401 The default maximum value is 99.
402
403 \sa setRange() specialValueText
404
405*/
406
407int QSpinBox::maximum() const
408{
409 Q_D(const QSpinBox);
410
411 return d->maximum.toInt();
412}
413
414void QSpinBox::setMaximum(int maximum)
415{
416 Q_D(QSpinBox);
417 const QVariant m(maximum);
418 d->setRange((d->variantCompare(d->minimum, m) < 0 ? d->minimum : m), m);
419}
420
421/*!
422 Convenience function to set the \a minimum, and \a maximum values
423 with a single function call.
424
425 \snippet doc/src/snippets/code/src_gui_widgets_qspinbox.cpp 2
426 is equivalent to:
427 \snippet doc/src/snippets/code/src_gui_widgets_qspinbox.cpp 3
428
429 \sa minimum maximum
430*/
431
432void QSpinBox::setRange(int minimum, int maximum)
433{
434 Q_D(QSpinBox);
435 d->setRange(QVariant(minimum), QVariant(maximum));
436}
437
438/*!
439 This virtual function is used by the spin box whenever it needs
440 to display the given \a value. The default implementation returns
441 a string containing \a value printed in the standard way using
442 QWidget::locale().toString(). Reimplementations may return anything. (See
443 the example in the detailed description.)
444
445 Note: QSpinBox does not call this function for specialValueText()
446 and that neither prefix() nor suffix() should be included in the
447 return value.
448
449 If you reimplement this, you may also need to reimplement
450 valueFromText() and validate()
451
452 \sa valueFromText(), validate()
453*/
454
455QString QSpinBox::textFromValue(int value) const