From 2d8910cbeda8e88223fa386e4398f13b455fd7ca Mon Sep 17 00:00:00 2001 From: Giuseppe D'Angelo Date: Thu, 15 Mar 2012 09:02:19 +0000 Subject: Introduce QRegularExpressionValidator QRegularExpression counterpart for QRegExpValidator. Change-Id: Ib391e73dd49e32aeb9b48e6f2217b67a17a83a11 Reviewed-by: David Faure Reviewed-by: Gunnar Sletta --- .../doc/snippets/code/src_gui_util_qvalidator.cpp | 43 ++++++ src/gui/util/qvalidator.cpp | 154 +++++++++++++++++++++ src/gui/util/qvalidator.h | 33 +++++ 3 files changed, 230 insertions(+) (limited to 'src/gui') diff --git a/src/gui/doc/snippets/code/src_gui_util_qvalidator.cpp b/src/gui/doc/snippets/code/src_gui_util_qvalidator.cpp index f571705558..c39a4dec99 100644 --- a/src/gui/doc/snippets/code/src_gui_util_qvalidator.cpp +++ b/src/gui/doc/snippets/code/src_gui_util_qvalidator.cpp @@ -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] diff --git a/src/gui/util/qvalidator.cpp b/src/gui/util/qvalidator.cpp index 6231a097d3..0d38ebaf14 100644 --- a/src/gui/util/qvalidator.cpp +++ b/src/gui/util/qvalidator.cpp @@ -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 ** 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 diff --git a/src/gui/util/qvalidator.h b/src/gui/util/qvalidator.h index e4aa55d578..53acdfb31e 100644 --- a/src/gui/util/qvalidator.h +++ b/src/gui/util/qvalidator.h @@ -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 ** Contact: http://www.qt-project.org/legal ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -45,6 +46,7 @@ #include #include #include +#include #include 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 -- cgit v1.2.3