Add a locale property to IntValidator and DoubleValidator.
authorAndrew den Exter <andrew.den-exter@nokia.com>
Thu, 19 Jan 2012 05:53:20 +0000 (15:53 +1000)
committerQt by Nokia <qt-info@nokia.com>
Wed, 25 Jan 2012 09:57:36 +0000 (10:57 +0100)
Allow the locale used for interpreting numbers to be changed from the
application default.

Task-number: QTBUG-23713
Change-Id: I28463485c86236fb2586eeb703ec4b051405c5a8
Reviewed-by: Martin Jones <martin.jones@nokia.com>
src/quick/items/qquickitemsmodule.cpp
src/quick/items/qquicktextinput.cpp
src/quick/items/qquicktextinput_p.h
tests/auto/qtquick2/qquicktextinput/tst_qquicktextinput.cpp

index b82a90d..3ecf5d0 100644 (file)
@@ -145,8 +145,8 @@ static void qt_quickitems_defineModule(const char *uri, int major, int minor)
     qmlRegisterUncreatableType<QQuickBasePositioner>(uri,major,minor,"Positioner",
                                                   QStringLiteral("Positioner is an abstract type that is only available as an attached property."));
 #ifndef QT_NO_VALIDATOR
-    qmlRegisterType<QIntValidator>(uri,major,minor,"IntValidator");
-    qmlRegisterType<QDoubleValidator>(uri,major,minor,"DoubleValidator");
+    qmlRegisterType<QQuickIntValidator>(uri,major,minor,"IntValidator");
+    qmlRegisterType<QQuickDoubleValidator>(uri,major,minor,"DoubleValidator");
     qmlRegisterType<QRegExpValidator>(uri,major,minor,"RegExpValidator");
 #endif
     qmlRegisterType<QQuickRectangle>(uri,major,minor,"Rectangle");
index 237db35..08892e1 100644 (file)
@@ -823,11 +823,48 @@ void QQuickTextInput::setAutoScroll(bool b)
 
     This element provides a validator for integer values.
 
-    IntValidator uses the \l {QLocale::setDefault()}{default locale} to interpret the number and
-    will accept locale specific digits, group separators, and positive and negative signs.  In
-    addition, IntValidator is always guaranteed to accept a number formatted according to the "C"
-    locale.
+    If no \l locale is set IntValidator uses the \l {QLocale::setDefault()}{default locale} to
+    interpret the number and will accept locale specific digits, group separators, and positive
+    and negative signs.  In addition, IntValidator is always guaranteed to accept a number
+    formatted according to the "C" locale.
 */
+
+
+QQuickIntValidator::QQuickIntValidator(QObject *parent)
+    : QIntValidator(parent)
+{
+}
+
+/*!
+    \qmlproperty string QtQuick2::IntValidator::locale
+
+    This property holds the name of the locale used to interpret the number.
+
+    \sa QML:Qt::locale()
+*/
+
+QString QQuickIntValidator::localeName() const
+{
+    return locale().name();
+}
+
+void QQuickIntValidator::setLocaleName(const QString &name)
+{
+    if (locale().name() != name) {
+        setLocale(QLocale(name));
+        emit localeNameChanged();
+    }
+}
+
+void QQuickIntValidator::resetLocaleName()
+{
+    QLocale defaultLocale;
+    if (locale() != defaultLocale) {
+        setLocale(defaultLocale);
+        emit localeNameChanged();
+    }
+}
+
 /*!
     \qmlproperty int QtQuick2::IntValidator::top
 
@@ -866,6 +903,41 @@ void QQuickTextInput::setAutoScroll(bool b)
     value may yet become valid by changing the exponent.
 */
 
