summaryrefslogtreecommitdiffstats
path: root/src/corelib/itemmodels/qabstractitemmodel.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/itemmodels/qabstractitemmodel.h')
-rw-r--r--src/corelib/itemmodels/qabstractitemmodel.h240
1 files changed, 160 insertions, 80 deletions
diff --git a/src/corelib/itemmodels/qabstractitemmodel.h b/src/corelib/itemmodels/qabstractitemmodel.h
index a7fb429cf3..8f22f14989 100644
--- a/src/corelib/itemmodels/qabstractitemmodel.h
+++ b/src/corelib/itemmodels/qabstractitemmodel.h
@@ -1,41 +1,6 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** 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) 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>
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QABSTRACTITEMMODEL_H
#define QABSTRACTITEMMODEL_H
@@ -49,6 +14,108 @@ QT_REQUIRE_CONFIG(itemmodel);
QT_BEGIN_NAMESPACE
+class QModelRoleData
+{
+ int m_role;
+ QVariant m_data;
+
+public:
+ explicit QModelRoleData(int role) noexcept
+ : m_role(role)
+ {}
+
+ constexpr int role() const noexcept { return m_role; }
+ constexpr QVariant &data() noexcept { return m_data; }
+ constexpr const QVariant &data() const noexcept { return m_data; }
+
+ template <typename T>
+ constexpr void setData(T &&value) noexcept(noexcept(m_data.setValue(std::forward<T>(value))))
+ { m_data.setValue(std::forward<T>(value)); }
+
+ void clearData() noexcept { m_data.clear(); }
+};
+
+Q_DECLARE_TYPEINFO(QModelRoleData, Q_RELOCATABLE_TYPE);
+
+class QModelRoleDataSpan;
+
+namespace QtPrivate {
+template <typename T, typename Enable = void>
+struct IsContainerCompatibleWithModelRoleDataSpan : std::false_type {};
+
+template <typename T>
+struct IsContainerCompatibleWithModelRoleDataSpan<T, std::enable_if_t<std::conjunction_v<
+ // lacking concepts and ranges, we accept any T whose std::data yields a suitable pointer ...
+ std::is_convertible<decltype( std::data(std::declval<T &>()) ), QModelRoleData *>,
+ // ... and that has a suitable size ...
+ std::is_convertible<decltype( std::size(std::declval<T &>()) ), qsizetype>,
+ // ... and it's a range as it defines an iterator-like API
+ std::is_convertible<
+ typename std::iterator_traits<decltype( std::begin(std::declval<T &>()) )>::value_type,
+ QModelRoleData
+ >,
+ std::is_convertible<
+ decltype( std::begin(std::declval<T &>()) != std::end(std::declval<T &>()) ),
+ bool>,
+ // Don't make an accidental copy constructor
+ std::negation<std::is_same<std::decay_t<T>, QModelRoleDataSpan>>
+ >>> : std::true_type {};
+} // namespace QtPrivate
+
+class QModelRoleDataSpan
+{
+ QModelRoleData *m_modelRoleData = nullptr;
+ qsizetype m_len = 0;
+
+ template <typename T>
+ using if_compatible_container = std::enable_if_t<QtPrivate::IsContainerCompatibleWithModelRoleDataSpan<T>::value, bool>;
+
+public:
+ constexpr QModelRoleDataSpan() noexcept {}
+
+ constexpr QModelRoleDataSpan(QModelRoleData &modelRoleData) noexcept
+ : m_modelRoleData(&modelRoleData),
+ m_len(1)
+ {}
+
+ constexpr QModelRoleDataSpan(QModelRoleData *modelRoleData, qsizetype len)
+ : m_modelRoleData(modelRoleData),
+ m_len(len)
+ {}
+
+ template <typename Container, if_compatible_container<Container> = true>
+ constexpr QModelRoleDataSpan(Container &c) noexcept(noexcept(std::data(c)) && noexcept(std::size(c)))
+ : m_modelRoleData(std::data(c)),
+ m_len(qsizetype(std::size(c)))
+ {}
+
+ constexpr qsizetype size() const noexcept { return m_len; }
+ constexpr qsizetype length() const noexcept { return m_len; }
+ constexpr QModelRoleData *data() const noexcept { return m_modelRoleData; }
+ constexpr QModelRoleData *begin() const noexcept { return m_modelRoleData; }
+ constexpr QModelRoleData *end() const noexcept { return m_modelRoleData + m_len; }
+ constexpr QModelRoleData &operator[](qsizetype index) const { return m_modelRoleData[index]; }
+
+ constexpr QVariant *dataForRole(int role) const
+ {
+#ifdef __cpp_lib_constexpr_algorithms
+ auto result = std::find_if(begin(), end(), [role](const QModelRoleData &roleData) {
+ return roleData.role() == role;
+ });
+#else
+ auto result = begin();
+ const auto e = end();
+ for (; result != e; ++result) {
+ if (result->role() == role)
+ break;
+ }
+#endif
+
+ return Q_ASSERT(result != end()), &result->data();
+ }
+};
+
+Q_DECLARE_TYPEINFO(QModelRoleDataSpan, Q_RELOCATABLE_TYPE);
class QAbstractItemModel;
class QPersistentModelIndex;
@@ -57,11 +124,11 @@ class QModelIndex
{
friend class QAbstractItemModel;
public:
- Q_DECL_CONSTEXPR inline QModelIndex() noexcept : r(-1), c(-1), i(0), m(nullptr) {}
+ constexpr inline QModelIndex() noexcept : r(-1), c(-1), i(0), m(nullptr) {}
// compiler-generated copy/move ctors/assignment operators are fine!
- Q_DECL_CONSTEXPR inline int row() const noexcept { return r; }
- Q_DECL_CONSTEXPR inline int column() const noexcept { return c; }
- Q_DECL_CONSTEXPR inline quintptr internalId() const noexcept { return i; }
+ constexpr inline int row() const noexcept { return r; }
+ constexpr inline int column() const noexcept { return c; }
+ constexpr inline quintptr internalId() const noexcept { return i; }
inline void *internalPointer() const noexcept { return reinterpret_cast<void*>(i); }
inline const void *constInternalPointer() const noexcept { return reinterpret_cast<const void *>(i); }
inline QModelIndex parent() const;
@@ -69,14 +136,15 @@ public:
inline QModelIndex siblingAtColumn(int column) const;
inline QModelIndex siblingAtRow(int row) const;
inline QVariant data(int role = Qt::DisplayRole) const;
+ inline void multiData(QModelRoleDataSpan roleDataSpan) const;
inline Qt::ItemFlags flags() const;
- Q_DECL_CONSTEXPR inline const QAbstractItemModel *model() const noexcept { return m; }
- Q_DECL_CONSTEXPR inline bool isValid() const noexcept { return (r >= 0) && (c >= 0) && (m != nullptr); }
- Q_DECL_CONSTEXPR inline bool operator==(const QModelIndex &other) const noexcept
+ constexpr inline const QAbstractItemModel *model() const noexcept { return m; }
+ constexpr inline bool isValid() const noexcept { return (r >= 0) && (c >= 0) && (m != nullptr); }
+ constexpr inline bool operator==(const QModelIndex &other) const noexcept
{ return (other.r == r) && (other.i == i) && (other.c == c) && (other.m == m); }
- Q_DECL_CONSTEXPR inline bool operator!=(const QModelIndex &other) const noexcept
+ constexpr inline bool operator!=(const QModelIndex &other) const noexcept
{ return !(*this == other); }
- Q_DECL_CONSTEXPR inline bool operator<(const QModelIndex &other) const noexcept
+ constexpr inline bool operator<(const QModelIndex &other) const noexcept
{
return r < other.r
|| (r == other.r && (c < other.c
@@ -86,13 +154,13 @@ public:
private:
inline QModelIndex(int arow, int acolumn, const void *ptr, const QAbstractItemModel *amodel) noexcept
: r(arow), c(acolumn), i(reinterpret_cast<quintptr>(ptr)), m(amodel) {}
- Q_DECL_CONSTEXPR inline QModelIndex(int arow, int acolumn, quintptr id, const QAbstractItemModel *amodel) noexcept
+ constexpr inline QModelIndex(int arow, int acolumn, quintptr id, const QAbstractItemModel *amodel) noexcept
: r(arow), c(acolumn), i(id), m(amodel) {}
int r, c;
quintptr i;
const QAbstractItemModel *m;
};
-Q_DECLARE_TYPEINFO(QModelIndex, Q_MOVABLE_TYPE);
+Q_DECLARE_TYPEINFO(QModelIndex, Q_RELOCATABLE_TYPE);
#ifndef QT_NO_DEBUG_STREAM
Q_CORE_EXPORT QDebug operator<<(QDebug, const QModelIndex &);
@@ -110,20 +178,19 @@ public:
QPersistentModelIndex(const QModelIndex &index);
QPersistentModelIndex(const QPersistentModelIndex &other);
~QPersistentModelIndex();
- bool operator<(const QPersistentModelIndex &other) const;
- bool operator==(const QPersistentModelIndex &other) const;
- inline bool operator!=(const QPersistentModelIndex &other) const
+ bool operator<(const QPersistentModelIndex &other) const noexcept;
+ bool operator==(const QPersistentModelIndex &other) const noexcept;
+ inline bool operator!=(const QPersistentModelIndex &other) const noexcept
{ return !operator==(other); }
QPersistentModelIndex &operator=(const QPersistentModelIndex &other);
inline QPersistentModelIndex(QPersistentModelIndex &&other) noexcept
- : d(other.d) { other.d = nullptr; }
- inline QPersistentModelIndex &operator=(QPersistentModelIndex &&other) noexcept
- { qSwap(d, other.d); return *this; }
- inline void swap(QPersistentModelIndex &other) noexcept { qSwap(d, other.d); }
- bool operator==(const QModelIndex &other) const;
- bool operator!=(const QModelIndex &other) const;
+ : d(std::exchange(other.d, nullptr)) {}
+ QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_PURE_SWAP(QPersistentModelIndex)
+ void swap(QPersistentModelIndex &other) noexcept { qt_ptr_swap(d, other.d); }
+ bool operator==(const QModelIndex &other) const noexcept;
+ bool operator!=(const QModelIndex &other) const noexcept;
QPersistentModelIndex &operator=(const QModelIndex &other);
- operator const QModelIndex&() const;
+ operator QModelIndex() const;
int row() const;
int column() const;
void *internalPointer() const;
@@ -132,12 +199,15 @@ public:
QModelIndex parent() const;
QModelIndex sibling(int row, int column) const;
QVariant data(int role = Qt::DisplayRole) const;
+ void multiData(QModelRoleDataSpan roleDataSpan) const;
Qt::ItemFlags flags() const;
const QAbstractItemModel *model() const;
bool isValid() const;
private:
QPersistentModelIndexData *d;
friend size_t qHash(const QPersistentModelIndex &, size_t seed) noexcept;
+ friend bool qHashEquals(const QPersistentModelIndex &a, const QPersistentModelIndex &b) noexcept
+ { return a.d == b.d; }
#ifndef QT_NO_DEBUG_STREAM
friend Q_CORE_EXPORT QDebug operator<<(QDebug, const QPersistentModelIndex &);
#endif
@@ -166,8 +236,7 @@ class Q_CORE_EXPORT QAbstractItemModel : public QObject
friend class QPersistentModelIndexData;
friend class QAbstractItemViewPrivate;
- friend class QIdentityProxyModel;
- friend class QTransposeProxyModelPrivate;
+ friend class QAbstractProxyModel;
public:
explicit QAbstractItemModel(QObject *parent = nullptr);
@@ -204,28 +273,28 @@ public:
virtual Qt::DropActions supportedDropActions() const;
virtual Qt::DropActions supportedDragActions() const;
- virtual bool insertRows(int row, int count, const QModelIndex &parent = QModelIndex());
- virtual bool insertColumns(int column, int count, const QModelIndex &parent = QModelIndex());
- virtual bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex());
- virtual bool removeColumns(int column, int count, const QModelIndex &parent = QModelIndex());
- virtual bool moveRows(const QModelIndex &sourceParent, int sourceRow, int count,
+ Q_INVOKABLE Q_REVISION(6, 4) virtual bool insertRows(int row, int count, const QModelIndex &parent = QModelIndex());
+ Q_INVOKABLE Q_REVISION(6, 4) virtual bool insertColumns(int column, int count, const QModelIndex &parent = QModelIndex());
+ Q_INVOKABLE Q_REVISION(6, 4) virtual bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex());
+ Q_INVOKABLE Q_REVISION(6, 4) virtual bool removeColumns(int column, int count, const QModelIndex &parent = QModelIndex());
+ Q_INVOKABLE Q_REVISION(6, 4) virtual bool moveRows(const QModelIndex &sourceParent, int sourceRow, int count,
const QModelIndex &destinationParent, int destinationChild);
- virtual bool moveColumns(const QModelIndex &sourceParent, int sourceColumn, int count,
+ Q_INVOKABLE Q_REVISION(6, 4) virtual bool moveColumns(const QModelIndex &sourceParent, int sourceColumn, int count,
const QModelIndex &destinationParent, int destinationChild);
- inline bool insertRow(int row, const QModelIndex &parent = QModelIndex());
- inline bool insertColumn(int column, const QModelIndex &parent = QModelIndex());
- inline bool removeRow(int row, const QModelIndex &parent = QModelIndex());
- inline bool removeColumn(int column, const QModelIndex &parent = QModelIndex());
- inline bool moveRow(const QModelIndex &sourceParent, int sourceRow,
+ Q_INVOKABLE Q_REVISION(6, 4) inline bool insertRow(int row, const QModelIndex &parent = QModelIndex());
+ Q_INVOKABLE Q_REVISION(6, 4) inline bool insertColumn(int column, const QModelIndex &parent = QModelIndex());
+ Q_INVOKABLE Q_REVISION(6, 4) inline bool removeRow(int row, const QModelIndex &parent = QModelIndex());
+ Q_INVOKABLE Q_REVISION(6, 4) inline bool removeColumn(int column, const QModelIndex &parent = QModelIndex());
+ Q_INVOKABLE Q_REVISION(6, 4) inline bool moveRow(const QModelIndex &sourceParent, int sourceRow,
const QModelIndex &destinationParent, int destinationChild);
- inline bool moveColumn(const QModelIndex &sourceParent, int sourceColumn,
+ Q_INVOKABLE Q_REVISION(6, 4) inline bool moveColumn(const QModelIndex &sourceParent, int sourceColumn,
const QModelIndex &destinationParent, int destinationChild);
Q_INVOKABLE virtual void fetchMore(const QModelIndex &parent);
Q_INVOKABLE virtual bool canFetchMore(const QModelIndex &parent) const;
Q_INVOKABLE virtual Qt::ItemFlags flags(const QModelIndex &index) const;
- virtual void sort(int column, Qt::SortOrder order = Qt::AscendingOrder);
+ Q_INVOKABLE Q_REVISION(6, 4) virtual void sort(int column, Qt::SortOrder order = Qt::AscendingOrder);
virtual QModelIndex buddy(const QModelIndex &index) const;
Q_INVOKABLE virtual QModelIndexList match(const QModelIndex &start, int role,
const QVariant &value, int hits = 1,
@@ -254,7 +323,9 @@ public:
Q_ENUM(CheckIndexOption)
Q_DECLARE_FLAGS(CheckIndexOptions, CheckIndexOption)
- Q_REQUIRED_RESULT bool checkIndex(const QModelIndex &index, CheckIndexOptions options = CheckIndexOption::NoOption) const;
+ [[nodiscard]] bool checkIndex(const QModelIndex &index, CheckIndexOptions options = CheckIndexOption::NoOption) const;
+
+ virtual void multiData(const QModelIndex &index, QModelRoleDataSpan roleDataSpan) const;
Q_SIGNALS:
void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight,
@@ -279,10 +350,10 @@ Q_SIGNALS:
void modelReset(QPrivateSignal);
void rowsAboutToBeMoved( const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destinationParent, int destinationRow, QPrivateSignal);
- void rowsMoved( const QModelIndex &parent, int start, int end, const QModelIndex &destination, int row, QPrivateSignal);
+ void rowsMoved( const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destinationParent, int destinationRow, QPrivateSignal);
void columnsAboutToBeMoved( const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destinationParent, int destinationColumn, QPrivateSignal);
- void columnsMoved( const QModelIndex &parent, int start, int end, const QModelIndex &destination, int column, QPrivateSignal);
+ void columnsMoved( const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destinationParent, int destinationColumn, QPrivateSignal);
public Q_SLOTS:
virtual bool submit();
@@ -421,14 +492,23 @@ inline QModelIndex QModelIndex::siblingAtRow(int arow) const
inline QVariant QModelIndex::data(int arole) const
{ return m ? m->data(*this, arole) : QVariant(); }
+inline void QModelIndex::multiData(QModelRoleDataSpan roleDataSpan) const
+{ if (m) m->multiData(*this, roleDataSpan); }
+
inline Qt::ItemFlags QModelIndex::flags() const
{ return m ? m->flags(*this) : Qt::ItemFlags(); }
-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; }
+inline size_t qHash(const QModelIndex &index, size_t seed = 0) noexcept
+{
+#if QT_VERSION >= QT_VERSION_CHECK(7, 0, 0)
+ return qHashMulti(seed, index.row(), index.column(), index.internalId());
+#else
+ return size_t((size_t(index.row()) << 4) + size_t(index.column()) + index.internalId()) ^ seed;
+#endif
+}
QT_END_NAMESPACE
-Q_DECLARE_METATYPE(QModelIndexList)
+QT_DECL_METATYPE_EXTERN(QModelIndexList, Q_CORE_EXPORT)
#endif // QABSTRACTITEMMODEL_H