/****************************************************************************+ −
**+ −
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).+ −
** All rights reserved.+ −
** Contact: Nokia Corporation (qt-info@nokia.com)+ −
**+ −
** This file is part of the QtGui module of the Qt Toolkit.+ −
**+ −
** $QT_BEGIN_LICENSE:LGPL$+ −
** No Commercial Usage+ −
** This file contains pre-release code and may not be distributed.+ −
** You may use this file in accordance with the terms and conditions+ −
** contained in the Technology Preview License Agreement accompanying+ −
** this package.+ −
**+ −
** GNU Lesser General Public License Usage+ −
** Alternatively, this file may be used under the terms of the GNU Lesser+ −
** General Public License version 2.1 as published by the Free Software+ −
** Foundation and appearing in the file LICENSE.LGPL included in the+ −
** packaging of this file. Please review the following information to+ −
** ensure the GNU Lesser General Public License version 2.1 requirements+ −
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.+ −
**+ −
** In addition, as a special exception, Nokia gives you certain additional+ −
** rights. These rights are described in the Nokia Qt LGPL Exception+ −
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.+ −
**+ −
** If you have questions regarding the use of this file, please contact+ −
** Nokia at qt-info@nokia.com.+ −
**+ −
**+ −
**+ −
**+ −
**+ −
**+ −
**+ −
**+ −
** $QT_END_LICENSE$+ −
**+ −
****************************************************************************/+ −
+ −
#include <private/qabstractspinbox_p.h>+ −
#include <qspinbox.h>+ −
+ −
#ifndef QT_NO_SPINBOX+ −
+ −
#include <qlineedit.h>+ −
#include <qlocale.h>+ −
#include <qvalidator.h>+ −
#include <qdebug.h>+ −
+ −
#include <math.h>+ −
#include <float.h>+ −
+ −
QT_BEGIN_NAMESPACE+ −
+ −
//#define QSPINBOX_QSBDEBUG+ −
#ifdef QSPINBOX_QSBDEBUG+ −
# define QSBDEBUG qDebug+ −
#else+ −
# define QSBDEBUG if (false) qDebug+ −
#endif+ −
+ −
class QSpinBoxPrivate : public QAbstractSpinBoxPrivate+ −
{+ −
Q_DECLARE_PUBLIC(QSpinBox)+ −
public:+ −
QSpinBoxPrivate();+ −
void emitSignals(EmitPolicy ep, const QVariant &);+ −
+ −
virtual QVariant valueFromText(const QString &n) const;+ −
virtual QString textFromValue(const QVariant &n) const;+ −
QVariant validateAndInterpret(QString &input, int &pos,+ −
QValidator::State &state) const;+ −
+ −
inline void init() {+ −
Q_Q(QSpinBox);+ −
q->setInputMethodHints(Qt::ImhDigitsOnly);+ −
setLayoutItemMargins(QStyle::SE_SpinBoxLayoutItem);+ −
}+ −
};+ −
+ −
class QDoubleSpinBoxPrivate : public QAbstractSpinBoxPrivate+ −
{+ −
Q_DECLARE_PUBLIC(QDoubleSpinBox)+ −
public:+ −
QDoubleSpinBoxPrivate();+ −
void emitSignals(EmitPolicy ep, const QVariant &);+ −
+ −
virtual QVariant valueFromText(const QString &n) const;+ −
virtual QString textFromValue(const QVariant &n) const;+ −
QVariant validateAndInterpret(QString &input, int &pos,+ −
QValidator::State &state) const;+ −
double round(double input) const;+ −
// variables+ −
int decimals;+ −
+ −
inline void init() {+ −
Q_Q(QDoubleSpinBox);+ −
q->setInputMethodHints(Qt::ImhFormattedNumbersOnly);+ −
}+ −
};+ −
+ −
+ −
/*!+ −
\class QSpinBox+ −
\brief The QSpinBox class provides a spin box widget.+ −
+ −
\ingroup basicwidgets+ −
+ −
+ −
QSpinBox is designed to handle integers and discrete sets of+ −
values (e.g., month names); use QDoubleSpinBox for floating point+ −
values.+ −
+ −
QSpinBox allows the user to choose a value by clicking the up/down+ −
buttons or pressing up/down on the keyboard to increase/decrease+ −
the value currently displayed. The user can also type the value in+ −
manually. The spin box supports integer values but can be extended to+ −
use different strings with validate(), textFromValue() and valueFromText().+ −
+ −
Every time the value changes QSpinBox emits the valueChanged()+ −
signals. The current value can be fetched with value() and set+ −
with setValue().+ −
+ −
Clicking the up/down buttons or using the keyboard accelerator's+ −
up and down arrows will increase or decrease the current value in+ −
steps of size singleStep(). If you want to change this behaviour you+ −
can reimplement the virtual function stepBy(). The minimum and+ −
maximum value and the step size can be set using one of the+ −
constructors, and can be changed later with setMinimum(),+ −
setMaximum() and setSingleStep().+ −
+ −
Most spin boxes are directional, but QSpinBox can also operate as+ −
a circular spin box, i.e. if the range is 0-99 and the current+ −
value is 99, clicking "up" will give 0 if wrapping() is set to+ −
true. Use setWrapping() if you want circular behavior.+ −
+ −
The displayed value can be prepended and appended with arbitrary+ −
strings indicating, for example, currency or the unit of+ −
measurement. See setPrefix() and setSuffix(). The text in the spin+ −
box is retrieved with text() (which includes any prefix() and+ −
suffix()), or with cleanText() (which has no prefix(), no suffix()+ −
and no leading or trailing whitespace).+ −
+ −
It is often desirable to give the user a special (often default)+ −
choice in addition to the range of numeric values. See+ −
setSpecialValueText() for how to do this with QSpinBox.+ −
+ −
\table 100%+ −
\row \o \inlineimage windowsxp-spinbox.png Screenshot of a Windows XP spin box+ −
\o A spin box shown in the \l{Windows XP Style Widget Gallery}{Windows XP widget style}.+ −
\row \o \inlineimage plastique-spinbox.png Screenshot of a Plastique spin box+ −
\o A spin box shown in the \l{Plastique Style Widget Gallery}{Plastique widget style}.+ −
\row \o \inlineimage macintosh-spinbox.png Screenshot of a Macintosh spin box+ −
\o A spin box shown in the \l{Macintosh Style Widget Gallery}{Macintosh widget style}.+ −
\endtable+ −
+ −
\section1 Subclassing QSpinBox+ −
+ −
If using prefix(), suffix(), and specialValueText() don't provide+ −
enough control, you subclass QSpinBox and reimplement+ −
valueFromText() and textFromValue(). For example, here's the code+ −
for a custom spin box that allows the user to enter icon sizes+ −
(e.g., "32 x 32"):+ −
+ −
\snippet examples/widgets/icons/iconsizespinbox.cpp 1+ −
\codeline+ −
\snippet examples/widgets/icons/iconsizespinbox.cpp 2+ −
+ −
See the \l{widgets/icons}{Icons} example for the full source+ −
code.+ −
+ −
\sa QDoubleSpinBox, QDateTimeEdit, QSlider, {Spin Boxes Example}+ −
*/+ −
+ −
/*!+ −
\fn void QSpinBox::valueChanged(int i)+ −
+ −
This signal is emitted whenever the spin box's value is changed.+ −
The new value's integer value is passed in \a i.+ −
*/+ −
+ −
/*!+ −
\fn void QSpinBox::valueChanged(const QString &text)+ −
+ −
\overload+ −
+ −
The new value is passed literally in \a text with no prefix() or+ −
suffix().+ −
*/+ −
+ −
/*!+ −
Constructs a spin box with 0 as minimum value and 99 as maximum value, a+ −
step value of 1. The value is initially set to 0. It is parented to \a+ −
parent.+ −
+ −
\sa setMinimum(), setMaximum(), setSingleStep()+ −
*/+ −
+ −
QSpinBox::QSpinBox(QWidget *parent)+ −
: QAbstractSpinBox(*new QSpinBoxPrivate, parent)+ −
{+ −
Q_D(QSpinBox);+ −
d->init();+ −
}+ −
+ −
#ifdef QT3_SUPPORT+ −
/*!+ −
Use one of the constructors that doesn't take the \a name+ −
argument and then use setObjectName() instead.+ −
*/+ −
QSpinBox::QSpinBox(QWidget *parent, const char *name)+ −
: QAbstractSpinBox(*new QSpinBoxPrivate, parent)+ −
{+ −
Q_D(QSpinBox);+ −
setObjectName(QString::fromAscii(name));+ −
d->init();+ −
}+ −
+ −
/*!+ −
Use one of the constructors that doesn't take the \a name+ −
argument and then use setObjectName() instead.+ −
*/+ −
QSpinBox::QSpinBox(int minimum, int maximum, int step, QWidget *parent, const char *name)+ −
: QAbstractSpinBox(*new QSpinBoxPrivate, parent)+ −
{+ −
Q_D(QSpinBox);+ −
d->minimum = QVariant(qMin<int>(minimum, maximum));+ −
d->maximum = QVariant(qMax<int>(minimum, maximum));+ −
d->singleStep = QVariant(step);+ −
setObjectName(QString::fromAscii(name));+ −
d->init();+ −
}+ −
+ −
#endif+ −
+ −
/*!+ −
\property QSpinBox::value+ −
\brief the value of the spin box+ −
+ −
setValue() will emit valueChanged() if the new value is different+ −
from the old one.+ −
*/+ −
+ −
int QSpinBox::value() const+ −
{+ −
Q_D(const QSpinBox);+ −
return d->value.toInt();+ −
}+ −
+ −
void QSpinBox::setValue(int value)+ −
{+ −
Q_D(QSpinBox);+ −
d->setValue(QVariant(value), EmitIfChanged);+ −
}+ −
+ −
/*!+ −
\property QSpinBox::prefix+ −
\brief the spin box's prefix+ −
+ −
The prefix is prepended to the start of the displayed value.+ −
Typical use is to display a unit of measurement or a currency+ −
symbol. For example:+ −
+ −
\snippet doc/src/snippets/code/src_gui_widgets_qspinbox.cpp 0+ −
+ −
To turn off the prefix display, set this property to an empty+ −
string. The default is no prefix. The prefix is not displayed when+ −
value() == minimum() and specialValueText() is set.+ −
+ −
If no prefix is set, prefix() returns an empty string.+ −
+ −
\sa suffix(), setSuffix(), specialValueText(), setSpecialValueText()+ −
*/+ −
+ −
QString QSpinBox::prefix() const+ −
{+ −
Q_D(const QSpinBox);+ −
return d->prefix;+ −
}+ −
+ −
void QSpinBox::setPrefix(const QString &prefix)+ −
{+ −
Q_D(QSpinBox);+ −
+ −
d->prefix = prefix;+ −
d->updateEdit();+ −
+ −
d->cachedSizeHint = QSize();+ −
updateGeometry();+ −
}+ −
+ −
/*!+ −
\property QSpinBox::suffix+ −
\brief the suffix of the spin box+ −
+ −
The suffix is appended to the end of the displayed value. Typical+ −
use is to display a unit of measurement or a currency symbol. For+ −
example:+ −
+ −
\snippet doc/src/snippets/code/src_gui_widgets_qspinbox.cpp 1+ −
+ −
To turn off the suffix display, set this property to an empty+ −
string. The default is no suffix. The suffix is not displayed for+ −
the minimum() if specialValueText() is set.+ −
+ −
If no suffix is set, suffix() returns an empty string.+ −
+ −
\sa prefix(), setPrefix(), specialValueText(), setSpecialValueText()+ −
*/+ −
+ −
QString QSpinBox::suffix() const+ −
{+ −
Q_D(const QSpinBox);+ −
+ −
return d->suffix;+ −
}+ −
+ −
void QSpinBox::setSuffix(const QString &suffix)+ −
{+ −
Q_D(QSpinBox);+ −
+ −
d->suffix = suffix;+ −
d->updateEdit();+ −
+ −
d->cachedSizeHint = QSize();+ −
updateGeometry();+ −
}+ −
+ −
/*!+ −
\property QSpinBox::cleanText+ −
+ −
\brief the text of the spin box excluding any prefix, suffix,+ −
or leading or trailing whitespace.+ −
+ −
\sa text, QSpinBox::prefix, QSpinBox::suffix+ −
*/+ −
+ −
QString QSpinBox::cleanText() const+ −
{+ −
Q_D(const QSpinBox);+ −
+ −
return d->stripped(d->edit->displayText());+ −
}+ −
+ −
+ −
/*!+ −
\property QSpinBox::singleStep+ −
\brief the step value+ −
+ −
When the user uses the arrows to change the spin box's value the+ −
value will be incremented/decremented by the amount of the+ −
singleStep. The default value is 1. Setting a singleStep value of+ −
less than 0 does nothing.+ −
*/+ −
+ −
int QSpinBox::singleStep() const+ −
{+ −
Q_D(const QSpinBox);+ −
+ −
return d->singleStep.toInt();+ −
}+ −
+ −
void QSpinBox::setSingleStep(int value)+ −
{+ −
Q_D(QSpinBox);+ −
if (value >= 0) {+ −
d->singleStep = QVariant(value);+ −
d->updateEdit();+ −
}+ −
}+ −
+ −
/*!+ −
\property QSpinBox::minimum+ −
+ −
\brief the minimum value of the spin box+ −
+ −
When setting this property the \l maximum is adjusted+ −
if necessary to ensure that the range remains valid.+ −
+ −
The default minimum value is 0.+ −
+ −
\sa setRange() specialValueText+ −
*/+ −
+ −
int QSpinBox::minimum() const+ −
{+ −
Q_D(const QSpinBox);+ −
+ −
return d->minimum.toInt();+ −
}+ −
+ −
void QSpinBox::setMinimum(int minimum)+ −
{+ −
Q_D(QSpinBox);+ −
const QVariant m(minimum);+ −
d->setRange(m, (d->variantCompare(d->maximum, m) > 0 ? d->maximum : m));+ −
}+ −
+ −
/*!+ −
\property QSpinBox::maximum+ −
+ −
\brief the maximum value of the spin box+ −
+ −
When setting this property the \l minimum is adjusted+ −
if necessary, to ensure that the range remains valid.+ −
+ −
The default maximum value is 99.+ −
+ −
\sa setRange() specialValueText+ −
+ −
*/+ −
+ −
int QSpinBox::maximum() const+ −
{+ −
Q_D(const QSpinBox);+ −
+ −
return d->maximum.toInt();+ −
}+ −
+ −
void QSpinBox::setMaximum(int maximum)+ −
{+ −
Q_D(QSpinBox);+ −
const QVariant m(maximum);+ −
d->setRange((d->variantCompare(d->minimum, m) < 0 ? d->minimum : m), m);+ −
}+ −
+ −
/*!+ −
Convenience function to set the \a minimum, and \a maximum values+ −
with a single function call.+ −
+ −
\snippet doc/src/snippets/code/src_gui_widgets_qspinbox.cpp 2+ −
is equivalent to:+ −
\snippet doc/src/snippets/code/src_gui_widgets_qspinbox.cpp 3+ −
+ −
\sa minimum maximum+ −
*/+ −
+ −
void QSpinBox::setRange(int minimum, int maximum)+ −
{+ −
Q_D(QSpinBox);+ −
d->setRange(QVariant(minimum), QVariant(maximum));+ −
}+ −
+ −
/*!+ −
This virtual function is used by the spin box whenever it needs+ −
to display the given \a value. The default implementation returns+ −
a string containing \a value printed in the standard way using+ −
QWidget::locale().toString(). Reimplementations may return anything. (See+ −
the example in the detailed description.)+ −
+ −
Note: QSpinBox does not call this function for specialValueText()+ −
and that neither prefix() nor suffix() should be included in the+ −
return value.+ −
+ −
If you reimplement this, you may also need to reimplement+ −
valueFromText() and validate()+ −
+ −
\sa valueFromText(), validate()+ −
*/+ −
+ −
QString QSpinBox::textFromValue(int value) const+ −
{+ −
QString str = locale().toString(value);+ −
if (qAbs(value) >= 1000 || value == INT_MIN) {+ −
str.remove(locale().groupSeparator());+ −
}+ −
+ −
return str;+ −
}+ −
+ −
/*!+ −
\fn int QSpinBox::valueFromText(const QString &text) const+ −
+ −
This virtual function is used by the spin box whenever it needs to+ −
interpret \a text entered by the user as a value.+ −
+ −
Subclasses that need to display spin box values in a non-numeric+ −
way need to reimplement this function.+ −
+ −
Note: QSpinBox handles specialValueText() separately; this+ −
function is only concerned with the other values.+ −
+ −
\sa textFromValue(), validate()+ −
*/+ −
+ −
int QSpinBox::valueFromText(const QString &text) const+ −
{+ −
Q_D(const QSpinBox);+ −
+ −
QString copy = text;+ −
int pos = d->edit->cursorPosition();+ −
QValidator::State state = QValidator::Acceptable;+ −
return d->validateAndInterpret(copy, pos, state).toInt();+ −
}+ −
+ −
/*!+ −
\reimp+ −
*/+ −
QValidator::State QSpinBox::validate(QString &text, int &pos) const+ −
{+ −
Q_D(const QSpinBox);+ −
+ −
QValidator::State state;+ −
d->validateAndInterpret(text, pos, state);+ −
return state;+ −
}+ −
+ −
+ −
/*!+ −
\reimp+ −
*/+ −
void QSpinBox::fixup(QString &input) const+ −
{+ −
input.remove(locale().groupSeparator());+ −
}+ −
+ −
+ −
// --- QDoubleSpinBox ---+ −
+ −
/*!+ −
\class QDoubleSpinBox+ −
\brief The QDoubleSpinBox class provides a spin box widget that+ −
takes doubles.+ −
+ −
\ingroup basicwidgets+ −
+ −
+ −
QDoubleSpinBox allows the user to choose a value by clicking the+ −
up and down buttons or by pressing Up or Down on the keyboard to+ −
increase or decrease the value currently displayed. The user can+ −
also type the value in manually. The spin box supports double+ −
values but can be extended to use different strings with+ −
validate(), textFromValue() and valueFromText().+ −
+ −
Every time the value changes QDoubleSpinBox emits the+ −
valueChanged() signal. The current value can be fetched with+ −
value() and set with setValue().+ −
+ −
Note: QDoubleSpinBox will round numbers so they can be displayed+ −
with the current precision. In a QDoubleSpinBox with decimals set+ −
to 2, calling setValue(2.555) will cause value() to return 2.56.+ −
+ −
Clicking the up and down buttons or using the keyboard accelerator's+ −
Up and Down arrows will increase or decrease the current value in+ −
steps of size singleStep(). If you want to change this behavior you+ −
can reimplement the virtual function stepBy(). The minimum and+ −
maximum value and the step size can be set using one of the+ −
constructors, and can be changed later with setMinimum(),+ −
setMaximum() and setSingleStep(). The spinbox has a default+ −
precision of 2 decimal places but this can be changed using+ −
setDecimals().+ −
+ −
Most spin boxes are directional, but QDoubleSpinBox can also+ −
operate as a circular spin box, i.e. if the range is 0.0-99.9 and+ −
the current value is 99.9, clicking "up" will give 0 if wrapping()+ −
is set to true. Use setWrapping() if you want circular behavior.+ −
+ −
The displayed value can be prepended and appended with arbitrary+ −
strings indicating, for example, currency or the unit of+ −
measurement. See setPrefix() and setSuffix(). The text in the spin+ −
box is retrieved with text() (which includes any prefix() and+ −
suffix()), or with cleanText() (which has no prefix(), no suffix()+ −
and no leading or trailing whitespace).+ −
+ −
It is often desirable to give the user a special (often default)+ −
choice in addition to the range of numeric values. See+ −
setSpecialValueText() for how to do this with QDoubleSpinBox.+ −
+ −
\sa QSpinBox, QDateTimeEdit, QSlider, {Spin Boxes Example}+ −
*/+ −
+ −
/*!+ −
\fn void QDoubleSpinBox::valueChanged(double d);+ −
+ −
This signal is emitted whenever the spin box's value is changed.+ −
The new value is passed in \a d.+ −
*/+ −
+ −
/*!+ −
\fn void QDoubleSpinBox::valueChanged(const QString &text);+ −
+ −
\overload+ −
+ −
The new value is passed literally in \a text with no prefix() or+ −
suffix().+ −
*/+ −
+ −
/*!+ −
Constructs a spin box with 0.0 as minimum value and 99.99 as maximum value,+ −
a step value of 1.0 and a precision of 2 decimal places. The value is+ −
initially set to 0.00. The spin box has the given \a parent.+ −
+ −
\sa setMinimum(), setMaximum(), setSingleStep()+ −
*/+ −
QDoubleSpinBox::QDoubleSpinBox(QWidget *parent)+ −
: QAbstractSpinBox(*new QDoubleSpinBoxPrivate, parent)+ −
{+ −
Q_D(QDoubleSpinBox);+ −
d->init();+ −
}+ −
+ −
/*!+ −
\property QDoubleSpinBox::value+ −
\brief the value of the spin box+ −
+ −
setValue() will emit valueChanged() if the new value is different+ −
from the old one.+ −
+ −
Note: The value will be rounded so it can be displayed with the+ −
current setting of decimals.+ −
+ −
\sa decimals+ −
*/+ −
double QDoubleSpinBox::value() const+ −
{+ −
Q_D(const QDoubleSpinBox);+ −
+ −
return d->value.toDouble();+ −
}+ −
+ −
void QDoubleSpinBox::setValue(double value)+ −
{+ −
Q_D(QDoubleSpinBox);+ −
QVariant v(d->round(value));+ −
d->setValue(v, EmitIfChanged);+ −
}+ −
/*!+ −
\property QDoubleSpinBox::prefix+ −
\brief the spin box's prefix+ −
+ −
The prefix is prepended to the start of the displayed value.+ −
Typical use is to display a unit of measurement or a currency+ −
symbol. For example:+ −
+ −
\snippet doc/src/snippets/code/src_gui_widgets_qspinbox.cpp 4+ −
+ −
To turn off the prefix display, set this property to an empty+ −
string. The default is no prefix. The prefix is not displayed when+ −
value() == minimum() and specialValueText() is set.+ −
+ −
If no prefix is set, prefix() returns an empty string.+ −
+ −
\sa suffix(), setSuffix(), specialValueText(), setSpecialValueText()+ −
*/+ −
+ −
QString QDoubleSpinBox::prefix() const+ −
{+ −
Q_D(const QDoubleSpinBox);+ −
+ −
return d->prefix;+ −
}+ −
+ −
void QDoubleSpinBox::setPrefix(const QString &prefix)+ −
{+ −
Q_D(QDoubleSpinBox);+ −
+ −
d->prefix = prefix;+ −
d->updateEdit();+ −
}+ −
+ −
/*!+ −
\property QDoubleSpinBox::suffix+ −
\brief the suffix of the spin box+ −
+ −
The suffix is appended to the end of the displayed value. Typical+ −
use is to display a unit of measurement or a currency symbol. For+ −
example:+ −
+ −
\snippet doc/src/snippets/code/src_gui_widgets_qspinbox.cpp 5+ −
+ −
To turn off the suffix display, set this property to an empty+ −
string. The default is no suffix. The suffix is not displayed for+ −
the minimum() if specialValueText() is set.+ −
+ −
If no suffix is set, suffix() returns an empty string.+ −
+ −
\sa prefix(), setPrefix(), specialValueText(), setSpecialValueText()+ −
*/+ −
+ −
QString QDoubleSpinBox::suffix() const+ −
{+ −
Q_D(const QDoubleSpinBox);+ −
+ −
return d->suffix;+ −
}+ −
+ −
void QDoubleSpinBox::setSuffix(const QString &suffix)+ −
{+ −
Q_D(QDoubleSpinBox);+ −
+ −
d->suffix = suffix;+ −
d->updateEdit();+ −
}+ −
+ −
/*!+ −
\property QDoubleSpinBox::cleanText+ −
+ −
\brief the text of the spin box excluding any prefix, suffix,+ −
or leading or trailing whitespace.+ −
+ −
\sa text, QDoubleSpinBox::prefix, QDoubleSpinBox::suffix+ −
*/+ −
+ −
QString QDoubleSpinBox::cleanText() const+ −
{+ −
Q_D(const QDoubleSpinBox);+ −
+ −
return d->stripped(d->edit->displayText());+ −
}+ −
+ −
/*!+ −
\property QDoubleSpinBox::singleStep+ −
\brief the step value+ −
+ −
When the user uses the arrows to change the spin box's value the+ −
value will be incremented/decremented by the amount of the+ −
singleStep. The default value is 1.0. Setting a singleStep value+ −
of less than 0 does nothing.+ −
*/+ −
double QDoubleSpinBox::singleStep() const+ −
{+ −
Q_D(const QDoubleSpinBox);+ −
+ −
return d->singleStep.toDouble();+ −
}+ −
+ −
void QDoubleSpinBox::setSingleStep(double value)+ −
{+ −
Q_D(QDoubleSpinBox);+ −
+ −
if (value >= 0) {+ −
d->singleStep = value;+ −
d->updateEdit();+ −
}+ −
}+ −
+ −
/*!+ −
\property QDoubleSpinBox::minimum+ −
+ −
\brief the minimum value of the spin box+ −
+ −
When setting this property the \l maximum is adjusted+ −
if necessary to ensure that the range remains valid.+ −
+ −
The default minimum value is 0.0.+ −
+ −
Note: The minimum value will be rounded to match the decimals+ −
property.+ −
+ −
\sa decimals, setRange() specialValueText+ −
*/+ −
+ −
double QDoubleSpinBox::minimum() const+ −
{+ −
Q_D(const QDoubleSpinBox);+ −
+ −
return d->minimum.toDouble();+ −
}+ −
+ −
void QDoubleSpinBox::setMinimum(double minimum)+ −
{+ −
Q_D(QDoubleSpinBox);+ −
const QVariant m(d->round(minimum));+ −
d->setRange(m, (d->variantCompare(d->maximum, m) > 0 ? d->maximum : m));+ −
}+ −
+ −
/*!+ −
\property QDoubleSpinBox::maximum+ −
+ −
\brief the maximum value of the spin box+ −
+ −
When setting this property the \l minimum is adjusted+ −
if necessary, to ensure that the range remains valid.+ −
+ −
The default maximum value is 99.99.+ −
+ −
Note: The maximum value will be rounded to match the decimals+ −
property.+ −
+ −
\sa decimals, setRange()+ −
*/+ −
+ −
double QDoubleSpinBox::maximum() const+ −
{+ −
Q_D(const QDoubleSpinBox);+ −
+ −
return d->maximum.toDouble();+ −
}+ −
+ −
void QDoubleSpinBox::setMaximum(double maximum)+ −
{+ −
Q_D(QDoubleSpinBox);+ −
const QVariant m(d->round(maximum));+ −
d->setRange((d->variantCompare(d->minimum, m) < 0 ? d->minimum : m), m);+ −
}+ −
+ −
/*!+ −
Convenience function to set the \a minimum and \a maximum values+ −
with a single function call.+ −
+ −
Note: The maximum and minimum values will be rounded to match the+ −
decimals property.+ −
+ −
\snippet doc/src/snippets/code/src_gui_widgets_qspinbox.cpp 6+ −
is equivalent to:+ −
\snippet doc/src/snippets/code/src_gui_widgets_qspinbox.cpp 7+ −
+ −
\sa minimum maximum+ −
*/+ −
+ −
void QDoubleSpinBox::setRange(double minimum, double maximum)+ −
{+ −
Q_D(QDoubleSpinBox);+ −
d->setRange(QVariant(d->round(minimum)), QVariant(d->round(maximum)));+ −
}+ −
+ −
/*!+ −
\property QDoubleSpinBox::decimals+ −
+ −
\brief the precision of the spin box, in decimals+ −
+ −
Sets how many decimals the spinbox will use for displaying and+ −
interpreting doubles.+ −
+ −
\warning The maximum value for \a decimals is DBL_MAX_10_EXP ++ −
DBL_DIG (ie. 323) because of the limitations of the double type.+ −
+ −
Note: The maximum, minimum and value might change as a result of+ −
changing this property.+ −
*/+ −
+ −
int QDoubleSpinBox::decimals() const+ −
{+ −
Q_D(const QDoubleSpinBox);+ −
+ −
return d->decimals;+ −
}+ −
+ −
void QDoubleSpinBox::setDecimals(int decimals)+ −
{+ −
Q_D(QDoubleSpinBox);+ −
d->decimals = qBound(0, decimals, DBL_MAX_10_EXP + DBL_DIG);+ −
+ −
setRange(minimum(), maximum()); // make sure values are rounded+ −
setValue(value());+ −
}+ −
+ −
/*!+ −
This virtual function is used by the spin box whenever it needs to+ −
display the given \a value. The default implementation returns a string+ −
containing \a value printed using QWidget::locale().toString(\a value,+ −
QLatin1Char('f'), decimals()) and will remove the thousand+ −
separator. Reimplementations may return anything.+ −
+ −
Note: QDoubleSpinBox does not call this function for+ −
specialValueText() and that neither prefix() nor suffix() should+ −
be included in the return value.+ −
+ −
If you reimplement this, you may also need to reimplement+ −
valueFromText().+ −
+ −
\sa valueFromText()+ −
*/+ −
+ −
+ −
QString QDoubleSpinBox::textFromValue(double value) const+ −
{+ −
Q_D(const QDoubleSpinBox);+ −
QString str = locale().toString(value, 'f', d->decimals);+ −
if (qAbs(value) >= 1000.0) {+ −
str.remove(locale().groupSeparator());+ −
}+ −
return str;+ −
}+ −
+ −
/*!+ −
This virtual function is used by the spin box whenever it needs to+ −
interpret \a text entered by the user as a value.+ −
+ −
Subclasses that need to display spin box values in a non-numeric+ −
way need to reimplement this function.+ −
+ −
Note: QDoubleSpinBox handles specialValueText() separately; this+ −
function is only concerned with the other values.+ −
+ −
\sa textFromValue(), validate()+ −
*/+ −
double QDoubleSpinBox::valueFromText(const QString &text) const+ −
{+ −
Q_D(const QDoubleSpinBox);+ −
+ −
QString copy = text;+ −
int pos = d->edit->cursorPosition();+ −
QValidator::State state = QValidator::Acceptable;+ −
return d->validateAndInterpret(copy, pos, state).toDouble();+ −
}+ −
+ −
/*!+ −
\reimp+ −
*/+ −
QValidator::State QDoubleSpinBox::validate(QString &text, int &pos) const+ −
{+ −
Q_D(const QDoubleSpinBox);+ −
+ −
QValidator::State state;+ −
d->validateAndInterpret(text, pos, state);+ −
return state;+ −
}+ −
+ −
+ −
/*!+ −
\reimp+ −
*/+ −
void QDoubleSpinBox::fixup(QString &input) const+ −
{+ −
input.remove(locale().groupSeparator());+ −
}+ −
+ −
// --- QSpinBoxPrivate ---+ −
+ −
/*!+ −
\internal+ −
Constructs a QSpinBoxPrivate object+ −
*/+ −
+ −
QSpinBoxPrivate::QSpinBoxPrivate()+ −
{+ −
minimum = QVariant((int)0);+ −
maximum = QVariant((int)99);+ −
value = minimum;+ −
singleStep = QVariant((int)1);+ −
type = QVariant::Int;+ −
}+ −
+ −
/*!+ −
\internal+ −
\reimp+ −
*/+ −
+ −
void QSpinBoxPrivate::emitSignals(EmitPolicy ep, const QVariant &old)+ −
{+ −
Q_Q(QSpinBox);+ −
if (ep != NeverEmit) {+ −
pendingEmit = false;+ −
if (ep == AlwaysEmit || value != old) {+ −
emit q->valueChanged(edit->displayText());+ −
emit q->valueChanged(value.toInt());+ −
}+ −
}+ −
}+ −
+ −
/*!+ −
\internal+ −
\reimp+ −
*/+ −
+ −
QString QSpinBoxPrivate::textFromValue(const QVariant &value) const+ −
{+ −
Q_Q(const QSpinBox);+ −
return q->textFromValue(value.toInt());+ −
}+ −
/*!+ −
\internal+ −
\reimp+ −
*/+ −
+ −
QVariant QSpinBoxPrivate::valueFromText(const QString &text) const+ −
{+ −
Q_Q(const QSpinBox);+ −
+ −
return QVariant(q->valueFromText(text));+ −
}+ −
+ −
+ −
/*!+ −
\internal Multi purpose function that parses input, sets state to+ −
the appropriate state and returns the value it will be interpreted+ −
as.+ −
*/+ −
+ −
QVariant QSpinBoxPrivate::validateAndInterpret(QString &input, int &pos,+ −
QValidator::State &state) const+ −
{+ −
if (cachedText == input && !input.isEmpty()) {+ −
state = cachedState;+ −
QSBDEBUG() << "cachedText was '" << cachedText << "' state was "+ −
<< state << " and value was " << cachedValue;+ −
+ −
return cachedValue;+ −
}+ −
const int max = maximum.toInt();+ −
const int min = minimum.toInt();+ −
+ −
QString copy = stripped(input, &pos);+ −
QSBDEBUG() << "input" << input << "copy" << copy;+ −
state = QValidator::Acceptable;+ −
int num = min;+ −
+ −
if (max != min && (copy.isEmpty()+ −
|| (min < 0 && copy == QLatin1String("-"))+ −
|| (min >= 0 && copy == QLatin1String("+")))) {+ −
state = QValidator::Intermediate;+ −
QSBDEBUG() << __FILE__ << __LINE__<< "num is set to" << num;+ −
} else if (copy.startsWith(QLatin1Char('-')) && min >= 0) {+ −
state = QValidator::Invalid; // special-case -0 will be interpreted as 0 and thus not be invalid with a range from 0-100+ −
} else {+ −
bool ok = false;+ −
num = locale.toInt(copy, &ok, 10);+ −
if (!ok && copy.contains(locale.groupSeparator()) && (max >= 1000 || min <= -1000)) {+ −
QString copy2 = copy;+ −
copy2.remove(locale.groupSeparator());+ −
num = locale.toInt(copy2, &ok, 10);+ −
}+ −
QSBDEBUG() << __FILE__ << __LINE__<< "num is set to" << num;+ −
if (!ok) {+ −
state = QValidator::Invalid;+ −
} else if (num >= min && num <= max) {+ −
state = QValidator::Acceptable;+ −
} else if (max == min) {+ −
state = QValidator::Invalid;+ −
} else {+ −
if ((num >= 0 && num > max) || (num < 0 && num < min)) {+ −
state = QValidator::Invalid;+ −
QSBDEBUG() << __FILE__ << __LINE__<< "state is set to Invalid";+ −
} else {+ −
state = QValidator::Intermediate;+ −
QSBDEBUG() << __FILE__ << __LINE__<< "state is set to Intermediate";+ −
}+ −
}+ −
}+ −
if (state != QValidator::Acceptable)+ −
num = max > 0 ? min : max;+ −
input = prefix + copy + suffix;+ −
cachedText = input;+ −
cachedState = state;+ −
cachedValue = QVariant((int)num);+ −
+ −
QSBDEBUG() << "cachedText is set to '" << cachedText << "' state is set to "+ −
<< state << " and value is set to " << cachedValue;+ −
return cachedValue;+ −
}+ −
+ −
// --- QDoubleSpinBoxPrivate ---+ −
+ −
/*!+ −
\internal+ −
Constructs a QSpinBoxPrivate object+ −
*/+ −
+ −
QDoubleSpinBoxPrivate::QDoubleSpinBoxPrivate()+ −
{+ −
minimum = QVariant(0.0);+ −
maximum = QVariant(99.99);+ −
value = minimum;+ −
singleStep = QVariant(1.0);+ −
decimals = 2;+ −
type = QVariant::Double;+ −
}+ −
+ −
/*!+ −
\internal+ −
\reimp+ −
*/+ −
+ −
void QDoubleSpinBoxPrivate::emitSignals(EmitPolicy ep, const QVariant &old)+ −
{+ −
Q_Q(QDoubleSpinBox);+ −
if (ep != NeverEmit) {+ −
pendingEmit = false;+ −
if (ep == AlwaysEmit || value != old) {+ −
emit q->valueChanged(edit->displayText());+ −
emit q->valueChanged(value.toDouble());+ −
}+ −
}+ −
}+ −
+ −
+ −
/*!+ −
\internal+ −
\reimp+ −
*/+ −
QVariant QDoubleSpinBoxPrivate::valueFromText(const QString &f) const+ −
{+ −
Q_Q(const QDoubleSpinBox);+ −
return QVariant(q->valueFromText(f));+ −
}+ −
+ −
/*!+ −
\internal+ −
Rounds to a double value that is restricted to decimals.+ −
E.g. // decimals = 2+ −
+ −
round(5.555) => 5.56+ −
*/+ −
+ −
double QDoubleSpinBoxPrivate::round(double value) const+ −
{+ −
return QString::number(value, 'f', decimals).toDouble();+ −
}+ −
+ −
+ −
/*!+ −
\internal Multi purpose function that parses input, sets state to+ −
the appropriate state and returns the value it will be interpreted+ −
as.+ −
*/+ −
+ −
QVariant QDoubleSpinBoxPrivate::validateAndInterpret(QString &input, int &pos,+ −
QValidator::State &state) const+ −
{+ −
if (cachedText == input && !input.isEmpty()) {+ −
state = cachedState;+ −
QSBDEBUG() << "cachedText was '" << cachedText << "' state was "+ −
<< state << " and value was " << cachedValue;+ −
return cachedValue;+ −
}+ −
const double max = maximum.toDouble();+ −
const double min = minimum.toDouble();+ −
+ −
QString copy = stripped(input, &pos);+ −
QSBDEBUG() << "input" << input << "copy" << copy;+ −
int len = copy.size();+ −
double num = min;+ −
const bool plus = max >= 0;+ −
const bool minus = min <= 0;+ −
+ −
switch (len) {+ −
case 0:+ −
state = max != min ? QValidator::Intermediate : QValidator::Invalid;+ −
goto end;+ −
case 1:+ −
if (copy.at(0) == locale.decimalPoint()+ −
|| (plus && copy.at(0) == QLatin1Char('+'))+ −
|| (minus && copy.at(0) == QLatin1Char('-'))) {+ −
state = QValidator::Intermediate;+ −
goto end;+ −
}+ −
break;+ −
case 2:+ −
if (copy.at(1) == locale.decimalPoint()+ −
&& ((plus && copy.at(0) == QLatin1Char('+')) || (minus && copy.at(0) == QLatin1Char('-')))) {+ −
state = QValidator::Intermediate;+ −
goto end;+ −
}+ −
break;+ −
default: break;+ −
}+ −
+ −
if (copy.at(0) == locale.groupSeparator()) {+ −
QSBDEBUG() << __FILE__ << __LINE__<< "state is set to Invalid";+ −
state = QValidator::Invalid;+ −
goto end;+ −
} else if (len > 1) {+ −
const int dec = copy.indexOf(locale.decimalPoint());+ −
if (dec != -1) {+ −
if (dec + 1 < copy.size() && copy.at(dec + 1) == locale.decimalPoint() && pos == dec + 1) {+ −
copy.remove(dec + 1, 1); // typing a delimiter when you are on the delimiter+ −
} // should be treated as typing right arrow+ −
+ −
if (copy.size() - dec > decimals + 1) {+ −
QSBDEBUG() << __FILE__ << __LINE__<< "state is set to Invalid";+ −
state = QValidator::Invalid;+ −
goto end;+ −
}+ −
for (int i=dec + 1; i<copy.size(); ++i) {+ −
if (copy.at(i).isSpace() || copy.at(i) == locale.groupSeparator()) {+ −
QSBDEBUG() << __FILE__ << __LINE__<< "state is set to Invalid";+ −
state = QValidator::Invalid;+ −
goto end;+ −
}+ −
}+ −
} else {+ −
const QChar &last = copy.at(len - 1);+ −
const QChar &secondLast = copy.at(len - 2);+ −
if ((last == locale.groupSeparator() || last.isSpace())+ −
&& (secondLast == locale.groupSeparator() || secondLast.isSpace())) {+ −
state = QValidator::Invalid;+ −
QSBDEBUG() << __FILE__ << __LINE__<< "state is set to Invalid";+ −
goto end;+ −
} else if (last.isSpace() && (!locale.groupSeparator().isSpace() || secondLast.isSpace())) {+ −
state = QValidator::Invalid;+ −
QSBDEBUG() << __FILE__ << __LINE__<< "state is set to Invalid";+ −
goto end;+ −
}+ −
}+ −
}+ −
+ −
{+ −
bool ok = false;+ −
num = locale.toDouble(copy, &ok);+ −
QSBDEBUG() << __FILE__ << __LINE__ << locale << copy << num << ok;+ −
+ −
if (!ok) {+ −
if (locale.groupSeparator().isPrint()) {+ −
if (max < 1000 && min > -1000 && copy.contains(locale.groupSeparator())) {+ −
state = QValidator::Invalid;+ −
QSBDEBUG() << __FILE__ << __LINE__<< "state is set to Invalid";+ −
goto end;+ −
}+ −
+ −
const int len = copy.size();+ −
for (int i=0; i<len- 1; ++i) {+ −
if (copy.at(i) == locale.groupSeparator() && copy.at(i + 1) == locale.groupSeparator()) {+ −
QSBDEBUG() << __FILE__ << __LINE__<< "state is set to Invalid";+ −
state = QValidator::Invalid;+ −
goto end;+ −
}+ −
}+ −
+ −
QString copy2 = copy;+ −
copy2.remove(locale.groupSeparator());+ −
num = locale.toDouble(copy2, &ok);+ −
QSBDEBUG() << locale.groupSeparator() << num << copy2 << ok;+ −
+ −
if (!ok) {+ −
state = QValidator::Invalid;+ −
QSBDEBUG() << __FILE__ << __LINE__<< "state is set to Invalid";+ −
goto end;+ −
}+ −
}+ −
}+ −
+ −
if (!ok) {+ −
state = QValidator::Invalid;+ −
QSBDEBUG() << __FILE__ << __LINE__<< "state is set to Invalid";+ −
} else if (num >= min && num <= max) {+ −
state = QValidator::Acceptable;+ −
QSBDEBUG() << __FILE__ << __LINE__<< "state is set to Acceptable";+ −
} else if (max == min) { // when max and min is the same the only non-Invalid input is max (or min)+ −
state = QValidator::Invalid;+ −
QSBDEBUG() << __FILE__ << __LINE__<< "state is set to Invalid";+ −
} else {+ −
if ((num >= 0 && num > max) || (num < 0 && num < min)) {+ −
state = QValidator::Invalid;+ −
QSBDEBUG() << __FILE__ << __LINE__<< "state is set to Invalid";+ −
} else {+ −
state = QValidator::Intermediate;+ −
QSBDEBUG() << __FILE__ << __LINE__<< "state is set to Intermediate";+ −
}+ −
}+ −
}+ −
+ −
end:+ −
if (state != QValidator::Acceptable) {+ −
num = max > 0 ? min : max;+ −
}+ −
+ −
input = prefix + copy + suffix;+ −
cachedText = input;+ −
cachedState = state;+ −
cachedValue = QVariant(num);+ −
return QVariant(num);+ −
}+ −
+ −
/*+ −
\internal+ −
\reimp+ −
*/+ −
+ −
QString QDoubleSpinBoxPrivate::textFromValue(const QVariant &f) const+ −
{+ −
Q_Q(const QDoubleSpinBox);+ −
return q->textFromValue(f.toDouble());+ −
}+ −
+ −
/*!+ −
\fn void QSpinBox::setLineStep(int step)+ −
+ −
Use setSingleStep() instead.+ −
*/+ −
+ −
/*!+ −
\fn void QSpinBox::setMaxValue(int value)+ −
+ −
Use setMaximum() instead.+ −
*/+ −
+ −
/*!+ −
\fn void QSpinBox::setMinValue(int value)+ −
+ −
Use setMinimum() instead.+ −
*/+ −
+ −
/*!+ −
\fn int QSpinBox::maxValue() const+ −
+ −
Use maximum() instead.+ −
*/+ −
+ −
/*!+ −
\fn int QSpinBox::minValue() const+ −
+ −
Use minimum() instead.+ −
*/+ −
+ −
/*! \reimp */+ −
bool QSpinBox::event(QEvent *event)+ −
{+ −
Q_D(QSpinBox);+ −
if (event->type() == QEvent::StyleChange+ −
#ifdef Q_WS_MAC+ −
|| event->type() == QEvent::MacSizeChange+ −
#endif+ −
)+ −
d->setLayoutItemMargins(QStyle::SE_SpinBoxLayoutItem);+ −
return QAbstractSpinBox::event(event);+ −
}+ −
+ −
QT_END_NAMESPACE+ −
+ −
#endif // QT_NO_SPINBOX+ −