From 8df8bc5062bf5848a616792c79dddd1626014072 Mon Sep 17 00:00:00 2001 From: Andrew den Exter Date: Thu, 19 Jan 2012 15:53:20 +1000 Subject: [PATCH] Add a locale property to IntValidator and DoubleValidator. 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 --- src/quick/items/qquickitemsmodule.cpp | 4 +- src/quick/items/qquicktextinput.cpp | 80 +++++++++++++++++- src/quick/items/qquicktextinput_p.h | 36 +++++++- .../qquicktextinput/tst_qquicktextinput.cpp | 95 ++++++++++++++++++++++ 4 files changed, 207 insertions(+), 8 deletions(-) diff --git a/src/quick/items/qquickitemsmodule.cpp b/src/quick/items/qquickitemsmodule.cpp index b82a90d..3ecf5d0 100644 --- a/src/quick/items/qquickitemsmodule.cpp +++ b/src/quick/items/qquickitemsmodule.cpp @@ -145,8 +145,8 @@ static void qt_quickitems_defineModule(const char *uri, int major, int minor) qmlRegisterUncreatableType(uri,major,minor,"Positioner", QStringLiteral("Positioner is an abstract type that is only available as an attached property.")); #ifndef QT_NO_VALIDATOR - qmlRegisterType(uri,major,minor,"IntValidator"); - qmlRegisterType(uri,major,minor,"DoubleValidator"); + qmlRegisterType(uri,major,minor,"IntValidator"); + qmlRegisterType(uri,major,minor,"DoubleValidator"); qmlRegisterType(uri,major,minor,"RegExpValidator"); #endif qmlRegisterType(uri,major,minor,"Rectangle"); diff --git a/src/quick/items/qquicktextinput.cpp b/src/quick/items/qquicktextinput.cpp index 237db35..08892e1 100644 --- a/src/quick/items/qquicktextinput.cpp +++ b/src/quick/items/qquicktextinput.cpp @@ -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 diff --git a/src/quick/items/qquicktextinput_p.h b/src/quick/items/qquicktextinput_p.h index 92d09c3..a98c5ee 100644 --- a/src/quick/items/qquicktextinput_p.h +++ b/src/quick/items/qquicktextinput_p.h @@ -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 diff --git a/tests/auto/qtquick2/qquicktextinput/tst_qquicktextinput.cpp b/tests/auto/qtquick2/qquicktextinput/tst_qquicktextinput.cpp index a4b1b1c..cae38bc 100644 --- a/tests/auto/qtquick2/qquicktextinput/tst_qquicktextinput.cpp +++ b/tests/auto/qtquick2/qquicktextinput/tst_qquicktextinput.cpp @@ -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(qvariant_cast(canvas.rootObject()->property("intInput"))); QVERIFY(intInput); QSignalSpy intSpy(intInput, SIGNAL(acceptableInputChanged())); + + QQuickIntValidator *intValidator = qobject_cast(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(qvariant_cast(canvas.rootObject()->property("dblInput"))); QVERIFY(dblInput); QSignalSpy dblSpy(dblInput, SIGNAL(acceptableInputChanged())); + + QQuickDoubleValidator *dblValidator = qobject_cast(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); -- 2.7.4