summaryrefslogtreecommitdiffstats
path: root/src/corelib/itemmodels
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/itemmodels')
-rw-r--r--src/corelib/itemmodels/qabstractitemmodel.cpp61
-rw-r--r--src/corelib/itemmodels/qabstractitemmodel.h11
-rw-r--r--src/corelib/itemmodels/qabstractproxymodel.h6
-rw-r--r--src/corelib/itemmodels/qconcatenatetablesproxymodel.cpp2
-rw-r--r--src/corelib/itemmodels/qidentityproxymodel.cpp2
-rw-r--r--src/corelib/itemmodels/qitemselectionmodel.h5
-rw-r--r--src/corelib/itemmodels/qsortfilterproxymodel.cpp351
-rw-r--r--src/corelib/itemmodels/qsortfilterproxymodel.h8
-rw-r--r--src/corelib/itemmodels/qtransposeproxymodel.cpp2
9 files changed, 163 insertions, 285 deletions
diff --git a/src/corelib/itemmodels/qabstractitemmodel.cpp b/src/corelib/itemmodels/qabstractitemmodel.cpp
index d88960ba0c..3bc3b546da 100644
--- a/src/corelib/itemmodels/qabstractitemmodel.cpp
+++ b/src/corelib/itemmodels/qabstractitemmodel.cpp
@@ -46,7 +46,9 @@
#include <qdebug.h>
#include <qvector.h>
#include <qregexp.h>
-#include <qregularexpression.h>
+#if QT_CONFIG(regularexpression)
+# include <qregularexpression.h>
+#endif
#include <qstack.h>
#include <qbitarray.h>
#include <qdatetime.h>
@@ -63,7 +65,7 @@ QPersistentModelIndexData *QPersistentModelIndexData::create(const QModelIndex &
Q_ASSERT(index.isValid()); // we will _never_ insert an invalid index in the list
QPersistentModelIndexData *d = nullptr;
QAbstractItemModel *model = const_cast<QAbstractItemModel *>(index.model());
- QHash<QModelIndex, QPersistentModelIndexData *> &indexes = model->d_func()->persistent.indexes;
+ QMultiHash<QModelIndex, QPersistentModelIndexData *> &indexes = model->d_func()->persistent.indexes;
const auto it = indexes.constFind(index);
if (it != indexes.cend()) {
d = (*it);
@@ -665,8 +667,7 @@ void QAbstractItemModelPrivate::rowsAboutToBeInserted(const QModelIndex &parent,
Q_UNUSED(last);
QVector<QPersistentModelIndexData *> persistent_moved;
if (first < q->rowCount(parent)) {
- for (QHash<QModelIndex, QPersistentModelIndexData *>::const_iterator it = persistent.indexes.constBegin();
- it != persistent.indexes.constEnd(); ++it) {
+ for (auto it = persistent.indexes.constBegin(); it != persistent.indexes.constEnd(); ++it) {
QPersistentModelIndexData *data = *it;
const QModelIndex &index = data->index;
if (index.row() >= first && index.isValid() && index.parent() == parent) {
@@ -702,14 +703,13 @@ void QAbstractItemModelPrivate::itemsAboutToBeMoved(const QModelIndex &srcParent
QVector<QPersistentModelIndexData *> persistent_moved_in_source;
QVector<QPersistentModelIndexData *> persistent_moved_in_destination;
- QHash<QModelIndex, QPersistentModelIndexData *>::const_iterator it;
- const QHash<QModelIndex, QPersistentModelIndexData *>::const_iterator begin = persistent.indexes.constBegin();
- const QHash<QModelIndex, QPersistentModelIndexData *>::const_iterator end = persistent.indexes.constEnd();
+ const auto begin = persistent.indexes.constBegin();
+ const auto end = persistent.indexes.constEnd();
const bool sameParent = (srcParent == destinationParent);
const bool movingUp = (srcFirst > destinationChild);
- for ( it = begin; it != end; ++it) {
+ for (auto it = begin; it != end; ++it) {
QPersistentModelIndexData *data = *it;
const QModelIndex &index = data->index;
const QModelIndex &parent = index.parent();
@@ -814,8 +814,7 @@ void QAbstractItemModelPrivate::rowsAboutToBeRemoved(const QModelIndex &parent,
QVector<QPersistentModelIndexData *> persistent_invalidated;
// find the persistent indexes that are affected by the change, either by being in the removed subtree
// or by being on the same level and below the removed rows
- for (QHash<QModelIndex, QPersistentModelIndexData *>::const_iterator it = persistent.indexes.constBegin();
- it != persistent.indexes.constEnd(); ++it) {
+ for (auto it = persistent.indexes.constBegin(); it != persistent.indexes.constEnd(); ++it) {
QPersistentModelIndexData *data = *it;
bool level_changed = false;
QModelIndex current = data->index;
@@ -858,7 +857,9 @@ void QAbstractItemModelPrivate::rowsRemoved(const QModelIndex &parent,
for (QVector<QPersistentModelIndexData *>::const_iterator it = persistent_invalidated.constBegin();
it != persistent_invalidated.constEnd(); ++it) {
QPersistentModelIndexData *data = *it;
- persistent.indexes.erase(persistent.indexes.constFind(data->index));
+ auto pit = persistent.indexes.constFind(data->index);
+ if (pit != persistent.indexes.cend())
+ persistent.indexes.erase(pit);
data->index = QModelIndex();
}
}
@@ -870,8 +871,7 @@ void QAbstractItemModelPrivate::columnsAboutToBeInserted(const QModelIndex &pare
Q_UNUSED(last);
QVector<QPersistentModelIndexData *> persistent_moved;
if (first < q->columnCount(parent)) {
- for (QHash<QModelIndex, QPersistentModelIndexData *>::const_iterator it = persistent.indexes.constBegin();
- it != persistent.indexes.constEnd(); ++it) {
+ for (auto it = persistent.indexes.constBegin(); it != persistent.indexes.constEnd(); ++it) {
QPersistentModelIndexData *data = *it;
const QModelIndex &index = data->index;
if (index.column() >= first && index.isValid() && index.parent() == parent)
@@ -907,8 +907,7 @@ void QAbstractItemModelPrivate::columnsAboutToBeRemoved(const QModelIndex &paren
QVector<QPersistentModelIndexData *> persistent_invalidated;
// find the persistent indexes that are affected by the change, either by being in the removed subtree
// or by being on the same level and to the right of the removed columns
- for (QHash<QModelIndex, QPersistentModelIndexData *>::const_iterator it = persistent.indexes.constBegin();
- it != persistent.indexes.constEnd(); ++it) {
+ for (auto it = persistent.indexes.constBegin(); it != persistent.indexes.constEnd(); ++it) {
QPersistentModelIndexData *data = *it;
bool level_changed = false;
QModelIndex current = data->index;
@@ -952,7 +951,9 @@ void QAbstractItemModelPrivate::columnsRemoved(const QModelIndex &parent,
for (QVector<QPersistentModelIndexData *>::const_iterator it = persistent_invalidated.constBegin();
it != persistent_invalidated.constEnd(); ++it) {
QPersistentModelIndexData *data = *it;
- persistent.indexes.erase(persistent.indexes.constFind(data->index));
+ auto index = persistent.indexes.constFind(data->index);
+ if (index != persistent.indexes.constEnd())
+ persistent.indexes.erase(index);
data->index = QModelIndex();
}
}
@@ -2362,7 +2363,9 @@ QModelIndexList QAbstractItemModel::match(const QModelIndex &start, int role,
bool wrap = flags & Qt::MatchWrap;
bool allHits = (hits == -1);
QString text; // only convert to a string if it is needed
+#if QT_CONFIG(regularexpression)
QRegularExpression rx; // only create it if needed
+#endif
const int column = start.column();
QModelIndex p = parent(start);
int from = start.row();
@@ -2380,6 +2383,7 @@ QModelIndexList QAbstractItemModel::match(const QModelIndex &start, int role,
if (value == v)
result.append(idx);
} else { // QString or regular expression based matching
+#if QT_CONFIG(regularexpression)
if (matchType == Qt::MatchRegularExpression) {
if (rx.pattern().isEmpty()) {
if (value.userType() == QMetaType::QRegularExpression) {
@@ -2395,25 +2399,23 @@ QModelIndexList QAbstractItemModel::match(const QModelIndex &start, int role,
rx.setPattern(QRegularExpression::wildcardToRegularExpression(value.toString()));
if (cs == Qt::CaseInsensitive)
rx.setPatternOptions(QRegularExpression::CaseInsensitiveOption);
- } else {
+ } else
+#endif
+ {
if (text.isEmpty()) // lazy conversion
text = value.toString();
}
QString t = v.toString();
switch (matchType) {
-#if QT_DEPRECATED_SINCE(5, 15)
- case Qt::MatchRegExp:
- if (QRegExp(text, cs).exactMatch(t))
- result.append(idx);
- break;
-#endif
+#if QT_CONFIG(regularexpression)
case Qt::MatchRegularExpression:
Q_FALLTHROUGH();
case Qt::MatchWildcard:
if (t.contains(rx))
result.append(idx);
break;
+#endif
case Qt::MatchStartsWith:
if (t.startsWith(text, cs))
result.append(idx);
@@ -3297,7 +3299,11 @@ void QAbstractItemModel::endResetModel()
{
Q_D(QAbstractItemModel);
d->invalidatePersistentIndexes();
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+ resetInternalData();
+#else
QMetaObject::invokeMethod(this, "resetInternalData");
+#endif
emit modelReset(QPrivateSignal());
}
@@ -3375,8 +3381,7 @@ QModelIndexList QAbstractItemModel::persistentIndexList() const
Q_D(const QAbstractItemModel);
QModelIndexList result;
result.reserve(d->persistent.indexes.count());
- for (QHash<QModelIndex, QPersistentModelIndexData *>::const_iterator it = d->persistent.indexes.constBegin();
- it != d->persistent.indexes.constEnd(); ++it) {
+ for (auto it = d->persistent.indexes.constBegin(); it != d->persistent.indexes.constEnd(); ++it) {
QPersistentModelIndexData *data = *it;
result.append(data->index);
}
@@ -3973,7 +3978,7 @@ bool QAbstractListModel::dropMimeData(const QMimeData *data, Qt::DropAction acti
*/
/*!
- \fn uint qHash(const QPersistentModelIndex &index, uint seed = 0)
+ \fn size_t qHash(const QPersistentModelIndex &index, size_t seed = 0)
\since 5.0
\relates QPersistentModelIndex
@@ -3994,8 +3999,8 @@ bool QAbstractListModel::dropMimeData(const QMimeData *data, Qt::DropAction acti
*/
void QAbstractItemModelPrivate::Persistent::insertMultiAtEnd(const QModelIndex& key, QPersistentModelIndexData *data)
{
- QHash<QModelIndex,QPersistentModelIndexData *>::iterator newIt = indexes.insert(key, data);
- QHash<QModelIndex,QPersistentModelIndexData *>::iterator it = newIt;
+ auto newIt = indexes.insert(key, data);
+ auto it = newIt;
++it;
while (it != indexes.end() && it.key() == key) {
qSwap(*newIt,*it);
diff --git a/src/corelib/itemmodels/qabstractitemmodel.h b/src/corelib/itemmodels/qabstractitemmodel.h
index 43649cf79b..86ff361ccb 100644
--- a/src/corelib/itemmodels/qabstractitemmodel.h
+++ b/src/corelib/itemmodels/qabstractitemmodel.h
@@ -103,7 +103,7 @@ Q_CORE_EXPORT QDebug operator<<(QDebug, const QModelIndex &);
class QPersistentModelIndexData;
// qHash is a friend, but we can't use default arguments for friends (ยง8.3.6.4)
-uint qHash(const QPersistentModelIndex &index, uint seed = 0) noexcept;
+size_t qHash(const QPersistentModelIndex &index, size_t seed = 0) noexcept;
class Q_CORE_EXPORT QPersistentModelIndex
{
@@ -141,14 +141,14 @@ public:
bool isValid() const;
private:
QPersistentModelIndexData *d;
- friend uint qHash(const QPersistentModelIndex &, uint seed) noexcept;
+ friend size_t qHash(const QPersistentModelIndex &, size_t seed) noexcept;
#ifndef QT_NO_DEBUG_STREAM
friend Q_CORE_EXPORT QDebug operator<<(QDebug, const QPersistentModelIndex &);
#endif
};
Q_DECLARE_SHARED(QPersistentModelIndex)
-inline uint qHash(const QPersistentModelIndex &index, uint seed) noexcept
+inline size_t qHash(const QPersistentModelIndex &index, size_t seed) noexcept
{ return qHash(index.d, seed); }
@@ -156,7 +156,6 @@ inline uint qHash(const QPersistentModelIndex &index, uint seed) noexcept
Q_CORE_EXPORT QDebug operator<<(QDebug, const QPersistentModelIndex &);
#endif
-template<typename T> class QList;
typedef QList<QModelIndex> QModelIndexList;
class QMimeData;
@@ -462,8 +461,8 @@ inline QVariant QModelIndex::data(int arole) const
inline Qt::ItemFlags QModelIndex::flags() const
{ return m ? m->flags(*this) : Qt::ItemFlags(); }
-inline uint qHash(const QModelIndex &index) noexcept
-{ return uint((uint(index.row()) << 4) + index.column() + index.internalId()); }
+inline size_t qHash(const QModelIndex &index, size_t seed) noexcept
+{ return size_t((size_t(index.row()) << 4) + size_t(index.column()) + index.internalId()) ^ seed; }
QT_END_NAMESPACE
diff --git a/src/corelib/itemmodels/qabstractproxymodel.h b/src/corelib/itemmodels/qabstractproxymodel.h
index c9a73b6a31..f6f6e45c1a 100644
--- a/src/corelib/itemmodels/qabstractproxymodel.h
+++ b/src/corelib/itemmodels/qabstractproxymodel.h
@@ -103,7 +103,11 @@ Q_SIGNALS:
void sourceModelChanged(QPrivateSignal);
protected Q_SLOTS:
- void resetInternalData();
+ void resetInternalData()
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+ override
+#endif
+ ;
protected:
QAbstractProxyModel(QAbstractProxyModelPrivate &, QObject *parent);
diff --git a/src/corelib/itemmodels/qconcatenatetablesproxymodel.cpp b/src/corelib/itemmodels/qconcatenatetablesproxymodel.cpp
index a2597faa93..0e29714677 100644
--- a/src/corelib/itemmodels/qconcatenatetablesproxymodel.cpp
+++ b/src/corelib/itemmodels/qconcatenatetablesproxymodel.cpp
@@ -642,7 +642,7 @@ void QConcatenateTablesProxyModelPrivate::_q_slotSourceLayoutAboutToBeChanged(co
layoutChangePersistentIndexes.reserve(persistentIndexList.size());
layoutChangeProxyIndexes.reserve(persistentIndexList.size());
- for (const QPersistentModelIndex &proxyPersistentIndex : persistentIndexList) {
+ for (const QModelIndex &proxyPersistentIndex : persistentIndexList) {
layoutChangeProxyIndexes.append(proxyPersistentIndex);
Q_ASSERT(proxyPersistentIndex.isValid());
const QPersistentModelIndex srcPersistentIndex = q->mapToSource(proxyPersistentIndex);
diff --git a/src/corelib/itemmodels/qidentityproxymodel.cpp b/src/corelib/itemmodels/qidentityproxymodel.cpp
index f5684c6eda..8210e27f8a 100644
--- a/src/corelib/itemmodels/qidentityproxymodel.cpp
+++ b/src/corelib/itemmodels/qidentityproxymodel.cpp
@@ -532,7 +532,7 @@ void QIdentityProxyModelPrivate::_q_sourceLayoutAboutToBeChanged(const QList<QPe
emit q->layoutAboutToBeChanged(parents, hint);
const auto proxyPersistentIndexes = q->persistentIndexList();
- for (const QPersistentModelIndex &proxyPersistentIndex : proxyPersistentIndexes) {
+ for (const QModelIndex &proxyPersistentIndex : proxyPersistentIndexes) {
proxyIndexes << proxyPersistentIndex;
Q_ASSERT(proxyPersistentIndex.isValid());
const QPersistentModelIndex srcPersistentIndex = q->mapToSource(proxyPersistentIndex);
diff --git a/src/corelib/itemmodels/qitemselectionmodel.h b/src/corelib/itemmodels/qitemselectionmodel.h
index 5820695592..a1badc7693 100644
--- a/src/corelib/itemmodels/qitemselectionmodel.h
+++ b/src/corelib/itemmodels/qitemselectionmodel.h
@@ -223,9 +223,6 @@ private:
Q_DECLARE_OPERATORS_FOR_FLAGS(QItemSelectionModel::SelectionFlags)
-// dummy implentation of qHash() necessary for instantiating QList<QItemSelectionRange>::toSet() with MSVC
-inline uint qHash(const QItemSelectionRange &) { return 0; }
-
#ifdef Q_CC_MSVC
/*
@@ -241,7 +238,7 @@ inline uint qHash(const QItemSelectionRange &) { return 0; }
# define Q_TEMPLATE_EXTERN extern
# endif
# endif
-Q_TEMPLATE_EXTERN template class Q_CORE_EXPORT QList<QItemSelectionRange>;
+Q_TEMPLATE_EXTERN template class Q_CORE_EXPORT QVector<QItemSelectionRange>;
#endif // Q_CC_MSVC
class Q_CORE_EXPORT QItemSelection : public QList<QItemSelectionRange>
diff --git a/src/corelib/itemmodels/qsortfilterproxymodel.cpp b/src/corelib/itemmodels/qsortfilterproxymodel.cpp
index 4f5593e0a0..79a9875073 100644
--- a/src/corelib/itemmodels/qsortfilterproxymodel.cpp
+++ b/src/corelib/itemmodels/qsortfilterproxymodel.cpp
@@ -142,145 +142,24 @@ 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)
public:
+ enum class Direction {
+ Rows = 1,
+ Columns = 2,
+ All = Rows | Columns
+ };
+
struct Mapping {
QVector<int> source_rows;
QVector<int> source_columns;
QVector<int> proxy_rows;
QVector<int> proxy_columns;
QVector<QModelIndex> mapped_children;
- QHash<QModelIndex, Mapping *>::const_iterator map_iter;
+ QModelIndex source_parent;
};
mutable QHash<QModelIndex, Mapping*> source_index_mapping;
@@ -294,7 +173,7 @@ public:
int filter_column;
int filter_role;
- RegularExpressionData filter_data;
+ QRegularExpression filter_data;
QModelIndex last_top_source;
bool filter_recursive;
@@ -321,7 +200,7 @@ public:
const void *p = proxy_index.internalPointer();
Q_ASSERT(p);
QHash<QModelIndex, Mapping *>::const_iterator it =
- static_cast<const Mapping*>(p)->map_iter;
+ source_index_mapping.constFind(static_cast<const Mapping*>(p)->source_parent);
Q_ASSERT(it != source_index_mapping.constEnd());
Q_ASSERT(it.value());
return it;
@@ -397,8 +276,8 @@ public:
QVector<int> &source_to_proxy, QVector<int> &proxy_to_source,
int proxy_start, int proxy_end, const QModelIndex &proxy_parent,
Qt::Orientation orient, bool emit_signal = true);
- void build_source_to_proxy_mapping(
- const QVector<int> &proxy_to_source, QVector<int> &source_to_proxy) const;
+ static inline void build_source_to_proxy_mapping(
+ const QVector<int> &proxy_to_source, QVector<int> &source_to_proxy, int start = 0);
void source_items_inserted(const QModelIndex &source_parent,
int start, int end, Qt::Orientation orient);
void source_items_about_to_be_removed(const QModelIndex &source_parent,
@@ -413,7 +292,7 @@ public:
void update_persistent_indexes(const QModelIndexPairList &source_indexes);
void filter_about_to_be_changed(const QModelIndex &source_parent = QModelIndex());
- void filter_changed(const QModelIndex &source_parent = QModelIndex());
+ void filter_changed(Direction dir, const QModelIndex &source_parent = QModelIndex());
QSet<int> handle_filter_changed(
QVector<int> &source_to_proxy, QVector<int> &proxy_to_source,
const QModelIndex &source_parent, Qt::Orientation orient);
@@ -431,6 +310,11 @@ public:
typedef QHash<QModelIndex, QSortFilterProxyModelPrivate::Mapping *> IndexMap;
+static bool operator&(QSortFilterProxyModelPrivate::Direction a, QSortFilterProxyModelPrivate::Direction b)
+{
+ return int(a) & int(b);
+}
+
void QSortFilterProxyModelPrivate::_q_sourceModelDestroyed()
{
QAbstractProxyModelPrivate::_q_sourceModelDestroyed();
@@ -517,8 +401,7 @@ IndexMap::const_iterator QSortFilterProxyModelPrivate::create_mapping(
m->proxy_columns.resize(source_cols);
build_source_to_proxy_mapping(m->source_columns, m->proxy_columns);
- it = IndexMap::const_iterator(source_index_mapping.insert(source_parent, m));
- m->map_iter = it;
+ m->source_parent = source_parent;
if (source_parent.isValid()) {
QModelIndex source_grand_parent = source_parent.parent();
@@ -527,6 +410,7 @@ IndexMap::const_iterator QSortFilterProxyModelPrivate::create_mapping(
it2.value()->mapped_children.append(source_parent);
}
+ it = IndexMap::const_iterator(source_index_mapping.insert(source_parent, m));
Q_ASSERT(it != source_index_mapping.constEnd());
Q_ASSERT(it.value());
@@ -787,9 +671,11 @@ void QSortFilterProxyModelPrivate::remove_proxy_interval(
}
// Remove items from proxy-to-source mapping
+ for (int i = proxy_start; i <= proxy_end; ++i)
+ source_to_proxy[proxy_to_source.at(i)] = -1;
proxy_to_source.remove(proxy_start, proxy_end - proxy_start + 1);
- build_source_to_proxy_mapping(proxy_to_source, source_to_proxy);
+ build_source_to_proxy_mapping(proxy_to_source, source_to_proxy, proxy_start);
if (emit_signal) {
if (orient == Qt::Vertical)
@@ -915,7 +801,7 @@ void QSortFilterProxyModelPrivate::insert_source_items(
for (int i = 0; i < source_items.size(); ++i)
proxy_to_source.insert(proxy_start + i, source_items.at(i));
- build_source_to_proxy_mapping(proxy_to_source, source_to_proxy);
+ build_source_to_proxy_mapping(proxy_to_source, source_to_proxy, proxy_start);
if (emit_signal) {
if (orient == Qt::Vertical)
@@ -1169,7 +1055,8 @@ void QSortFilterProxyModelPrivate::updateChildrenMapping(const QModelIndex &sour
// reinsert moved, mapped indexes
QVector<QPair<QModelIndex, Mapping*> >::iterator it = moved_source_index_mappings.begin();
for (; it != moved_source_index_mappings.end(); ++it) {
- (*it).second->map_iter = QHash<QModelIndex, Mapping *>::const_iterator(source_index_mapping.insert((*it).first, (*it).second));
+ it->second->source_parent = it->first;
+ source_index_mapping.insert(it->first, it->second);
}
}
@@ -1196,11 +1083,12 @@ void QSortFilterProxyModelPrivate::proxy_item_range(
\internal
*/
void QSortFilterProxyModelPrivate::build_source_to_proxy_mapping(
- const QVector<int> &proxy_to_source, QVector<int> &source_to_proxy) const
+ const QVector<int> &proxy_to_source, QVector<int> &source_to_proxy, int start)
{
- source_to_proxy.fill(-1);
- int proxy_count = proxy_to_source.size();
- for (int i = 0; i < proxy_count; ++i)
+ if (start == 0)
+ source_to_proxy.fill(-1);
+ const int proxy_count = proxy_to_source.size();
+ for (int i = start; i < proxy_count; ++i)
source_to_proxy[proxy_to_source.at(i)] = i;
}
@@ -1256,7 +1144,7 @@ void QSortFilterProxyModelPrivate::update_persistent_indexes(
*/
void QSortFilterProxyModelPrivate::filter_about_to_be_changed(const QModelIndex &source_parent)
{
- if (!filter_data.isEmpty() &&
+ if (!filter_data.pattern().isEmpty() &&
source_index_mapping.constFind(source_parent) == source_index_mapping.constEnd())
create_mapping(source_parent);
}
@@ -1268,14 +1156,14 @@ void QSortFilterProxyModelPrivate::filter_about_to_be_changed(const QModelIndex
Updates the proxy model (adds/removes rows) based on the
new filter.
*/
-void QSortFilterProxyModelPrivate::filter_changed(const QModelIndex &source_parent)
+void QSortFilterProxyModelPrivate::filter_changed(Direction dir, const QModelIndex &source_parent)
{
IndexMap::const_iterator it = source_index_mapping.constFind(source_parent);
if (it == source_index_mapping.constEnd())
return;
Mapping *m = it.value();
- QSet<int> rows_removed = handle_filter_changed(m->proxy_rows, m->source_rows, source_parent, Qt::Vertical);
- QSet<int> columns_removed = handle_filter_changed(m->proxy_columns, m->source_columns, source_parent, Qt::Horizontal);
+ const QSet<int> rows_removed = (dir & Direction::Rows) ? handle_filter_changed(m->proxy_rows, m->source_rows, source_parent, Qt::Vertical) : QSet<int>();
+ const QSet<int> columns_removed = (dir & Direction::Columns) ? handle_filter_changed(m->proxy_columns, m->source_columns, source_parent, Qt::Horizontal) : QSet<int>();
// We need to iterate over a copy of m->mapped_children because otherwise it may be changed by other code, invalidating
// the iterator it2.
@@ -1289,7 +1177,7 @@ void QSortFilterProxyModelPrivate::filter_changed(const QModelIndex &source_pare
indexesToRemove.push_back(i);
remove_from_mapping(source_child_index);
} else {
- filter_changed(source_child_index);
+ filter_changed(dir, source_child_index);
}
}
QVector<int>::const_iterator removeIt = indexesToRemove.constEnd();
@@ -1919,9 +1807,9 @@ void QSortFilterProxyModelPrivate::_q_sourceColumnsMoved(
\section1 Filtering
In addition to sorting, QSortFilterProxyModel can be used to hide items
- that do not match a certain filter. The filter is specified using a QRegExp
+ that do not match a certain filter. The filter is specified using a QRegularExpression
object and is applied to the filterRole() (Qt::DisplayRole by default) of
- each item, for a given column. The QRegExp object can be used to match a
+ each item, for a given column. The QRegularExpression object can be used to match a
regular expression, a wildcard pattern, or a fixed string. For example:
\snippet qsortfilterproxymodel-details/main.cpp 5
@@ -1970,21 +1858,6 @@ 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
*/
@@ -2580,33 +2453,6 @@ Qt::SortOrder QSortFilterProxyModel::sortOrder() const
return d->sort_order;
}
-/*!
- \property QSortFilterProxyModel::filterRegExp
- \brief the QRegExp used to filter the contents of the source model
-
- Setting this property overwrites the current
- \l{QSortFilterProxyModel::filterCaseSensitivity}{filterCaseSensitivity}.
- By default, the QRegExp is an empty string matching all contents.
-
- If no QRegExp or an empty string is set, everything in the source model
- will be accepted.
-
- \sa filterCaseSensitivity, setFilterWildcard(), setFilterFixedString()
-*/
-QRegExp QSortFilterProxyModel::filterRegExp() const
-{
- Q_D(const QSortFilterProxyModel);
- return d->filter_data.regExp();
-}
-
-void QSortFilterProxyModel::setFilterRegExp(const QRegExp &regExp)
-{
- Q_D(QSortFilterProxyModel);
- d->filter_about_to_be_changed();
- d->filter_data.setRegExp(regExp);
- d->filter_changed();
-}
-
#if QT_CONFIG(regularexpression)
/*!
\since 5.12
@@ -2625,15 +2471,15 @@ void QSortFilterProxyModel::setFilterRegExp(const QRegExp &regExp)
QRegularExpression QSortFilterProxyModel::filterRegularExpression() const
{
Q_D(const QSortFilterProxyModel);
- return d->filter_data.regularExpression();
+ return d->filter_data;
}
void QSortFilterProxyModel::setFilterRegularExpression(const QRegularExpression &regularExpression)
{
Q_D(QSortFilterProxyModel);
d->filter_about_to_be_changed();
- d->filter_data.setRegularExpression(regularExpression);
- d->filter_changed();
+ d->filter_data = regularExpression;
+ d->filter_changed(QSortFilterProxyModelPrivate::Direction::Rows);
}
#endif
@@ -2656,18 +2502,18 @@ void QSortFilterProxyModel::setFilterKeyColumn(int column)
Q_D(QSortFilterProxyModel);
d->filter_about_to_be_changed();
d->filter_column = column;
- d->filter_changed();
+ d->filter_changed(QSortFilterProxyModelPrivate::Direction::Rows);
}
/*!
\property QSortFilterProxyModel::filterCaseSensitivity
- \brief the case sensitivity of the QRegExp pattern used to filter the
+ \brief the case sensitivity of the QRegularExpression pattern used to filter the
contents of the source model.
By default, the filter is case sensitive.
- \sa filterRegExp, sortCaseSensitivity
+ \sa filterRegularExpression, sortCaseSensitivity
*/
/*!
@@ -2679,17 +2525,21 @@ void QSortFilterProxyModel::setFilterKeyColumn(int column)
Qt::CaseSensitivity QSortFilterProxyModel::filterCaseSensitivity() const
{
Q_D(const QSortFilterProxyModel);
- return d->filter_data.caseSensitivity();
+ return d->filter_data.patternOptions() & QRegularExpression::CaseInsensitiveOption ?
+ Qt::CaseInsensitive : Qt::CaseSensitive;
}
void QSortFilterProxyModel::setFilterCaseSensitivity(Qt::CaseSensitivity cs)
{
Q_D(QSortFilterProxyModel);
- if (cs == d->filter_data.caseSensitivity())
+ QRegularExpression::PatternOptions o = QRegularExpression::NoPatternOption;
+ if (cs == Qt::CaseInsensitive)
+ o = QRegularExpression::CaseInsensitiveOption;
+ if (o == d->filter_data.patternOptions())
return;
d->filter_about_to_be_changed();
- d->filter_data.setCaseSensitivity(cs);
- d->filter_changed();
+ d->filter_data.setPatternOptions(o);
+ d->filter_changed(QSortFilterProxyModelPrivate::Direction::Rows);
emit filterCaseSensitivityChanged(cs);
}
@@ -2759,24 +2609,6 @@ void QSortFilterProxyModel::setSortLocaleAware(bool on)
emit sortLocaleAwareChanged(on);
}
-/*!
- \overload
-
- Sets the regular expression used to filter the contents
- of the source model to \a pattern.
-
- \sa setFilterCaseSensitivity(), setFilterWildcard(), setFilterFixedString(), filterRegExp()
-*/
-void QSortFilterProxyModel::setFilterRegExp(const QString &pattern)
-{
- Q_D(QSortFilterProxyModel);
- d->filter_about_to_be_changed();
- QRegExp rx(pattern);
- rx.setCaseSensitivity(d->filter_data.caseSensitivity());
- d->filter_data.setRegExp(rx);
- d->filter_changed();
-}
-
#if QT_CONFIG(regularexpression)
/*!
\since 5.12
@@ -2794,8 +2626,8 @@ 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();
+ d->filter_data.setPattern(pattern);
+ d->filter_changed(QSortFilterProxyModelPrivate::Direction::Rows);
}
#endif
@@ -2803,30 +2635,29 @@ void QSortFilterProxyModel::setFilterRegularExpression(const QString &pattern)
Sets the wildcard expression used to filter the contents
of the source model to the given \a pattern.
- \sa setFilterCaseSensitivity(), setFilterRegExp(), setFilterFixedString(), filterRegExp()
+ \sa setFilterCaseSensitivity(), setFilterRegularExpression(), setFilterFixedString(), filterRegularExpression()
*/
void QSortFilterProxyModel::setFilterWildcard(const QString &pattern)
{
Q_D(QSortFilterProxyModel);
d->filter_about_to_be_changed();
- QRegExp rx(pattern, d->filter_data.caseSensitivity(), QRegExp::Wildcard);
- d->filter_data.setRegExp(rx);
- d->filter_changed();
+ QString p = QRegularExpression::wildcardToRegularExpression(pattern, QRegularExpression::UnanchoredWildcardConversion);
+ d->filter_data.setPattern(p);
+ d->filter_changed(QSortFilterProxyModelPrivate::Direction::Rows);
}
/*!
Sets the fixed string used to filter the contents
of the source model to the given \a pattern.
- \sa setFilterCaseSensitivity(), setFilterRegExp(), setFilterWildcard(), filterRegExp()
+ \sa setFilterCaseSensitivity(), setFilterRegularExpression(), setFilterWildcard(), filterRegularExpression()
*/
void QSortFilterProxyModel::setFilterFixedString(const QString &pattern)
{
Q_D(QSortFilterProxyModel);
d->filter_about_to_be_changed();
- QRegExp rx(pattern, d->filter_data.caseSensitivity(), QRegExp::FixedString);
- d->filter_data.setRegExp(rx);
- d->filter_changed();
+ d->filter_data.setPattern(QRegularExpression::escape(pattern));
+ d->filter_changed(QSortFilterProxyModelPrivate::Direction::Rows);
}
/*!
@@ -2920,7 +2751,7 @@ void QSortFilterProxyModel::setFilterRole(int role)
return;
d->filter_about_to_be_changed();
d->filter_role = role;
- d->filter_changed();
+ d->filter_changed(QSortFilterProxyModelPrivate::Direction::Rows);
emit filterRoleChanged(role);
}
@@ -2954,7 +2785,7 @@ void QSortFilterProxyModel::setRecursiveFilteringEnabled(bool recursive)
return;
d->filter_about_to_be_changed();
d->filter_recursive = recursive;
- d->filter_changed();
+ d->filter_changed(QSortFilterProxyModelPrivate::Direction::Rows);
emit recursiveFilteringEnabledChanged(recursive);
}
@@ -3005,11 +2836,57 @@ void QSortFilterProxyModel::filterChanged()
(e.g. filterAcceptsRow()), and your filter parameters have changed.
\sa invalidate()
+ \sa invalidateColumnsFilter()
+ \sa invalidateRowsFilter()
*/
void QSortFilterProxyModel::invalidateFilter()
{
Q_D(QSortFilterProxyModel);
- d->filter_changed();
+ d->filter_changed(QSortFilterProxyModelPrivate::Direction::All);
+}
+
+/*!
+ \since 6.0
+
+ Invalidates the current filtering for the columns.
+
+ This function should be called if you are implementing custom filtering
+ (by filterAcceptsColumn()), and your filter parameters have changed.
+ This differs from invalidateFilter() in that it will not invoke
+ filterAcceptsRow(), but only filterAcceptsColumn(). You can use this
+ instead of invalidateFilter() if you want to hide or show a column where
+ the rows don't change.
+
+ \sa invalidate()
+ \sa invalidateFilter()
+ \sa invalidateRowsFilter()
+*/
+void QSortFilterProxyModel::invalidateColumnsFilter()
+{
+ Q_D(QSortFilterProxyModel);
+ d->filter_changed(QSortFilterProxyModelPrivate::Direction::Columns);
+}
+
+/*!
+ \since 6.0
+
+ Invalidates the current filtering for the rows.
+
+ This function should be called if you are implementing custom filtering
+ (by filterAcceptsRow()), and your filter parameters have changed.
+ This differs from invalidateFilter() in that it will not invoke
+ filterAcceptsColumn(), but only filterAcceptsRow(). You can use this
+ instead of invalidateFilter() if you want to hide or show a row where
+ the columns don't change.
+
+ \sa invalidate()
+ \sa invalidateFilter()
+ \sa invalidateColumnsFilter()
+*/
+void QSortFilterProxyModel::invalidateRowsFilter()
+{
+ Q_D(QSortFilterProxyModel);
+ d->filter_changed(QSortFilterProxyModelPrivate::Direction::Rows);
}
/*!
@@ -3069,20 +2946,20 @@ bool QSortFilterProxyModel::lessThan(const QModelIndex &source_left, const QMode
should be accepted or not. This can be changed by setting the
\l{QSortFilterProxyModel::filterRole}{filterRole} property.
- \sa filterAcceptsColumn(), setFilterFixedString(), setFilterRegExp(), setFilterWildcard()
+ \sa filterAcceptsColumn(), setFilterFixedString(), setFilterRegularExpression(), setFilterWildcard()
*/
bool QSortFilterProxyModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
{
Q_D(const QSortFilterProxyModel);
- if (d->filter_data.isEmpty())
+ if (d->filter_data.pattern().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 (d->filter_data.hasMatch(key))
+ if (d->filter_data.match(key).hasMatch())
return true;
}
return false;
@@ -3091,7 +2968,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 d->filter_data.hasMatch(key);
+ return d->filter_data.match(key).hasMatch();
}
/*!
@@ -3101,7 +2978,7 @@ bool QSortFilterProxyModel::filterAcceptsRow(int source_row, const QModelIndex &
\note The default implementation always returns \c true. You must reimplement this
method to get the described behavior.
- \sa filterAcceptsRow(), setFilterFixedString(), setFilterRegExp(), setFilterWildcard()
+ \sa filterAcceptsRow(), setFilterFixedString(), setFilterRegularExpression(), setFilterWildcard()
*/
bool QSortFilterProxyModel::filterAcceptsColumn(int source_column, const QModelIndex &source_parent) const
{
diff --git a/src/corelib/itemmodels/qsortfilterproxymodel.h b/src/corelib/itemmodels/qsortfilterproxymodel.h
index 91253dd601..b7d4e69cb9 100644
--- a/src/corelib/itemmodels/qsortfilterproxymodel.h
+++ b/src/corelib/itemmodels/qsortfilterproxymodel.h
@@ -41,7 +41,6 @@
#define QSORTFILTERPROXYMODEL_H
#include <QtCore/qabstractproxymodel.h>
-#include <QtCore/qregexp.h>
#if QT_CONFIG(regularexpression)
# include <QtCore/qregularexpression.h>
@@ -62,7 +61,6 @@ class Q_CORE_EXPORT QSortFilterProxyModel : public QAbstractProxyModel
friend class QSortFilterProxyModelGreaterThan;
Q_OBJECT
- Q_PROPERTY(QRegExp filterRegExp READ filterRegExp WRITE setFilterRegExp)
#if QT_CONFIG(regularexpression)
Q_PROPERTY(QRegularExpression filterRegularExpression READ filterRegularExpression WRITE setFilterRegularExpression)
#endif
@@ -87,8 +85,6 @@ public:
QItemSelection mapSelectionToSource(const QItemSelection &proxySelection) const override;
QItemSelection mapSelectionFromSource(const QItemSelection &sourceSelection) const override;
- QRegExp filterRegExp() const;
-
#if QT_CONFIG(regularexpression)
QRegularExpression filterRegularExpression() const;
#endif
@@ -121,8 +117,6 @@ public:
void setRecursiveFilteringEnabled(bool recursive);
public Q_SLOTS:
- void setFilterRegExp(const QString &pattern);
- void setFilterRegExp(const QRegExp &regExp);
#if QT_CONFIG(regularexpression)
void setFilterRegularExpression(const QString &pattern);
void setFilterRegularExpression(const QRegularExpression &regularExpression);
@@ -143,6 +137,8 @@ protected:
QT_DEPRECATED_X("Use QSortFilterProxyModel::invalidateFilter") void filterChanged();
#endif
void invalidateFilter();
+ void invalidateRowsFilter();
+ void invalidateColumnsFilter();
public:
using QObject::parent;
diff --git a/src/corelib/itemmodels/qtransposeproxymodel.cpp b/src/corelib/itemmodels/qtransposeproxymodel.cpp
index 4853f90632..207faa6151 100644
--- a/src/corelib/itemmodels/qtransposeproxymodel.cpp
+++ b/src/corelib/itemmodels/qtransposeproxymodel.cpp
@@ -92,7 +92,7 @@ void QTransposeProxyModelPrivate::onLayoutAboutToBeChanged(const QList<QPersiste
layoutChangePersistentIndexes.clear();
layoutChangeProxyIndexes.reserve(proxyPersistentIndexes.size());
layoutChangePersistentIndexes.reserve(proxyPersistentIndexes.size());
- for (const QPersistentModelIndex &proxyPersistentIndex : proxyPersistentIndexes) {
+ for (const QModelIndex &proxyPersistentIndex : proxyPersistentIndexes) {
layoutChangeProxyIndexes << proxyPersistentIndex;
Q_ASSERT(proxyPersistentIndex.isValid());
const QPersistentModelIndex srcPersistentIndex = q->mapToSource(proxyPersistentIndex);