summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gui/widgets/qspinbox.cpp214
-rw-r--r--tests/auto/qdoublespinbox/tst_qdoublespinbox.cpp45
-rw-r--r--tests/auto/qspinbox/tst_qspinbox.cpp8
3 files changed, 45 insertions, 222 deletions
diff --git a/src/gui/widgets/qspinbox.cpp b/src/gui/widgets/qspinbox.cpp
index a2e4c15..8d21f3f 100644
--- a/src/gui/widgets/qspinbox.cpp
+++ b/src/gui/widgets/qspinbox.cpp
@@ -60,8 +60,6 @@ QT_BEGIN_NAMESPACE
# define QSBDEBUG if (false) qDebug
#endif
-static bool isIntermediateValueHelper(qint64 num, qint64 minimum, qint64 maximum, qint64 *match = 0);
-
class QSpinBoxPrivate : public QAbstractSpinBoxPrivate
{
Q_DECLARE_PUBLIC(QSpinBox)
@@ -73,7 +71,6 @@ public:
virtual QString textFromValue(const QVariant &n) const;
QVariant validateAndInterpret(QString &input, int &pos,
QValidator::State &state) const;
- bool isIntermediateValue(const QString &str) const;
QChar thousand;
inline void init() {
@@ -87,7 +84,6 @@ class QDoubleSpinBoxPrivate : public QAbstractSpinBoxPrivate
public:
QDoubleSpinBoxPrivate(QWidget *parent = 0);
void emitSignals(EmitPolicy ep, const QVariant &);
- bool isIntermediateValue(const QString &str) const;
virtual QVariant valueFromText(const QString &n) const;
virtual QString textFromValue(const QVariant &n) const;
@@ -975,51 +971,6 @@ QVariant QSpinBoxPrivate::valueFromText(const QString &text) const
/*!
- \internal
-
- Return true if str can become a number which is between minimum and
- maximum or false if this is not possible.
-*/
-
-bool QSpinBoxPrivate::isIntermediateValue(const QString &str) const
-{
- const int num = q_func()->locale().toInt(str, 0, 10);
- const int min = minimum.toInt();
- const int max = maximum.toInt();
-
- int numDigits = 0;
- int digits[10];
- int tmp = num;
- if (tmp == 0) {
- numDigits = 1;
- digits[0] = 0;
- } else {
- tmp = num;
- for (int i=0; tmp != 0; ++i) {
- digits[numDigits++] = qAbs(tmp % 10);
- tmp /= 10;
- }
- }
-
- int failures = 0;
- for (int number=min; /*number<=max*/; ++number) {
- tmp = number;
- for (int i=0; tmp != 0;) {
- if (digits[i] == qAbs(tmp % 10)) {
- if (++i == numDigits)
- return true;
- }
- tmp /= 10;
- }
- if (failures++ == 500000) //upper bound
- return true;
- if (number == max) // needed for INT_MAX
- break;
- }
- return false;
-}
-
-/*!
\internal Multi purpose function that parses input, sets state to
the appropriate state and returns the value it will be interpreted
as.
@@ -1073,9 +1024,8 @@ QVariant QSpinBoxPrivate::validateAndInterpret(QString &input, int &pos,
state = QValidator::Invalid;
QSBDEBUG() << __FILE__ << __LINE__<< "state is set to Invalid";
} else {
- state = isIntermediateValue(copy) ? QValidator::Intermediate : QValidator::Invalid;
- QSBDEBUG() << __FILE__ << __LINE__<< "state is set to "
- << (state == QValidator::Intermediate ? "Intermediate" : "Acceptable");
+ state = QValidator::Intermediate;
+ QSBDEBUG() << __FILE__ << __LINE__<< "state is set to Intermediate";
}
}
}
@@ -1135,105 +1085,6 @@ void QDoubleSpinBoxPrivate::emitSignals(EmitPolicy ep, const QVariant &old)
}
-bool QDoubleSpinBoxPrivate::isIntermediateValue(const QString &str) const
-{
- QSBDEBUG() << "input is" << str << minimum << maximum;
- qint64 dec = 1;
- for (int i=0; i<decimals; ++i)
- dec *= 10;
-
- const QLatin1Char dot('.');
-
- // I know QString::number() uses CLocale so I use dot
- const QString minstr = QString::number(minimum.toDouble(), 'f', decimals);
- bool ok;
- qint64 min_left = minstr.left(minstr.indexOf(dot)).toLongLong(&ok);
- if (!ok)
- return false;
- qint64 min_right = minstr.mid(minstr.indexOf(dot) + 1).toLongLong();
-
- const QString maxstr = QString::number(maximum.toDouble(), 'f', decimals);
- qint64 max_left = maxstr.left(maxstr.indexOf(dot)).toLongLong(&ok);
- if (!ok)
- return true;
- qint64 max_right = maxstr.mid(maxstr.indexOf(dot) + 1).toLongLong();
-
- const int dotindex = str.indexOf(delimiter);
- const bool negative = maximum.toDouble() < 0;
- qint64 left = 0, right = 0;
- bool doleft = true;
- bool doright = true;
- if (dotindex == -1) {
- left = str.toLongLong();
- doright = false;
- } else if (dotindex == 0 || (dotindex == 1 && str.at(0) == QLatin1Char('+'))) {
- if (negative) {
- QSBDEBUG() << __FILE__ << __LINE__ << "returns false";
- return false;
- }
- doleft = false;
- right = str.mid(dotindex + 1).toLongLong();
- } else if (dotindex == 1 && str.at(0) == QLatin1Char('-')) {
- if (!negative) {
- QSBDEBUG() << __FILE__ << __LINE__ << "returns false";
- return false;
- }
- doleft = false;
- right = str.mid(dotindex + 1).toLongLong();
- } else {
- left = str.left(dotindex).toLongLong();
- if (dotindex == str.size() - 1) {
- doright = false;
- } else {
- right = str.mid(dotindex + 1).toLongLong();
- }
- }
- if ((left >= 0 && max_left < 0 && !str.startsWith(QLatin1Char('-'))) || (left < 0 && min_left >= 0)) {
- QSBDEBUG("returns false 0");
- return false;
- }
-
- qint64 match = min_left;
- if (doleft && !isIntermediateValueHelper(left, min_left, max_left, &match)) {
- QSBDEBUG() << __FILE__ << __LINE__ << "returns false";
- return false;
- }
- if (doright) {
- QSBDEBUG("match %lld min_left %lld max_left %lld", match, min_left, max_left);
- if (!doleft) {
- if (min_left == max_left) {
- const bool ret = isIntermediateValueHelper(qAbs(left),
- negative ? max_right : min_right,
- negative ? min_right : max_right);
- QSBDEBUG() << __FILE__ << __LINE__ << "returns" << ret;
- return ret;
- } else if (qAbs(max_left - min_left) == 1) {
- const bool ret = isIntermediateValueHelper(qAbs(left), min_right, negative ? 0 : dec)
- || isIntermediateValueHelper(qAbs(left), negative ? dec : 0, max_right);
- QSBDEBUG() << __FILE__ << __LINE__ << "returns" << ret;
- return ret;
- } else {
- const bool ret = isIntermediateValueHelper(qAbs(left), 0, dec);
- QSBDEBUG() << __FILE__ << __LINE__ << "returns" << ret;
- return ret;
- }
- }
- if (match != min_left) {
- min_right = negative ? dec : 0;
- }
- if (match != max_left) {
- max_right = negative ? 0 : dec;
- }
- qint64 tmpl = negative ? max_right : min_right;
- qint64 tmpr = negative ? min_right : max_right;
- const bool ret = isIntermediateValueHelper(right, tmpl, tmpr);
- QSBDEBUG() << __FILE__ << __LINE__ << "returns" << ret;
- return ret;
- }
- QSBDEBUG() << __FILE__ << __LINE__ << "returns true";
- return true;
-}
-
/*!
\internal
\reimp
@@ -1402,9 +1253,8 @@ QVariant QDoubleSpinBoxPrivate::validateAndInterpret(QString &input, int &pos,
state = QValidator::Invalid;
QSBDEBUG() << __FILE__ << __LINE__<< "state is set to Invalid";
} else {
- state = isIntermediateValue(copy) ? QValidator::Intermediate : QValidator::Invalid;
- QSBDEBUG() << __FILE__ << __LINE__<< "state is set to "
- << (state == QValidator::Intermediate ? "Intermediate" : "Acceptable");
+ state = QValidator::Intermediate;
+ QSBDEBUG() << __FILE__ << __LINE__<< "state is set to Intermediate";
}
}
}
@@ -1462,62 +1312,6 @@ QString QDoubleSpinBoxPrivate::textFromValue(const QVariant &f) const
Use minimum() instead.
*/
-/*!
- \internal Returns whether \a str is a string which value cannot be
- parsed but still might turn into something valid.
-*/
-
-static bool isIntermediateValueHelper(qint64 num, qint64 min, qint64 max, qint64 *match)
-{
- QSBDEBUG("%lld %lld %lld", num, min, max);
-
- if (num >= min && num <= max) {
- if (match)
- *match = num;
- QSBDEBUG("returns true 0");
- return true;
- }
- qint64 tmp = num;
-
- int numDigits = 0;
- int digits[10];
- if (tmp == 0) {
- numDigits = 1;
- digits[0] = 0;
- } else {
- tmp = qAbs(num);
- for (int i=0; tmp > 0; ++i) {
- digits[numDigits++] = tmp % 10;
- tmp /= 10;
- }
- }
-
- int failures = 0;
- qint64 number;
- for (number=max; number>=min; --number) {
- tmp = qAbs(number);
- for (int i=0; tmp > 0;) {
- if (digits[i] == (tmp % 10)) {
- if (++i == numDigits) {
- if (match)
- *match = number;
- QSBDEBUG("returns true 1");
- return true;
- }
- }
- tmp /= 10;
- }
- if (failures++ == 500000) { //upper bound
- if (match)
- *match = num;
- QSBDEBUG("returns true 2");
- return true;
- }
- }
- QSBDEBUG("returns false");
- return false;
-}
-
/*! \reimp */
bool QSpinBox::event(QEvent *event)
{
diff --git a/tests/auto/qdoublespinbox/tst_qdoublespinbox.cpp b/tests/auto/qdoublespinbox/tst_qdoublespinbox.cpp
index dada015..1fb0e1e 100644
--- a/tests/auto/qdoublespinbox/tst_qdoublespinbox.cpp
+++ b/tests/auto/qdoublespinbox/tst_qdoublespinbox.cpp
@@ -52,6 +52,9 @@
#include <qlineedit.h>
#include <qdebug.h>
+
+#include "../../shared/util.h"
+
//TESTED_CLASS=
//TESTED_FILES=gui/widgets/qspinbox.h gui/widgets/qspinbox.cpp gui/widgets/qabstractspinbox.cpp gui/widgets/qabstractspinbox_p.h gui/widgets/qabstractspinbox.h
@@ -142,6 +145,7 @@ private slots:
void task224497_fltMax();
void task221221();
+ void task255471_decimalsValidation();
public slots:
void valueChangedHelper(const QString &);
@@ -665,7 +669,7 @@ void tst_QDoubleSpinBox::valueFromTextAndValidate_data()
QTest::addColumn<int>("language");
QTest::addColumn<QString>("expectedText"); // if empty we don't check
- QTest::newRow("data0") << QString("2.2") << Invalid << 3.0 << 5.0 << (int)QLocale::C << QString();
+ QTest::newRow("data0") << QString("2.2") << Intermediate << 3.0 << 5.0 << (int)QLocale::C << QString();
QTest::newRow("data1") << QString() << Intermediate << 0.0 << 100.0 << (int)QLocale::C << QString();
QTest::newRow("data2") << QString("asd") << Invalid << 0.0 << 100.0 << (int)QLocale::C << QString();
QTest::newRow("data3") << QString("2.2") << Acceptable << 0.0 << 100.0 << (int)QLocale::C << QString();
@@ -682,20 +686,20 @@ void tst_QDoubleSpinBox::valueFromTextAndValidate_data()
QTest::newRow("data14") << QString("1, ") << Acceptable << 0.0 << 100.0 << (int)QLocale::Norwegian << QString("1,");
QTest::newRow("data15") << QString("1, ") << Invalid << 0.0 << 100.0 << (int)QLocale::C << QString();
QTest::newRow("data16") << QString("2") << Intermediate << 100.0 << 102.0 << (int)QLocale::C << QString();
- QTest::newRow("data17") << QString("22.0") << Invalid << 100.0 << 102.0 << (int)QLocale::C << QString();
+ QTest::newRow("data17") << QString("22.0") << Intermediate << 100.0 << 102.0 << (int)QLocale::C << QString();
QTest::newRow("data18") << QString("12.0") << Intermediate << 100.0 << 102.0 << (int)QLocale::C << QString();
- QTest::newRow("data19") << QString("12.2") << Invalid << 100. << 102.0 << (int)QLocale::C << QString();
- QTest::newRow("data20") << QString("21.") << Invalid << 100.0 << 102.0 << (int)QLocale::C << QString();
- QTest::newRow("data21") << QString("-21.") << Invalid << -102.0 << -100.0 << (int)QLocale::C << QString();
+ QTest::newRow("data19") << QString("12.2") << Intermediate << 100. << 102.0 << (int)QLocale::C << QString();
+ QTest::newRow("data20") << QString("21.") << Intermediate << 100.0 << 102.0 << (int)QLocale::C << QString();
+ QTest::newRow("data21") << QString("-21.") << Intermediate << -102.0 << -100.0 << (int)QLocale::C << QString();
QTest::newRow("data22") << QString("-12.") << Intermediate << -102.0 << -100.0 << (int)QLocale::C << QString();
- QTest::newRow("data23") << QString("-11.11") << Invalid << -102.0 << -101.2 << (int)QLocale::C << QString();
+ QTest::newRow("data23") << QString("-11.11") << Intermediate << -102.0 << -101.2 << (int)QLocale::C << QString();
QTest::newRow("data24") << QString("-11.4") << Intermediate << -102.0 << -101.3 << (int)QLocale::C << QString();
QTest::newRow("data25") << QString("11.400") << Invalid << 0.0 << 100.0 << (int)QLocale::C << QString();
QTest::newRow("data26") << QString(".4") << Intermediate << 0.45 << 0.5 << (int)QLocale::C << QString();
QTest::newRow("data27") << QString("+.4") << Intermediate << 0.45 << 0.5 << (int)QLocale::C << QString();
QTest::newRow("data28") << QString("-.4") << Intermediate << -0.5 << -0.45 << (int)QLocale::C << QString();
QTest::newRow("data29") << QString(".4") << Intermediate << 1.0 << 2.4 << (int)QLocale::C << QString();
- QTest::newRow("data30") << QString("-.4") << Invalid << -2.3 << -1.9 << (int)QLocale::C << QString();
+ QTest::newRow("data30") << QString("-.4") << Intermediate << -2.3 << -1.9 << (int)QLocale::C << QString();
QTest::newRow("data31") << QString("-42") << Invalid << -2.43 << -1.0 << (int)QLocale::C << QString();
QTest::newRow("data32") << QString("-4") << Invalid << -1.4 << -1.0 << (int)QLocale::C << QString();
QTest::newRow("data33") << QString("-42") << Invalid << -1.4 << -1.0 << (int)QLocale::C << QString();
@@ -709,7 +713,7 @@ void tst_QDoubleSpinBox::valueFromTextAndValidate_data()
QTest::newRow("data41") << QString("103.") << Invalid << -102.0 << 11.0 << (int)QLocale::C << QString();
QTest::newRow("data42") << QString("122") << Invalid << 10.0 << 12.2 << (int)QLocale::C << QString();
QTest::newRow("data43") << QString("-2.2") << Intermediate << -12.2 << -3.2 << (int)QLocale::C << QString();
- QTest::newRow("data44") << QString("-2.20") << Invalid << -12.1 << -3.2 << (int)QLocale::C << QString();
+ QTest::newRow("data44") << QString("-2.20") << Intermediate << -12.1 << -3.2 << (int)QLocale::C << QString();
QTest::newRow("data45") << QString("200,2") << Invalid << 0.0 << 1000.0 << (int)QLocale::C << QString();
QTest::newRow("data46") << QString("200,2") << Acceptable << 0.0 << 1000.0 << (int)QLocale::German << QString();
QTest::newRow("data47") << QString("2.2") << Acceptable << 0.0 << 1000.0 << (int)QLocale::C << QString();
@@ -1003,6 +1007,31 @@ void tst_QDoubleSpinBox::task221221()
QCOMPARE(spin.text(), QLatin1String("1"));
}
+void tst_QDoubleSpinBox::task255471_decimalsValidation()
+{
+ // QDoubleSpinBox shouldn't crash with large numbers of decimals. Even if
+ // the results are useless ;-)
+ for (int i = 0; i < 32; ++i)
+ {
+ QDoubleSpinBox spinBox;
+ spinBox.setDecimals(i);
+ spinBox.setMinimum(0.3);
+ spinBox.setMaximum(12);
+
+ spinBox.show();
+ QTRY_VERIFY(spinBox.isVisible());
+ spinBox.setFocus();
+ QTRY_VERIFY(spinBox.hasFocus());
+
+ QTest::keyPress(&spinBox, Qt::Key_Right);
+ QTest::keyPress(&spinBox, Qt::Key_Right);
+ QTest::keyPress(&spinBox, Qt::Key_Delete);
+
+ // Don't crash!
+ QTest::keyPress(&spinBox, Qt::Key_2);
+ }
+}
+
QTEST_MAIN(tst_QDoubleSpinBox)
#include "tst_qdoublespinbox.moc"
diff --git a/tests/auto/qspinbox/tst_qspinbox.cpp b/tests/auto/qspinbox/tst_qspinbox.cpp
index 9f00be6..79e3ca7 100644
--- a/tests/auto/qspinbox/tst_qspinbox.cpp
+++ b/tests/auto/qspinbox/tst_qspinbox.cpp
@@ -643,21 +643,21 @@ void tst_QSpinBox::valueFromTextAndValidate_data()
QTest::addColumn<int>("maxi");
QTest::addColumn<QString>("expectedText"); // if empty we don't check
- QTest::newRow("data0") << QString("2") << Invalid << 3 << 5 << QString();
+ QTest::newRow("data0") << QString("2") << Intermediate << 3 << 5 << QString();
QTest::newRow("data1") << QString() << Intermediate << 0 << 100 << QString();
QTest::newRow("data2") << QString("asd") << Invalid << 0 << 100 << QString();
QTest::newRow("data3") << QString("2") << Acceptable << 0 << 100 << QString();
QTest::newRow("data4") << QString() << Intermediate << 0 << 1 << QString();
QTest::newRow("data5") << QString() << Invalid << 0 << 0 << QString();
QTest::newRow("data5") << QString("5") << Intermediate << 2004 << 2005 << QString();
- QTest::newRow("data6") << QString("50") << Invalid << 2004 << 2005 << QString();
+ QTest::newRow("data6") << QString("50") << Intermediate << 2004 << 2005 << QString();
QTest::newRow("data7") << QString("205") << Intermediate << 2004 << 2005 << QString();
QTest::newRow("data8") << QString("2005") << Acceptable << 2004 << 2005 << QString();
- QTest::newRow("data9") << QString("3") << Invalid << 2004 << 2005 << QString();
+ QTest::newRow("data9") << QString("3") << Intermediate << 2004 << 2005 << QString();
QTest::newRow("data10") << QString("-") << Intermediate << -20 << -10 << QString();
QTest::newRow("data11") << QString("-1") << Intermediate << -20 << -10 << QString();
QTest::newRow("data12") << QString("-5") << Intermediate << -20 << -10 << QString();
- QTest::newRow("data13") << QString("-5") << Invalid << -20 << -16 << QString();
+ QTest::newRow("data13") << QString("-5") << Intermediate << -20 << -16 << QString();
QTest::newRow("data14") << QString("-2") << Intermediate << -20 << -16 << QString();
QTest::newRow("data15") << QString("2") << Invalid << -20 << -16 << QString();
QTest::newRow("data16") << QString() << Intermediate << -20 << -16 << QString();