QAbstractItemModel: implement QRegularExpression support for match
This is part of the migration of qtbase from QRexExp to QRegularExpression. [ChangeLog][QtCore][QAbstractItemModel] The match() method now supports the new Qt::RegularExpression match flag value. This will allow users to use either a string or a fully configured QRegularExpression when doing searches. In the second case, the case sensitivity flag will be ignored if passed. Task-number: QTBUG-72587 Change-Id: I07c8d72a661c48b7f4fcf13ef8e95980bcdcb998 Reviewed-by: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
This commit is contained in:
parent
85ed676dff
commit
c222a9283d
@ -1575,9 +1575,12 @@ public:
|
|||||||
MatchContains = 1,
|
MatchContains = 1,
|
||||||
MatchStartsWith = 2,
|
MatchStartsWith = 2,
|
||||||
MatchEndsWith = 3,
|
MatchEndsWith = 3,
|
||||||
MatchRegExp = 4,
|
#if QT_DEPRECATED_SINCE(5, 15)
|
||||||
|
MatchRegExp Q_DECL_ENUMERATOR_DEPRECATED_X("MatchRegExp is deprecated. Use MatchRegularExpression instead") = 4,
|
||||||
|
#endif
|
||||||
MatchWildcard = 5,
|
MatchWildcard = 5,
|
||||||
MatchFixedString = 8,
|
MatchFixedString = 8,
|
||||||
|
MatchRegularExpression = 9,
|
||||||
MatchCaseSensitive = 16,
|
MatchCaseSensitive = 16,
|
||||||
MatchWrap = 32,
|
MatchWrap = 32,
|
||||||
MatchRecursive = 64
|
MatchRecursive = 64
|
||||||
|
@ -2840,24 +2840,32 @@
|
|||||||
This enum describes the type of matches that can be used when searching
|
This enum describes the type of matches that can be used when searching
|
||||||
for items in a model.
|
for items in a model.
|
||||||
|
|
||||||
\value MatchExactly Performs QVariant-based matching.
|
\value MatchExactly Performs QVariant-based matching.
|
||||||
\value MatchFixedString Performs string-based matching.
|
\value MatchFixedString Performs string-based matching.
|
||||||
String-based comparisons are case-insensitive unless the
|
String-based comparisons are case-insensitive unless the
|
||||||
\c MatchCaseSensitive flag is also specified.
|
\c MatchCaseSensitive flag is also specified.
|
||||||
\value MatchContains The search term is contained in the item.
|
\value MatchContains The search term is contained in the item.
|
||||||
\value MatchStartsWith The search term matches the start of the item.
|
\value MatchStartsWith The search term matches the start of the item.
|
||||||
\value MatchEndsWith The search term matches the end of the item.
|
\value MatchEndsWith The search term matches the end of the item.
|
||||||
\value MatchCaseSensitive The search is case sensitive.
|
\value MatchCaseSensitive The search is case sensitive.
|
||||||
\value MatchRegExp Performs string-based matching using a regular
|
\value MatchRegExp Performs string-based matching using a regular
|
||||||
expression as the search term.
|
expression as the search term. Uses the deprecated QRegExp class.
|
||||||
\value MatchWildcard Performs string-based matching using a string with
|
\e{This enum value is deprecated since Qt 5.15.}
|
||||||
|
\value MatchRegularExpression Performs string-based matching using a regular
|
||||||
|
expression as the search term. Uses QRegularExpression.
|
||||||
|
When using this flag, a QRegularExpression object can be passed as
|
||||||
|
parameter and will directly be used to perform the search. The case
|
||||||
|
sensitivity flag will be ignored as the QRegularExpression object is
|
||||||
|
expected to be fully configured.
|
||||||
|
This enum value was added in Qt 5.15.
|
||||||
|
\value MatchWildcard Performs string-based matching using a string with
|
||||||
wildcards as the search term.
|
wildcards as the search term.
|
||||||
\value MatchWrap Perform a search that wraps around, so that when
|
\value MatchWrap Perform a search that wraps around, so that when
|
||||||
the search reaches the last item in the model, it begins again at
|
the search reaches the last item in the model, it begins again at
|
||||||
the first item and continues until all items have been examined.
|
the first item and continues until all items have been examined.
|
||||||
\value MatchRecursive Searches the entire hierarchy.
|
\value MatchRecursive Searches the entire hierarchy.
|
||||||
|
|
||||||
\sa QString::compare(), QRegExp
|
\sa QString::compare(), QRegExp, QRegularExpression
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
@ -46,6 +46,7 @@
|
|||||||
#include <qdebug.h>
|
#include <qdebug.h>
|
||||||
#include <qvector.h>
|
#include <qvector.h>
|
||||||
#include <qregexp.h>
|
#include <qregexp.h>
|
||||||
|
#include <qregularexpression.h>
|
||||||
#include <qstack.h>
|
#include <qstack.h>
|
||||||
#include <qbitarray.h>
|
#include <qbitarray.h>
|
||||||
#include <qdatetime.h>
|
#include <qdatetime.h>
|
||||||
@ -2358,6 +2359,7 @@ QModelIndexList QAbstractItemModel::match(const QModelIndex &start, int role,
|
|||||||
bool wrap = flags & Qt::MatchWrap;
|
bool wrap = flags & Qt::MatchWrap;
|
||||||
bool allHits = (hits == -1);
|
bool allHits = (hits == -1);
|
||||||
QString text; // only convert to a string if it is needed
|
QString text; // only convert to a string if it is needed
|
||||||
|
QRegularExpression rx; // only create it if needed
|
||||||
const int column = start.column();
|
const int column = start.column();
|
||||||
QModelIndex p = parent(start);
|
QModelIndex p = parent(start);
|
||||||
int from = start.row();
|
int from = start.row();
|
||||||
@ -2374,17 +2376,39 @@ QModelIndexList QAbstractItemModel::match(const QModelIndex &start, int role,
|
|||||||
if (matchType == Qt::MatchExactly) {
|
if (matchType == Qt::MatchExactly) {
|
||||||
if (value == v)
|
if (value == v)
|
||||||
result.append(idx);
|
result.append(idx);
|
||||||
} else { // QString based matching
|
} else { // QString or regular expression based matching
|
||||||
if (text.isEmpty()) // lazy conversion
|
if (matchType == Qt::MatchRegularExpression) {
|
||||||
text = value.toString();
|
if (rx.pattern().isEmpty()) {
|
||||||
|
if (value.type() == QVariant::RegularExpression) {
|
||||||
|
rx = value.toRegularExpression();
|
||||||
|
} else {
|
||||||
|
rx.setPattern(value.toString());
|
||||||
|
if (cs == Qt::CaseInsensitive)
|
||||||
|
rx.setPatternOptions(QRegularExpression::CaseInsensitiveOption);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (matchType == Qt::MatchWildcard) {
|
||||||
|
if (rx.pattern().isEmpty())
|
||||||
|
rx.setPattern(QRegularExpression::wildcardToRegularExpression(value.toString()));
|
||||||
|
if (cs == Qt::CaseInsensitive)
|
||||||
|
rx.setPatternOptions(QRegularExpression::CaseInsensitiveOption);
|
||||||
|
} else {
|
||||||
|
if (text.isEmpty()) // lazy conversion
|
||||||
|
text = value.toString();
|
||||||
|
}
|
||||||
|
|
||||||
QString t = v.toString();
|
QString t = v.toString();
|
||||||
switch (matchType) {
|
switch (matchType) {
|
||||||
|
#if QT_DEPRECATED_SINCE(5, 15)
|
||||||
case Qt::MatchRegExp:
|
case Qt::MatchRegExp:
|
||||||
if (QRegExp(text, cs).exactMatch(t))
|
if (QRegExp(text, cs).exactMatch(t))
|
||||||
result.append(idx);
|
result.append(idx);
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
|
case Qt::MatchRegularExpression:
|
||||||
|
Q_FALLTHROUGH();
|
||||||
case Qt::MatchWildcard:
|
case Qt::MatchWildcard:
|
||||||
if (QRegExp(text, cs, QRegExp::Wildcard).exactMatch(t))
|
if (t.contains(rx))
|
||||||
result.append(idx);
|
result.append(idx);
|
||||||
break;
|
break;
|
||||||
case Qt::MatchStartsWith:
|
case Qt::MatchStartsWith:
|
||||||
|
@ -458,6 +458,34 @@ void tst_QAbstractItemModel::match()
|
|||||||
res = model.match(start, Qt::DisplayRole, QVariant("bat"), -1,
|
res = model.match(start, Qt::DisplayRole, QVariant("bat"), -1,
|
||||||
Qt::MatchFixedString | Qt::MatchCaseSensitive);
|
Qt::MatchFixedString | Qt::MatchCaseSensitive);
|
||||||
QCOMPARE(res.count(), 1);
|
QCOMPARE(res.count(), 1);
|
||||||
|
|
||||||
|
res = model.match(start, Qt::DisplayRole, QVariant(".*O.*"), -1,
|
||||||
|
Qt::MatchRegularExpression);
|
||||||
|
QCOMPARE(res.count(), 2);
|
||||||
|
res = model.match(start, Qt::DisplayRole, QVariant(".*O.*"), -1,
|
||||||
|
Qt::MatchRegularExpression | Qt::MatchCaseSensitive);
|
||||||
|
QCOMPARE(res.count(), 0);
|
||||||
|
|
||||||
|
res = model.match(start, Qt::DisplayRole, QVariant(QRegularExpression(".*O.*")),
|
||||||
|
-1, Qt::MatchRegularExpression);
|
||||||
|
QCOMPARE(res.count(), 0);
|
||||||
|
res = model.match(start,
|
||||||
|
Qt::DisplayRole,
|
||||||
|
QVariant(QRegularExpression(".*O.*",
|
||||||
|
QRegularExpression::CaseInsensitiveOption)),
|
||||||
|
-1,
|
||||||
|
Qt::MatchRegularExpression);
|
||||||
|
QCOMPARE(res.count(), 2);
|
||||||
|
|
||||||
|
// Ensure that the case sensitivity is properly ignored when passing a
|
||||||
|
// QRegularExpression object.
|
||||||
|
res = model.match(start,
|
||||||
|
Qt::DisplayRole,
|
||||||
|
QVariant(QRegularExpression(".*O.*",
|
||||||
|
QRegularExpression::CaseInsensitiveOption)),
|
||||||
|
-1,
|
||||||
|
Qt::MatchRegularExpression | Qt::MatchCaseSensitive);
|
||||||
|
QCOMPARE(res.count(), 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef QPair<int, int> Position;
|
typedef QPair<int, int> Position;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user