diff options
Diffstat (limited to 'src/gui/widgets/qspinbox.cpp')
-rw-r--r-- | src/gui/widgets/qspinbox.cpp | 118 |
1 files changed, 49 insertions, 69 deletions
diff --git a/src/gui/widgets/qspinbox.cpp b/src/gui/widgets/qspinbox.cpp index 9eb07ac..726426d 100644 --- a/src/gui/widgets/qspinbox.cpp +++ b/src/gui/widgets/qspinbox.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** @@ -65,14 +65,13 @@ class QSpinBoxPrivate : public QAbstractSpinBoxPrivate { Q_DECLARE_PUBLIC(QSpinBox) public: - QSpinBoxPrivate(QWidget *parent = 0); + 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; - QChar thousand; inline void init() { Q_Q(QSpinBox); @@ -85,7 +84,7 @@ class QDoubleSpinBoxPrivate : public QAbstractSpinBoxPrivate { Q_DECLARE_PUBLIC(QDoubleSpinBox) public: - QDoubleSpinBoxPrivate(QWidget *parent = 0); + QDoubleSpinBoxPrivate(); void emitSignals(EmitPolicy ep, const QVariant &); virtual QVariant valueFromText(const QString &n) const; @@ -95,12 +94,15 @@ public: double round(double input) const; // variables int decimals; - QChar delimiter, thousand; 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; }; @@ -201,7 +203,7 @@ public: */ QSpinBox::QSpinBox(QWidget *parent) - : QAbstractSpinBox(*new QSpinBoxPrivate(parent), parent) + : QAbstractSpinBox(*new QSpinBoxPrivate, parent) { Q_D(QSpinBox); d->init(); @@ -213,7 +215,7 @@ QSpinBox::QSpinBox(QWidget *parent) argument and then use setObjectName() instead. */ QSpinBox::QSpinBox(QWidget *parent, const char *name) - : QAbstractSpinBox(*new QSpinBoxPrivate(parent), parent) + : QAbstractSpinBox(*new QSpinBoxPrivate, parent) { Q_D(QSpinBox); setObjectName(QString::fromAscii(name)); @@ -225,7 +227,7 @@ QSpinBox::QSpinBox(QWidget *parent, const char *name) argument and then use setObjectName() instead. */ QSpinBox::QSpinBox(int minimum, int maximum, int step, QWidget *parent, const char *name) - : QAbstractSpinBox(*new QSpinBoxPrivate(parent), parent) + : QAbstractSpinBox(*new QSpinBoxPrivate, parent) { Q_D(QSpinBox); d->minimum = QVariant(qMin<int>(minimum, maximum)); @@ -464,10 +466,9 @@ void QSpinBox::setRange(int minimum, int maximum) QString QSpinBox::textFromValue(int value) const { - Q_D(const QSpinBox); QString str = locale().toString(value); if (qAbs(value) >= 1000 || value == INT_MIN) { - str.remove(d->thousand); + str.remove(locale().groupSeparator()); } return str; @@ -516,9 +517,7 @@ QValidator::State QSpinBox::validate(QString &text, int &pos) const */ void QSpinBox::fixup(QString &input) const { - Q_D(const QSpinBox); - - input.remove(d->thousand); + input.remove(locale().groupSeparator()); } @@ -600,7 +599,7 @@ void QSpinBox::fixup(QString &input) const \sa setMinimum(), setMaximum(), setSingleStep() */ QDoubleSpinBox::QDoubleSpinBox(QWidget *parent) - : QAbstractSpinBox(*new QDoubleSpinBoxPrivate(parent), parent) + : QAbstractSpinBox(*new QDoubleSpinBoxPrivate, parent) { Q_D(QDoubleSpinBox); d->init(); @@ -767,6 +766,7 @@ double QDoubleSpinBox::minimum() const 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)); } @@ -797,6 +797,7 @@ double QDoubleSpinBox::maximum() const 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); } @@ -818,6 +819,8 @@ void QDoubleSpinBox::setMaximum(double 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))); } @@ -848,7 +851,7 @@ void QDoubleSpinBox::setDecimals(int decimals) Q_D(QDoubleSpinBox); d->decimals = qBound(0, decimals, DBL_MAX_10_EXP + DBL_DIG); - setRange(minimum(), maximum()); // make sure values are rounded + setRange(d->actualMin, d->actualMax); // make sure values are rounded setValue(value()); } @@ -875,7 +878,7 @@ 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(d->thousand); + str.remove(locale().groupSeparator()); } return str; } @@ -920,9 +923,7 @@ QValidator::State QDoubleSpinBox::validate(QString &text, int &pos) const */ void QDoubleSpinBox::fixup(QString &input) const { - Q_D(const QDoubleSpinBox); - - input.remove(d->thousand); + input.remove(locale().groupSeparator()); } // --- QSpinBoxPrivate --- @@ -932,18 +933,13 @@ void QDoubleSpinBox::fixup(QString &input) const Constructs a QSpinBoxPrivate object */ -QSpinBoxPrivate::QSpinBoxPrivate(QWidget *parent) +QSpinBoxPrivate::QSpinBoxPrivate() { minimum = QVariant((int)0); maximum = QVariant((int)99); value = minimum; singleStep = QVariant((int)1); type = QVariant::Int; - const QString str = (parent ? parent->locale() : QLocale()).toString(4567); - if (str.size() == 5) { - thousand = QChar(str.at(1)); - } - } /*! @@ -1019,20 +1015,17 @@ QVariant QSpinBoxPrivate::validateAndInterpret(QString &input, int &pos, 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; - bool removedThousand = false; num = locale.toInt(copy, &ok, 10); - if (!ok && copy.contains(thousand) && (max >= 1000 || min <= -1000)) { - const int s = copy.size(); - copy.remove(thousand); - pos = qMax(0, pos - (s - copy.size())); - removedThousand = true; - 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 = removedThousand ? QValidator::Intermediate : QValidator::Acceptable; + state = QValidator::Acceptable; } else if (max == min) { state = QValidator::Invalid; } else { @@ -1064,23 +1057,16 @@ QVariant QSpinBoxPrivate::validateAndInterpret(QString &input, int &pos, Constructs a QSpinBoxPrivate object */ -QDoubleSpinBoxPrivate::QDoubleSpinBoxPrivate(QWidget *parent) +QDoubleSpinBoxPrivate::QDoubleSpinBoxPrivate() { - minimum = QVariant(0.0); - maximum = QVariant(99.99); + actualMin = 0.0; + actualMax = 99.99; + minimum = QVariant(actualMin); + maximum = QVariant(actualMax); value = minimum; singleStep = QVariant(1.0); decimals = 2; type = QVariant::Double; - const QString str = (parent ? parent->locale() : QLocale()).toString(4567.1); - if (str.size() == 6) { - delimiter = str.at(4); - thousand = QChar((ushort)0); - } else if (str.size() == 7) { - thousand = str.at(1); - delimiter = str.at(5); - } - Q_ASSERT(!delimiter.isNull()); } /*! @@ -1155,7 +1141,7 @@ QVariant QDoubleSpinBoxPrivate::validateAndInterpret(QString &input, int &pos, state = max != min ? QValidator::Intermediate : QValidator::Invalid; goto end; case 1: - if (copy.at(0) == delimiter + if (copy.at(0) == locale.decimalPoint() || (plus && copy.at(0) == QLatin1Char('+')) || (minus && copy.at(0) == QLatin1Char('-'))) { state = QValidator::Intermediate; @@ -1163,7 +1149,7 @@ QVariant QDoubleSpinBoxPrivate::validateAndInterpret(QString &input, int &pos, } break; case 2: - if (copy.at(1) == delimiter + if (copy.at(1) == locale.decimalPoint() && ((plus && copy.at(0) == QLatin1Char('+')) || (minus && copy.at(0) == QLatin1Char('-')))) { state = QValidator::Intermediate; goto end; @@ -1172,14 +1158,14 @@ QVariant QDoubleSpinBoxPrivate::validateAndInterpret(QString &input, int &pos, default: break; } - if (copy.at(0) == thousand) { + 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(delimiter); + const int dec = copy.indexOf(locale.decimalPoint()); if (dec != -1) { - if (dec + 1 < copy.size() && copy.at(dec + 1) == delimiter && pos == 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 @@ -1189,7 +1175,7 @@ QVariant QDoubleSpinBoxPrivate::validateAndInterpret(QString &input, int &pos, goto end; } for (int i=dec + 1; i<copy.size(); ++i) { - if (copy.at(i).isSpace() || copy.at(i) == thousand) { + if (copy.at(i).isSpace() || copy.at(i) == locale.groupSeparator()) { QSBDEBUG() << __FILE__ << __LINE__<< "state is set to Invalid"; state = QValidator::Invalid; goto end; @@ -1198,12 +1184,12 @@ QVariant QDoubleSpinBoxPrivate::validateAndInterpret(QString &input, int &pos, } else { const QChar &last = copy.at(len - 1); const QChar &secondLast = copy.at(len - 2); - if ((last == thousand || last.isSpace()) - && (secondLast == thousand || secondLast.isSpace())) { + 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() && (!thousand.isSpace() || secondLast.isSpace())) { + } else if (last.isSpace() && (!locale.groupSeparator().isSpace() || secondLast.isSpace())) { state = QValidator::Invalid; QSBDEBUG() << __FILE__ << __LINE__<< "state is set to Invalid"; goto end; @@ -1215,11 +1201,10 @@ QVariant QDoubleSpinBoxPrivate::validateAndInterpret(QString &input, int &pos, bool ok = false; num = locale.toDouble(copy, &ok); QSBDEBUG() << __FILE__ << __LINE__ << locale << copy << num << ok; - bool notAcceptable = false; if (!ok) { - if (thousand.isPrint()) { - if (max < 1000 && min > -1000 && copy.contains(thousand)) { + 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; @@ -1227,27 +1212,23 @@ QVariant QDoubleSpinBoxPrivate::validateAndInterpret(QString &input, int &pos, const int len = copy.size(); for (int i=0; i<len- 1; ++i) { - if (copy.at(i) == thousand && copy.at(i + 1) == thousand) { + 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; } } - const int s = copy.size(); - copy.remove(thousand); - pos = qMax(0, pos - (s - copy.size())); - - - num = locale.toDouble(copy, &ok); - QSBDEBUG() << thousand << num << copy << ok; + 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; } - notAcceptable = true; } } @@ -1255,9 +1236,8 @@ QVariant QDoubleSpinBoxPrivate::validateAndInterpret(QString &input, int &pos, state = QValidator::Invalid; QSBDEBUG() << __FILE__ << __LINE__<< "state is set to Invalid"; } else if (num >= min && num <= max) { - state = notAcceptable ? QValidator::Intermediate : QValidator::Acceptable; - QSBDEBUG() << __FILE__ << __LINE__<< "state is set to " - << (state == QValidator::Intermediate ? "Intermediate" : "Acceptable"); + 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"; |