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
@ -43,6 +43,7 @@
|
||||
#include <qdebug.h>
|
||||
#include <qdatetime.h>
|
||||
#include <qpair.h>
|
||||
#include <qregularexpression.h>
|
||||
#include <qstringlist.h>
|
||||
#include <private/qabstractitemmodel_p.h>
|
||||
#include <private/qabstractproxymodel_p.h>
|
||||
@ -146,6 +147,133 @@ private:
|
||||
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
|
||||
{
|
||||
Q_DECLARE_PUBLIC(QSortFilterProxyModel)
|
||||
@ -171,7 +299,7 @@ public:
|
||||
|
||||
int filter_column;
|
||||
int filter_role;
|
||||
QRegExp filter_regexp;
|
||||
RegularExpressionData filter_data;
|
||||
QModelIndex last_top_source;
|
||||
|
||||
bool filter_recursive;
|
||||
@ -1109,7 +1237,7 @@ void QSortFilterProxyModelPrivate::update_persistent_indexes(
|
||||
*/
|
||||
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())
|
||||
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
|
||||
shown.
|
||||
|
||||
A common use case is to let the user specify the filter regexp, wildcard
|
||||
pattern, or fixed string in a QLineEdit and to connect the
|
||||
\l{QLineEdit::textChanged()}{textChanged()} signal to setFilterRegExp(),
|
||||
A common use case is to let the user specify the filter regular expression,
|
||||
wildcard pattern, or fixed string in a QLineEdit and to connect the
|
||||
\l{QLineEdit::textChanged()}{textChanged()} signal to setFilterRegularExpression(),
|
||||
setFilterWildcard(), or setFilterFixedString() to reapply the filter.
|
||||
|
||||
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
|
||||
\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},
|
||||
{Basic Sort/Filter Model Example}, {Custom Sort/Filter Model Example}, QIdentityProxyModel
|
||||
*/
|
||||
@ -2437,17 +2580,47 @@ Qt::SortOrder QSortFilterProxyModel::sortOrder() const
|
||||
QRegExp QSortFilterProxyModel::filterRegExp() const
|
||||
{
|
||||
Q_D(const QSortFilterProxyModel);
|
||||
return d->filter_regexp;
|
||||
return d->filter_data.regExp();
|
||||
}
|
||||
|
||||
void QSortFilterProxyModel::setFilterRegExp(const QRegExp ®Exp)
|
||||
{
|
||||
Q_D(QSortFilterProxyModel);
|
||||
d->filter_about_to_be_changed();
|
||||
d->filter_regexp = regExp;
|
||||
d->filter_data.setRegExp(regExp);
|
||||
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
|
||||
\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
|
||||
{
|
||||
Q_D(const QSortFilterProxyModel);
|
||||
return d->filter_regexp.caseSensitivity();
|
||||
return d->filter_data.caseSensitivity();
|
||||
}
|
||||
|
||||
void QSortFilterProxyModel::setFilterCaseSensitivity(Qt::CaseSensitivity cs)
|
||||
{
|
||||
Q_D(QSortFilterProxyModel);
|
||||
if (cs == d->filter_regexp.caseSensitivity())
|
||||
if (cs == d->filter_data.caseSensitivity())
|
||||
return;
|
||||
d->filter_about_to_be_changed();
|
||||
d->filter_regexp.setCaseSensitivity(cs);
|
||||
d->filter_data.setCaseSensitivity(cs);
|
||||
d->filter_changed();
|
||||
}
|
||||
|
||||
@ -2558,11 +2731,33 @@ void QSortFilterProxyModel::setFilterRegExp(const QString &pattern)
|
||||
{
|
||||
Q_D(QSortFilterProxyModel);
|
||||
d->filter_about_to_be_changed();
|
||||
d->filter_regexp.setPatternSyntax(QRegExp::RegExp);
|
||||
d->filter_regexp.setPattern(pattern);
|
||||
QRegExp rx(pattern);
|
||||
d->filter_data.setRegExp(rx);
|
||||
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
|
||||
of the source model to the given \a pattern.
|
||||
@ -2573,8 +2768,8 @@ void QSortFilterProxyModel::setFilterWildcard(const QString &pattern)
|
||||
{
|
||||
Q_D(QSortFilterProxyModel);
|
||||
d->filter_about_to_be_changed();
|
||||
d->filter_regexp.setPatternSyntax(QRegExp::Wildcard);
|
||||
d->filter_regexp.setPattern(pattern);
|
||||
QRegExp rx(pattern, d->filter_data.caseSensitivity(), QRegExp::Wildcard);
|
||||
d->filter_data.setRegExp(rx);
|
||||
d->filter_changed();
|
||||
}
|
||||
|
||||
@ -2588,8 +2783,8 @@ void QSortFilterProxyModel::setFilterFixedString(const QString &pattern)
|
||||
{
|
||||
Q_D(QSortFilterProxyModel);
|
||||
d->filter_about_to_be_changed();
|
||||
d->filter_regexp.setPatternSyntax(QRegExp::FixedString);
|
||||
d->filter_regexp.setPattern(pattern);
|
||||
QRegExp rx(pattern, d->filter_data.caseSensitivity(), QRegExp::FixedString);
|
||||
d->filter_data.setRegExp(rx);
|
||||
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
|
||||
{
|
||||
Q_D(const QSortFilterProxyModel);
|
||||
if (d->filter_regexp.isEmpty())
|
||||
|
||||
if (d->filter_data.isEmpty())
|
||||
return true;
|
||||
if (d->filter_column == -1) {
|
||||
int column_count = d->model->columnCount(source_parent);
|
||||
for (int column = 0; column < column_count; ++column) {
|
||||
QModelIndex source_index = d->model->index(source_row, column, source_parent);
|
||||
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 false;
|
||||
@ -2830,7 +3026,7 @@ bool QSortFilterProxyModel::filterAcceptsRow(int source_row, const QModelIndex &
|
||||
if (!source_index.isValid()) // the column may not exist
|
||||
return true;
|
||||
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/qregexp.h>
|
||||
#include <QtCore/qregularexpression.h>
|
||||
|
||||
QT_REQUIRE_CONFIG(sortfilterproxymodel);
|
||||
|
||||
@ -59,6 +60,9 @@ class Q_CORE_EXPORT QSortFilterProxyModel : public QAbstractProxyModel
|
||||
|
||||
Q_OBJECT
|
||||
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(bool dynamicSortFilter READ dynamicSortFilter WRITE setDynamicSortFilter)
|
||||
Q_PROPERTY(Qt::CaseSensitivity filterCaseSensitivity READ filterCaseSensitivity WRITE setFilterCaseSensitivity)
|
||||
@ -83,6 +87,9 @@ public:
|
||||
QRegExp filterRegExp() const;
|
||||
void setFilterRegExp(const QRegExp ®Exp);
|
||||
|
||||
QRegularExpression filterRegularExpression() const;
|
||||
void setFilterRegularExpression(const QRegularExpression ®ularExpression);
|
||||
|
||||
int filterKeyColumn() const;
|
||||
void setFilterKeyColumn(int column);
|
||||
|
||||
@ -112,6 +119,9 @@ public:
|
||||
|
||||
public Q_SLOTS:
|
||||
void setFilterRegExp(const QString &pattern);
|
||||
#if QT_CONFIG(regularexpression)
|
||||
void setFilterRegularExpression(const QString &pattern);
|
||||
#endif
|
||||
void setFilterWildcard(const QString &pattern);
|
||||
void setFilterFixedString(const QString &pattern);
|
||||
#if QT_DEPRECATED_SINCE(5, 11)
|
||||
|
@ -11,7 +11,8 @@ qtHaveModule(gui): SUBDIRS += \
|
||||
|
||||
qtHaveModule(widgets) {
|
||||
SUBDIRS += \
|
||||
qsortfilterproxymodel
|
||||
qsortfilterproxymodel_regexp \
|
||||
qsortfilterproxymodel_regularexpression
|
||||
|
||||
qtHaveModule(sql): SUBDIRS += \
|
||||
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 "tst_qsortfilterproxymodel.h"
|
||||
#include "dynamictreemodel.h"
|
||||
|
||||
#include <QtCore/QCoreApplication>
|
||||
@ -36,137 +37,6 @@
|
||||
|
||||
#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
|
||||
void tst_QSortFilterProxyModel::getSetCheck()
|
||||
{
|
||||
@ -204,7 +74,15 @@ void tst_QSortFilterProxyModel::cleanupTestCase()
|
||||
|
||||
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_model->clear();
|
||||
m_model->insertColumns(0, 1);
|
||||
@ -915,8 +793,9 @@ void tst_QSortFilterProxyModel::removeRows()
|
||||
|
||||
if (sortOrder != -1)
|
||||
proxy.sort(0, static_cast<Qt::SortOrder>(sortOrder));
|
||||
|
||||
if (!filter.isEmpty())
|
||||
proxy.setFilterRegExp(QRegExp(filter));
|
||||
setupFilter(&proxy, filter);
|
||||
|
||||
// remove the rows
|
||||
QCOMPARE(proxy.removeRows(position, count, QModelIndex()), success);
|
||||
@ -938,14 +817,29 @@ class MyFilteredColumnProxyModel : public QSortFilterProxyModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
MyFilteredColumnProxyModel(QObject *parent = 0)
|
||||
: QSortFilterProxyModel(parent) { }
|
||||
MyFilteredColumnProxyModel(FilterType filterType, QObject *parent = 0) :
|
||||
QSortFilterProxyModel(parent),
|
||||
m_filterType(filterType)
|
||||
{ }
|
||||
|
||||
protected:
|
||||
bool filterAcceptsColumn(int sourceColumn, const QModelIndex &) const
|
||||
{
|
||||
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()
|
||||
@ -1154,10 +1048,10 @@ void tst_QSortFilterProxyModel::removeColumns()
|
||||
QFETCH(QStringList, expectedSource);
|
||||
|
||||
QStandardItemModel model;
|
||||
MyFilteredColumnProxyModel proxy;
|
||||
MyFilteredColumnProxyModel proxy(m_filterType);
|
||||
proxy.setSourceModel(&model);
|
||||
if (!filter.isEmpty())
|
||||
proxy.setFilterRegExp(QRegExp(filter));
|
||||
setupFilter(&proxy, filter);
|
||||
|
||||
// prepare model
|
||||
model.setHorizontalHeaderLabels(initial);
|
||||
@ -1225,7 +1119,8 @@ void tst_QSortFilterProxyModel::filterColumns()
|
||||
QModelIndex index = m_model->index(0, col, QModelIndex());
|
||||
m_model->setData(index, initial.at(col), Qt::DisplayRole);
|
||||
}
|
||||
m_proxy->setFilterRegExp(pattern);
|
||||
setupFilter(m_proxy, pattern);
|
||||
|
||||
m_proxy->setFilterKeyColumn(-1);
|
||||
// make sure the model is unchanged
|
||||
for (int col = 0; col < m_model->columnCount(QModelIndex()); ++col) {
|
||||
@ -1291,6 +1186,7 @@ void tst_QSortFilterProxyModel::filter()
|
||||
QFETCH(QString, pattern);
|
||||
QFETCH(QStringList, initial);
|
||||
QFETCH(QStringList, expected);
|
||||
|
||||
// prepare model
|
||||
QVERIFY(m_model->insertRows(0, initial.count(), QModelIndex()));
|
||||
QCOMPARE(m_model->rowCount(QModelIndex()), initial.count());
|
||||
@ -1300,7 +1196,7 @@ void tst_QSortFilterProxyModel::filter()
|
||||
QModelIndex index = m_model->index(row, 0, QModelIndex());
|
||||
m_model->setData(index, initial.at(row), Qt::DisplayRole);
|
||||
}
|
||||
m_proxy->setFilterRegExp(pattern);
|
||||
setupFilter(m_proxy, pattern);
|
||||
// make sure the proxy is unfiltered
|
||||
QCOMPARE(m_proxy->columnCount(QModelIndex()), 1);
|
||||
QCOMPARE(m_proxy->rowCount(QModelIndex()), expected.count());
|
||||
@ -1339,7 +1235,7 @@ void tst_QSortFilterProxyModel::filterHierarchy()
|
||||
QFETCH(QStringList, initial);
|
||||
QFETCH(QStringList, expected);
|
||||
buildHierarchy(initial, m_model);
|
||||
m_proxy->setFilterRegExp(pattern);
|
||||
setupFilter(m_proxy, pattern);
|
||||
checkHierarchy(initial, m_model);
|
||||
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
|
||||
{
|
||||
public:
|
||||
@ -1422,7 +1330,7 @@ void tst_QSortFilterProxyModel::filterTable()
|
||||
TestModel model;
|
||||
QSortFilterProxyModel filter;
|
||||
filter.setSourceModel(&model);
|
||||
filter.setFilterRegExp("9");
|
||||
setupFilter(&filter, QLatin1String("9"));
|
||||
|
||||
for (int i = 0; i < filter.rowCount(); ++i)
|
||||
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));
|
||||
QCOMPARE(spy.count(), 1);
|
||||
proxy.setFilterRegExp(QRegExp("^B"));
|
||||
setupFilter(&proxy, QLatin1String("^B"));
|
||||
QCOMPARE(spy.count(), 2);
|
||||
}
|
||||
|
||||
@ -1497,7 +1405,7 @@ void tst_QSortFilterProxyModel::filter_qtbug30662()
|
||||
proxy.setSourceModel(&model);
|
||||
|
||||
// make sure the filter does not match any entry
|
||||
proxy.setFilterRegExp(QRegExp("[0-9]+"));
|
||||
setupFilter(&proxy, QLatin1String("[0-9]+"));
|
||||
|
||||
QStringList slSource;
|
||||
slSource << "z" << "x" << "a" << "b";
|
||||
@ -1507,7 +1415,7 @@ void tst_QSortFilterProxyModel::filter_qtbug30662()
|
||||
model.setStringList(slSource);
|
||||
|
||||
// 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;
|
||||
for (int i = 0; i < proxy.rowCount(); ++i)
|
||||
@ -1553,7 +1461,8 @@ void tst_QSortFilterProxyModel::changeSourceLayoutFilteredOut()
|
||||
|
||||
QSignalSpy removeSpy(&proxy, &QSortFilterProxyModel::rowsRemoved);
|
||||
// Filter everything out
|
||||
proxy.setFilterRegExp(QRegExp("c"));
|
||||
setupFilter(&proxy, QLatin1String("c"));
|
||||
|
||||
QCOMPARE(removeSpy.count(), 1);
|
||||
QCOMPARE(0, proxy.rowCount());
|
||||
|
||||
@ -1562,7 +1471,8 @@ void tst_QSortFilterProxyModel::changeSourceLayoutFilteredOut()
|
||||
|
||||
QSignalSpy insertSpy(&proxy, &QSortFilterProxyModel::rowsInserted);
|
||||
// Remove filter; we expect an insert
|
||||
proxy.setFilterRegExp(QRegExp(""));
|
||||
setupFilter(&proxy, "");
|
||||
|
||||
QCOMPARE(insertSpy.count(), 1);
|
||||
QCOMPARE(beforeSortFilter, proxy.rowCount());
|
||||
}
|
||||
@ -1842,7 +1752,7 @@ void tst_QSortFilterProxyModel::changeFilter()
|
||||
QVERIFY(initialRemoveSpy.isValid());
|
||||
QVERIFY(initialInsertSpy.isValid());
|
||||
|
||||
proxy.setFilterRegExp(initialFilter);
|
||||
setupFilter(&proxy, initialFilter);
|
||||
|
||||
QCOMPARE(initialRemoveSpy.count(), initialRemoveIntervals.count());
|
||||
QCOMPARE(initialInsertSpy.count(), 0);
|
||||
@ -1866,7 +1776,7 @@ void tst_QSortFilterProxyModel::changeFilter()
|
||||
QVERIFY(finalRemoveSpy.isValid());
|
||||
QVERIFY(finalInsertSpy.isValid());
|
||||
|
||||
proxy.setFilterRegExp(finalFilter);
|
||||
setupFilter(&proxy, finalFilter);
|
||||
|
||||
QCOMPARE(finalRemoveSpy.count(), finalRemoveIntervals.count());
|
||||
for (int i = 0; i < finalRemoveSpy.count(); ++i) {
|
||||
@ -2060,7 +1970,7 @@ void tst_QSortFilterProxyModel::changeSourceData()
|
||||
proxy.sort(0, static_cast<Qt::SortOrder>(sortOrder));
|
||||
(void)proxy.rowCount(QModelIndex()); // force mapping
|
||||
|
||||
proxy.setFilterRegExp(filter);
|
||||
setupFilter(&proxy, filter);
|
||||
|
||||
QCOMPARE(proxy.rowCount(), expectedInitialProxyItems.count());
|
||||
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);
|
||||
}
|
||||
|
||||
proxy.setFilterRegExp("2");
|
||||
setupFilter(&proxy, QLatin1String("2"));
|
||||
|
||||
QCOMPARE(proxy.rowCount(), 0); // Qt::DisplayRole is default role
|
||||
|
||||
proxy.setFilterRole(Qt::UserRole);
|
||||
@ -2262,7 +2173,8 @@ void tst_QSortFilterProxyModel::sortFilterRole()
|
||||
proxy.setFilterRole(Qt::DisplayRole);
|
||||
QCOMPARE(proxy.rowCount(), 0);
|
||||
|
||||
proxy.setFilterRegExp("1|2|3");
|
||||
setupFilter(&proxy, QLatin1String("1|2|3"));
|
||||
|
||||
QCOMPARE(proxy.rowCount(), 0);
|
||||
|
||||
proxy.setFilterRole(Qt::UserRole);
|
||||
@ -2273,7 +2185,8 @@ void tst_QSortFilterProxyModel::sortFilterRole()
|
||||
|
||||
proxy.setSortRole(Qt::UserRole);
|
||||
proxy.setFilterRole(Qt::DisplayRole);
|
||||
proxy.setFilterRegExp("a|c");
|
||||
setupFilter(&proxy, QLatin1String("a|c"));
|
||||
|
||||
QCOMPARE(proxy.rowCount(), orderedItems.count());
|
||||
for (int i = 0; i < proxy.rowCount(); ++i) {
|
||||
QModelIndex index = proxy.index(i, 0, QModelIndex());
|
||||
@ -2297,7 +2210,8 @@ void tst_QSortFilterProxyModel::selectionFilteredOut()
|
||||
|
||||
view.setCurrentIndex(proxy.index(0, 0));
|
||||
QCOMPARE(spy.count(), 1);
|
||||
proxy.setFilterRegExp(QRegExp("^B"));
|
||||
|
||||
setupFilter(&proxy, QLatin1String("^B"));
|
||||
QCOMPARE(spy.count(), 2);
|
||||
}
|
||||
|
||||
@ -2383,7 +2297,7 @@ void tst_QSortFilterProxyModel::match()
|
||||
}
|
||||
|
||||
proxy.sort(0, static_cast<Qt::SortOrder>(sortOrder));
|
||||
proxy.setFilterRegExp(filter);
|
||||
setupFilter(&proxy, filter);
|
||||
|
||||
QModelIndex startIndex = proxy.index(proxyStartRow, 0);
|
||||
QModelIndexList indexes = proxy.match(startIndex, Qt::DisplayRole, what,
|
||||
@ -2508,7 +2422,8 @@ void tst_QSortFilterProxyModel::filterOutParentAndFilterInChild()
|
||||
QSortFilterProxyModel proxy;
|
||||
proxy.setSourceModel(&model);
|
||||
|
||||
proxy.setFilterRegExp("A|B");
|
||||
setupFilter(&proxy, QLatin1String("A|B"));
|
||||
|
||||
QStandardItem *itemA = new QStandardItem("A");
|
||||
model.appendRow(itemA); // not filtered
|
||||
QStandardItem *itemB = new QStandardItem("B");
|
||||
@ -2522,7 +2437,7 @@ void tst_QSortFilterProxyModel::filterOutParentAndFilterInChild()
|
||||
QVERIFY(removedSpy.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
|
||||
QCOMPARE(removedSpy.count(), 1);
|
||||
@ -2935,7 +2850,7 @@ void tst_QSortFilterProxyModel::hiddenChildren()
|
||||
itemA->appendRow(itemB);
|
||||
QStandardItem *itemC = new QStandardItem("C");
|
||||
itemA->appendRow(itemC);
|
||||
proxy.setFilterRegExp("VISIBLE");
|
||||
setupFilter(&proxy, QLatin1String("VISIBLE"));
|
||||
|
||||
QCOMPARE(proxy.rowCount(QModelIndex()) , 1);
|
||||
QPersistentModelIndex indexA = proxy.index(0,0);
|
||||
@ -2962,7 +2877,8 @@ void tst_QSortFilterProxyModel::hiddenChildren()
|
||||
QModelIndex indexC = proxy.index(0, 0, indexA);
|
||||
QCOMPARE(proxy.data(indexC).toString(), QString::fromLatin1("C VISIBLE"));
|
||||
|
||||
proxy.setFilterRegExp("C");
|
||||
setupFilter(&proxy, QLatin1String("C"));
|
||||
|
||||
QCOMPARE(proxy.rowCount(QModelIndex()), 0);
|
||||
itemC->setText("invisible");
|
||||
itemA->setText("AC");
|
||||
@ -3284,7 +3200,8 @@ void tst_QSortFilterProxyModel::mapSelectionFromSource()
|
||||
|
||||
QSortFilterProxyModel proxy;
|
||||
proxy.setDynamicSortFilter(true);
|
||||
proxy.setFilterRegExp("d.*");
|
||||
setupFilter(&proxy, QLatin1String("d.*"));
|
||||
|
||||
proxy.setSourceModel(&model);
|
||||
|
||||
// Only "delta" remains.
|
||||
@ -3839,13 +3756,13 @@ void tst_QSortFilterProxyModel::moveSourceRows()
|
||||
filterProxy.setDynamicSortFilter(true);
|
||||
filterProxy.sort(0, Qt::AscendingOrder);
|
||||
filterProxy.setSourceModel(&proxy);
|
||||
filterProxy.setFilterRegExp("6"); // One of the parents
|
||||
setupFilter(&filterProxy, QLatin1String("6")); // One of the parents
|
||||
|
||||
QSortFilterProxyModel filterBothProxy;
|
||||
filterBothProxy.setDynamicSortFilter(true);
|
||||
filterBothProxy.sort(0, Qt::AscendingOrder);
|
||||
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 modelAfterSpy(&model, &DynamicTreeModel::rowsMoved);
|
||||
@ -4243,7 +4160,7 @@ void tst_QSortFilterProxyModel::filterHint()
|
||||
QSortFilterProxyModel proxy2;
|
||||
proxy2.setSourceModel(&proxy1);
|
||||
proxy2.setFilterRole(Qt::DisplayRole);
|
||||
proxy2.setFilterRegExp("^[^ ]*$");
|
||||
setupFilter(&proxy2, QLatin1String("^[^ ]*$"));
|
||||
proxy2.setDynamicSortFilter(true);
|
||||
|
||||
QSignalSpy proxy1BeforeSpy(&proxy1, &QSortFilterProxyModel::layoutAboutToBeChanged);
|
||||
@ -4371,8 +4288,7 @@ void tst_QSortFilterProxyModel::sourceLayoutChangeLeavesValidPersistentIndexes()
|
||||
QSortFilterProxyModel proxy1;
|
||||
proxy1.setSourceModel(&model);
|
||||
Q_SET_OBJECT_NAME(proxy1);
|
||||
|
||||
proxy1.setFilterRegExp("1|2");
|
||||
setupFilter(&proxy1, QLatin1String("1|2"));
|
||||
|
||||
// The current state of things:
|
||||
// model proxy
|
||||
@ -4419,7 +4335,7 @@ void tst_QSortFilterProxyModel::rowMoveLeavesValidPersistentIndexes()
|
||||
proxy1.setSourceModel(&model);
|
||||
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 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)
|
||||
proxy.sort(0, static_cast<Qt::SortOrder>(sortOrder));
|
||||
if (!filter.isEmpty())
|
||||
proxy.setFilterRegExp(QRegExp(filter));
|
||||
setupFilter(&proxy, filter);
|
||||
|
||||
(void)proxy.rowCount(QModelIndex()); // force mapping
|
||||
|
||||
@ -4746,5 +4662,4 @@ void tst_QSortFilterProxyModel::checkSetNewModel()
|
||||
QCoreApplication::processEvents();
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QSortFilterProxyModel)
|
||||
#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