Introduce QRegularExpressionValidator
QRegularExpression counterpart for QRegExpValidator. Change-Id: Ib391e73dd49e32aeb9b48e6f2217b67a17a83a11 Reviewed-by: David Faure <david.faure@kdab.com> Reviewed-by: Gunnar Sletta <gunnar.sletta@digia.com>
This commit is contained in:
parent
ca2f44680c
commit
2d8910cbed
@ -133,3 +133,46 @@ s = "README.1ST"; v.validate(s, pos); // Returns Acceptable
|
||||
s = "read me.txt"; v.validate(s, pos); // Returns Invalid
|
||||
s = "readm"; v.validate(s, pos); // Returns Intermediate
|
||||
//! [4]
|
||||
|
||||
//! [5]
|
||||
// regexp: optional '-' followed by between 1 and 3 digits
|
||||
QRegularExpression rx("-?\\d{1,3}");
|
||||
QValidator *validator = new QRegularExpressionValidator(rx, this);
|
||||
|
||||
QLineEdit *edit = new QLineEdit(this);
|
||||
edit->setValidator(validator);
|
||||
//! [5]
|
||||
|
||||
//! [6]
|
||||
// integers 1 to 9999
|
||||
QRegularExpression re("[1-9]\\d{0,3}");
|
||||
// the validator treats the regexp as "^[1-9]\\d{0,3}$"
|
||||
QRegularExpressionValidator v(re, 0);
|
||||
QString s;
|
||||
int pos = 0;
|
||||
|
||||
s = "0"; v.validate(s, pos); // returns Invalid
|
||||
s = "12345"; v.validate(s, pos); // returns Invalid
|
||||
s = "1"; v.validate(s, pos); // returns Acceptable
|
||||
|
||||
re.setPattern("\\S+"); // one or more non-whitespace characters
|
||||
v.setRegularExpression(re);
|
||||
s = "myfile.txt"; v.validate(s, pos); // Returns Acceptable
|
||||
s = "my file.txt"; v.validate(s, pos); // Returns Invalid
|
||||
|
||||
// A, B or C followed by exactly five digits followed by W, X, Y or Z
|
||||
re.setPattern("[A-C]\\d{5}[W-Z]");
|
||||
v.setRegularExpression(re);
|
||||
s = "a12345Z"; v.validate(s, pos); // Returns Invalid
|
||||
s = "A12345Z"; v.validate(s, pos); // Returns Acceptable
|
||||
s = "B12"; v.validate(s, pos); // Returns Intermediate
|
||||
|
||||
// match most 'readme' files
|
||||
re.setPattern("read\\S?me(\.(txt|asc|1st))?");
|
||||
re.setPatternOptions(QRegularExpression::CaseInsensitiveOption);
|
||||
v.setRegularExpression(re);
|
||||
s = "readme"; v.validate(s, pos); // Returns Acceptable
|
||||
s = "README.1ST"; v.validate(s, pos); // Returns Acceptable
|
||||
s = "read me.txt"; v.validate(s, pos); // Returns Invalid
|
||||
s = "readm"; v.validate(s, pos); // Returns Intermediate
|
||||
//! [6]
|
||||
|
@ -1,6 +1,7 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
|
||||
** Copyright (C) 2012 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the QtGui module of the Qt Toolkit.
|
||||
@ -906,6 +907,159 @@ void QRegExpValidator::setRegExp(const QRegExp& rx)
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef QT_NO_REGEXP
|
||||
|
||||
/*!
|
||||
\class QRegularExpressionValidator
|
||||
\brief The QRegularExpressionValidator class is used to check a string
|
||||
against a regular expression.
|
||||
|
||||
\since 5.1
|
||||
|
||||
QRegularExpressionValidator uses a regular expression (regexp) to
|
||||
determine whether an input string is \l Acceptable, \l
|
||||
Intermediate, or \l Invalid. The regexp can either be supplied
|
||||
when the QRegularExpressionValidator is constructed, or at a later time.
|
||||
|
||||
If the regexp partially matches against the string, the result is
|
||||
considered \l Intermediate. For example, "" and "A" are \l Intermediate for
|
||||
the regexp \b{[A-Z][0-9]} (whereas "_" would be \l Invalid).
|
||||
|
||||
QRegularExpressionValidator automatically wraps the regular expression in
|
||||
the \c{\\A} and \c{\\z} anchors; in other words, it always attempts to do
|
||||
an exact match.
|
||||
|
||||
Example of use:
|
||||
\snippet code/src_gui_util_qvalidator.cpp 5
|
||||
|
||||
Below we present some examples of validators. In practice they would
|
||||
normally be associated with a widget as in the example above.
|
||||
|
||||
\snippet code/src_gui_util_qvalidator.cpp 6
|
||||
|
||||
\sa QRegularExpression, QIntValidator, QDoubleValidator, QRegExpValidator
|
||||
*/
|
||||
|
||||
class QRegularExpressionValidatorPrivate : public QValidatorPrivate
|
||||
{
|
||||
Q_DECLARE_PUBLIC(QRegularExpressionValidator)
|
||||
|
||||
public:
|
||||
QRegularExpression origRe; // the one set by the user
|
||||
QRegularExpression usedRe; // the one actually used
|
||||
void setRegularExpression(const QRegularExpression &re);
|
||||
};
|
||||
|
||||
/*!
|
||||
Constructs a validator with a \a parent object that accepts
|
||||
any string (including an empty one) as valid.
|
||||
*/
|
||||
|
||||
QRegularExpressionValidator::QRegularExpressionValidator(QObject *parent)
|
||||
: QValidator(*new QRegularExpressionValidatorPrivate, parent)
|
||||
{
|
||||
// origRe in the private will be an empty QRegularExpression,
|
||||
// and therefore this validator will match any string.
|
||||
}
|
||||
|
||||
/*!
|
||||
Constructs a validator with a \a parent object that
|
||||
accepts all strings that match the regular expression \a re.
|
||||
*/
|
||||
|
||||
QRegularExpressionValidator::QRegularExpressionValidator(const QRegularExpression &re, QObject *parent)
|
||||
: QValidator(*new QRegularExpressionValidatorPrivate, parent)
|
||||
{
|
||||
Q_D(QRegularExpressionValidator);
|
||||
d->setRegularExpression(re);
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
Destroys the validator.
|
||||
*/
|
||||
|
||||
QRegularExpressionValidator::~QRegularExpressionValidator()
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns \l Acceptable if \a input is matched by the regular expression for
|
||||
this validator, \l Intermediate if it has matched partially (i.e. could be
|
||||
a valid match if additional valid characters are added), and \l Invalid if
|
||||
\a input is not matched.
|
||||
|
||||
In case the \a input is not matched, the \a pos parameter is set to
|
||||
the length of the \a input parameter; otherwise, it is not modified.
|
||||
|
||||
For example, if the regular expression is \b{\\w\\d\\d} (word-character,
|
||||
digit, digit) then "A57" is \l Acceptable, "E5" is \l Intermediate, and
|
||||
"+9" is \l Invalid.
|
||||
|
||||
\sa QRegularExpression::match()
|
||||
*/
|
||||
|
||||
QValidator::State QRegularExpressionValidator::validate(QString &input, int &pos) const
|
||||
{
|
||||
Q_D(const QRegularExpressionValidator);
|
||||
|
||||
// We want a validator with an empty QRegularExpression to match anything;
|
||||
// since we're going to do an exact match (by using d->usedRe), first check if the rx is empty
|
||||
// (and, if so, accept the input).
|
||||
if (d->origRe.pattern().isEmpty())
|
||||
return Acceptable;
|
||||
|
||||
const QRegularExpressionMatch m = d->usedRe.match(input, 0, QRegularExpression::PartialPreferCompleteMatch);
|
||||
if (m.hasMatch()) {
|
||||
return Acceptable;
|
||||
} else if (m.hasPartialMatch()) {
|
||||
return Intermediate;
|
||||
} else {
|
||||
pos = input.size();
|
||||
return Invalid;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\property QRegularExpressionValidator::regularExpression
|
||||
\brief the regular expression used for validation
|
||||
|
||||
By default, this property contains a regular expression with an empty
|
||||
pattern (which therefore matches any string).
|
||||
*/
|
||||
|
||||
QRegularExpression QRegularExpressionValidator::regularExpression() const
|
||||
{
|
||||
Q_D(const QRegularExpressionValidator);
|
||||
return d->origRe;
|
||||
}
|
||||
|
||||
void QRegularExpressionValidator::setRegularExpression(const QRegularExpression &re)
|
||||
{
|
||||
Q_D(QRegularExpressionValidator);
|
||||
d->setRegularExpression(re);
|
||||
}
|
||||
|
||||
/*!
|
||||
\internal
|
||||
|
||||
Sets \a re as the regular expression. It wraps the regexp that's actually used
|
||||
between \\A and \\z, therefore forcing an exact match.
|
||||
*/
|
||||
void QRegularExpressionValidatorPrivate::setRegularExpression(const QRegularExpression &re)
|
||||
{
|
||||
Q_Q(QRegularExpressionValidator);
|
||||
|
||||
if (origRe != re) {
|
||||
usedRe = origRe = re; // copies also the pattern options
|
||||
usedRe.setPattern(QStringLiteral("\\A(?:") + re.pattern() + QStringLiteral(")\\z"));
|
||||
emit q->regularExpressionChanged(re);
|
||||
emit q->changed();
|
||||
}
|
||||
}
|
||||
|
||||
#endif // QT_NO_REGEXP
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QT_NO_VALIDATOR
|
||||
|
@ -1,6 +1,7 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
|
||||
** Copyright (C) 2012 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the QtGui module of the Qt Toolkit.
|
||||
@ -45,6 +46,7 @@
|
||||
#include <QtCore/qobject.h>
|
||||
#include <QtCore/qstring.h>
|
||||
#include <QtCore/qregexp.h>
|
||||
#include <QtCore/qregularexpression.h>
|
||||
#include <QtCore/qlocale.h>
|
||||
|
||||
QT_BEGIN_HEADER
|
||||
@ -195,6 +197,37 @@ private:
|
||||
|
||||
#endif // QT_NO_REGEXP
|
||||
|
||||
#ifndef QT_NO_REGEXP
|
||||
|
||||
class QRegularExpressionValidatorPrivate;
|
||||
|
||||
class Q_GUI_EXPORT QRegularExpressionValidator : public QValidator
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(QRegularExpression regularExpression READ regularExpression WRITE setRegularExpression NOTIFY regularExpressionChanged)
|
||||
|
||||
public:
|
||||
explicit QRegularExpressionValidator(QObject *parent = 0);
|
||||
explicit QRegularExpressionValidator(const QRegularExpression &re, QObject *parent = 0);
|
||||
~QRegularExpressionValidator();
|
||||
|
||||
virtual QValidator::State validate(QString &input, int &pos) const Q_DECL_OVERRIDE;
|
||||
|
||||
QRegularExpression regularExpression() const;
|
||||
|
||||
public Q_SLOTS:
|
||||
void setRegularExpression(const QRegularExpression &re);
|
||||
|
||||
Q_SIGNALS:
|
||||
void regularExpressionChanged(const QRegularExpression &re);
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY(QRegularExpressionValidator)
|
||||
Q_DECLARE_PRIVATE(QRegularExpressionValidator)
|
||||
};
|
||||
|
||||
#endif // QT_NO_REGEXP
|
||||
|
||||
#endif // QT_NO_VALIDATOR
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
1
tests/auto/gui/util/qregularexpressionvalidator/.gitignore
vendored
Normal file
1
tests/auto/gui/util/qregularexpressionvalidator/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
tst_qregularexpressionvalidator
|
@ -0,0 +1,4 @@
|
||||
CONFIG += testcase parallel_test
|
||||
TARGET = tst_qregularexpressionvalidator
|
||||
SOURCES += tst_qregularexpressionvalidator.cpp
|
||||
QT += testlib
|
@ -0,0 +1,120 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
|
||||
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the test suite of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Digia. For licensing terms and
|
||||
** conditions see http://qt.digia.com/licensing. For further information
|
||||
** use the contact form at http://qt.digia.com/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Digia gives you certain additional
|
||||
** rights. These rights are described in the Digia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <QtGui/QRegularExpressionValidator>
|
||||
#include <QtTest/QtTest>
|
||||
|
||||
class tst_QRegularExpressionValidator : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private slots:
|
||||
void validate_data();
|
||||
void validate();
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(QValidator::State)
|
||||
|
||||
void tst_QRegularExpressionValidator::validate_data()
|
||||
{
|
||||
QTest::addColumn<QRegularExpression>("re");
|
||||
QTest::addColumn<QString>("value");
|
||||
QTest::addColumn<QValidator::State>("state");
|
||||
|
||||
QTest::newRow("data0") << QRegularExpression("[1-9]\\d{0,3}") << QString("0") << QValidator::Invalid;
|
||||
QTest::newRow("data1") << QRegularExpression("[1-9]\\d{0,3}") << QString("12345") << QValidator::Invalid;
|
||||
QTest::newRow("data2") << QRegularExpression("[1-9]\\d{0,3}") << QString("1") << QValidator::Acceptable;
|
||||
|
||||
QTest::newRow("data3") << QRegularExpression("\\S+") << QString("myfile.txt") << QValidator::Acceptable;
|
||||
QTest::newRow("data4") << QRegularExpression("\\S+") << QString("my file.txt") << QValidator::Invalid;
|
||||
|
||||
QTest::newRow("data5") << QRegularExpression("[A-C]\\d{5}[W-Z]") << QString("a12345Z") << QValidator::Invalid;
|
||||
QTest::newRow("data6") << QRegularExpression("[A-C]\\d{5}[W-Z]") << QString("A12345Z") << QValidator::Acceptable;
|
||||
QTest::newRow("data7") << QRegularExpression("[A-C]\\d{5}[W-Z]") << QString("B12") << QValidator::Intermediate;
|
||||
|
||||
QTest::newRow("data8") << QRegularExpression("read\\S?me(\\.(txt|asc|1st))?") << QString("readme") << QValidator::Acceptable;
|
||||
QTest::newRow("data9") << QRegularExpression("read\\S?me(\\.(txt|asc|1st))?") << QString("read me.txt") << QValidator::Invalid;
|
||||
QTest::newRow("data10") << QRegularExpression("read\\S?me(\\.(txt|asc|1st))?") << QString("readm") << QValidator::Intermediate;
|
||||
|
||||
QTest::newRow("data11") << QRegularExpression("read\\S?me(\\.(txt|asc|1st))?") << QString("read me.txt") << QValidator::Invalid;
|
||||
QTest::newRow("data12") << QRegularExpression("read\\S?me(\\.(txt|asc|1st))?") << QString("readm") << QValidator::Intermediate;
|
||||
|
||||
QTest::newRow("data13") << QRegularExpression("\\w\\d\\d") << QString("A57") << QValidator::Acceptable;
|
||||
QTest::newRow("data14") << QRegularExpression("\\w\\d\\d") << QString("E5") << QValidator::Intermediate;
|
||||
QTest::newRow("data15") << QRegularExpression("\\w\\d\\d") << QString("+9") << QValidator::Invalid;
|
||||
|
||||
QTest::newRow("empty01") << QRegularExpression() << QString() << QValidator::Acceptable;
|
||||
QTest::newRow("empty02") << QRegularExpression() << QString("test") << QValidator::Acceptable;
|
||||
}
|
||||
|
||||
void tst_QRegularExpressionValidator::validate()
|
||||
{
|
||||
QFETCH(QRegularExpression, re);
|
||||
QFETCH(QString, value);
|
||||
|
||||
QRegularExpressionValidator rv;
|
||||
|
||||
// setting the same regexp won't emit signals
|
||||
const int signalCount = (rv.regularExpression() == re) ? 0 : 1;
|
||||
|
||||
QSignalSpy spy(&rv, SIGNAL(regularExpressionChanged(QRegularExpression)));
|
||||
QSignalSpy changedSpy(&rv, SIGNAL(changed()));
|
||||
|
||||
rv.setRegularExpression(re);
|
||||
QCOMPARE(rv.regularExpression(), re);
|
||||
|
||||
int pos = -1;
|
||||
QValidator::State result = rv.validate(value, pos);
|
||||
|
||||
QTEST(result, "state");
|
||||
if (result == QValidator::Invalid)
|
||||
QCOMPARE(pos, value.length());
|
||||
else
|
||||
QCOMPARE(pos, -1); // ensure pos is not modified if validate returned Acceptable or Intermediate
|
||||
|
||||
QCOMPARE(spy.count(), signalCount);
|
||||
QCOMPARE(changedSpy.count(), signalCount);
|
||||
}
|
||||
|
||||
QTEST_GUILESS_MAIN(tst_QRegularExpressionValidator)
|
||||
|
||||
#include "tst_qregularexpressionvalidator.moc"
|
@ -4,4 +4,5 @@ SUBDIRS= \
|
||||
qdoublevalidator \
|
||||
qintvalidator \
|
||||
qregexpvalidator \
|
||||
qregularexpressionvalidator \
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user