Add support for QRegularExpression to QSortFilterProxyModel
This patch implements the support for QRegularExpression in QSortFilterProxyModel. [ChangeLog][QtCore][QSFPM] QSortFilterProxyModel now supports QRegularExpression. Task-number: QTBUG-46810 Change-Id: If932d55f98f9b8bcf3a72c03ffd51da52cb50ad1 Reviewed-by: Christian Ehrlicher <ch.ehrlicher@gmx.de> Reviewed-by: Luca Beldi <v.ronin@yahoo.it> Reviewed-by: David Faure <david.faure@kdab.com>
This commit is contained in:
parent
bcd80eebf9
commit
346c15102b
src/corelib/itemmodels
tests/auto/corelib/itemmodels
itemmodels.pro
qsortfilterproxymodel
qsortfilterproxymodel_common
qsortfilterproxymodel_regexp
qsortfilterproxymodel_regularexpression
@ -43,6 +43,7 @@
|
|||||||
#include <qdebug.h>
|
#include <qdebug.h>
|
||||||
#include <qdatetime.h>
|
#include <qdatetime.h>
|
||||||
#include <qpair.h>
|
#include <qpair.h>
|
||||||
|
#include <qregularexpression.h>
|
||||||
#include <qstringlist.h>
|
#include <qstringlist.h>
|
||||||
#include <private/qabstractitemmodel_p.h>
|
#include <private/qabstractitemmodel_p.h>
|
||||||
#include <private/qabstractproxymodel_p.h>
|
#include <private/qabstractproxymodel_p.h>
|
||||||
@ -146,6 +147,133 @@ private:
|
|||||||
int end;
|
int end;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class RegularExpressionData {
|
||||||
|
|
||||||
|
private:
|
||||||
|
enum class ExpressionType {
|
||||||
|
RegExp,
|
||||||
|
#if QT_CONFIG(regularexpression)
|
||||||
|
RegularExpression
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
RegularExpressionData() :
|
||||||
|
m_type(ExpressionType::RegExp)
|
||||||
|
{}
|
||||||
|
|
||||||
|
#if QT_CONFIG(regularexpression)
|
||||||
|
QRegularExpression regularExpression() const
|
||||||
|
{
|
||||||
|
if (m_type == ExpressionType::RegularExpression)
|
||||||
|
return m_regularExpression;
|
||||||
|
return QRegularExpression();
|
||||||
|
}
|
||||||
|
|
||||||
|
void setRegularExpression(const QRegularExpression &rx)
|
||||||
|
{
|
||||||
|
m_type = ExpressionType::RegularExpression;
|
||||||
|
m_regularExpression = rx;
|
||||||
|
m_regExp = QRegExp();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
QRegExp regExp() const
|
||||||
|
{
|
||||||
|
if (m_type == ExpressionType::RegExp)
|
||||||
|
return m_regExp;
|
||||||
|
return QRegExp();
|
||||||
|
}
|
||||||
|
|
||||||
|
void setRegExp(const QRegExp &rx)
|
||||||
|
{
|
||||||
|
m_type = ExpressionType::RegExp;
|
||||||
|
m_regExp = rx;
|
||||||
|
#if QT_CONFIG(regularexpression)
|
||||||
|
m_regularExpression = QRegularExpression();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isEmpty() const
|
||||||
|
{
|
||||||
|
bool result = true;
|
||||||
|
switch (m_type) {
|
||||||
|
case ExpressionType::RegExp:
|
||||||
|
result = m_regExp.isEmpty();
|
||||||
|
break;
|
||||||
|
#if QT_CONFIG(regularexpression)
|
||||||
|
case ExpressionType::RegularExpression:
|
||||||
|
result = m_regularExpression.pattern().isEmpty();
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
Qt::CaseSensitivity caseSensitivity() const
|
||||||
|
{
|
||||||
|
Qt::CaseSensitivity sensitivity = Qt::CaseInsensitive;
|
||||||
|
switch (m_type) {
|
||||||
|
case ExpressionType::RegExp:
|
||||||
|
sensitivity = m_regExp.caseSensitivity();
|
||||||
|
break;
|
||||||
|
#if QT_CONFIG(regularexpression)
|
||||||
|
case ExpressionType::RegularExpression:
|
||||||
|
{
|
||||||
|
QRegularExpression::PatternOptions options = m_regularExpression.patternOptions();
|
||||||
|
if (!(options & QRegularExpression::CaseInsensitiveOption))
|
||||||
|
sensitivity = Qt::CaseSensitive;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
return sensitivity;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setCaseSensitivity(Qt::CaseSensitivity cs)
|
||||||
|
{
|
||||||
|
switch (m_type) {
|
||||||
|
case ExpressionType::RegExp:
|
||||||
|
m_regExp.setCaseSensitivity(cs);
|
||||||
|
break;
|
||||||
|
#if QT_CONFIG(regularexpression)
|
||||||
|
case ExpressionType::RegularExpression:
|
||||||
|
{
|
||||||
|
QRegularExpression::PatternOptions options = m_regularExpression.patternOptions();
|
||||||
|
options.setFlag(QRegularExpression::CaseInsensitiveOption, cs == Qt::CaseSensitive);
|
||||||
|
m_regularExpression.setPatternOptions(options);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool hasMatch(const QString &str) const
|
||||||
|
{
|
||||||
|
bool result = false;
|
||||||
|
switch (m_type) {
|
||||||
|
case ExpressionType::RegExp:
|
||||||
|
result = str.contains(m_regExp);
|
||||||
|
break;
|
||||||
|
#if QT_CONFIG(regularexpression)
|
||||||
|
case ExpressionType::RegularExpression:
|
||||||
|
result = str.contains(m_regularExpression);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
ExpressionType m_type;
|
||||||
|
QRegExp m_regExp;
|
||||||
|
#if QT_CONFIG(regularexpression)
|
||||||
|
QRegularExpression m_regularExpression;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
class QSortFilterProxyModelPrivate : public QAbstractProxyModelPrivate
|
class QSortFilterProxyModelPrivate : public QAbstractProxyModelPrivate
|
||||||
{
|
{
|
||||||
Q_DECLARE_PUBLIC(QSortFilterProxyModel)
|
Q_DECLARE_PUBLIC(QSortFilterProxyModel)
|
||||||
@ -171,7 +299,7 @@ public:
|
|||||||
|
|
||||||
int filter_column;
|
int filter_column;
|
||||||
int filter_role;
|
int filter_role;
|
||||||
QRegExp filter_regexp;
|
RegularExpressionData filter_data;
|
||||||
QModelIndex last_top_source;
|
QModelIndex last_top_source;
|
||||||
|
|
||||||
bool filter_recursive;
|
bool filter_recursive;
|
||||||
@ -1109,7 +1237,7 @@ void QSortFilterProxyModelPrivate::update_persistent_indexes(
|
|||||||
*/
|
*/
|
||||||
void QSortFilterProxyModelPrivate::filter_about_to_be_changed(const QModelIndex &source_parent)
|
void QSortFilterProxyModelPrivate::filter_about_to_be_changed(const QModelIndex &source_parent)
|
||||||
{
|
{
|
||||||
if (!filter_regexp.pattern().isEmpty() &&
|
if (!filter_data.isEmpty() &&
|
||||||
source_index_mapping.constFind(source_parent) == source_index_mapping.constEnd())
|
source_index_mapping.constFind(source_parent) == source_index_mapping.constEnd())
|
||||||
create_mapping(source_parent);
|
create_mapping(source_parent);
|
||||||
}
|
}
|
||||||
@ -1786,9 +1914,9 @@ void QSortFilterProxyModelPrivate::_q_sourceColumnsMoved(
|
|||||||
If a parent item doesn't match the filter, none of its children will be
|
If a parent item doesn't match the filter, none of its children will be
|
||||||
shown.
|
shown.
|
||||||
|
|
||||||
A common use case is to let the user specify the filter regexp, wildcard
|
A common use case is to let the user specify the filter regular expression,
|
||||||
pattern, or fixed string in a QLineEdit and to connect the
|
wildcard pattern, or fixed string in a QLineEdit and to connect the
|
||||||
\l{QLineEdit::textChanged()}{textChanged()} signal to setFilterRegExp(),
|
\l{QLineEdit::textChanged()}{textChanged()} signal to setFilterRegularExpression(),
|
||||||
setFilterWildcard(), or setFilterFixedString() to reapply the filter.
|
setFilterWildcard(), or setFilterFixedString() to reapply the filter.
|
||||||
|
|
||||||
Custom filtering behavior can be achieved by reimplementing the
|
Custom filtering behavior can be achieved by reimplementing the
|
||||||
@ -1825,6 +1953,21 @@ void QSortFilterProxyModelPrivate::_q_sourceColumnsMoved(
|
|||||||
\note Some general guidelines for subclassing models are available in the
|
\note Some general guidelines for subclassing models are available in the
|
||||||
\l{Model Subclassing Reference}.
|
\l{Model Subclassing Reference}.
|
||||||
|
|
||||||
|
\note With Qt 5, regular expression support has been improved through the
|
||||||
|
QRegularExpression class. QSortFilterProxyModel dating back prior to that
|
||||||
|
class creation, it originally supported only QRegExp. Since Qt 5.12,
|
||||||
|
QRegularExpression APIs have been added. Therefore, QRegExp APIs should be
|
||||||
|
considered deprecated and the QRegularExpression version should be used in
|
||||||
|
place.
|
||||||
|
|
||||||
|
\warning Don't mix calls to the getters and setters of different regexp types
|
||||||
|
as this will lead to unexpected results. For maximum compatibility, the original
|
||||||
|
implementation has been kept. Therefore, if, for example, a call to
|
||||||
|
setFilterRegularExpression is made followed by another one to
|
||||||
|
setFilterFixedString, the first call will setup a QRegularExpression object
|
||||||
|
to use as filter while the second will setup a QRegExp in FixedString mode.
|
||||||
|
However, this is an implementation detail that might change in the future.
|
||||||
|
|
||||||
\sa QAbstractProxyModel, QAbstractItemModel, {Model/View Programming},
|
\sa QAbstractProxyModel, QAbstractItemModel, {Model/View Programming},
|
||||||
{Basic Sort/Filter Model Example}, {Custom Sort/Filter Model Example}, QIdentityProxyModel
|
{Basic Sort/Filter Model Example}, {Custom Sort/Filter Model Example}, QIdentityProxyModel
|
||||||
*/
|
*/
|
||||||
@ -2437,17 +2580,47 @@ Qt::SortOrder QSortFilterProxyModel::sortOrder() const
|
|||||||
QRegExp QSortFilterProxyModel::filterRegExp() const
|
QRegExp QSortFilterProxyModel::filterRegExp() const
|
||||||
{
|
{
|
||||||
Q_D(const QSortFilterProxyModel);
|
Q_D(const QSortFilterProxyModel);
|
||||||
return d->filter_regexp;
|
return d->filter_data.regExp();
|
||||||
}
|
}
|
||||||
|
|
||||||
void QSortFilterProxyModel::setFilterRegExp(const QRegExp ®Exp)
|
void QSortFilterProxyModel::setFilterRegExp(const QRegExp ®Exp)
|
||||||
{
|
{
|
||||||
Q_D(QSortFilterProxyModel);
|
Q_D(QSortFilterProxyModel);
|
||||||
d->filter_about_to_be_changed();
|
d->filter_about_to_be_changed();
|
||||||
d->filter_regexp = regExp;
|
d->filter_data.setRegExp(regExp);
|
||||||
d->filter_changed();
|
d->filter_changed();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if QT_CONFIG(regularexpression)
|
||||||
|
/*!
|
||||||
|
\since 5.12
|
||||||
|
\property QSortFilterProxyModel::filterRegularExpression
|
||||||
|
\brief the QRegularExpression used to filter the contents of the source model
|
||||||
|
|
||||||
|
Setting this property overwrites the current
|
||||||
|
\l{QSortFilterProxyModel::filterCaseSensitivity}{filterCaseSensitivity}.
|
||||||
|
By default, the QRegularExpression is an empty string matching all contents.
|
||||||
|
|
||||||
|
If no QRegularExpression or an empty string is set, everything in the source
|
||||||
|
model will be accepted.
|
||||||
|
|
||||||
|
\sa filterCaseSensitivity, setFilterWildcard(), setFilterFixedString()
|
||||||
|
*/
|
||||||
|
QRegularExpression QSortFilterProxyModel::filterRegularExpression() const
|
||||||
|
{
|
||||||
|
Q_D(const QSortFilterProxyModel);
|
||||||
|
return d->filter_data.regularExpression();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QSortFilterProxyModel::setFilterRegularExpression(const QRegularExpression ®ularExpression)
|
||||||
|
{
|
||||||
|
Q_D(QSortFilterProxyModel);
|
||||||
|
d->filter_about_to_be_changed();
|
||||||
|
d->filter_data.setRegularExpression(regularExpression);
|
||||||
|
d->filter_changed();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\property QSortFilterProxyModel::filterKeyColumn
|
\property QSortFilterProxyModel::filterKeyColumn
|
||||||
\brief the column where the key used to filter the contents of the
|
\brief the column where the key used to filter the contents of the
|
||||||
@ -2483,16 +2656,16 @@ void QSortFilterProxyModel::setFilterKeyColumn(int column)
|
|||||||
Qt::CaseSensitivity QSortFilterProxyModel::filterCaseSensitivity() const
|
Qt::CaseSensitivity QSortFilterProxyModel::filterCaseSensitivity() const
|
||||||
{
|
{
|
||||||
Q_D(const QSortFilterProxyModel);
|
Q_D(const QSortFilterProxyModel);
|
||||||
return d->filter_regexp.caseSensitivity();
|
return d->filter_data.caseSensitivity();
|
||||||
}
|
}
|
||||||
|
|
||||||
void QSortFilterProxyModel::setFilterCaseSensitivity(Qt::CaseSensitivity cs)
|
void QSortFilterProxyModel::setFilterCaseSensitivity(Qt::CaseSensitivity cs)
|
||||||
{
|
{
|
||||||
Q_D(QSortFilterProxyModel);
|
Q_D(QSortFilterProxyModel);
|
||||||
if (cs == d->filter_regexp.caseSensitivity())
|
if (cs == d->filter_data.caseSensitivity())
|
||||||
return;
|
return;
|
||||||
d->filter_about_to_be_changed();
|
d->filter_about_to_be_changed();
|
||||||
d->filter_regexp.setCaseSensitivity(cs);
|
d->filter_data.setCaseSensitivity(cs);
|
||||||
d->filter_changed();
|
d->filter_changed();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2558,11 +2731,33 @@ void QSortFilterProxyModel::setFilterRegExp(const QString &pattern)
|
|||||||
{
|
{
|
||||||
Q_D(QSortFilterProxyModel);
|
Q_D(QSortFilterProxyModel);
|
||||||
d->filter_about_to_be_changed();
|
d->filter_about_to_be_changed();
|
||||||
d->filter_regexp.setPatternSyntax(QRegExp::RegExp);
|
QRegExp rx(pattern);
|
||||||
d->filter_regexp.setPattern(pattern);
|
d->filter_data.setRegExp(rx);
|
||||||
d->filter_changed();
|
d->filter_changed();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if QT_CONFIG(regularexpression)
|
||||||
|
/*!
|
||||||
|
\since 5.12
|
||||||
|
|
||||||
|
Sets the regular expression used to filter the contents
|
||||||
|
of the source model to \a pattern.
|
||||||
|
|
||||||
|
This method should be preferred for new code as it will use
|
||||||
|
QRegularExpression internally.
|
||||||
|
|
||||||
|
\sa setFilterCaseSensitivity(), setFilterWildcard(), setFilterFixedString(), filterRegularExpression()
|
||||||
|
*/
|
||||||
|
void QSortFilterProxyModel::setFilterRegularExpression(const QString &pattern)
|
||||||
|
{
|
||||||
|
Q_D(QSortFilterProxyModel);
|
||||||
|
d->filter_about_to_be_changed();
|
||||||
|
QRegularExpression rx(pattern);
|
||||||
|
d->filter_data.setRegularExpression(rx);
|
||||||
|
d->filter_changed();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Sets the wildcard expression used to filter the contents
|
Sets the wildcard expression used to filter the contents
|
||||||
of the source model to the given \a pattern.
|
of the source model to the given \a pattern.
|
||||||
@ -2573,8 +2768,8 @@ void QSortFilterProxyModel::setFilterWildcard(const QString &pattern)
|
|||||||
{
|
{
|
||||||
Q_D(QSortFilterProxyModel);
|
Q_D(QSortFilterProxyModel);
|
||||||
d->filter_about_to_be_changed();
|
d->filter_about_to_be_changed();
|
||||||
d->filter_regexp.setPatternSyntax(QRegExp::Wildcard);
|
QRegExp rx(pattern, d->filter_data.caseSensitivity(), QRegExp::Wildcard);
|
||||||
d->filter_regexp.setPattern(pattern);
|
d->filter_data.setRegExp(rx);
|
||||||
d->filter_changed();
|
d->filter_changed();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2588,8 +2783,8 @@ void QSortFilterProxyModel::setFilterFixedString(const QString &pattern)
|
|||||||
{
|
{
|
||||||
Q_D(QSortFilterProxyModel);
|
Q_D(QSortFilterProxyModel);
|
||||||
d->filter_about_to_be_changed();
|
d->filter_about_to_be_changed();
|
||||||
d->filter_regexp.setPatternSyntax(QRegExp::FixedString);
|
QRegExp rx(pattern, d->filter_data.caseSensitivity(), QRegExp::FixedString);
|
||||||
d->filter_regexp.setPattern(pattern);
|
d->filter_data.setRegExp(rx);
|
||||||
d->filter_changed();
|
d->filter_changed();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2814,14 +3009,15 @@ bool QSortFilterProxyModel::lessThan(const QModelIndex &source_left, const QMode
|
|||||||
bool QSortFilterProxyModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
|
bool QSortFilterProxyModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
|
||||||
{
|
{
|
||||||
Q_D(const QSortFilterProxyModel);
|
Q_D(const QSortFilterProxyModel);
|
||||||
if (d->filter_regexp.isEmpty())
|
|
||||||
|
if (d->filter_data.isEmpty())
|
||||||
return true;
|
return true;
|
||||||
if (d->filter_column == -1) {
|
if (d->filter_column == -1) {
|
||||||
int column_count = d->model->columnCount(source_parent);
|
int column_count = d->model->columnCount(source_parent);
|
||||||
for (int column = 0; column < column_count; ++column) {
|
for (int column = 0; column < column_count; ++column) {
|
||||||
QModelIndex source_index = d->model->index(source_row, column, source_parent);
|
QModelIndex source_index = d->model->index(source_row, column, source_parent);
|
||||||
QString key = d->model->data(source_index, d->filter_role).toString();
|
QString key = d->model->data(source_index, d->filter_role).toString();
|
||||||
if (key.contains(d->filter_regexp))
|
if (d->filter_data.hasMatch(key))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -2830,7 +3026,7 @@ bool QSortFilterProxyModel::filterAcceptsRow(int source_row, const QModelIndex &
|
|||||||
if (!source_index.isValid()) // the column may not exist
|
if (!source_index.isValid()) // the column may not exist
|
||||||
return true;
|
return true;
|
||||||
QString key = d->model->data(source_index, d->filter_role).toString();
|
QString key = d->model->data(source_index, d->filter_role).toString();
|
||||||
return key.contains(d->filter_regexp);
|
return d->filter_data.hasMatch(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
@ -42,6 +42,7 @@
|
|||||||
|
|
||||||
#include <QtCore/qabstractproxymodel.h>
|
#include <QtCore/qabstractproxymodel.h>
|
||||||
#include <QtCore/qregexp.h>
|
#include <QtCore/qregexp.h>
|
||||||
|
#include <QtCore/qregularexpression.h>
|
||||||
|
|
||||||
QT_REQUIRE_CONFIG(sortfilterproxymodel);
|
QT_REQUIRE_CONFIG(sortfilterproxymodel);
|
||||||
|
|
||||||
@ -59,6 +60,9 @@ class Q_CORE_EXPORT QSortFilterProxyModel : public QAbstractProxyModel
|
|||||||
|
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_PROPERTY(QRegExp filterRegExp READ filterRegExp WRITE setFilterRegExp)
|
Q_PROPERTY(QRegExp filterRegExp READ filterRegExp WRITE setFilterRegExp)
|
||||||
|
#if QT_CONFIG(regularexpression)
|
||||||
|
Q_PROPERTY(QRegularExpression filterRegularExpression READ filterRegularExpression WRITE setFilterRegularExpression)
|
||||||
|
#endif
|
||||||
Q_PROPERTY(int filterKeyColumn READ filterKeyColumn WRITE setFilterKeyColumn)
|
Q_PROPERTY(int filterKeyColumn READ filterKeyColumn WRITE setFilterKeyColumn)
|
||||||
Q_PROPERTY(bool dynamicSortFilter READ dynamicSortFilter WRITE setDynamicSortFilter)
|
Q_PROPERTY(bool dynamicSortFilter READ dynamicSortFilter WRITE setDynamicSortFilter)
|
||||||
Q_PROPERTY(Qt::CaseSensitivity filterCaseSensitivity READ filterCaseSensitivity WRITE setFilterCaseSensitivity)
|
Q_PROPERTY(Qt::CaseSensitivity filterCaseSensitivity READ filterCaseSensitivity WRITE setFilterCaseSensitivity)
|
||||||
@ -83,6 +87,9 @@ public:
|
|||||||
QRegExp filterRegExp() const;
|
QRegExp filterRegExp() const;
|
||||||
void setFilterRegExp(const QRegExp ®Exp);
|
void setFilterRegExp(const QRegExp ®Exp);
|
||||||
|
|
||||||
|
QRegularExpression filterRegularExpression() const;
|
||||||
|
void setFilterRegularExpression(const QRegularExpression ®ularExpression);
|
||||||
|
|
||||||
int filterKeyColumn() const;
|
int filterKeyColumn() const;
|
||||||
void setFilterKeyColumn(int column);
|
void setFilterKeyColumn(int column);
|
||||||
|
|
||||||
@ -112,6 +119,9 @@ public:
|
|||||||
|
|
||||||
public Q_SLOTS:
|
public Q_SLOTS:
|
||||||
void setFilterRegExp(const QString &pattern);
|
void setFilterRegExp(const QString &pattern);
|
||||||
|
#if QT_CONFIG(regularexpression)
|
||||||
|
void setFilterRegularExpression(const QString &pattern);
|
||||||
|
#endif
|
||||||
void setFilterWildcard(const QString &pattern);
|
void setFilterWildcard(const QString &pattern);
|
||||||
void setFilterFixedString(const QString &pattern);
|
void setFilterFixedString(const QString &pattern);
|
||||||
#if QT_DEPRECATED_SINCE(5, 11)
|
#if QT_DEPRECATED_SINCE(5, 11)
|
||||||
|
@ -11,7 +11,8 @@ qtHaveModule(gui): SUBDIRS += \
|
|||||||
|
|
||||||
qtHaveModule(widgets) {
|
qtHaveModule(widgets) {
|
||||||
SUBDIRS += \
|
SUBDIRS += \
|
||||||
qsortfilterproxymodel
|
qsortfilterproxymodel_regexp \
|
||||||
|
qsortfilterproxymodel_regularexpression
|
||||||
|
|
||||||
qtHaveModule(sql): SUBDIRS += \
|
qtHaveModule(sql): SUBDIRS += \
|
||||||
qitemmodel
|
qitemmodel
|
||||||
|
@ -1 +0,0 @@
|
|||||||
tst_qsortfilterproxymodel
|
|
@ -1,9 +0,0 @@
|
|||||||
CONFIG += testcase
|
|
||||||
TARGET = tst_qsortfilterproxymodel
|
|
||||||
|
|
||||||
QT += widgets testlib
|
|
||||||
mtdir = ../../../other/qabstractitemmodelutils
|
|
||||||
|
|
||||||
INCLUDEPATH += $$PWD/$${mtdir}
|
|
||||||
SOURCES += tst_qsortfilterproxymodel.cpp $${mtdir}/dynamictreemodel.cpp
|
|
||||||
HEADERS += $${mtdir}/dynamictreemodel.h
|
|
@ -27,6 +27,7 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include <QtTest/QtTest>
|
#include <QtTest/QtTest>
|
||||||
|
#include "tst_qsortfilterproxymodel.h"
|
||||||
#include "dynamictreemodel.h"
|
#include "dynamictreemodel.h"
|
||||||
|
|
||||||
#include <QtCore/QCoreApplication>
|
#include <QtCore/QCoreApplication>
|
||||||
@ -36,137 +37,6 @@
|
|||||||
|
|
||||||
#include <qdebug.h>
|
#include <qdebug.h>
|
||||||
|
|
||||||
typedef QList<int> IntList;
|
|
||||||
typedef QPair<int, int> IntPair;
|
|
||||||
typedef QList<IntPair> IntPairList;
|
|
||||||
|
|
||||||
Q_DECLARE_METATYPE(QList<QPersistentModelIndex>)
|
|
||||||
|
|
||||||
class tst_QSortFilterProxyModel : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
tst_QSortFilterProxyModel();
|
|
||||||
|
|
||||||
public slots:
|
|
||||||
void initTestCase();
|
|
||||||
void cleanupTestCase();
|
|
||||||
void cleanup();
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
void getSetCheck();
|
|
||||||
void sort_data();
|
|
||||||
void sort();
|
|
||||||
void sortHierarchy_data();
|
|
||||||
void sortHierarchy();
|
|
||||||
|
|
||||||
void insertRows_data();
|
|
||||||
void insertRows();
|
|
||||||
void prependRow();
|
|
||||||
void removeRows_data();
|
|
||||||
void removeRows();
|
|
||||||
void removeColumns_data();
|
|
||||||
void removeColumns();
|
|
||||||
void insertAfterSelect();
|
|
||||||
void removeAfterSelect();
|
|
||||||
void filter_data();
|
|
||||||
void filter();
|
|
||||||
void filterHierarchy_data();
|
|
||||||
void filterHierarchy();
|
|
||||||
void filterColumns_data();
|
|
||||||
void filterColumns();
|
|
||||||
|
|
||||||
void filterTable();
|
|
||||||
void filterCurrent();
|
|
||||||
void filter_qtbug30662();
|
|
||||||
|
|
||||||
void changeSourceLayout();
|
|
||||||
void changeSourceLayoutFilteredOut();
|
|
||||||
void removeSourceRows_data();
|
|
||||||
void removeSourceRows();
|
|
||||||
void insertSourceRows_data();
|
|
||||||
void insertSourceRows();
|
|
||||||
void changeFilter_data();
|
|
||||||
void changeFilter();
|
|
||||||
void changeSourceData_data();
|
|
||||||
void changeSourceData();
|
|
||||||
void changeSourceDataKeepsStableSorting_qtbug1548();
|
|
||||||
void changeSourceDataForwardsRoles_qtbug35440();
|
|
||||||
void resortingDoesNotBreakTreeModels();
|
|
||||||
void dynamicFilterWithoutSort();
|
|
||||||
void sortFilterRole();
|
|
||||||
void selectionFilteredOut();
|
|
||||||
void match_data();
|
|
||||||
void match();
|
|
||||||
void insertIntoChildrenlessItem();
|
|
||||||
void invalidateMappedChildren();
|
|
||||||
void insertRowIntoFilteredParent();
|
|
||||||
void filterOutParentAndFilterInChild();
|
|
||||||
|
|
||||||
void sourceInsertRows();
|
|
||||||
void sourceModelDeletion();
|
|
||||||
|
|
||||||
void sortColumnTracking1();
|
|
||||||
void sortColumnTracking2();
|
|
||||||
|
|
||||||
void sortStable();
|
|
||||||
|
|
||||||
void hiddenColumns();
|
|
||||||
void insertRowsSort();
|
|
||||||
void staticSorting();
|
|
||||||
void dynamicSorting();
|
|
||||||
void fetchMore();
|
|
||||||
void hiddenChildren();
|
|
||||||
void mapFromToSource();
|
|
||||||
void removeRowsRecursive();
|
|
||||||
void doubleProxySelectionSetSourceModel();
|
|
||||||
void appearsAndSort();
|
|
||||||
void unnecessaryDynamicSorting();
|
|
||||||
void unnecessaryMapCreation();
|
|
||||||
void resetInvalidate_data();
|
|
||||||
void resetInvalidate();
|
|
||||||
|
|
||||||
void testMultipleProxiesWithSelection();
|
|
||||||
void mapSelectionFromSource();
|
|
||||||
void testResetInternalData();
|
|
||||||
void filteredColumns();
|
|
||||||
void headerDataChanged();
|
|
||||||
|
|
||||||
void testParentLayoutChanged();
|
|
||||||
void moveSourceRows();
|
|
||||||
|
|
||||||
void hierarchyFilterInvalidation();
|
|
||||||
void simpleFilterInvalidation();
|
|
||||||
|
|
||||||
void chainedProxyModelRoleNames();
|
|
||||||
|
|
||||||
void noMapAfterSourceDelete();
|
|
||||||
void forwardDropApi();
|
|
||||||
void canDropMimeData();
|
|
||||||
void filterHint();
|
|
||||||
|
|
||||||
void sourceLayoutChangeLeavesValidPersistentIndexes();
|
|
||||||
void rowMoveLeavesValidPersistentIndexes();
|
|
||||||
|
|
||||||
void emitLayoutChangedOnlyIfSortingChanged_data();
|
|
||||||
void emitLayoutChangedOnlyIfSortingChanged();
|
|
||||||
|
|
||||||
void checkSetNewModel();
|
|
||||||
|
|
||||||
void removeIntervals_data();
|
|
||||||
void removeIntervals();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void buildHierarchy(const QStringList &data, QAbstractItemModel *model);
|
|
||||||
void checkHierarchy(const QStringList &data, const QAbstractItemModel *model);
|
|
||||||
|
|
||||||
private:
|
|
||||||
QStandardItemModel *m_model;
|
|
||||||
QSortFilterProxyModel *m_proxy;
|
|
||||||
};
|
|
||||||
|
|
||||||
Q_DECLARE_METATYPE(QAbstractItemModel::LayoutChangeHint)
|
|
||||||
|
|
||||||
// Testing get/set functions
|
// Testing get/set functions
|
||||||
void tst_QSortFilterProxyModel::getSetCheck()
|
void tst_QSortFilterProxyModel::getSetCheck()
|
||||||
{
|
{
|
||||||
@ -204,7 +74,15 @@ void tst_QSortFilterProxyModel::cleanupTestCase()
|
|||||||
|
|
||||||
void tst_QSortFilterProxyModel::cleanup()
|
void tst_QSortFilterProxyModel::cleanup()
|
||||||
{
|
{
|
||||||
m_proxy->setFilterRegExp(QRegExp());
|
switch (m_filterType) {
|
||||||
|
case FilterType::RegExp:
|
||||||
|
m_proxy->setFilterRegExp(QRegExp());
|
||||||
|
break;
|
||||||
|
case FilterType::RegularExpression:
|
||||||
|
m_proxy->setFilterRegularExpression(QRegularExpression());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
m_proxy->sort(-1, Qt::AscendingOrder);
|
m_proxy->sort(-1, Qt::AscendingOrder);
|
||||||
m_model->clear();
|
m_model->clear();
|
||||||
m_model->insertColumns(0, 1);
|
m_model->insertColumns(0, 1);
|
||||||
@ -915,8 +793,9 @@ void tst_QSortFilterProxyModel::removeRows()
|
|||||||
|
|
||||||
if (sortOrder != -1)
|
if (sortOrder != -1)
|
||||||
proxy.sort(0, static_cast<Qt::SortOrder>(sortOrder));
|
proxy.sort(0, static_cast<Qt::SortOrder>(sortOrder));
|
||||||
|
|
||||||
if (!filter.isEmpty())
|
if (!filter.isEmpty())
|
||||||
proxy.setFilterRegExp(QRegExp(filter));
|
setupFilter(&proxy, filter);
|
||||||
|
|
||||||
// remove the rows
|
// remove the rows
|
||||||
QCOMPARE(proxy.removeRows(position, count, QModelIndex()), success);
|
QCOMPARE(proxy.removeRows(position, count, QModelIndex()), success);
|
||||||
@ -938,14 +817,29 @@ class MyFilteredColumnProxyModel : public QSortFilterProxyModel
|
|||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
MyFilteredColumnProxyModel(QObject *parent = 0)
|
MyFilteredColumnProxyModel(FilterType filterType, QObject *parent = 0) :
|
||||||
: QSortFilterProxyModel(parent) { }
|
QSortFilterProxyModel(parent),
|
||||||
|
m_filterType(filterType)
|
||||||
|
{ }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool filterAcceptsColumn(int sourceColumn, const QModelIndex &) const
|
bool filterAcceptsColumn(int sourceColumn, const QModelIndex &) const
|
||||||
{
|
{
|
||||||
QString key = sourceModel()->headerData(sourceColumn, Qt::Horizontal).toString();
|
QString key = sourceModel()->headerData(sourceColumn, Qt::Horizontal).toString();
|
||||||
return key.contains(filterRegExp());
|
bool result = false;
|
||||||
|
switch (m_filterType) {
|
||||||
|
case FilterType::RegExp:
|
||||||
|
result = key.contains(filterRegExp());
|
||||||
|
break;
|
||||||
|
case FilterType::RegularExpression:
|
||||||
|
result = key.contains(filterRegularExpression());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
FilterType m_filterType;
|
||||||
};
|
};
|
||||||
|
|
||||||
void tst_QSortFilterProxyModel::removeColumns_data()
|
void tst_QSortFilterProxyModel::removeColumns_data()
|
||||||
@ -1154,10 +1048,10 @@ void tst_QSortFilterProxyModel::removeColumns()
|
|||||||
QFETCH(QStringList, expectedSource);
|
QFETCH(QStringList, expectedSource);
|
||||||
|
|
||||||
QStandardItemModel model;
|
QStandardItemModel model;
|
||||||
MyFilteredColumnProxyModel proxy;
|
MyFilteredColumnProxyModel proxy(m_filterType);
|
||||||
proxy.setSourceModel(&model);
|
proxy.setSourceModel(&model);
|
||||||
if (!filter.isEmpty())
|
if (!filter.isEmpty())
|
||||||
proxy.setFilterRegExp(QRegExp(filter));
|
setupFilter(&proxy, filter);
|
||||||
|
|
||||||
// prepare model
|
// prepare model
|
||||||
model.setHorizontalHeaderLabels(initial);
|
model.setHorizontalHeaderLabels(initial);
|
||||||
@ -1225,7 +1119,8 @@ void tst_QSortFilterProxyModel::filterColumns()
|
|||||||
QModelIndex index = m_model->index(0, col, QModelIndex());
|
QModelIndex index = m_model->index(0, col, QModelIndex());
|
||||||
m_model->setData(index, initial.at(col), Qt::DisplayRole);
|
m_model->setData(index, initial.at(col), Qt::DisplayRole);
|
||||||
}
|
}
|
||||||
m_proxy->setFilterRegExp(pattern);
|
setupFilter(m_proxy, pattern);
|
||||||
|
|
||||||
m_proxy->setFilterKeyColumn(-1);
|
m_proxy->setFilterKeyColumn(-1);
|
||||||
// make sure the model is unchanged
|
// make sure the model is unchanged
|
||||||
for (int col = 0; col < m_model->columnCount(QModelIndex()); ++col) {
|
for (int col = 0; col < m_model->columnCount(QModelIndex()); ++col) {
|
||||||
@ -1291,6 +1186,7 @@ void tst_QSortFilterProxyModel::filter()
|
|||||||
QFETCH(QString, pattern);
|
QFETCH(QString, pattern);
|
||||||
QFETCH(QStringList, initial);
|
QFETCH(QStringList, initial);
|
||||||
QFETCH(QStringList, expected);
|
QFETCH(QStringList, expected);
|
||||||
|
|
||||||
// prepare model
|
// prepare model
|
||||||
QVERIFY(m_model->insertRows(0, initial.count(), QModelIndex()));
|
QVERIFY(m_model->insertRows(0, initial.count(), QModelIndex()));
|
||||||
QCOMPARE(m_model->rowCount(QModelIndex()), initial.count());
|
QCOMPARE(m_model->rowCount(QModelIndex()), initial.count());
|
||||||
@ -1300,7 +1196,7 @@ void tst_QSortFilterProxyModel::filter()
|
|||||||
QModelIndex index = m_model->index(row, 0, QModelIndex());
|
QModelIndex index = m_model->index(row, 0, QModelIndex());
|
||||||
m_model->setData(index, initial.at(row), Qt::DisplayRole);
|
m_model->setData(index, initial.at(row), Qt::DisplayRole);
|
||||||
}
|
}
|
||||||
m_proxy->setFilterRegExp(pattern);
|
setupFilter(m_proxy, pattern);
|
||||||
// make sure the proxy is unfiltered
|
// make sure the proxy is unfiltered
|
||||||
QCOMPARE(m_proxy->columnCount(QModelIndex()), 1);
|
QCOMPARE(m_proxy->columnCount(QModelIndex()), 1);
|
||||||
QCOMPARE(m_proxy->rowCount(QModelIndex()), expected.count());
|
QCOMPARE(m_proxy->rowCount(QModelIndex()), expected.count());
|
||||||
@ -1339,7 +1235,7 @@ void tst_QSortFilterProxyModel::filterHierarchy()
|
|||||||
QFETCH(QStringList, initial);
|
QFETCH(QStringList, initial);
|
||||||
QFETCH(QStringList, expected);
|
QFETCH(QStringList, expected);
|
||||||
buildHierarchy(initial, m_model);
|
buildHierarchy(initial, m_model);
|
||||||
m_proxy->setFilterRegExp(pattern);
|
setupFilter(m_proxy, pattern);
|
||||||
checkHierarchy(initial, m_model);
|
checkHierarchy(initial, m_model);
|
||||||
checkHierarchy(expected, m_proxy);
|
checkHierarchy(expected, m_proxy);
|
||||||
}
|
}
|
||||||
@ -1404,6 +1300,18 @@ void tst_QSortFilterProxyModel::checkHierarchy(const QStringList &l, const QAbst
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tst_QSortFilterProxyModel::setupFilter(QSortFilterProxyModel *model, const QString& pattern)
|
||||||
|
{
|
||||||
|
switch (m_filterType) {
|
||||||
|
case FilterType::RegExp:
|
||||||
|
model->setFilterRegExp(pattern);
|
||||||
|
break;
|
||||||
|
case FilterType::RegularExpression:
|
||||||
|
model->setFilterRegularExpression(pattern);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class TestModel: public QAbstractTableModel
|
class TestModel: public QAbstractTableModel
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -1422,7 +1330,7 @@ void tst_QSortFilterProxyModel::filterTable()
|
|||||||
TestModel model;
|
TestModel model;
|
||||||
QSortFilterProxyModel filter;
|
QSortFilterProxyModel filter;
|
||||||
filter.setSourceModel(&model);
|
filter.setSourceModel(&model);
|
||||||
filter.setFilterRegExp("9");
|
setupFilter(&filter, QLatin1String("9"));
|
||||||
|
|
||||||
for (int i = 0; i < filter.rowCount(); ++i)
|
for (int i = 0; i < filter.rowCount(); ++i)
|
||||||
QVERIFY(filter.data(filter.index(i, 0)).toString().contains(QLatin1Char('9')));
|
QVERIFY(filter.data(filter.index(i, 0)).toString().contains(QLatin1Char('9')));
|
||||||
@ -1486,7 +1394,7 @@ void tst_QSortFilterProxyModel::filterCurrent()
|
|||||||
|
|
||||||
view.setCurrentIndex(proxy.index(0, 0));
|
view.setCurrentIndex(proxy.index(0, 0));
|
||||||
QCOMPARE(spy.count(), 1);
|
QCOMPARE(spy.count(), 1);
|
||||||
proxy.setFilterRegExp(QRegExp("^B"));
|
setupFilter(&proxy, QLatin1String("^B"));
|
||||||
QCOMPARE(spy.count(), 2);
|
QCOMPARE(spy.count(), 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1497,7 +1405,7 @@ void tst_QSortFilterProxyModel::filter_qtbug30662()
|
|||||||
proxy.setSourceModel(&model);
|
proxy.setSourceModel(&model);
|
||||||
|
|
||||||
// make sure the filter does not match any entry
|
// make sure the filter does not match any entry
|
||||||
proxy.setFilterRegExp(QRegExp("[0-9]+"));
|
setupFilter(&proxy, QLatin1String("[0-9]+"));
|
||||||
|
|
||||||
QStringList slSource;
|
QStringList slSource;
|
||||||
slSource << "z" << "x" << "a" << "b";
|
slSource << "z" << "x" << "a" << "b";
|
||||||
@ -1507,7 +1415,7 @@ void tst_QSortFilterProxyModel::filter_qtbug30662()
|
|||||||
model.setStringList(slSource);
|
model.setStringList(slSource);
|
||||||
|
|
||||||
// without fix for QTBUG-30662 this will make all entries visible - but unsorted
|
// without fix for QTBUG-30662 this will make all entries visible - but unsorted
|
||||||
proxy.setFilterRegExp(QRegExp("[a-z]+"));
|
setupFilter(&proxy, QLatin1String("[a-z]+"));
|
||||||
|
|
||||||
QStringList slResult;
|
QStringList slResult;
|
||||||
for (int i = 0; i < proxy.rowCount(); ++i)
|
for (int i = 0; i < proxy.rowCount(); ++i)
|
||||||
@ -1553,7 +1461,8 @@ void tst_QSortFilterProxyModel::changeSourceLayoutFilteredOut()
|
|||||||
|
|
||||||
QSignalSpy removeSpy(&proxy, &QSortFilterProxyModel::rowsRemoved);
|
QSignalSpy removeSpy(&proxy, &QSortFilterProxyModel::rowsRemoved);
|
||||||
// Filter everything out
|
// Filter everything out
|
||||||
proxy.setFilterRegExp(QRegExp("c"));
|
setupFilter(&proxy, QLatin1String("c"));
|
||||||
|
|
||||||
QCOMPARE(removeSpy.count(), 1);
|
QCOMPARE(removeSpy.count(), 1);
|
||||||
QCOMPARE(0, proxy.rowCount());
|
QCOMPARE(0, proxy.rowCount());
|
||||||
|
|
||||||
@ -1562,7 +1471,8 @@ void tst_QSortFilterProxyModel::changeSourceLayoutFilteredOut()
|
|||||||
|
|
||||||
QSignalSpy insertSpy(&proxy, &QSortFilterProxyModel::rowsInserted);
|
QSignalSpy insertSpy(&proxy, &QSortFilterProxyModel::rowsInserted);
|
||||||
// Remove filter; we expect an insert
|
// Remove filter; we expect an insert
|
||||||
proxy.setFilterRegExp(QRegExp(""));
|
setupFilter(&proxy, "");
|
||||||
|
|
||||||
QCOMPARE(insertSpy.count(), 1);
|
QCOMPARE(insertSpy.count(), 1);
|
||||||
QCOMPARE(beforeSortFilter, proxy.rowCount());
|
QCOMPARE(beforeSortFilter, proxy.rowCount());
|
||||||
}
|
}
|
||||||
@ -1842,7 +1752,7 @@ void tst_QSortFilterProxyModel::changeFilter()
|
|||||||
QVERIFY(initialRemoveSpy.isValid());
|
QVERIFY(initialRemoveSpy.isValid());
|
||||||
QVERIFY(initialInsertSpy.isValid());
|
QVERIFY(initialInsertSpy.isValid());
|
||||||
|
|
||||||
proxy.setFilterRegExp(initialFilter);
|
setupFilter(&proxy, initialFilter);
|
||||||
|
|
||||||
QCOMPARE(initialRemoveSpy.count(), initialRemoveIntervals.count());
|
QCOMPARE(initialRemoveSpy.count(), initialRemoveIntervals.count());
|
||||||
QCOMPARE(initialInsertSpy.count(), 0);
|
QCOMPARE(initialInsertSpy.count(), 0);
|
||||||
@ -1866,7 +1776,7 @@ void tst_QSortFilterProxyModel::changeFilter()
|
|||||||
QVERIFY(finalRemoveSpy.isValid());
|
QVERIFY(finalRemoveSpy.isValid());
|
||||||
QVERIFY(finalInsertSpy.isValid());
|
QVERIFY(finalInsertSpy.isValid());
|
||||||
|
|
||||||
proxy.setFilterRegExp(finalFilter);
|
setupFilter(&proxy, finalFilter);
|
||||||
|
|
||||||
QCOMPARE(finalRemoveSpy.count(), finalRemoveIntervals.count());
|
QCOMPARE(finalRemoveSpy.count(), finalRemoveIntervals.count());
|
||||||
for (int i = 0; i < finalRemoveSpy.count(); ++i) {
|
for (int i = 0; i < finalRemoveSpy.count(); ++i) {
|
||||||
@ -2060,7 +1970,7 @@ void tst_QSortFilterProxyModel::changeSourceData()
|
|||||||
proxy.sort(0, static_cast<Qt::SortOrder>(sortOrder));
|
proxy.sort(0, static_cast<Qt::SortOrder>(sortOrder));
|
||||||
(void)proxy.rowCount(QModelIndex()); // force mapping
|
(void)proxy.rowCount(QModelIndex()); // force mapping
|
||||||
|
|
||||||
proxy.setFilterRegExp(filter);
|
setupFilter(&proxy, filter);
|
||||||
|
|
||||||
QCOMPARE(proxy.rowCount(), expectedInitialProxyItems.count());
|
QCOMPARE(proxy.rowCount(), expectedInitialProxyItems.count());
|
||||||
for (int i = 0; i < expectedInitialProxyItems.count(); ++i) {
|
for (int i = 0; i < expectedInitialProxyItems.count(); ++i) {
|
||||||
@ -2253,7 +2163,8 @@ void tst_QSortFilterProxyModel::sortFilterRole()
|
|||||||
model.setData(index, sourceItems.at(i).second, Qt::UserRole);
|
model.setData(index, sourceItems.at(i).second, Qt::UserRole);
|
||||||
}
|
}
|
||||||
|
|
||||||
proxy.setFilterRegExp("2");
|
setupFilter(&proxy, QLatin1String("2"));
|
||||||
|
|
||||||
QCOMPARE(proxy.rowCount(), 0); // Qt::DisplayRole is default role
|
QCOMPARE(proxy.rowCount(), 0); // Qt::DisplayRole is default role
|
||||||
|
|
||||||
proxy.setFilterRole(Qt::UserRole);
|
proxy.setFilterRole(Qt::UserRole);
|
||||||
@ -2262,7 +2173,8 @@ void tst_QSortFilterProxyModel::sortFilterRole()
|
|||||||
proxy.setFilterRole(Qt::DisplayRole);
|
proxy.setFilterRole(Qt::DisplayRole);
|
||||||
QCOMPARE(proxy.rowCount(), 0);
|
QCOMPARE(proxy.rowCount(), 0);
|
||||||
|
|
||||||
proxy.setFilterRegExp("1|2|3");
|
setupFilter(&proxy, QLatin1String("1|2|3"));
|
||||||
|
|
||||||
QCOMPARE(proxy.rowCount(), 0);
|
QCOMPARE(proxy.rowCount(), 0);
|
||||||
|
|
||||||
proxy.setFilterRole(Qt::UserRole);
|
proxy.setFilterRole(Qt::UserRole);
|
||||||
@ -2273,7 +2185,8 @@ void tst_QSortFilterProxyModel::sortFilterRole()
|
|||||||
|
|
||||||
proxy.setSortRole(Qt::UserRole);
|
proxy.setSortRole(Qt::UserRole);
|
||||||
proxy.setFilterRole(Qt::DisplayRole);
|
proxy.setFilterRole(Qt::DisplayRole);
|
||||||
proxy.setFilterRegExp("a|c");
|
setupFilter(&proxy, QLatin1String("a|c"));
|
||||||
|
|
||||||
QCOMPARE(proxy.rowCount(), orderedItems.count());
|
QCOMPARE(proxy.rowCount(), orderedItems.count());
|
||||||
for (int i = 0; i < proxy.rowCount(); ++i) {
|
for (int i = 0; i < proxy.rowCount(); ++i) {
|
||||||
QModelIndex index = proxy.index(i, 0, QModelIndex());
|
QModelIndex index = proxy.index(i, 0, QModelIndex());
|
||||||
@ -2297,7 +2210,8 @@ void tst_QSortFilterProxyModel::selectionFilteredOut()
|
|||||||
|
|
||||||
view.setCurrentIndex(proxy.index(0, 0));
|
view.setCurrentIndex(proxy.index(0, 0));
|
||||||
QCOMPARE(spy.count(), 1);
|
QCOMPARE(spy.count(), 1);
|
||||||
proxy.setFilterRegExp(QRegExp("^B"));
|
|
||||||
|
setupFilter(&proxy, QLatin1String("^B"));
|
||||||
QCOMPARE(spy.count(), 2);
|
QCOMPARE(spy.count(), 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2383,7 +2297,7 @@ void tst_QSortFilterProxyModel::match()
|
|||||||
}
|
}
|
||||||
|
|
||||||
proxy.sort(0, static_cast<Qt::SortOrder>(sortOrder));
|
proxy.sort(0, static_cast<Qt::SortOrder>(sortOrder));
|
||||||
proxy.setFilterRegExp(filter);
|
setupFilter(&proxy, filter);
|
||||||
|
|
||||||
QModelIndex startIndex = proxy.index(proxyStartRow, 0);
|
QModelIndex startIndex = proxy.index(proxyStartRow, 0);
|
||||||
QModelIndexList indexes = proxy.match(startIndex, Qt::DisplayRole, what,
|
QModelIndexList indexes = proxy.match(startIndex, Qt::DisplayRole, what,
|
||||||
@ -2508,7 +2422,8 @@ void tst_QSortFilterProxyModel::filterOutParentAndFilterInChild()
|
|||||||
QSortFilterProxyModel proxy;
|
QSortFilterProxyModel proxy;
|
||||||
proxy.setSourceModel(&model);
|
proxy.setSourceModel(&model);
|
||||||
|
|
||||||
proxy.setFilterRegExp("A|B");
|
setupFilter(&proxy, QLatin1String("A|B"));
|
||||||
|
|
||||||
QStandardItem *itemA = new QStandardItem("A");
|
QStandardItem *itemA = new QStandardItem("A");
|
||||||
model.appendRow(itemA); // not filtered
|
model.appendRow(itemA); // not filtered
|
||||||
QStandardItem *itemB = new QStandardItem("B");
|
QStandardItem *itemB = new QStandardItem("B");
|
||||||
@ -2522,7 +2437,7 @@ void tst_QSortFilterProxyModel::filterOutParentAndFilterInChild()
|
|||||||
QVERIFY(removedSpy.isValid());
|
QVERIFY(removedSpy.isValid());
|
||||||
QVERIFY(insertedSpy.isValid());
|
QVERIFY(insertedSpy.isValid());
|
||||||
|
|
||||||
proxy.setFilterRegExp("C"); // A and B will be filtered out, C filtered in
|
setupFilter(&proxy, QLatin1String("C")); // A and B will be filtered out, C filtered in
|
||||||
|
|
||||||
// we should now have been notified that the subtree represented by itemA has been removed
|
// we should now have been notified that the subtree represented by itemA has been removed
|
||||||
QCOMPARE(removedSpy.count(), 1);
|
QCOMPARE(removedSpy.count(), 1);
|
||||||
@ -2935,7 +2850,7 @@ void tst_QSortFilterProxyModel::hiddenChildren()
|
|||||||
itemA->appendRow(itemB);
|
itemA->appendRow(itemB);
|
||||||
QStandardItem *itemC = new QStandardItem("C");
|
QStandardItem *itemC = new QStandardItem("C");
|
||||||
itemA->appendRow(itemC);
|
itemA->appendRow(itemC);
|
||||||
proxy.setFilterRegExp("VISIBLE");
|
setupFilter(&proxy, QLatin1String("VISIBLE"));
|
||||||
|
|
||||||
QCOMPARE(proxy.rowCount(QModelIndex()) , 1);
|
QCOMPARE(proxy.rowCount(QModelIndex()) , 1);
|
||||||
QPersistentModelIndex indexA = proxy.index(0,0);
|
QPersistentModelIndex indexA = proxy.index(0,0);
|
||||||
@ -2962,7 +2877,8 @@ void tst_QSortFilterProxyModel::hiddenChildren()
|
|||||||
QModelIndex indexC = proxy.index(0, 0, indexA);
|
QModelIndex indexC = proxy.index(0, 0, indexA);
|
||||||
QCOMPARE(proxy.data(indexC).toString(), QString::fromLatin1("C VISIBLE"));
|
QCOMPARE(proxy.data(indexC).toString(), QString::fromLatin1("C VISIBLE"));
|
||||||
|
|
||||||
proxy.setFilterRegExp("C");
|
setupFilter(&proxy, QLatin1String("C"));
|
||||||
|
|
||||||
QCOMPARE(proxy.rowCount(QModelIndex()), 0);
|
QCOMPARE(proxy.rowCount(QModelIndex()), 0);
|
||||||
itemC->setText("invisible");
|
itemC->setText("invisible");
|
||||||
itemA->setText("AC");
|
itemA->setText("AC");
|
||||||
@ -3284,7 +3200,8 @@ void tst_QSortFilterProxyModel::mapSelectionFromSource()
|
|||||||
|
|
||||||
QSortFilterProxyModel proxy;
|
QSortFilterProxyModel proxy;
|
||||||
proxy.setDynamicSortFilter(true);
|
proxy.setDynamicSortFilter(true);
|
||||||
proxy.setFilterRegExp("d.*");
|
setupFilter(&proxy, QLatin1String("d.*"));
|
||||||
|
|
||||||
proxy.setSourceModel(&model);
|
proxy.setSourceModel(&model);
|
||||||
|
|
||||||
// Only "delta" remains.
|
// Only "delta" remains.
|
||||||
@ -3839,13 +3756,13 @@ void tst_QSortFilterProxyModel::moveSourceRows()
|
|||||||
filterProxy.setDynamicSortFilter(true);
|
filterProxy.setDynamicSortFilter(true);
|
||||||
filterProxy.sort(0, Qt::AscendingOrder);
|
filterProxy.sort(0, Qt::AscendingOrder);
|
||||||
filterProxy.setSourceModel(&proxy);
|
filterProxy.setSourceModel(&proxy);
|
||||||
filterProxy.setFilterRegExp("6"); // One of the parents
|
setupFilter(&filterProxy, QLatin1String("6")); // One of the parents
|
||||||
|
|
||||||
QSortFilterProxyModel filterBothProxy;
|
QSortFilterProxyModel filterBothProxy;
|
||||||
filterBothProxy.setDynamicSortFilter(true);
|
filterBothProxy.setDynamicSortFilter(true);
|
||||||
filterBothProxy.sort(0, Qt::AscendingOrder);
|
filterBothProxy.sort(0, Qt::AscendingOrder);
|
||||||
filterBothProxy.setSourceModel(&proxy);
|
filterBothProxy.setSourceModel(&proxy);
|
||||||
filterBothProxy.setFilterRegExp("5"); // The parents are 6 and 3. This filters both out.
|
setupFilter(&filterBothProxy, QLatin1String("5")); // The parents are 6 and 3. This filters both out.
|
||||||
|
|
||||||
QSignalSpy modelBeforeSpy(&model, &DynamicTreeModel::rowsAboutToBeMoved);
|
QSignalSpy modelBeforeSpy(&model, &DynamicTreeModel::rowsAboutToBeMoved);
|
||||||
QSignalSpy modelAfterSpy(&model, &DynamicTreeModel::rowsMoved);
|
QSignalSpy modelAfterSpy(&model, &DynamicTreeModel::rowsMoved);
|
||||||
@ -4243,7 +4160,7 @@ void tst_QSortFilterProxyModel::filterHint()
|
|||||||
QSortFilterProxyModel proxy2;
|
QSortFilterProxyModel proxy2;
|
||||||
proxy2.setSourceModel(&proxy1);
|
proxy2.setSourceModel(&proxy1);
|
||||||
proxy2.setFilterRole(Qt::DisplayRole);
|
proxy2.setFilterRole(Qt::DisplayRole);
|
||||||
proxy2.setFilterRegExp("^[^ ]*$");
|
setupFilter(&proxy2, QLatin1String("^[^ ]*$"));
|
||||||
proxy2.setDynamicSortFilter(true);
|
proxy2.setDynamicSortFilter(true);
|
||||||
|
|
||||||
QSignalSpy proxy1BeforeSpy(&proxy1, &QSortFilterProxyModel::layoutAboutToBeChanged);
|
QSignalSpy proxy1BeforeSpy(&proxy1, &QSortFilterProxyModel::layoutAboutToBeChanged);
|
||||||
@ -4371,8 +4288,7 @@ void tst_QSortFilterProxyModel::sourceLayoutChangeLeavesValidPersistentIndexes()
|
|||||||
QSortFilterProxyModel proxy1;
|
QSortFilterProxyModel proxy1;
|
||||||
proxy1.setSourceModel(&model);
|
proxy1.setSourceModel(&model);
|
||||||
Q_SET_OBJECT_NAME(proxy1);
|
Q_SET_OBJECT_NAME(proxy1);
|
||||||
|
setupFilter(&proxy1, QLatin1String("1|2"));
|
||||||
proxy1.setFilterRegExp("1|2");
|
|
||||||
|
|
||||||
// The current state of things:
|
// The current state of things:
|
||||||
// model proxy
|
// model proxy
|
||||||
@ -4419,7 +4335,7 @@ void tst_QSortFilterProxyModel::rowMoveLeavesValidPersistentIndexes()
|
|||||||
proxy1.setSourceModel(&model);
|
proxy1.setSourceModel(&model);
|
||||||
Q_SET_OBJECT_NAME(proxy1);
|
Q_SET_OBJECT_NAME(proxy1);
|
||||||
|
|
||||||
proxy1.setFilterRegExp("1|2");
|
setupFilter(&proxy1, QLatin1String("1|2"));
|
||||||
|
|
||||||
auto item5 = model.match(model.index(0, 0), Qt::DisplayRole, "5", 1, Qt::MatchRecursive).first();
|
auto item5 = model.match(model.index(0, 0), Qt::DisplayRole, "5", 1, Qt::MatchRecursive).first();
|
||||||
auto item3 = model.match(model.index(0, 0), Qt::DisplayRole, "3", 1, Qt::MatchRecursive).first();
|
auto item3 = model.match(model.index(0, 0), Qt::DisplayRole, "3", 1, Qt::MatchRecursive).first();
|
||||||
@ -4653,7 +4569,7 @@ void tst_QSortFilterProxyModel::removeIntervals()
|
|||||||
if (sortOrder != -1)
|
if (sortOrder != -1)
|
||||||
proxy.sort(0, static_cast<Qt::SortOrder>(sortOrder));
|
proxy.sort(0, static_cast<Qt::SortOrder>(sortOrder));
|
||||||
if (!filter.isEmpty())
|
if (!filter.isEmpty())
|
||||||
proxy.setFilterRegExp(QRegExp(filter));
|
setupFilter(&proxy, filter);
|
||||||
|
|
||||||
(void)proxy.rowCount(QModelIndex()); // force mapping
|
(void)proxy.rowCount(QModelIndex()); // force mapping
|
||||||
|
|
||||||
@ -4746,5 +4662,4 @@ void tst_QSortFilterProxyModel::checkSetNewModel()
|
|||||||
QCoreApplication::processEvents();
|
QCoreApplication::processEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
QTEST_MAIN(tst_QSortFilterProxyModel)
|
|
||||||
#include "tst_qsortfilterproxymodel.moc"
|
#include "tst_qsortfilterproxymodel.moc"
|
@ -0,0 +1,183 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2016 The Qt Company Ltd.
|
||||||
|
** Contact: https://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of the test suite of the Qt Toolkit.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
||||||
|
** 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 The Qt Company. For licensing terms
|
||||||
|
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||||
|
** information use the contact form at https://www.qt.io/contact-us.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU
|
||||||
|
** General Public License version 3 as published by the Free Software
|
||||||
|
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||||
|
** included in the packaging of this file. Please review the following
|
||||||
|
** information to ensure the GNU General Public License requirements will
|
||||||
|
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef TST_QSORTFILTERPROXYMODEL_H
|
||||||
|
#define TST_QSORTFILTERPROXYMODEL_H
|
||||||
|
|
||||||
|
#include <QtTest/QtTest>
|
||||||
|
#include "dynamictreemodel.h"
|
||||||
|
|
||||||
|
#include <QtCore/QCoreApplication>
|
||||||
|
#include <QtGui/QStandardItem>
|
||||||
|
#include <QtWidgets/QTreeView>
|
||||||
|
#include <QtWidgets/QTableView>
|
||||||
|
|
||||||
|
#include <qdebug.h>
|
||||||
|
|
||||||
|
typedef QList<int> IntList;
|
||||||
|
typedef QPair<int, int> IntPair;
|
||||||
|
typedef QList<IntPair> IntPairList;
|
||||||
|
|
||||||
|
enum class FilterType {
|
||||||
|
RegExp,
|
||||||
|
RegularExpression
|
||||||
|
};
|
||||||
|
|
||||||
|
Q_DECLARE_METATYPE(QList<QPersistentModelIndex>)
|
||||||
|
|
||||||
|
class tst_QSortFilterProxyModel : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
tst_QSortFilterProxyModel();
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void initTestCase();
|
||||||
|
void cleanupTestCase();
|
||||||
|
void cleanup();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void getSetCheck();
|
||||||
|
void sort_data();
|
||||||
|
void sort();
|
||||||
|
void sortHierarchy_data();
|
||||||
|
void sortHierarchy();
|
||||||
|
|
||||||
|
void insertRows_data();
|
||||||
|
void insertRows();
|
||||||
|
void prependRow();
|
||||||
|
void removeRows_data();
|
||||||
|
void removeRows();
|
||||||
|
void removeColumns_data();
|
||||||
|
void removeColumns();
|
||||||
|
void insertAfterSelect();
|
||||||
|
void removeAfterSelect();
|
||||||
|
void filter_data();
|
||||||
|
void filter();
|
||||||
|
void filterHierarchy_data();
|
||||||
|
void filterHierarchy();
|
||||||
|
void filterColumns_data();
|
||||||
|
void filterColumns();
|
||||||
|
|
||||||
|
void filterTable();
|
||||||
|
void filterCurrent();
|
||||||
|
void filter_qtbug30662();
|
||||||
|
|
||||||
|
void changeSourceLayout();
|
||||||
|
void changeSourceLayoutFilteredOut();
|
||||||
|
void removeSourceRows_data();
|
||||||
|
void removeSourceRows();
|
||||||
|
void insertSourceRows_data();
|
||||||
|
void insertSourceRows();
|
||||||
|
void changeFilter_data();
|
||||||
|
void changeFilter();
|
||||||
|
void changeSourceData_data();
|
||||||
|
void changeSourceData();
|
||||||
|
void changeSourceDataKeepsStableSorting_qtbug1548();
|
||||||
|
void changeSourceDataForwardsRoles_qtbug35440();
|
||||||
|
void resortingDoesNotBreakTreeModels();
|
||||||
|
void dynamicFilterWithoutSort();
|
||||||
|
void sortFilterRole();
|
||||||
|
void selectionFilteredOut();
|
||||||
|
void match_data();
|
||||||
|
void match();
|
||||||
|
void insertIntoChildrenlessItem();
|
||||||
|
void invalidateMappedChildren();
|
||||||
|
void insertRowIntoFilteredParent();
|
||||||
|
void filterOutParentAndFilterInChild();
|
||||||
|
|
||||||
|
void sourceInsertRows();
|
||||||
|
void sourceModelDeletion();
|
||||||
|
|
||||||
|
void sortColumnTracking1();
|
||||||
|
void sortColumnTracking2();
|
||||||
|
|
||||||
|
void sortStable();
|
||||||
|
|
||||||
|
void hiddenColumns();
|
||||||
|
void insertRowsSort();
|
||||||
|
void staticSorting();
|
||||||
|
void dynamicSorting();
|
||||||
|
void fetchMore();
|
||||||
|
void hiddenChildren();
|
||||||
|
void mapFromToSource();
|
||||||
|
void removeRowsRecursive();
|
||||||
|
void doubleProxySelectionSetSourceModel();
|
||||||
|
void appearsAndSort();
|
||||||
|
void unnecessaryDynamicSorting();
|
||||||
|
void unnecessaryMapCreation();
|
||||||
|
void resetInvalidate_data();
|
||||||
|
void resetInvalidate();
|
||||||
|
|
||||||
|
void testMultipleProxiesWithSelection();
|
||||||
|
void mapSelectionFromSource();
|
||||||
|
void testResetInternalData();
|
||||||
|
void filteredColumns();
|
||||||
|
void headerDataChanged();
|
||||||
|
|
||||||
|
void testParentLayoutChanged();
|
||||||
|
void moveSourceRows();
|
||||||
|
|
||||||
|
void hierarchyFilterInvalidation();
|
||||||
|
void simpleFilterInvalidation();
|
||||||
|
|
||||||
|
void chainedProxyModelRoleNames();
|
||||||
|
|
||||||
|
void noMapAfterSourceDelete();
|
||||||
|
void forwardDropApi();
|
||||||
|
void canDropMimeData();
|
||||||
|
void filterHint();
|
||||||
|
|
||||||
|
void sourceLayoutChangeLeavesValidPersistentIndexes();
|
||||||
|
void rowMoveLeavesValidPersistentIndexes();
|
||||||
|
|
||||||
|
void emitLayoutChangedOnlyIfSortingChanged_data();
|
||||||
|
void emitLayoutChangedOnlyIfSortingChanged();
|
||||||
|
|
||||||
|
void checkSetNewModel();
|
||||||
|
|
||||||
|
void removeIntervals_data();
|
||||||
|
void removeIntervals();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void buildHierarchy(const QStringList &data, QAbstractItemModel *model);
|
||||||
|
void checkHierarchy(const QStringList &data, const QAbstractItemModel *model);
|
||||||
|
void setupFilter(QSortFilterProxyModel *model, const QString& pattern);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
FilterType m_filterType;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QStandardItemModel *m_model;
|
||||||
|
QSortFilterProxyModel *m_proxy;
|
||||||
|
};
|
||||||
|
|
||||||
|
Q_DECLARE_METATYPE(QAbstractItemModel::LayoutChangeHint)
|
||||||
|
|
||||||
|
#endif // TST_QSORTFILTERPROXYMODEL_H
|
1
tests/auto/corelib/itemmodels/qsortfilterproxymodel_regexp/.gitignore
vendored
Normal file
1
tests/auto/corelib/itemmodels/qsortfilterproxymodel_regexp/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
tst_qsortfilterproxymodel_regexp
|
@ -0,0 +1,16 @@
|
|||||||
|
CONFIG += testcase
|
||||||
|
TARGET = tst_qsortfilterproxymodel_regexp
|
||||||
|
|
||||||
|
QT += widgets testlib
|
||||||
|
mtdir = ../../../other/qabstractitemmodelutils
|
||||||
|
qsfpmdir = ../qsortfilterproxymodel_common
|
||||||
|
|
||||||
|
INCLUDEPATH += $$PWD/$${mtdir} $$PWD/$${qsfpmdir}
|
||||||
|
SOURCES += \
|
||||||
|
tst_qsortfilterproxymodel_regexp.cpp \
|
||||||
|
$${qsfpmdir}/tst_qsortfilterproxymodel.cpp \
|
||||||
|
$${mtdir}/dynamictreemodel.cpp
|
||||||
|
|
||||||
|
HEADERS += \
|
||||||
|
$${qsfpmdir}/tst_qsortfilterproxymodel.h \
|
||||||
|
$${mtdir}/dynamictreemodel.h
|
@ -0,0 +1,59 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2016 The Qt Company Ltd.
|
||||||
|
** Contact: https://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of the test suite of the Qt Toolkit.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
||||||
|
** 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 The Qt Company. For licensing terms
|
||||||
|
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||||
|
** information use the contact form at https://www.qt.io/contact-us.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU
|
||||||
|
** General Public License version 3 as published by the Free Software
|
||||||
|
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||||
|
** included in the packaging of this file. Please review the following
|
||||||
|
** information to ensure the GNU General Public License requirements will
|
||||||
|
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include <QtTest/QtTest>
|
||||||
|
|
||||||
|
#include "tst_qsortfilterproxymodel.h"
|
||||||
|
|
||||||
|
class tst_QSortFilterProxyModelRegExp : public tst_QSortFilterProxyModel
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
tst_QSortFilterProxyModelRegExp();
|
||||||
|
private slots:
|
||||||
|
void tst_invalid();
|
||||||
|
};
|
||||||
|
|
||||||
|
tst_QSortFilterProxyModelRegExp::tst_QSortFilterProxyModelRegExp() :
|
||||||
|
tst_QSortFilterProxyModel()
|
||||||
|
{
|
||||||
|
m_filterType = FilterType::RegExp;
|
||||||
|
}
|
||||||
|
|
||||||
|
void tst_QSortFilterProxyModelRegExp::tst_invalid()
|
||||||
|
{
|
||||||
|
const QLatin1String pattern("test");
|
||||||
|
QSortFilterProxyModel model;
|
||||||
|
model.setFilterRegExp(pattern);
|
||||||
|
QCOMPARE(model.filterRegExp(), QRegExp(pattern));
|
||||||
|
model.setFilterRegularExpression(pattern);
|
||||||
|
QCOMPARE(model.filterRegExp(), QRegExp());
|
||||||
|
}
|
||||||
|
|
||||||
|
QTEST_MAIN(tst_QSortFilterProxyModelRegExp)
|
||||||
|
#include "tst_qsortfilterproxymodel_regexp.moc"
|
1
tests/auto/corelib/itemmodels/qsortfilterproxymodel_regularexpression/.gitignore
vendored
Normal file
1
tests/auto/corelib/itemmodels/qsortfilterproxymodel_regularexpression/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
tst_qsortfilterproxymodel_regularexpression
|
@ -0,0 +1,16 @@
|
|||||||
|
CONFIG += testcase
|
||||||
|
TARGET = tst_qsortfilterproxymodel_regularexpression
|
||||||
|
|
||||||
|
QT += widgets testlib
|
||||||
|
mtdir = ../../../other/qabstractitemmodelutils
|
||||||
|
qsfpmdir = ../qsortfilterproxymodel_common
|
||||||
|
|
||||||
|
INCLUDEPATH += $$PWD/$${mtdir} $${qsfpmdir}
|
||||||
|
SOURCES += \
|
||||||
|
tst_qsortfilterproxymodel_regularexpression.cpp \
|
||||||
|
$${qsfpmdir}/tst_qsortfilterproxymodel.cpp \
|
||||||
|
$${mtdir}/dynamictreemodel.cpp
|
||||||
|
|
||||||
|
HEADERS += \
|
||||||
|
$${qsfpmdir}/tst_qsortfilterproxymodel.h \
|
||||||
|
$${mtdir}/dynamictreemodel.h
|
@ -0,0 +1,59 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2016 The Qt Company Ltd.
|
||||||
|
** Contact: https://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of the test suite of the Qt Toolkit.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
||||||
|
** 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 The Qt Company. For licensing terms
|
||||||
|
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||||
|
** information use the contact form at https://www.qt.io/contact-us.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU
|
||||||
|
** General Public License version 3 as published by the Free Software
|
||||||
|
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||||
|
** included in the packaging of this file. Please review the following
|
||||||
|
** information to ensure the GNU General Public License requirements will
|
||||||
|
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include <QtTest/QtTest>
|
||||||
|
|
||||||
|
#include "tst_qsortfilterproxymodel.h"
|
||||||
|
|
||||||
|
class tst_QSortFilterProxyModelRegularExpression : public tst_QSortFilterProxyModel
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
tst_QSortFilterProxyModelRegularExpression();
|
||||||
|
private slots:
|
||||||
|
void tst_invalid();
|
||||||
|
};
|
||||||
|
|
||||||
|
tst_QSortFilterProxyModelRegularExpression::tst_QSortFilterProxyModelRegularExpression() :
|
||||||
|
tst_QSortFilterProxyModel()
|
||||||
|
{
|
||||||
|
m_filterType = FilterType::RegularExpression;
|
||||||
|
}
|
||||||
|
|
||||||
|
void tst_QSortFilterProxyModelRegularExpression::tst_invalid()
|
||||||
|
{
|
||||||
|
const QLatin1String pattern("test");
|
||||||
|
QSortFilterProxyModel model;
|
||||||
|
model.setFilterRegularExpression(pattern);
|
||||||
|
QCOMPARE(model.filterRegularExpression(), QRegularExpression(pattern));
|
||||||
|
model.setFilterRegExp(pattern);
|
||||||
|
QCOMPARE(model.filterRegularExpression(), QRegularExpression());
|
||||||
|
}
|
||||||
|
|
||||||
|
QTEST_MAIN(tst_QSortFilterProxyModelRegularExpression)
|
||||||
|
#include "tst_qsortfilterproxymodel_regularexpression.moc"
|
Loading…
Reference in New Issue
Block a user