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 <martin.jones@nokia.com>
This commit is contained in:
Andrew den Exter 2012-01-19 15:53:20 +10:00 committed by Qt by Nokia
parent 100f7ee211
commit 8df8bc5062
4 changed files with 207 additions and 8 deletions

View File

@ -145,8 +145,8 @@ static void qt_quickitems_defineModule(const char *uri, int major, int minor)
qmlRegisterUncreatableType<QQuickBasePositioner>(uri,major,minor,"Positioner", qmlRegisterUncreatableType<QQuickBasePositioner>(uri,major,minor,"Positioner",
QStringLiteral("Positioner is an abstract type that is only available as an attached property.")); QStringLiteral("Positioner is an abstract type that is only available as an attached property."));
#ifndef QT_NO_VALIDATOR #ifndef QT_NO_VALIDATOR
qmlRegisterType<QIntValidator>(uri,major,minor,"IntValidator"); qmlRegisterType<QQuickIntValidator>(uri,major,minor,"IntValidator");
qmlRegisterType<QDoubleValidator>(uri,major,minor,"DoubleValidator"); qmlRegisterType<QQuickDoubleValidator>(uri,major,minor,"DoubleValidator");
qmlRegisterType<QRegExpValidator>(uri,major,minor,"RegExpValidator"); qmlRegisterType<QRegExpValidator>(uri,major,minor,"RegExpValidator");
#endif #endif
qmlRegisterType<QQuickRectangle>(uri,major,minor,"Rectangle"); qmlRegisterType<QQuickRectangle>(uri,major,minor,"Rectangle");

View File

@ -823,11 +823,48 @@ void QQuickTextInput::setAutoScroll(bool b)
This element provides a validator for integer values. This element provides a validator for integer values.
IntValidator uses the \l {QLocale::setDefault()}{default locale} to interpret the number and If no \l locale is set IntValidator uses the \l {QLocale::setDefault()}{default locale} to
will accept locale specific digits, group separators, and positive and negative signs. In interpret the number and will accept locale specific digits, group separators, and positive
addition, IntValidator is always guaranteed to accept a number formatted according to the "C" and negative signs. In addition, IntValidator is always guaranteed to accept a number
locale. 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 \qmlproperty int QtQuick2::IntValidator::top
@ -866,6 +903,41 @@ void QQuickTextInput::setAutoScroll(bool b)
value may yet become valid by changing the exponent. 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 \qmlproperty real QtQuick2::DoubleValidator::top

View File

@ -330,13 +330,45 @@ private:
Q_DECLARE_PRIVATE(QQuickTextInput) 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 QT_END_NAMESPACE
QML_DECLARE_TYPE(QQuickTextInput) QML_DECLARE_TYPE(QQuickTextInput)
#ifndef QT_NO_VALIDATOR #ifndef QT_NO_VALIDATOR
QML_DECLARE_TYPE(QValidator) QML_DECLARE_TYPE(QValidator)
QML_DECLARE_TYPE(QIntValidator) QML_DECLARE_TYPE(QQuickIntValidator)
QML_DECLARE_TYPE(QDoubleValidator) QML_DECLARE_TYPE(QQuickDoubleValidator)
QML_DECLARE_TYPE(QRegExpValidator) QML_DECLARE_TYPE(QRegExpValidator)
#endif #endif

View File

@ -1565,15 +1565,33 @@ void tst_qquicktextinput::validators()
// so you may need to run their tests first. All validators are checked // so you may need to run their tests first. All validators are checked
// here to ensure that their exposure to QML is working. // here to ensure that their exposure to QML is working.
QLocale::setDefault(QLocale(QStringLiteral("C")));
QQuickView canvas(testFileUrl("validators.qml")); QQuickView canvas(testFileUrl("validators.qml"));
canvas.show(); canvas.show();
canvas.requestActivateWindow(); canvas.requestActivateWindow();
QVERIFY(canvas.rootObject() != 0); 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"))); QQuickTextInput *intInput = qobject_cast<QQuickTextInput *>(qvariant_cast<QObject *>(canvas.rootObject()->property("intInput")));
QVERIFY(intInput); QVERIFY(intInput);
QSignalSpy intSpy(intInput, SIGNAL(acceptableInputChanged())); 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); intInput->setFocus(true);
QTRY_VERIFY(intInput->hasActiveFocus()); QTRY_VERIFY(intInput->hasActiveFocus());
QCOMPARE(intInput->hasAcceptableInput(), false); QCOMPARE(intInput->hasAcceptableInput(), false);
@ -1592,6 +1610,33 @@ void tst_qquicktextinput::validators()
QCOMPARE(intInput->hasAcceptableInput(), false); QCOMPARE(intInput->hasAcceptableInput(), false);
QCOMPARE(intInput->property("acceptable").toBool(), false); QCOMPARE(intInput->property("acceptable").toBool(), false);
QCOMPARE(intSpy.count(), 0); 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::keyPress(&canvas, Qt::Key_1);
QTest::keyRelease(&canvas, Qt::Key_1, Qt::NoModifier ,10); QTest::keyRelease(&canvas, Qt::Key_1, Qt::NoModifier ,10);
QTest::qWait(50); QTest::qWait(50);
@ -1610,6 +1655,18 @@ void tst_qquicktextinput::validators()
QQuickTextInput *dblInput = qobject_cast<QQuickTextInput *>(qvariant_cast<QObject *>(canvas.rootObject()->property("dblInput"))); QQuickTextInput *dblInput = qobject_cast<QQuickTextInput *>(qvariant_cast<QObject *>(canvas.rootObject()->property("dblInput")));
QVERIFY(dblInput); QVERIFY(dblInput);
QSignalSpy dblSpy(dblInput, SIGNAL(acceptableInputChanged())); 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); dblInput->setFocus(true);
QVERIFY(dblInput->hasActiveFocus() == true); QVERIFY(dblInput->hasActiveFocus() == true);
QCOMPARE(dblInput->hasAcceptableInput(), false); QCOMPARE(dblInput->hasAcceptableInput(), false);
@ -1628,6 +1685,44 @@ void tst_qquicktextinput::validators()
QCOMPARE(dblInput->hasAcceptableInput(), true); QCOMPARE(dblInput->hasAcceptableInput(), true);
QCOMPARE(dblInput->property("acceptable").toBool(), true); QCOMPARE(dblInput->property("acceptable").toBool(), true);
QCOMPARE(dblSpy.count(), 1); 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::keyPress(&canvas, Qt::Key_Period);
QTest::keyRelease(&canvas, Qt::Key_Period, Qt::NoModifier ,10); QTest::keyRelease(&canvas, Qt::Key_Period, Qt::NoModifier ,10);
QTest::qWait(50); QTest::qWait(50);