summaryrefslogtreecommitdiffstats
path: root/src/corelib/itemmodels/qabstractitemmodel.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/itemmodels/qabstractitemmodel.cpp')
-rw-r--r--src/corelib/itemmodels/qabstractitemmodel.cpp180
1 files changed, 81 insertions, 99 deletions
diff --git a/src/corelib/itemmodels/qabstractitemmodel.cpp b/src/corelib/itemmodels/qabstractitemmodel.cpp
index 2fa4f62021..c1749526bc 100644
--- a/src/corelib/itemmodels/qabstractitemmodel.cpp
+++ b/src/corelib/itemmodels/qabstractitemmodel.cpp
@@ -1,42 +1,6 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Copyright (C) 2020 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** 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 Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** 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-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2022 The Qt Company Ltd.
+// Copyright (C) 2020 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qabstractitemmodel.h"
#include <private/qabstractitemmodel_p.h>
@@ -50,16 +14,21 @@
# include <qregularexpression.h>
#endif
#include <qstack.h>
+#include <qmap.h>
#include <qbitarray.h>
#include <qdatetime.h>
#include <qloggingcategory.h>
+#include <functional>
+
#include <limits.h>
QT_BEGIN_NAMESPACE
Q_LOGGING_CATEGORY(lcCheckIndex, "qt.core.qabstractitemmodel.checkindex")
+QT_IMPL_METATYPE_EXTERN(QModelIndexList)
+
QPersistentModelIndexData *QPersistentModelIndexData::create(const QModelIndex &index)
{
Q_ASSERT(index.isValid()); // we will _never_ insert an invalid index in the list
@@ -243,7 +212,7 @@ void QPersistentModelIndexData::destroy(QPersistentModelIndexData *data)
*/
/*!
- \fn template <typename Container> QModelRoleDataSpan::QModelRoleDataSpan(Container &c) noexcept
+ \fn template <typename Container, QModelRoleDataSpan::if_compatible_container<Container> = true> QModelRoleDataSpan::QModelRoleDataSpan(Container &c) noexcept
Constructs an QModelRoleDataSpan spanning over the container \a c,
which can be any contiguous container of QModelRoleData objects.
@@ -413,7 +382,7 @@ QPersistentModelIndex::~QPersistentModelIndex()
model index are used when comparing with another persistent model index.
*/
-bool QPersistentModelIndex::operator==(const QPersistentModelIndex &other) const
+bool QPersistentModelIndex::operator==(const QPersistentModelIndex &other) const noexcept
{
if (d && other.d)
return d->index == other.d->index;
@@ -430,12 +399,12 @@ bool QPersistentModelIndex::operator==(const QPersistentModelIndex &other) const
model index are used when comparing with another persistent model index.
*/
-bool QPersistentModelIndex::operator<(const QPersistentModelIndex &other) const
+bool QPersistentModelIndex::operator<(const QPersistentModelIndex &other) const noexcept
{
if (d && other.d)
return d->index < other.d->index;
- return d < other.d;
+ return std::less<>{}(d, other.d);
}
/*!
@@ -488,17 +457,16 @@ QPersistentModelIndex &QPersistentModelIndex::operator=(const QModelIndex &other
}
/*!
- \fn QPersistentModelIndex::operator const QModelIndex&() const
+ \fn QPersistentModelIndex::operator QModelIndex() const
- Cast operator that returns a const QModelIndex&.
+ Cast operator that returns a QModelIndex.
*/
-QPersistentModelIndex::operator const QModelIndex&() const
+QPersistentModelIndex::operator QModelIndex() const
{
- static const QModelIndex invalid;
if (d)
return d->index;
- return invalid;
+ return QModelIndex();
}
/*!
@@ -509,7 +477,7 @@ QPersistentModelIndex::operator const QModelIndex&() const
model index are used when comparing with another model index.
*/
-bool QPersistentModelIndex::operator==(const QModelIndex &other) const
+bool QPersistentModelIndex::operator==(const QModelIndex &other) const noexcept
{
if (d)
return d->index == other;
@@ -523,7 +491,7 @@ bool QPersistentModelIndex::operator==(const QModelIndex &other) const
location as the \a other model index; otherwise returns \c{false}.
*/
-bool QPersistentModelIndex::operator!=(const QModelIndex &other) const
+bool QPersistentModelIndex::operator!=(const QModelIndex &other) const noexcept
{
if (d)
return d->index != other;
@@ -747,7 +715,7 @@ QAbstractItemModel *QAbstractItemModelPrivate::staticEmptyModel()
void QAbstractItemModelPrivate::invalidatePersistentIndexes()
{
- for (QPersistentModelIndexData *data : qAsConst(persistent.indexes))
+ for (QPersistentModelIndexData *data : std::as_const(persistent.indexes))
data->index = QModelIndex();
persistent.indexes.clear();
}
@@ -767,7 +735,7 @@ void QAbstractItemModelPrivate::invalidatePersistentIndex(const QModelIndex &ind
}
using DefaultRoleNames = QHash<int, QByteArray>;
-Q_GLOBAL_STATIC_WITH_ARGS(DefaultRoleNames, qDefaultRoleNames, (
+Q_GLOBAL_STATIC(DefaultRoleNames, qDefaultRoleNames,
{
{ Qt::DisplayRole, "display" },
{ Qt::DecorationRole, "decoration" },
@@ -775,7 +743,7 @@ Q_GLOBAL_STATIC_WITH_ARGS(DefaultRoleNames, qDefaultRoleNames, (
{ Qt::ToolTipRole, "toolTip" },
{ Qt::StatusTipRole, "statusTip" },
{ Qt::WhatsThisRole, "whatsThis" },
- }))
+ })
const QHash<int,QByteArray> &QAbstractItemModelPrivate::defaultRoleNames()
{
@@ -874,13 +842,13 @@ void QAbstractItemModelPrivate::removePersistentIndexData(QPersistentModelIndexD
Q_UNUSED(removed);
}
// make sure our optimization still works
- for (int i = persistent.moved.count() - 1; i >= 0; --i) {
+ for (int i = persistent.moved.size() - 1; i >= 0; --i) {
int idx = persistent.moved.at(i).indexOf(data);
if (idx >= 0)
persistent.moved[i].remove(idx);
}
// update the references to invalidated persistent indexes
- for (int i = persistent.invalidated.count() - 1; i >= 0; --i) {
+ for (int i = persistent.invalidated.size() - 1; i >= 0; --i) {
int idx = persistent.invalidated.at(i).indexOf(data);
if (idx >= 0)
persistent.invalidated[i].remove(idx);
@@ -895,7 +863,7 @@ void QAbstractItemModelPrivate::rowsAboutToBeInserted(const QModelIndex &parent,
Q_UNUSED(last);
QList<QPersistentModelIndexData *> persistent_moved;
if (first < q->rowCount(parent)) {
- for (auto *data : qAsConst(persistent.indexes)) {
+ for (auto *data : std::as_const(persistent.indexes)) {
const QModelIndex &index = data->index;
if (index.row() >= first && index.isValid() && index.parent() == parent) {
persistent_moved.append(data);
@@ -931,7 +899,7 @@ void QAbstractItemModelPrivate::itemsAboutToBeMoved(const QModelIndex &srcParent
const bool sameParent = (srcParent == destinationParent);
const bool movingUp = (srcFirst > destinationChild);
- for (auto *data : qAsConst(persistent.indexes)) {
+ for (auto *data : std::as_const(persistent.indexes)) {
const QModelIndex &index = data->index;
const QModelIndex &parent = index.parent();
const bool isSourceIndex = (parent == srcParent);
@@ -1029,7 +997,7 @@ void QAbstractItemModelPrivate::rowsAboutToBeRemoved(const QModelIndex &parent,
QList<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 (auto *data : qAsConst(persistent.indexes)) {
+ for (auto *data : std::as_const(persistent.indexes)) {
bool level_changed = false;
QModelIndex current = data->index;
while (current.isValid()) {
@@ -1081,7 +1049,7 @@ void QAbstractItemModelPrivate::columnsAboutToBeInserted(const QModelIndex &pare
Q_UNUSED(last);
QList<QPersistentModelIndexData *> persistent_moved;
if (first < q->columnCount(parent)) {
- for (auto *data : qAsConst(persistent.indexes)) {
+ for (auto *data : std::as_const(persistent.indexes)) {
const QModelIndex &index = data->index;
if (index.column() >= first && index.isValid() && index.parent() == parent)
persistent_moved.append(data);
@@ -1114,7 +1082,7 @@ void QAbstractItemModelPrivate::columnsAboutToBeRemoved(const QModelIndex &paren
QList<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 (auto *data : qAsConst(persistent.indexes)) {
+ for (auto *data : std::as_const(persistent.indexes)) {
bool level_changed = false;
QModelIndex current = data->index;
while (current.isValid()) {
@@ -1531,10 +1499,12 @@ void QAbstractItemModel::resetInternalData()
rows to the model, \l{QAbstractItemModel::}{beginInsertRows()} and
\l{QAbstractItemModel::}{endInsertRows()} must be called.
+ \include models.qdocinc {thread-safety-section1}{QAbstractItemModel}
+
\sa {Model Classes}, {Model Subclassing Reference}, QModelIndex,
QAbstractItemView, {Using drag and drop with item views},
- {Simple DOM Model Example}, {Simple Tree Model Example},
- {Editable Tree Model Example}, {Fetch More Example}
+ {Simple Tree Model Example}, {Editable Tree Model Example},
+ {Fetch More Example}
*/
/*!
@@ -1773,7 +1743,13 @@ QAbstractItemModel::~QAbstractItemModel()
For example:
- \snippet ../widgets/itemviews/simpledommodel/dommodel.cpp 2
+ \code
+ int MyModel::columnCount(const QModelIndex &parent) const
+ {
+ Q_UNUSED(parent);
+ return 3;
+ }
+ \endcode
\note When implementing a table based model, columnCount() should return 0
when the parent is valid.
@@ -1858,13 +1834,13 @@ QAbstractItemModel::~QAbstractItemModel()
*/
/*!
- \fn void QAbstractItemModel::rowsMoved(const QModelIndex &parent, int start, int end, const QModelIndex &destination, int row)
+ \fn void QAbstractItemModel::rowsMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destinationParent, int destinationRow)
\since 4.6
This signal is emitted after rows have been moved within the
- model. The items between \a start and \a end
- inclusive, under the given \a parent item have been moved to \a destination
- starting at the row \a row.
+ model. The items between \a sourceStart and \a sourceEnd
+ inclusive, under the given \a sourceParent item have been moved to \a destinationParent
+ starting at the row \a destinationRow.
\b{Note:} Components connected to this signal use it to adapt to changes
in the model's dimensions. It can only be emitted by the QAbstractItemModel
@@ -1890,13 +1866,13 @@ QAbstractItemModel::~QAbstractItemModel()
*/
/*!
- \fn void QAbstractItemModel::columnsMoved(const QModelIndex &parent, int start, int end, const QModelIndex &destination, int column)
+ \fn void QAbstractItemModel::columnsMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destinationParent, int destinationColumn)
\since 4.6
This signal is emitted after columns have been moved within the
- model. The items between \a start and \a end
- inclusive, under the given \a parent item have been moved to \a destination
- starting at the column \a column.
+ model. The items between \a sourceStart and \a sourceEnd
+ inclusive, under the given \a sourceParent item have been moved to \a destinationParent
+ starting at the column \a destinationColumn.
\b{Note:} Components connected to this signal use it to adapt to changes
in the model's dimensions. It can only be emitted by the QAbstractItemModel
@@ -2087,7 +2063,7 @@ bool QAbstractItemModel::clearItemData(const QModelIndex &index)
by the \a index.
\note If you do not have a value to return, return an \b invalid
- QVariant instead of returning 0.
+ (default-constructed) QVariant.
\sa Qt::ItemDataRole, setData(), headerData()
*/
@@ -2104,7 +2080,7 @@ bool QAbstractItemModel::clearItemData(const QModelIndex &index)
*/
bool QAbstractItemModel::setItemData(const QModelIndex &index, const QMap<int, QVariant> &roles)
{
- // ### Qt 6: Consider change the semantics of this function,
+ // ### TODO: Consider change the semantics of this function,
// or deprecating/removing it altogether.
//
// For instance, it should try setting *all* the data
@@ -2147,14 +2123,14 @@ QStringList QAbstractItemModel::mimeTypes() const
mimeTypes(). If you reimplement mimeTypes() in your custom model to return
more MIME types, reimplement this function to make use of them.
- If the list of \a indexes is empty, or there are no supported MIME types, 0
- is returned rather than a serialized empty list.
+ If the list of \a indexes is empty, or there are no supported MIME types,
+ \nullptr is returned rather than a serialized empty list.
\sa mimeTypes(), dropMimeData()
*/
QMimeData *QAbstractItemModel::mimeData(const QModelIndexList &indexes) const
{
- if (indexes.count() <= 0)
+ if (indexes.size() <= 0)
return nullptr;
QStringList types = mimeTypes();
if (types.isEmpty())
@@ -2193,7 +2169,7 @@ bool QAbstractItemModel::canDropMimeData(const QMimeData *data, Qt::DropAction a
return false;
const QStringList modelTypes = mimeTypes();
- for (int i = 0; i < modelTypes.count(); ++i) {
+ for (int i = 0; i < modelTypes.size(); ++i) {
if (data->hasFormat(modelTypes.at(i)))
return true;
}
@@ -2534,10 +2510,10 @@ QModelIndexList QAbstractItemModel::match(const QModelIndex &start, int role,
Qt::MatchFlags flags) const
{
QModelIndexList result;
- uint matchType = flags & 0x0F;
+ uint matchType = (flags & Qt::MatchTypeMask).toInt();
Qt::CaseSensitivity cs = flags & Qt::MatchCaseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive;
- bool recurse = flags & Qt::MatchRecursive;
- bool wrap = flags & Qt::MatchWrap;
+ bool recurse = flags.testAnyFlag(Qt::MatchRecursive);
+ bool wrap = flags.testAnyFlag(Qt::MatchWrap);
bool allHits = (hits == -1);
QString text; // only convert to a string if it is needed
#if QT_CONFIG(regularexpression)
@@ -2550,7 +2526,7 @@ QModelIndexList QAbstractItemModel::match(const QModelIndex &start, int role,
// iterates twice if wrapping
for (int i = 0; (wrap && i < 2) || (!wrap && i < 1); ++i) {
- for (int r = from; (r < to) && (allHits || result.count() < hits); ++r) {
+ for (int r = from; (r < to) && (allHits || result.size() < hits); ++r) {
QModelIndex idx = index(r, column, p);
if (!idx.isValid())
continue;
@@ -2572,8 +2548,10 @@ QModelIndexList QAbstractItemModel::match(const QModelIndex &start, int role,
}
}
} else if (matchType == Qt::MatchWildcard) {
- if (rx.pattern().isEmpty())
- rx.setPattern(QRegularExpression::wildcardToRegularExpression(value.toString()));
+ if (rx.pattern().isEmpty()) {
+ const QString pattern = QRegularExpression::wildcardToRegularExpression(value.toString(), QRegularExpression::NonPathWildcardConversion);
+ rx.setPattern(pattern);
+ }
if (cs == Qt::CaseInsensitive)
rx.setPatternOptions(QRegularExpression::CaseInsensitiveOption);
} else
@@ -2616,7 +2594,7 @@ QModelIndexList QAbstractItemModel::match(const QModelIndex &start, int role,
if (hasChildren(parent)) { // search the hierarchy
result += match(index(0, column, parent), role,
(text.isEmpty() ? value : text),
- (allHits ? -1 : hits - result.count()), flags);
+ (allHits ? -1 : hits - result.size()), flags);
}
}
}
@@ -2809,15 +2787,15 @@ bool QAbstractItemModel::decodeData(int row, int column, const QModelIndex &pare
// Compute the number of continuous rows upon insertion and modify the rows to match
QList<int> rowsToInsert(bottom + 1);
- for (int i = 0; i < rows.count(); ++i)
+ for (int i = 0; i < rows.size(); ++i)
rowsToInsert[rows.at(i)] = 1;
- for (int i = 0; i < rowsToInsert.count(); ++i) {
+ for (int i = 0; i < rowsToInsert.size(); ++i) {
if (rowsToInsert.at(i) == 1){
rowsToInsert[i] = dragRowCount;
++dragRowCount;
}
}
- for (int i = 0; i < rows.count(); ++i)
+ for (int i = 0; i < rows.size(); ++i)
rows[i] = top + rowsToInsert.at(rows.at(i));
QBitArray isWrittenTo(dragRowCount * dragColumnCount);
@@ -3019,6 +2997,13 @@ bool QAbstractItemModelPrivate::allowMove(const QModelIndex &srcParent, int star
}
/*!
+ \internal
+
+ see QTBUG-94546
+ */
+void QAbstractItemModelPrivate::executePendingOperations() const { }
+
+/*!
\since 4.6
Begins a row move operation.
@@ -3346,9 +3331,8 @@ bool QAbstractItemModel::beginMoveColumns(const QModelIndex &sourceParent, int s
destinationChange.needsAdjust = destinationParent.isValid() && destinationParent.row() >= sourceLast && destinationParent.parent() == sourceParent;
d->changes.push(destinationChange);
- d->itemsAboutToBeMoved(sourceParent, sourceFirst, sourceLast, destinationParent, destinationChild, Qt::Horizontal);
-
emit columnsAboutToBeMoved(sourceParent, sourceFirst, sourceLast, destinationParent, destinationChild, QPrivateSignal());
+ d->itemsAboutToBeMoved(sourceParent, sourceFirst, sourceLast, destinationParent, destinationChild, Qt::Horizontal);
return true;
}
@@ -3381,7 +3365,6 @@ void QAbstractItemModel::endMoveColumns()
adjustedSource = createIndex(adjustedSource.row(), adjustedSource.column() + numMoved, adjustedSource.internalPointer());
d->itemsMoved(adjustedSource, removeChange.first, removeChange.last, adjustedDestination, insertChange.first, Qt::Horizontal);
-
emit columnsMoved(adjustedSource, removeChange.first, removeChange.last, adjustedDestination, insertChange.first, QPrivateSignal());
}
@@ -3475,8 +3458,8 @@ void QAbstractItemModel::changePersistentIndexList(const QModelIndexList &from,
if (d->persistent.indexes.isEmpty())
return;
QList<QPersistentModelIndexData *> toBeReinserted;
- toBeReinserted.reserve(to.count());
- for (int i = 0; i < from.count(); ++i) {
+ toBeReinserted.reserve(to.size());
+ for (int i = 0; i < from.size(); ++i) {
if (from.at(i) == to.at(i))
continue;
const auto it = d->persistent.indexes.constFind(from.at(i));
@@ -3489,7 +3472,7 @@ void QAbstractItemModel::changePersistentIndexList(const QModelIndexList &from,
}
}
- for (auto *data : qAsConst(toBeReinserted))
+ for (auto *data : std::as_const(toBeReinserted))
d->persistent.insertMultiAtEnd(data->index, data);
}
@@ -3502,8 +3485,8 @@ QModelIndexList QAbstractItemModel::persistentIndexList() const
{
Q_D(const QAbstractItemModel);
QModelIndexList result;
- result.reserve(d->persistent.indexes.count());
- for (auto *data : qAsConst(d->persistent.indexes))
+ result.reserve(d->persistent.indexes.size());
+ for (auto *data : std::as_const(d->persistent.indexes))
result.append(data->index);
return result;
}
@@ -3755,10 +3738,9 @@ void QAbstractItemModel::multiData(const QModelIndex &index, QModelRoleDataSpan
\note Some general guidelines for subclassing models are available in the
\l{Model Subclassing Reference}.
- \note
+ \include models.qdocinc {thread-safety-section1}{QAbstractTableModel}
- \sa {Model Classes}, QAbstractItemModel, QAbstractListModel,
- {Pixelator Example}
+ \sa {Model Classes}, QAbstractItemModel, QAbstractListModel
*/
/*!
@@ -3909,7 +3891,7 @@ Qt::ItemFlags QAbstractTableModel::flags(const QModelIndex &index) const
\l{Model Subclassing Reference}.
\sa {Model Classes}, {Model Subclassing Reference}, QAbstractItemView,
- QAbstractTableModel, {Item Views Puzzle Example}
+ QAbstractTableModel
*/
/*!