+QQuickDoubleValidator::QQuickDoubleValidator(QObject *parent)
+    : QDoubleValidator(parent)
+{
+}
+
+/*!
+    \qmlproperty string QtQuick2::DoubleValidator::locale
+
+    This property holds the name of the locale used to interpret the number.
+
+    \sa QML:Qt::locale()
+*/
+
+QString QQuickDoubleValidator::localeName() const
+{
+    return locale().name();
+}
+
+void QQuickDoubleValidator::setLocaleName(const QString &name)
+{
+    if (locale().name() != name) {
+        setLocale(QLocale(name));
+        emit localeNameChanged();
+    }
+}
+
+void QQuickDoubleValidator::resetLocaleName()
+{
+    QLocale defaultLocale;
+    if (locale() != defaultLocale) {
+        setLocale(defaultLocale);
+        emit localeNameChanged();
+    }
+}
+
 /*!
     \qmlproperty real QtQuick2::DoubleValidator::top
 
index 92d09c3..a98c5ee 100644 (file)
@@ -330,13 +330,45 @@ private:
     Q_DECLARE_PRIVATE(QQuickTextInput)
 };
 
+#ifndef QT_NO_VALIDATOR
+class Q_AUTOTEST_EXPORT QQuickIntValidator : public QIntValidator
+{
+    Q_OBJECT
+    Q_PROPERTY(QString locale READ localeName WRITE setLocaleName RESET resetLocaleName NOTIFY localeNameChanged)
+public:
+    QQuickIntValidator(QObject *parent = 0);
+
+    QString localeName() const;
+    void setLocaleName(const QString &name);
+    void resetLocaleName();
+
+Q_SIGNALS:
+    void localeNameChanged();
+};
+
+class Q_AUTOTEST_EXPORT QQuickDoubleValidator : public QDoubleValidator
+{
+    Q_OBJECT
+    Q_PROPERTY(QString locale READ localeName WRITE setLocaleName RESET resetLocaleName NOTIFY localeNameChanged)
+public:
+    QQuickDoubleValidator(QObject *parent = 0);
+
+    QString localeName() const;
+    void setLocaleName(const QString &name);
+    void resetLocaleName();
+
+Q_SIGNALS:
+    void localeNameChanged();
+};
+#endif
+
 QT_END_NAMESPACE
 
 QML_DECLARE_TYPE(QQuickTextInput)
 #ifndef QT_NO_VALIDATOR
 QML_DECLARE_TYPE(QValidator)
-QML_DECLARE_TYPE(QIntValidator)
-QML_DECLARE_TYPE(QDoubleValidator)
+QML_DECLARE_TYPE(QQuickIntValidator)
+QML_DECLARE_TYPE(QQuickDoubleValidator)
 QML_DECLARE_TYPE(QRegExpValidator)
 #endif
 
index a4b1b1c..cae38bc 100644 (file)
@@ -1565,15 +1565,33 @@ void tst_qquicktextinput::validators()
     // so you may need to run their tests first. All validators are checked
     // here to ensure that their exposure to QML is working.
 
+    QLocale::setDefault(QLocale(QStringLiteral("C")));
+
     QQuickView canvas(testFileUrl("validators.qml"));
     canvas.show();
     canvas.requestActivateWindow();
 
     QVERIFY(canvas.rootObject() != 0);
 
+    QLocale defaultLocale;
+    QLocale enLocale("en");
+    QLocale deLocale("de_DE");
+
     QQuickTextInput *intInput = qobject_cast<QQuickTextInput *>(qvariant_cast<QObject *>(canvas.rootObject()->property("intInput")));
     QVERIFY(intInput);
     QSignalSpy intSpy(intInput, SIGNAL(acceptableInputChanged()));
+
+    QQuickIntValidator *intValidator = qobject_cast<QQuickIntValidator *>(intInput->validator());
+    QVERIFY(intValidator);
+    QCOMPARE(intValidator->localeName(), defaultLocale.name());
+    QCOMPARE(intInput->validator()->locale(), defaultLocale);
+    intValidator->setLocaleName(enLocale.name());
+    QCOMPARE(intValidator->localeName(), enLocale.name());
+    QCOMPARE(intInput->validator()->locale(), enLocale);
+    intValidator->resetLocaleName();
+    QCOMPARE(intValidator->localeName(), defaultLocale.name());
+    QCOMPARE(intInput->validator()->locale(), defaultLocale);
+
     intInput->setFocus(true);
     QTRY_VERIFY(intInput->hasActiveFocus());
     QCOMPARE(intInput->hasAcceptableInput(), false);
@@ -1592,6 +1610,33 @@ void tst_qquicktextinput::validators()
     QCOMPARE(intInput->hasAcceptableInput(), false);
     QCOMPARE(intInput->property("acceptable").toBool(), false);
     QCOMPARE(intSpy.count(), 0);
+    QTest::keyPress(&canvas, Qt::Key_Period);
+    QTest::keyRelease(&canvas, Qt::Key_Period, Qt::NoModifier ,10);
+    QTest::qWait(50);
+    QTRY_COMPARE(intInput->text(), QLatin1String("1"));
+    QCOMPARE(intInput->hasAcceptableInput(), false);
+    QTest::keyPress(&canvas, Qt::Key_Comma);
+    QTest::keyRelease(&canvas, Qt::Key_Comma, Qt::NoModifier ,10);
+    QTest::qWait(50);
+    QTRY_COMPARE(intInput->text(), QLatin1String("1,"));
+    QCOMPARE(intInput->hasAcceptableInput(), false);
+    QTest::keyPress(&canvas, Qt::Key_Backspace);
+    QTest::keyRelease(&canvas, Qt::Key_Backspace, Qt::NoModifier ,10);
+    QTest::qWait(50);
+    QTRY_COMPARE(intInput->text(), QLatin1String("1"));
+    QCOMPARE(intInput->hasAcceptableInput(), false);
+    intValidator->setLocaleName(deLocale.name());
+    QTest::keyPress(&canvas, Qt::Key_Period);
+    QTest::keyRelease(&canvas, Qt::Key_Period, Qt::NoModifier ,10);
+    QTest::qWait(50);
+    QTRY_COMPARE(intInput->text(), QLatin1String("1."));
+    QCOMPARE(intInput->hasAcceptableInput(), false);
+    QTest::keyPress(&canvas, Qt::Key_Backspace);
+    QTest::keyRelease(&canvas, Qt::Key_Backspace, Qt::NoModifier ,10);
+    QTest::qWait(50);
+    QTRY_COMPARE(intInput->text(), QLatin1String("1"));
+    QCOMPARE(intInput->hasAcceptableInput(), false);
+    intValidator->resetLocaleName();
     QTest::keyPress(&canvas, Qt::Key_1);
     QTest::keyRelease(&canvas, Qt::Key_1, Qt::NoModifier ,10);
     QTest::qWait(50);
@@ -1610,6 +1655,18 @@ void tst_qquicktextinput::validators()
     QQuickTextInput *dblInput = qobject_cast<QQuickTextInput *>(qvariant_cast<QObject *>(canvas.rootObject()->property("dblInput")));
     QVERIFY(dblInput);
     QSignalSpy dblSpy(dblInput, SIGNAL(acceptableInputChanged()));
+
+    QQuickDoubleValidator *dblValidator = qobject_cast<QQuickDoubleValidator *>(dblInput->validator());
+    QVERIFY(dblValidator);
+    QCOMPARE(dblValidator->localeName(), defaultLocale.name());
+    QCOMPARE(dblInput->validator()->locale(), defaultLocale);
+    dblValidator->setLocaleName(enLocale.name());
+    QCOMPARE(dblValidator->localeName(), enLocale.name());
+    QCOMPARE(dblInput->validator()->locale(), enLocale);
+    dblValidator->resetLocaleName();
+    QCOMPARE(dblValidator->localeName(), defaultLocale.name());
+    QCOMPARE(dblInput->validator()->locale(), defaultLocale);
+
     dblInput->setFocus(true);
     QVERIFY(dblInput->hasActiveFocus() == true);
     QCOMPARE(dblInput->hasAcceptableInput(), false);
@@ -1628,6 +1685,44 @@ void tst_qquicktextinput::validators()
     QCOMPARE(dblInput->hasAcceptableInput(), true);
     QCOMPARE(dblInput->property("acceptable").toBool(), true);
     QCOMPARE(dblSpy.count(), 1);
+    QTest::keyPress(&canvas, Qt::Key_Comma);
+    QTest::keyRelease(&canvas, Qt::Key_Comma, Qt::NoModifier ,10);
+    QTest::qWait(50);
+    QTRY_COMPARE(dblInput->text(), QLatin1String("12,"));
+    QCOMPARE(dblInput->hasAcceptableInput(), true);
+    QTest::keyPress(&canvas, Qt::Key_1);
+    QTest::keyRelease(&canvas, Qt::Key_1, Qt::NoModifier ,10);
+    QTest::qWait(50);
+    QTRY_COMPARE(dblInput->text(), QLatin1String("12,"));
+    QCOMPARE(dblInput->hasAcceptableInput(), true);
+    dblValidator->setLocaleName(deLocale.name());
+    QCOMPARE(dblInput->hasAcceptableInput(), true);
+    QTest::keyPress(&canvas, Qt::Key_1);
+    QTest::keyRelease(&canvas, Qt::Key_1, Qt::NoModifier ,10);
+    QTest::qWait(50);
+    QTRY_COMPARE(dblInput->text(), QLatin1String("12,1"));
+    QCOMPARE(dblInput->hasAcceptableInput(), true);
+    QTest::keyPress(&canvas, Qt::Key_1);
+    QTest::keyRelease(&canvas, Qt::Key_1, Qt::NoModifier ,10);
+    QTest::qWait(50);
+    QTRY_COMPARE(dblInput->text(), QLatin1String("12,11"));
+    QCOMPARE(dblInput->hasAcceptableInput(), true);
+    QTest::keyPress(&canvas, Qt::Key_Backspace);
+    QTest::keyRelease(&canvas, Qt::Key_Backspace, Qt::NoModifier ,10);
+    QTest::qWait(50);
+    QTRY_COMPARE(dblInput->text(), QLatin1String("12,1"));
+    QCOMPARE(dblInput->hasAcceptableInput(), true);
+    QTest::keyPress(&canvas, Qt::Key_Backspace);
+    QTest::keyRelease(&canvas, Qt::Key_Backspace, Qt::NoModifier ,10);
+    QTest::qWait(50);
+    QTRY_COMPARE(dblInput->text(), QLatin1String("12,"));
+    QCOMPARE(dblInput->hasAcceptableInput(), true);
+    QTest::keyPress(&canvas, Qt::Key_Backspace);
+    QTest::keyRelease(&canvas, Qt::Key_Backspace, Qt::NoModifier ,10);
+    QTest::qWait(50);
+    QTRY_COMPARE(dblInput->text(), QLatin1String("12"));
+    QCOMPARE(dblInput->hasAcceptableInput(), true);
+    dblValidator->resetLocaleName();
     QTest::keyPress(&canvas, Qt::Key_Period);
     QTest::keyRelease(&canvas, Qt::Key_Period, Qt::NoModifier ,10);
     QTest::qWait(50);