src/gui/widgets/qspinbox.cpp
changeset 0 1918ee327afb
child 3 41300fa6a67c
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the QtGui module of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    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 #include <float.h>
       
    54 
       
    55 QT_BEGIN_NAMESPACE
       
    56 
       
    57 //#define QSPINBOX_QSBDEBUG
       
    58 #ifdef QSPINBOX_QSBDEBUG
       
    59 #  define QSBDEBUG qDebug
       
    60 #else
       
    61 #  define QSBDEBUG if (false) qDebug
       
    62 #endif
       
    63 
       
    64 class QSpinBoxPrivate : public QAbstractSpinBoxPrivate
       
    65 {
       
    66     Q_DECLARE_PUBLIC(QSpinBox)
       
    67 public:
       
    68     QSpinBoxPrivate(QWidget *parent = 0);
       
    69     void emitSignals(EmitPolicy ep, const QVariant &);
       
    70 
       
    71     virtual QVariant valueFromText(const QString &n) const;
       
    72     virtual QString textFromValue(const QVariant &n) const;
       
    73     QVariant validateAndInterpret(QString &input, int &pos,
       
    74                                   QValidator::State &state) const;
       
    75     QChar thousand;
       
    76 
       
    77     inline void init() {
       
    78         Q_Q(QSpinBox);
       
    79         q->setInputMethodHints(Qt::ImhDigitsOnly);
       
    80         setLayoutItemMargins(QStyle::SE_SpinBoxLayoutItem);
       
    81     }
       
    82 };
       
    83 
       
    84 class QDoubleSpinBoxPrivate : public QAbstractSpinBoxPrivate
       
    85 {
       
    86     Q_DECLARE_PUBLIC(QDoubleSpinBox)
       
    87 public:
       
    88     QDoubleSpinBoxPrivate(QWidget *parent = 0);
       
    89     void emitSignals(EmitPolicy ep, const QVariant &);
       
    90 
       
    91     virtual QVariant valueFromText(const QString &n) const;
       
    92     virtual QString textFromValue(const QVariant &n) const;
       
    93     QVariant validateAndInterpret(QString &input, int &pos,
       
    94                                   QValidator::State &state) const;
       
    95     double round(double input) const;
       
    96     // variables
       
    97     int decimals;
       
    98     QChar delimiter, thousand;
       
    99 
       
   100     inline void init() {
       
   101         Q_Q(QDoubleSpinBox);
       
   102         q->setInputMethodHints(Qt::ImhFormattedNumbersOnly);
       
   103     }
       
   104 };
       
   105 
       
   106 
       
   107 /*!
       
   108     \class QSpinBox
       
   109     \brief The QSpinBox class provides a spin box widget.
       
   110 
       
   111     \ingroup basicwidgets
       
   112 
       
   113 
       
   114     QSpinBox is designed to handle integers and discrete sets of
       
   115     values (e.g., month names); use QDoubleSpinBox for floating point
       
   116     values.
       
   117 
       
   118     QSpinBox allows the user to choose a value by clicking the up/down
       
   119     buttons or pressing up/down on the keyboard to increase/decrease
       
   120     the value currently displayed. The user can also type the value in
       
   121     manually. The spin box supports integer values but can be extended to
       
   122     use different strings with validate(), textFromValue() and valueFromText().
       
   123 
       
   124     Every time the value changes QSpinBox emits the valueChanged()
       
   125     signals. The current value can be fetched with value() and set
       
   126     with setValue().
       
   127 
       
   128     Clicking the up/down buttons or using the keyboard accelerator's
       
   129     up and down arrows will increase or decrease the current value in
       
   130     steps of size singleStep(). If you want to change this behaviour you
       
   131     can reimplement the virtual function stepBy(). The minimum and
       
   132     maximum value and the step size can be set using one of the
       
   133     constructors, and can be changed later with setMinimum(),
       
   134     setMaximum() and setSingleStep().
       
   135 
       
   136     Most spin boxes are directional, but QSpinBox can also operate as
       
   137     a circular spin box, i.e. if the range is 0-99 and the current
       
   138     value is 99, clicking "up" will give 0 if wrapping() is set to
       
   139     true. Use setWrapping() if you want circular behavior.
       
   140 
       
   141     The displayed value can be prepended and appended with arbitrary
       
   142     strings indicating, for example, currency or the unit of
       
   143     measurement. See setPrefix() and setSuffix(). The text in the spin
       
   144     box is retrieved with text() (which includes any prefix() and
       
   145     suffix()), or with cleanText() (which has no prefix(), no suffix()
       
   146     and no leading or trailing whitespace).
       
   147 
       
   148     It is often desirable to give the user a special (often default)
       
   149     choice in addition to the range of numeric values. See
       
   150     setSpecialValueText() for how to do this with QSpinBox.
       
   151 
       
   152     \table 100%
       
   153     \row \o \inlineimage windowsxp-spinbox.png Screenshot of a Windows XP spin box
       
   154          \o A spin box shown in the \l{Windows XP Style Widget Gallery}{Windows XP widget style}.
       
   155     \row \o \inlineimage plastique-spinbox.png Screenshot of a Plastique spin box
       
   156          \o A spin box shown in the \l{Plastique Style Widget Gallery}{Plastique widget style}.
       
   157     \row \o \inlineimage macintosh-spinbox.png Screenshot of a Macintosh spin box
       
   158          \o A spin box shown in the \l{Macintosh Style Widget Gallery}{Macintosh widget style}.
       
   159     \endtable
       
   160 
       
   161     \section1 Subclassing QSpinBox
       
   162 
       
   163     If using prefix(), suffix(), and specialValueText() don't provide
       
   164     enough control, you subclass QSpinBox and reimplement
       
   165     valueFromText() and textFromValue(). For example, here's the code
       
   166     for a custom spin box that allows the user to enter icon sizes
       
   167     (e.g., "32 x 32"):
       
   168 
       
   169     \snippet examples/widgets/icons/iconsizespinbox.cpp 1
       
   170     \codeline
       
   171     \snippet examples/widgets/icons/iconsizespinbox.cpp 2
       
   172 
       
   173     See the \l{widgets/icons}{Icons} example for the full source
       
   174     code.
       
   175 
       
   176     \sa QDoubleSpinBox, QDateTimeEdit, QSlider, {Spin Boxes Example}
       
   177 */
       
   178 
       
   179 /*!
       
   180     \fn void QSpinBox::valueChanged(int i)
       
   181 
       
   182     This signal is emitted whenever the spin box's value is changed.
       
   183     The new value's integer value is passed in \a i.
       
   184 */
       
   185 
       
   186 /*!
       
   187     \fn void QSpinBox::valueChanged(const QString &text)
       
   188 
       
   189     \overload
       
   190 
       
   191     The new value is passed literally in \a text with no prefix() or
       
   192     suffix().
       
   193 */
       
   194 
       
   195 /*!
       
   196     Constructs a spin box with 0 as minimum value and 99 as maximum value, a
       
   197     step value of 1. The value is initially set to 0. It is parented to \a
       
   198     parent.
       
   199 
       
   200     \sa setMinimum(), setMaximum(), setSingleStep()
       
   201 */
       
   202 
       
   203 QSpinBox::QSpinBox(QWidget *parent)
       
   204     : QAbstractSpinBox(*new QSpinBoxPrivate(parent), parent)
       
   205 {
       
   206     Q_D(QSpinBox);
       
   207     d->init();
       
   208 }
       
   209 
       
   210 #ifdef QT3_SUPPORT
       
   211 /*!
       
   212     Use one of the constructors that doesn't take the \a name
       
   213     argument and then use setObjectName() instead.
       
   214 */
       
   215 QSpinBox::QSpinBox(QWidget *parent, const char *name)
       
   216     : QAbstractSpinBox(*new QSpinBoxPrivate(parent), parent)
       
   217 {
       
   218     Q_D(QSpinBox);
       
   219     setObjectName(QString::fromAscii(name));
       
   220     d->init();
       
   221 }
       
   222 
       
   223 /*!
       
   224     Use one of the constructors that doesn't take the \a name
       
   225     argument and then use setObjectName() instead.
       
   226 */
       
   227 QSpinBox::QSpinBox(int minimum, int maximum, int step, QWidget *parent, const char *name)
       
   228     : QAbstractSpinBox(*new QSpinBoxPrivate(parent), parent)
       
   229 {
       
   230     Q_D(QSpinBox);
       
   231     d->minimum = QVariant(qMin<int>(minimum, maximum));
       
   232     d->maximum = QVariant(qMax<int>(minimum, maximum));
       
   233     d->singleStep = QVariant(step);
       
   234     setObjectName(QString::fromAscii(name));
       
   235     d->init();
       
   236 }
       
   237 
       
   238 #endif
       
   239 
       
   240 /*!
       
   241     \property QSpinBox::value
       
   242     \brief the value of the spin box
       
   243 
       
   244     setValue() will emit valueChanged() if the new value is different
       
   245     from the old one.
       
   246 */
       
   247 
       
   248 int QSpinBox::value() const
       
   249 {
       
   250     Q_D(const QSpinBox);
       
   251     return d->value.toInt();
       
   252 }
       
   253 
       
   254 void QSpinBox::setValue(int value)
       
   255 {
       
   256     Q_D(QSpinBox);
       
   257     d->setValue(QVariant(value), EmitIfChanged);
       
   258 }
       
   259 
       
   260 /*!
       
   261     \property QSpinBox::prefix
       
   262     \brief the spin box's prefix
       
   263 
       
   264     The prefix is prepended to the start of the displayed value.
       
   265     Typical use is to display a unit of measurement or a currency
       
   266     symbol. For example:
       
   267 
       
   268     \snippet doc/src/snippets/code/src_gui_widgets_qspinbox.cpp 0
       
   269 
       
   270     To turn off the prefix display, set this property to an empty
       
   271     string. The default is no prefix. The prefix is not displayed when
       
   272     value() == minimum() and specialValueText() is set.
       
   273 
       
   274     If no prefix is set, prefix() returns an empty string.
       
   275 
       
   276     \sa suffix(), setSuffix(), specialValueText(), setSpecialValueText()
       
   277 */
       
   278 
       
   279 QString QSpinBox::prefix() const
       
   280 {
       
   281     Q_D(const QSpinBox);
       
   282     return d->prefix;
       
   283 }
       
   284 
       
   285 void QSpinBox::setPrefix(const QString &prefix)
       
   286 {
       
   287     Q_D(QSpinBox);
       
   288 
       
   289     d->prefix = prefix;
       
   290     d->updateEdit();
       
   291 
       
   292     d->cachedSizeHint = QSize();
       
   293     updateGeometry();
       
   294 }
       
   295 
       
   296 /*!
       
   297     \property QSpinBox::suffix
       
   298     \brief the suffix of the spin box
       
   299 
       
   300     The suffix is appended to the end of the displayed value. Typical
       
   301     use is to display a unit of measurement or a currency symbol. For
       
   302     example:
       
   303 
       
   304     \snippet doc/src/snippets/code/src_gui_widgets_qspinbox.cpp 1
       
   305 
       
   306     To turn off the suffix display, set this property to an empty
       
   307     string. The default is no suffix. The suffix is not displayed for
       
   308     the minimum() if specialValueText() is set.
       
   309 
       
   310     If no suffix is set, suffix() returns an empty string.
       
   311 
       
   312     \sa prefix(), setPrefix(), specialValueText(), setSpecialValueText()
       
   313 */
       
   314 
       
   315 QString QSpinBox::suffix() const
       
   316 {
       
   317     Q_D(const QSpinBox);
       
   318 
       
   319     return d->suffix;
       
   320 }
       
   321 
       
   322 void QSpinBox::setSuffix(const QString &suffix)
       
   323 {
       
   324     Q_D(QSpinBox);
       
   325 
       
   326     d->suffix = suffix;
       
   327     d->updateEdit();
       
   328 
       
   329     d->cachedSizeHint = QSize();
       
   330     updateGeometry();
       
   331 }
       
   332 
       
   333 /*!
       
   334     \property QSpinBox::cleanText
       
   335 
       
   336     \brief the text of the spin box excluding any prefix, suffix,
       
   337     or leading or trailing whitespace.
       
   338 
       
   339     \sa text, QSpinBox::prefix, QSpinBox::suffix
       
   340 */
       
   341 
       
   342 QString QSpinBox::cleanText() const
       
   343 {
       
   344     Q_D(const QSpinBox);
       
   345 
       
   346     return d->stripped(d->edit->displayText());
       
   347 }
       
   348 
       
   349 
       
   350 /*!
       
   351     \property QSpinBox::singleStep
       
   352     \brief the step value
       
   353 
       
   354     When the user uses the arrows to change the spin box's value the
       
   355     value will be incremented/decremented by the amount of the
       
   356     singleStep. The default value is 1. Setting a singleStep value of
       
   357     less than 0 does nothing.
       
   358 */
       
   359 
       
   360 int QSpinBox::singleStep() const
       
   361 {
       
   362     Q_D(const QSpinBox);
       
   363 
       
   364     return d->singleStep.toInt();
       
   365 }
       
   366 
       
   367 void QSpinBox::setSingleStep(int value)
       
   368 {
       
   369     Q_D(QSpinBox);
       
   370     if (value >= 0) {
       
   371         d->singleStep = QVariant(value);
       
   372         d->updateEdit();
       
   373     }
       
   374 }
       
   375 
       
   376 /*!
       
   377     \property QSpinBox::minimum
       
   378 
       
   379     \brief the minimum value of the spin box
       
   380 
       
   381     When setting this property the \l maximum is adjusted
       
   382     if necessary to ensure that the range remains valid.
       
   383 
       
   384     The default minimum value is 0.
       
   385 
       
   386     \sa setRange()  specialValueText
       
   387 */
       
   388 
       
   389 int QSpinBox::minimum() const
       
   390 {
       
   391     Q_D(const QSpinBox);
       
   392 
       
   393     return d->minimum.toInt();
       
   394 }
       
   395 
       
   396 void QSpinBox::setMinimum(int minimum)
       
   397 {
       
   398     Q_D(QSpinBox);
       
   399     const QVariant m(minimum);
       
   400     d->setRange(m, (d->variantCompare(d->maximum, m) > 0 ? d->maximum : m));
       
   401 }
       
   402 
       
   403 /*!
       
   404     \property QSpinBox::maximum
       
   405 
       
   406     \brief the maximum value of the spin box
       
   407 
       
   408     When setting this property the \l minimum is adjusted
       
   409     if necessary, to ensure that the range remains valid.
       
   410 
       
   411     The default maximum value is 99.
       
   412 
       
   413     \sa setRange() specialValueText
       
   414 
       
   415 */
       
   416 
       
   417 int QSpinBox::maximum() const
       
   418 {
       
   419     Q_D(const QSpinBox);
       
   420 
       
   421     return d->maximum.toInt();
       
   422 }
       
   423 
       
   424 void QSpinBox::setMaximum(int maximum)
       
   425 {
       
   426     Q_D(QSpinBox);
       
   427     const QVariant m(maximum);
       
   428     d->setRange((d->variantCompare(d->minimum, m) < 0 ? d->minimum : m), m);
       
   429 }
       
   430 
       
   431 /*!
       
   432     Convenience function to set the \a minimum, and \a maximum values
       
   433     with a single function call.
       
   434 
       
   435     \snippet doc/src/snippets/code/src_gui_widgets_qspinbox.cpp 2
       
   436     is equivalent to:
       
   437     \snippet doc/src/snippets/code/src_gui_widgets_qspinbox.cpp 3
       
   438 
       
   439     \sa minimum maximum
       
   440 */
       
   441 
       
   442 void QSpinBox::setRange(int minimum, int maximum)
       
   443 {
       
   444     Q_D(QSpinBox);
       
   445     d->setRange(QVariant(minimum), QVariant(maximum));
       
   446 }
       
   447 
       
   448 /*!
       
   449     This virtual function is used by the spin box whenever it needs
       
   450     to display the given \a value. The default implementation returns
       
   451     a string containing \a value printed in the standard way using
       
   452     QWidget::locale().toString(). Reimplementations may return anything. (See
       
   453     the example in the detailed description.)
       
   454 
       
   455     Note: QSpinBox does not call this function for specialValueText()
       
   456     and that neither prefix() nor suffix() should be included in the
       
   457     return value.
       
   458 
       
   459     If you reimplement this, you may also need to reimplement
       
   460     valueFromText() and validate()
       
   461 
       
   462     \sa valueFromText(), validate()
       
   463 */
       
   464 
       
   465 QString QSpinBox::textFromValue(int value) const
       
   466 {
       
   467     Q_D(const QSpinBox);
       
   468     QString str = locale().toString(value);
       
   469     if (qAbs(value) >= 1000 || value == INT_MIN) {
       
   470         str.remove(d->thousand);
       
   471     }
       
   472 
       
   473     return str;
       
   474 }
       
   475 
       
   476 /*!
       
   477     \fn int QSpinBox::valueFromText(const QString &text) const
       
   478 
       
   479     This virtual function is used by the spin box whenever it needs to
       
   480     interpret \a text entered by the user as a value.
       
   481 
       
   482     Subclasses that need to display spin box values in a non-numeric
       
   483     way need to reimplement this function.
       
   484 
       
   485     Note: QSpinBox handles specialValueText() separately; this
       
   486     function is only concerned with the other values.
       
   487 
       
   488     \sa textFromValue(), validate()
       
   489 */
       
   490 
       
   491 int QSpinBox::valueFromText(const QString &text) const
       
   492 {
       
   493     Q_D(const QSpinBox);
       
   494 
       
   495     QString copy = text;
       
   496     int pos = d->edit->cursorPosition();
       
   497     QValidator::State state = QValidator::Acceptable;
       
   498     return d->validateAndInterpret(copy, pos, state).toInt();
       
   499 }
       
   500 
       
   501 /*!
       
   502   \reimp
       
   503 */
       
   504 QValidator::State QSpinBox::validate(QString &text, int &pos) const
       
   505 {
       
   506     Q_D(const QSpinBox);
       
   507 
       
   508     QValidator::State state;
       
   509     d->validateAndInterpret(text, pos, state);
       
   510     return state;
       
   511 }
       
   512 
       
   513 
       
   514 /*!
       
   515   \reimp
       
   516 */
       
   517 void QSpinBox::fixup(QString &input) const
       
   518 {
       
   519     Q_D(const QSpinBox);
       
   520 
       
   521     input.remove(d->thousand);
       
   522 }
       
   523 
       
   524 
       
   525 // --- QDoubleSpinBox ---
       
   526 
       
   527 /*!
       
   528     \class QDoubleSpinBox
       
   529     \brief The QDoubleSpinBox class provides a spin box widget that
       
   530     takes doubles.
       
   531 
       
   532     \ingroup basicwidgets
       
   533 
       
   534 
       
   535     QDoubleSpinBox allows the user to choose a value by clicking the
       
   536     up and down buttons or by pressing Up or Down on the keyboard to
       
   537     increase or decrease the value currently displayed. The user can
       
   538     also type the value in manually. The spin box supports double
       
   539     values but can be extended to use different strings with
       
   540     validate(), textFromValue() and valueFromText().
       
   541 
       
   542     Every time the value changes QDoubleSpinBox emits the
       
   543     valueChanged() signal. The current value can be fetched with
       
   544     value() and set with setValue().
       
   545 
       
   546     Note: QDoubleSpinBox will round numbers so they can be displayed
       
   547     with the current precision. In a QDoubleSpinBox with decimals set
       
   548     to 2, calling setValue(2.555) will cause value() to return 2.56.
       
   549 
       
   550     Clicking the up and down buttons or using the keyboard accelerator's
       
   551     Up and Down arrows will increase or decrease the current value in
       
   552     steps of size singleStep(). If you want to change this behavior you
       
   553     can reimplement the virtual function stepBy(). The minimum and
       
   554     maximum value and the step size can be set using one of the
       
   555     constructors, and can be changed later with setMinimum(),
       
   556     setMaximum() and setSingleStep(). The spinbox has a default
       
   557     precision of 2 decimal places but this can be changed using
       
   558     setDecimals().
       
   559 
       
   560     Most spin boxes are directional, but QDoubleSpinBox can also
       
   561     operate as a circular spin box, i.e. if the range is 0.0-99.9 and
       
   562     the current value is 99.9, clicking "up" will give 0 if wrapping()
       
   563     is set to true. Use setWrapping() if you want circular behavior.
       
   564 
       
   565     The displayed value can be prepended and appended with arbitrary
       
   566     strings indicating, for example, currency or the unit of
       
   567     measurement. See setPrefix() and setSuffix(). The text in the spin
       
   568     box is retrieved with text() (which includes any prefix() and
       
   569     suffix()), or with cleanText() (which has no prefix(), no suffix()
       
   570     and no leading or trailing whitespace).
       
   571 
       
   572     It is often desirable to give the user a special (often default)
       
   573     choice in addition to the range of numeric values. See
       
   574     setSpecialValueText() for how to do this with QDoubleSpinBox.
       
   575 
       
   576     \sa QSpinBox, QDateTimeEdit, QSlider, {Spin Boxes Example}
       
   577 */
       
   578 
       
   579 /*!
       
   580     \fn void QDoubleSpinBox::valueChanged(double d);
       
   581 
       
   582     This signal is emitted whenever the spin box's value is changed.
       
   583     The new value is passed in \a d.
       
   584 */
       
   585 
       
   586 /*!
       
   587     \fn void QDoubleSpinBox::valueChanged(const QString &text);
       
   588 
       
   589     \overload
       
   590 
       
   591     The new value is passed literally in \a text with no prefix() or
       
   592     suffix().
       
   593 */
       
   594 
       
   595 /*!
       
   596     Constructs a spin box with 0.0 as minimum value and 99.99 as maximum value,
       
   597     a step value of 1.0 and a precision of 2 decimal places. The value is
       
   598     initially set to 0.00. The spin box has the given \a parent.
       
   599 
       
   600     \sa setMinimum(), setMaximum(), setSingleStep()
       
   601 */
       
   602 QDoubleSpinBox::QDoubleSpinBox(QWidget *parent)
       
   603     : QAbstractSpinBox(*new QDoubleSpinBoxPrivate(parent), parent)
       
   604 {
       
   605     Q_D(QDoubleSpinBox);
       
   606     d->init();
       
   607 }
       
   608 
       
   609 /*!
       
   610     \property QDoubleSpinBox::value
       
   611     \brief the value of the spin box
       
   612 
       
   613     setValue() will emit valueChanged() if the new value is different
       
   614     from the old one.
       
   615 
       
   616     Note: The value will be rounded so it can be displayed with the
       
   617     current setting of decimals.
       
   618 
       
   619     \sa decimals
       
   620 */
       
   621 double QDoubleSpinBox::value() const
       
   622 {
       
   623     Q_D(const QDoubleSpinBox);
       
   624 
       
   625     return d->value.toDouble();
       
   626 }
       
   627 
       
   628 void QDoubleSpinBox::setValue(double value)
       
   629 {
       
   630     Q_D(QDoubleSpinBox);
       
   631     QVariant v(d->round(value));
       
   632     d->setValue(v, EmitIfChanged);
       
   633 }
       
   634 /*!
       
   635     \property QDoubleSpinBox::prefix
       
   636     \brief the spin box's prefix
       
   637 
       
   638     The prefix is prepended to the start of the displayed value.
       
   639     Typical use is to display a unit of measurement or a currency
       
   640     symbol. For example:
       
   641 
       
   642     \snippet doc/src/snippets/code/src_gui_widgets_qspinbox.cpp 4
       
   643 
       
   644     To turn off the prefix display, set this property to an empty
       
   645     string. The default is no prefix. The prefix is not displayed when
       
   646     value() == minimum() and specialValueText() is set.
       
   647 
       
   648     If no prefix is set, prefix() returns an empty string.
       
   649 
       
   650     \sa suffix(), setSuffix(), specialValueText(), setSpecialValueText()
       
   651 */
       
   652 
       
   653 QString QDoubleSpinBox::prefix() const
       
   654 {
       
   655     Q_D(const QDoubleSpinBox);
       
   656 
       
   657     return d->prefix;
       
   658 }
       
   659 
       
   660 void QDoubleSpinBox::setPrefix(const QString &prefix)
       
   661 {
       
   662     Q_D(QDoubleSpinBox);
       
   663 
       
   664     d->prefix = prefix;
       
   665     d->updateEdit();
       
   666 }
       
   667 
       
   668 /*!
       
   669     \property QDoubleSpinBox::suffix
       
   670     \brief the suffix of the spin box
       
   671 
       
   672     The suffix is appended to the end of the displayed value. Typical
       
   673     use is to display a unit of measurement or a currency symbol. For
       
   674     example:
       
   675 
       
   676     \snippet doc/src/snippets/code/src_gui_widgets_qspinbox.cpp 5
       
   677 
       
   678     To turn off the suffix display, set this property to an empty
       
   679     string. The default is no suffix. The suffix is not displayed for
       
   680     the minimum() if specialValueText() is set.
       
   681 
       
   682     If no suffix is set, suffix() returns an empty string.
       
   683 
       
   684     \sa prefix(), setPrefix(), specialValueText(), setSpecialValueText()
       
   685 */
       
   686 
       
   687 QString QDoubleSpinBox::suffix() const
       
   688 {
       
   689     Q_D(const QDoubleSpinBox);
       
   690 
       
   691     return d->suffix;
       
   692 }
       
   693 
       
   694 void QDoubleSpinBox::setSuffix(const QString &suffix)
       
   695 {
       
   696     Q_D(QDoubleSpinBox);
       
   697 
       
   698     d->suffix = suffix;
       
   699     d->updateEdit();
       
   700 }
       
   701 
       
   702 /*!
       
   703     \property QDoubleSpinBox::cleanText
       
   704 
       
   705     \brief the text of the spin box excluding any prefix, suffix,
       
   706     or leading or trailing whitespace.
       
   707 
       
   708     \sa text, QDoubleSpinBox::prefix, QDoubleSpinBox::suffix
       
   709 */
       
   710 
       
   711 QString QDoubleSpinBox::cleanText() const
       
   712 {
       
   713     Q_D(const QDoubleSpinBox);
       
   714 
       
   715     return d->stripped(d->edit->displayText());
       
   716 }
       
   717 
       
   718 /*!
       
   719     \property QDoubleSpinBox::singleStep
       
   720     \brief the step value
       
   721 
       
   722     When the user uses the arrows to change the spin box's value the
       
   723     value will be incremented/decremented by the amount of the
       
   724     singleStep. The default value is 1.0. Setting a singleStep value
       
   725     of less than 0 does nothing.
       
   726 */
       
   727 double QDoubleSpinBox::singleStep() const
       
   728 {
       
   729     Q_D(const QDoubleSpinBox);
       
   730 
       
   731     return d->singleStep.toDouble();
       
   732 }
       
   733 
       
   734 void QDoubleSpinBox::setSingleStep(double value)
       
   735 {
       
   736     Q_D(QDoubleSpinBox);
       
   737 
       
   738     if (value >= 0) {
       
   739         d->singleStep = value;
       
   740         d->updateEdit();
       
   741     }
       
   742 }
       
   743 
       
   744 /*!
       
   745     \property QDoubleSpinBox::minimum
       
   746 
       
   747     \brief the minimum value of the spin box
       
   748 
       
   749     When setting this property the \l maximum is adjusted
       
   750     if necessary to ensure that the range remains valid.
       
   751 
       
   752     The default minimum value is 0.0.
       
   753 
       
   754     Note: The minimum value will be rounded to match the decimals
       
   755     property.
       
   756 
       
   757     \sa decimals, setRange() specialValueText
       
   758 */
       
   759 
       
   760 double QDoubleSpinBox::minimum() const
       
   761 {
       
   762     Q_D(const QDoubleSpinBox);
       
   763 
       
   764     return d->minimum.toDouble();
       
   765 }
       
   766 
       
   767 void QDoubleSpinBox::setMinimum(double minimum)
       
   768 {
       
   769     Q_D(QDoubleSpinBox);
       
   770     const QVariant m(d->round(minimum));
       
   771     d->setRange(m, (d->variantCompare(d->maximum, m) > 0 ? d->maximum : m));
       
   772 }
       
   773 
       
   774 /*!
       
   775     \property QDoubleSpinBox::maximum
       
   776 
       
   777     \brief the maximum value of the spin box
       
   778 
       
   779     When setting this property the \l minimum is adjusted
       
   780     if necessary, to ensure that the range remains valid.
       
   781 
       
   782     The default maximum value is 99.99.
       
   783 
       
   784     Note: The maximum value will be rounded to match the decimals
       
   785     property.
       
   786 
       
   787     \sa decimals, setRange()
       
   788 */
       
   789 
       
   790 double QDoubleSpinBox::maximum() const
       
   791 {
       
   792     Q_D(const QDoubleSpinBox);
       
   793 
       
   794     return d->maximum.toDouble();
       
   795 }
       
   796 
       
   797 void QDoubleSpinBox::setMaximum(double maximum)
       
   798 {
       
   799     Q_D(QDoubleSpinBox);
       
   800     const QVariant m(d->round(maximum));
       
   801     d->setRange((d->variantCompare(d->minimum, m) < 0 ? d->minimum : m), m);
       
   802 }
       
   803 
       
   804 /*!
       
   805     Convenience function to set the \a minimum and \a maximum values
       
   806     with a single function call.
       
   807 
       
   808     Note: The maximum and minimum values will be rounded to match the
       
   809     decimals property.
       
   810 
       
   811     \snippet doc/src/snippets/code/src_gui_widgets_qspinbox.cpp 6
       
   812     is equivalent to:
       
   813     \snippet doc/src/snippets/code/src_gui_widgets_qspinbox.cpp 7
       
   814 
       
   815     \sa minimum maximum
       
   816 */
       
   817 
       
   818 void QDoubleSpinBox::setRange(double minimum, double maximum)
       
   819 {
       
   820     Q_D(QDoubleSpinBox);
       
   821     d->setRange(QVariant(d->round(minimum)), QVariant(d->round(maximum)));
       
   822 }
       
   823 
       
   824 /*!
       
   825      \property QDoubleSpinBox::decimals
       
   826 
       
   827      \brief the precision of the spin box, in decimals
       
   828 
       
   829      Sets how many decimals the spinbox will use for displaying and
       
   830      interpreting doubles.
       
   831 
       
   832      \warning The maximum value for \a decimals is DBL_MAX_10_EXP +
       
   833      DBL_DIG (ie. 323) because of the limitations of the double type.
       
   834 
       
   835      Note: The maximum, minimum and value might change as a result of
       
   836      changing this property.
       
   837 */
       
   838 
       
   839 int QDoubleSpinBox::decimals() const
       
   840 {
       
   841     Q_D(const QDoubleSpinBox);
       
   842 
       
   843     return d->decimals;
       
   844 }
       
   845 
       
   846 void QDoubleSpinBox::setDecimals(int decimals)
       
   847 {
       
   848     Q_D(QDoubleSpinBox);
       
   849     d->decimals = qBound(0, decimals, DBL_MAX_10_EXP + DBL_DIG);
       
   850 
       
   851     setRange(minimum(), maximum()); // make sure values are rounded
       
   852     setValue(value());
       
   853 }
       
   854 
       
   855 /*!
       
   856     This virtual function is used by the spin box whenever it needs to
       
   857     display the given \a value. The default implementation returns a string
       
   858     containing \a value printed using QWidget::locale().toString(\a value,
       
   859     QLatin1Char('f'), decimals()) and will remove the thousand
       
   860     separator. Reimplementations may return anything.
       
   861 
       
   862     Note: QDoubleSpinBox does not call this function for
       
   863     specialValueText() and that neither prefix() nor suffix() should
       
   864     be included in the return value.
       
   865 
       
   866     If you reimplement this, you may also need to reimplement
       
   867     valueFromText().
       
   868 
       
   869     \sa valueFromText()
       
   870 */
       
   871 
       
   872 
       
   873 QString QDoubleSpinBox::textFromValue(double value) const
       
   874 {
       
   875     Q_D(const QDoubleSpinBox);
       
   876     QString str = locale().toString(value, 'f', d->decimals);
       
   877     if (qAbs(value) >= 1000.0) {
       
   878         str.remove(d->thousand);
       
   879     }
       
   880     return str;
       
   881 }
       
   882 
       
   883 /*!
       
   884     This virtual function is used by the spin box whenever it needs to
       
   885     interpret \a text entered by the user as a value.
       
   886 
       
   887     Subclasses that need to display spin box values in a non-numeric
       
   888     way need to reimplement this function.
       
   889 
       
   890     Note: QDoubleSpinBox handles specialValueText() separately; this
       
   891     function is only concerned with the other values.
       
   892 
       
   893     \sa textFromValue(), validate()
       
   894 */
       
   895 double QDoubleSpinBox::valueFromText(const QString &text) const
       
   896 {
       
   897     Q_D(const QDoubleSpinBox);
       
   898 
       
   899     QString copy = text;
       
   900     int pos = d->edit->cursorPosition();
       
   901     QValidator::State state = QValidator::Acceptable;
       
   902     return d->validateAndInterpret(copy, pos, state).toDouble();
       
   903 }
       
   904 
       
   905 /*!
       
   906   \reimp
       
   907 */
       
   908 QValidator::State QDoubleSpinBox::validate(QString &text, int &pos) const
       
   909 {
       
   910     Q_D(const QDoubleSpinBox);
       
   911 
       
   912     QValidator::State state;
       
   913     d->validateAndInterpret(text, pos, state);
       
   914     return state;
       
   915 }
       
   916 
       
   917 
       
   918 /*!
       
   919   \reimp
       
   920 */
       
   921 void QDoubleSpinBox::fixup(QString &input) const
       
   922 {
       
   923     Q_D(const QDoubleSpinBox);
       
   924 
       
   925     input.remove(d->thousand);
       
   926 }
       
   927 
       
   928 // --- QSpinBoxPrivate ---
       
   929 
       
   930 /*!
       
   931     \internal
       
   932     Constructs a QSpinBoxPrivate object
       
   933 */
       
   934 
       
   935 QSpinBoxPrivate::QSpinBoxPrivate(QWidget *parent)
       
   936 {
       
   937     minimum = QVariant((int)0);
       
   938     maximum = QVariant((int)99);
       
   939     value = minimum;
       
   940     singleStep = QVariant((int)1);
       
   941     type = QVariant::Int;
       
   942     const QString str = (parent ? parent->locale() : QLocale()).toString(4567);
       
   943     if (str.size() == 5) {
       
   944         thousand = QChar(str.at(1));
       
   945     }
       
   946 
       
   947 }
       
   948 
       
   949 /*!
       
   950     \internal
       
   951     \reimp
       
   952 */
       
   953 
       
   954 void QSpinBoxPrivate::emitSignals(EmitPolicy ep, const QVariant &old)
       
   955 {
       
   956     Q_Q(QSpinBox);
       
   957     if (ep != NeverEmit) {
       
   958         pendingEmit = false;
       
   959         if (ep == AlwaysEmit || value != old) {
       
   960             emit q->valueChanged(edit->displayText());
       
   961             emit q->valueChanged(value.toInt());
       
   962         }
       
   963     }
       
   964 }
       
   965 
       
   966 /*!
       
   967     \internal
       
   968     \reimp
       
   969 */
       
   970 
       
   971 QString QSpinBoxPrivate::textFromValue(const QVariant &value) const
       
   972 {
       
   973     Q_Q(const QSpinBox);
       
   974     return q->textFromValue(value.toInt());
       
   975 }
       
   976 /*!
       
   977     \internal
       
   978     \reimp
       
   979 */
       
   980 
       
   981 QVariant QSpinBoxPrivate::valueFromText(const QString &text) const
       
   982 {
       
   983     Q_Q(const QSpinBox);
       
   984 
       
   985     return QVariant(q->valueFromText(text));
       
   986 }
       
   987 
       
   988 
       
   989 /*!
       
   990     \internal Multi purpose function that parses input, sets state to
       
   991     the appropriate state and returns the value it will be interpreted
       
   992     as.
       
   993 */
       
   994 
       
   995 QVariant QSpinBoxPrivate::validateAndInterpret(QString &input, int &pos,
       
   996                                                QValidator::State &state) const
       
   997 {
       
   998     if (cachedText == input && !input.isEmpty()) {
       
   999         state = cachedState;
       
  1000         QSBDEBUG() << "cachedText was '" << cachedText << "' state was "
       
  1001                    << state << " and value was " << cachedValue;
       
  1002 
       
  1003         return cachedValue;
       
  1004     }
       
  1005     const int max = maximum.toInt();
       
  1006     const int min = minimum.toInt();
       
  1007 
       
  1008     QString copy = stripped(input, &pos);
       
  1009     QSBDEBUG() << "input" << input << "copy" << copy;
       
  1010     state = QValidator::Acceptable;
       
  1011     int num = min;
       
  1012 
       
  1013     if (max != min && (copy.isEmpty()
       
  1014                        || (min < 0 && copy == QLatin1String("-"))
       
  1015                        || (min >= 0 && copy == QLatin1String("+")))) {
       
  1016         state = QValidator::Intermediate;
       
  1017         QSBDEBUG() << __FILE__ << __LINE__<< "num is set to" << num;
       
  1018     } else if (copy.startsWith(QLatin1Char('-')) && min >= 0) {
       
  1019         state = QValidator::Invalid; // special-case -0 will be interpreted as 0 and thus not be invalid with a range from 0-100
       
  1020     } else {
       
  1021         bool ok = false;
       
  1022         bool removedThousand = false;
       
  1023         num = locale.toInt(copy, &ok, 10);
       
  1024         if (!ok && copy.contains(thousand) && (max >= 1000 || min <= -1000)) {
       
  1025             const int s = copy.size();
       
  1026             copy.remove(thousand);
       
  1027             pos = qMax(0, pos - (s - copy.size()));
       
  1028             removedThousand = true;
       
  1029             num = locale.toInt(copy, &ok, 10);
       
  1030         }
       
  1031         QSBDEBUG() << __FILE__ << __LINE__<< "num is set to" << num;
       
  1032         if (!ok) {
       
  1033             state = QValidator::Invalid;
       
  1034         } else if (num >= min && num <= max) {
       
  1035             state = removedThousand ? QValidator::Intermediate : QValidator::Acceptable;
       
  1036         } else if (max == min) {
       
  1037             state = QValidator::Invalid;
       
  1038         } else {
       
  1039             if ((num >= 0 && num > max) || (num < 0 && num < min)) {
       
  1040                 state = QValidator::Invalid;
       
  1041                 QSBDEBUG() << __FILE__ << __LINE__<< "state is set to Invalid";
       
  1042             } else {
       
  1043                 state = QValidator::Intermediate;
       
  1044                 QSBDEBUG() << __FILE__ << __LINE__<< "state is set to Intermediate";
       
  1045             }
       
  1046         }
       
  1047     }
       
  1048     if (state != QValidator::Acceptable)
       
  1049         num = max > 0 ? min : max;
       
  1050     input = prefix + copy + suffix;
       
  1051     cachedText = input;
       
  1052     cachedState = state;
       
  1053     cachedValue = QVariant((int)num);
       
  1054 
       
  1055     QSBDEBUG() << "cachedText is set to '" << cachedText << "' state is set to "
       
  1056                << state << " and value is set to " << cachedValue;
       
  1057     return cachedValue;
       
  1058 }
       
  1059 
       
  1060 // --- QDoubleSpinBoxPrivate ---
       
  1061 
       
  1062 /*!
       
  1063     \internal
       
  1064     Constructs a QSpinBoxPrivate object
       
  1065 */
       
  1066 
       
  1067 QDoubleSpinBoxPrivate::QDoubleSpinBoxPrivate(QWidget *parent)
       
  1068 {
       
  1069     minimum = QVariant(0.0);
       
  1070     maximum = QVariant(99.99);
       
  1071     value = minimum;
       
  1072     singleStep = QVariant(1.0);
       
  1073     decimals = 2;
       
  1074     type = QVariant::Double;
       
  1075     const QString str = (parent ? parent->locale() : QLocale()).toString(4567.1);
       
  1076     if (str.size() == 6) {
       
  1077         delimiter = str.at(4);
       
  1078         thousand = QChar((ushort)0);
       
  1079     } else if (str.size() == 7) {
       
  1080         thousand = str.at(1);
       
  1081         delimiter = str.at(5);
       
  1082     }
       
  1083     Q_ASSERT(!delimiter.isNull());
       
  1084 }
       
  1085 
       
  1086 /*!
       
  1087     \internal
       
  1088     \reimp
       
  1089 */
       
  1090 
       
  1091 void QDoubleSpinBoxPrivate::emitSignals(EmitPolicy ep, const QVariant &old)
       
  1092 {
       
  1093     Q_Q(QDoubleSpinBox);
       
  1094     if (ep != NeverEmit) {
       
  1095         pendingEmit = false;
       
  1096         if (ep == AlwaysEmit || value != old) {
       
  1097             emit q->valueChanged(edit->displayText());
       
  1098             emit q->valueChanged(value.toDouble());
       
  1099         }
       
  1100     }
       
  1101 }
       
  1102 
       
  1103 
       
  1104 /*!
       
  1105     \internal
       
  1106     \reimp
       
  1107 */
       
  1108 QVariant QDoubleSpinBoxPrivate::valueFromText(const QString &f) const
       
  1109 {
       
  1110     Q_Q(const QDoubleSpinBox);
       
  1111     return QVariant(q->valueFromText(f));
       
  1112 }
       
  1113 
       
  1114 /*!
       
  1115     \internal
       
  1116     Rounds to a double value that is restricted to decimals.
       
  1117     E.g. // decimals = 2
       
  1118 
       
  1119     round(5.555) => 5.56
       
  1120     */
       
  1121 
       
  1122 double QDoubleSpinBoxPrivate::round(double value) const
       
  1123 {
       
  1124     return QString::number(value, 'f', decimals).toDouble();
       
  1125 }
       
  1126 
       
  1127 
       
  1128 /*!
       
  1129     \internal Multi purpose function that parses input, sets state to
       
  1130     the appropriate state and returns the value it will be interpreted
       
  1131     as.
       
  1132 */
       
  1133 
       
  1134 QVariant QDoubleSpinBoxPrivate::validateAndInterpret(QString &input, int &pos,
       
  1135                                                      QValidator::State &state) const
       
  1136 {
       
  1137     if (cachedText == input && !input.isEmpty()) {
       
  1138         state = cachedState;
       
  1139         QSBDEBUG() << "cachedText was '" << cachedText << "' state was "
       
  1140                    << state << " and value was " << cachedValue;
       
  1141         return cachedValue;
       
  1142     }
       
  1143     const double max = maximum.toDouble();
       
  1144     const double min = minimum.toDouble();
       
  1145 
       
  1146     QString copy = stripped(input, &pos);
       
  1147     QSBDEBUG() << "input" << input << "copy" << copy;
       
  1148     int len = copy.size();
       
  1149     double num = min;
       
  1150     const bool plus = max >= 0;
       
  1151     const bool minus = min <= 0;
       
  1152 
       
  1153     switch (len) {
       
  1154     case 0:
       
  1155         state = max != min ? QValidator::Intermediate : QValidator::Invalid;
       
  1156         goto end;
       
  1157     case 1:
       
  1158         if (copy.at(0) == delimiter
       
  1159             || (plus && copy.at(0) == QLatin1Char('+'))
       
  1160             || (minus && copy.at(0) == QLatin1Char('-'))) {
       
  1161             state = QValidator::Intermediate;
       
  1162             goto end;
       
  1163         }
       
  1164         break;
       
  1165     case 2:
       
  1166         if (copy.at(1) == delimiter
       
  1167             && ((plus && copy.at(0) == QLatin1Char('+')) || (minus && copy.at(0) == QLatin1Char('-')))) {
       
  1168             state = QValidator::Intermediate;
       
  1169             goto end;
       
  1170         }
       
  1171         break;
       
  1172     default: break;
       
  1173     }
       
  1174 
       
  1175     if (copy.at(0) == thousand) {
       
  1176         QSBDEBUG() << __FILE__ << __LINE__<< "state is set to Invalid";
       
  1177         state = QValidator::Invalid;
       
  1178         goto end;
       
  1179     } else if (len > 1) {
       
  1180         const int dec = copy.indexOf(delimiter);
       
  1181         if (dec != -1) {
       
  1182             if (dec + 1 < copy.size() && copy.at(dec + 1) == delimiter && pos == dec + 1) {
       
  1183                 copy.remove(dec + 1, 1); // typing a delimiter when you are on the delimiter
       
  1184             } // should be treated as typing right arrow
       
  1185 
       
  1186             if (copy.size() - dec > decimals + 1) {
       
  1187                 QSBDEBUG() << __FILE__ << __LINE__<< "state is set to Invalid";
       
  1188                 state = QValidator::Invalid;
       
  1189                 goto end;
       
  1190             }
       
  1191             for (int i=dec + 1; i<copy.size(); ++i) {
       
  1192                 if (copy.at(i).isSpace() || copy.at(i) == thousand) {
       
  1193                     QSBDEBUG() << __FILE__ << __LINE__<< "state is set to Invalid";
       
  1194                     state = QValidator::Invalid;
       
  1195                     goto end;
       
  1196                 }
       
  1197             }
       
  1198         } else {
       
  1199             const QChar &last = copy.at(len - 1);
       
  1200             const QChar &secondLast = copy.at(len - 2);
       
  1201             if ((last == thousand || last.isSpace())
       
  1202                 && (secondLast == thousand || secondLast.isSpace())) {
       
  1203                 state = QValidator::Invalid;
       
  1204                 QSBDEBUG() << __FILE__ << __LINE__<< "state is set to Invalid";
       
  1205                 goto end;
       
  1206             } else if (last.isSpace() && (!thousand.isSpace() || secondLast.isSpace())) {
       
  1207                 state = QValidator::Invalid;
       
  1208                 QSBDEBUG() << __FILE__ << __LINE__<< "state is set to Invalid";
       
  1209                 goto end;
       
  1210             }
       
  1211         }
       
  1212     }
       
  1213 
       
  1214     {
       
  1215         bool ok = false;
       
  1216         num = locale.toDouble(copy, &ok);
       
  1217         QSBDEBUG() << __FILE__ << __LINE__ << locale << copy << num << ok;
       
  1218         bool notAcceptable = false;
       
  1219 
       
  1220         if (!ok) {
       
  1221             if (thousand.isPrint()) {
       
  1222                 if (max < 1000 && min > -1000 && copy.contains(thousand)) {
       
  1223                     state = QValidator::Invalid;
       
  1224                     QSBDEBUG() << __FILE__ << __LINE__<< "state is set to Invalid";
       
  1225                     goto end;
       
  1226                 }
       
  1227 
       
  1228                 const int len = copy.size();
       
  1229                 for (int i=0; i<len- 1; ++i) {
       
  1230                     if (copy.at(i) == thousand && copy.at(i + 1) == thousand) {
       
  1231                         QSBDEBUG() << __FILE__ << __LINE__<< "state is set to Invalid";
       
  1232                         state = QValidator::Invalid;
       
  1233                         goto end;
       
  1234                     }
       
  1235                 }
       
  1236 
       
  1237                 const int s = copy.size();
       
  1238                 copy.remove(thousand);
       
  1239                 pos = qMax(0, pos - (s - copy.size()));
       
  1240 
       
  1241 
       
  1242                 num = locale.toDouble(copy, &ok);
       
  1243                 QSBDEBUG() << thousand << num << copy << ok;
       
  1244 
       
  1245                 if (!ok) {
       
  1246                     state = QValidator::Invalid;
       
  1247                     QSBDEBUG() << __FILE__ << __LINE__<< "state is set to Invalid";
       
  1248                     goto end;
       
  1249                 }
       
  1250                 notAcceptable = true;
       
  1251             }
       
  1252         }
       
  1253 
       
  1254         if (!ok) {
       
  1255             state = QValidator::Invalid;
       
  1256             QSBDEBUG() << __FILE__ << __LINE__<< "state is set to Invalid";
       
  1257         } else if (num >= min && num <= max) {
       
  1258             state = notAcceptable ? QValidator::Intermediate : QValidator::Acceptable;
       
  1259             QSBDEBUG() << __FILE__ << __LINE__<< "state is set to "
       
  1260                        << (state == QValidator::Intermediate ? "Intermediate" : "Acceptable");
       
  1261         } else if (max == min) { // when max and min is the same the only non-Invalid input is max (or min)
       
  1262             state = QValidator::Invalid;
       
  1263             QSBDEBUG() << __FILE__ << __LINE__<< "state is set to Invalid";
       
  1264         } else {
       
  1265             if ((num >= 0 && num > max) || (num < 0 && num < min)) {
       
  1266                 state = QValidator::Invalid;
       
  1267                 QSBDEBUG() << __FILE__ << __LINE__<< "state is set to Invalid";
       
  1268             } else {
       
  1269                 state = QValidator::Intermediate;
       
  1270                 QSBDEBUG() << __FILE__ << __LINE__<< "state is set to Intermediate";
       
  1271             }
       
  1272         }
       
  1273     }
       
  1274 
       
  1275 end:
       
  1276     if (state != QValidator::Acceptable) {
       
  1277         num = max > 0 ? min : max;
       
  1278     }
       
  1279 
       
  1280     input = prefix + copy + suffix;
       
  1281     cachedText = input;
       
  1282     cachedState = state;
       
  1283     cachedValue = QVariant(num);
       
  1284     return QVariant(num);
       
  1285 }
       
  1286 
       
  1287 /*
       
  1288     \internal
       
  1289     \reimp
       
  1290 */
       
  1291 
       
  1292 QString QDoubleSpinBoxPrivate::textFromValue(const QVariant &f) const
       
  1293 {
       
  1294     Q_Q(const QDoubleSpinBox);
       
  1295     return q->textFromValue(f.toDouble());
       
  1296 }
       
  1297 
       
  1298 /*!
       
  1299     \fn void QSpinBox::setLineStep(int step)
       
  1300 
       
  1301     Use setSingleStep() instead.
       
  1302 */
       
  1303 
       
  1304 /*!
       
  1305     \fn void QSpinBox::setMaxValue(int value)
       
  1306 
       
  1307     Use setMaximum() instead.
       
  1308 */
       
  1309 
       
  1310 /*!
       
  1311     \fn void QSpinBox::setMinValue(int value)
       
  1312 
       
  1313     Use setMinimum() instead.
       
  1314 */
       
  1315 
       
  1316 /*!
       
  1317     \fn int QSpinBox::maxValue() const
       
  1318 
       
  1319     Use maximum() instead.
       
  1320 */
       
  1321 
       
  1322 /*!
       
  1323     \fn int QSpinBox::minValue() const
       
  1324 
       
  1325     Use minimum() instead.
       
  1326 */
       
  1327 
       
  1328 /*! \reimp */
       
  1329 bool QSpinBox::event(QEvent *event)
       
  1330 {
       
  1331     Q_D(QSpinBox);
       
  1332     if (event->type() == QEvent::StyleChange
       
  1333 #ifdef Q_WS_MAC
       
  1334             || event->type() == QEvent::MacSizeChange
       
  1335 #endif
       
  1336             )
       
  1337         d->setLayoutItemMargins(QStyle::SE_SpinBoxLayoutItem);
       
  1338     return QAbstractSpinBox::event(event);
       
  1339 }
       
  1340 
       
  1341 QT_END_NAMESPACE
       
  1342 
       
  1343 #endif // QT_NO_SPINBOX