diff options
Diffstat (limited to 'src/gui/widgets/qspinbox.cpp')
-rw-r--r-- | src/gui/widgets/qspinbox.cpp | 1327 |
1 files changed, 0 insertions, 1327 deletions
diff --git a/src/gui/widgets/qspinbox.cpp b/src/gui/widgets/qspinbox.cpp deleted file mode 100644 index 22fd2a9cc4..0000000000 --- a/src/gui/widgets/qspinbox.cpp +++ /dev/null @@ -1,1327 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 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); - } - - // When fiddling with the decimals property, we may lose precision in these properties. - double actualMin; - double actualMax; -}; - - -/*! - \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(), but with the thousand separator - removed. 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(), QLocale::groupSeparator() -*/ - -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(); - - d->cachedSizeHint = QSize(); - updateGeometry(); -} - -/*! - \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); - d->actualMin = minimum; - 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); - d->actualMax = maximum; - 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->actualMin = minimum; - d->actualMax = maximum; - 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(d->actualMin, d->actualMax); // 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(), QLocale::groupSeparator() -*/ - - -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() -{ - actualMin = 0.0; - actualMax = 99.99; - minimum = QVariant(actualMin); - maximum = QVariant(actualMax); - 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 |