1// Copyright (C) 2016 The Qt Company Ltd.
2// Copyright (C) 2020 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
3// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
4// Qt-Security score:significant reason:default
5
6#ifndef QABSTRACTITEMMODEL_H
7#define QABSTRACTITEMMODEL_H
8
9#include <QtCore/qcompare.h>
10#include <QtCore/qhash.h>
11#include <QtCore/qlist.h>
12#include <QtCore/qobject.h>
13#include <QtCore/qvariant.h>
14
15QT_REQUIRE_CONFIG(itemmodel);
16
17QT_BEGIN_NAMESPACE
18
19class QModelRoleData
20{
21 int m_role;
22 QVariant m_data;
23
24public:
25 explicit QModelRoleData(int role) noexcept
26 : m_role(role)
27 {}
28
29 constexpr int role() const noexcept { return m_role; }
30 constexpr QVariant &data() noexcept { return m_data; }
31 constexpr const QVariant &data() const noexcept { return m_data; }
32
33 template <typename T>
34 constexpr void setData(T &&value) noexcept(noexcept(m_data.setValue(std::forward<T>(value))))
35 { m_data.setValue(std::forward<T>(value)); }
36
37 void clearData() noexcept { m_data.clear(); }
38};
39
40Q_DECLARE_TYPEINFO(QModelRoleData, Q_RELOCATABLE_TYPE);
41
42class QModelRoleDataSpan;
43
44namespace QtPrivate {
45template <typename T, typename Enable = void>
46struct IsContainerCompatibleWithModelRoleDataSpan : std::false_type {};
47
48template <typename T>
49struct IsContainerCompatibleWithModelRoleDataSpan<T, std::enable_if_t<std::conjunction_v<
50 // lacking concepts and ranges, we accept any T whose std::data yields a suitable pointer ...
51 std::is_convertible<decltype( std::data(std::declval<T &>()) ), QModelRoleData *>,
52 // ... and that has a suitable size ...
53 std::is_convertible<decltype( std::size(std::declval<T &>()) ), qsizetype>,
54 // ... and it's a range as it defines an iterator-like API
55 std::is_convertible<
56 typename std::iterator_traits<decltype( std::begin(std::declval<T &>()) )>::value_type,
57 QModelRoleData
58 >,
59 std::is_convertible<
60 decltype( std::begin(std::declval<T &>()) != std::end(std::declval<T &>()) ),
61 bool>,
62 // Don't make an accidental copy constructor
63 std::negation<std::is_same<std::decay_t<T>, QModelRoleDataSpan>>
64 >>> : std::true_type {};
65} // namespace QtPrivate
66
67class QModelRoleDataSpan
68{
69 QModelRoleData *m_modelRoleData = nullptr;
70 qsizetype m_len = 0;
71
72 template <typename T>
73 using if_compatible_container = std::enable_if_t<QtPrivate::IsContainerCompatibleWithModelRoleDataSpan<T>::value, bool>;
74
75public:
76 constexpr QModelRoleDataSpan() noexcept {}
77
78 constexpr QModelRoleDataSpan(QModelRoleData &modelRoleData) noexcept
79 : m_modelRoleData(&modelRoleData),
80 m_len(1)
81 {}
82
83 constexpr QModelRoleDataSpan(QModelRoleData *modelRoleData, qsizetype len)
84 : m_modelRoleData(modelRoleData),
85 m_len(len)
86 {}
87
88 template <typename Container, if_compatible_container<Container> = true>
89 constexpr QModelRoleDataSpan(Container &c) noexcept(noexcept(std::data(c)) && noexcept(std::size(c)))
90 : m_modelRoleData(std::data(c)),
91 m_len(qsizetype(std::size(c)))
92 {}
93
94 constexpr qsizetype size() const noexcept { return m_len; }
95 constexpr qsizetype length() const noexcept { return m_len; }
96 constexpr QModelRoleData *data() const noexcept { return m_modelRoleData; }
97 constexpr QModelRoleData *begin() const noexcept { return m_modelRoleData; }
98 constexpr QModelRoleData *end() const noexcept { return m_modelRoleData + m_len; }
99 constexpr QModelRoleData &operator[](qsizetype index) const { return m_modelRoleData[index]; }
100
101 constexpr QVariant *dataForRole(int role) const
102 {
103#ifdef __cpp_lib_constexpr_algorithms
104 auto result = std::find_if(begin(), end(), [role](const QModelRoleData &roleData) {
105 return roleData.role() == role;
106 });
107#else
108 auto result = begin();
109 const auto e = end();
110 for (; result != e; ++result) {
111 if (result->role() == role)
112 break;
113 }
114#endif
115
116 return Q_ASSERT(result != end()), &result->data();
117 }
118};
119
120Q_DECLARE_TYPEINFO(QModelRoleDataSpan, Q_RELOCATABLE_TYPE);
121
122class QAbstractItemModel;
123class QPersistentModelIndex;
124
125class QModelIndex
126{
127 friend class QAbstractItemModel;
128public:
129 constexpr inline QModelIndex() noexcept : r(-1), c(-1), i(0), m(nullptr) {}
130 // compiler-generated copy/move ctors/assignment operators are fine!
131 constexpr inline int row() const noexcept { return r; }
132 constexpr inline int column() const noexcept { return c; }
133 constexpr inline quintptr internalId() const noexcept { return i; }
134 inline void *internalPointer() const noexcept { return reinterpret_cast<void*>(i); }
135 inline const void *constInternalPointer() const noexcept { return reinterpret_cast<const void *>(i); }
136 inline QModelIndex parent() const;
137 inline QModelIndex sibling(int row, int column) const;
138 inline QModelIndex siblingAtColumn(int column) const;
139 inline QModelIndex siblingAtRow(int row) const;
140 inline QVariant data(int role = Qt::DisplayRole) const;
141 inline void multiData(QModelRoleDataSpan roleDataSpan) const;
142 inline Qt::ItemFlags flags() const;
143 constexpr inline const QAbstractItemModel *model() const noexcept { return m.get(); }
144 constexpr inline bool isValid() const noexcept { return (r >= 0) && (c >= 0) && (m != nullptr); }
145
146private:
147 friend constexpr bool comparesEqual(const QModelIndex &lhs, const QModelIndex &rhs) noexcept
148 {
149 return lhs.r == rhs.r && lhs.c == rhs.c && lhs.i == rhs.i && lhs.m == rhs.m;
150 }
151 friend constexpr Qt::strong_ordering compareThreeWay(const QModelIndex &lhs, const QModelIndex &rhs) noexcept
152 {
153 if (auto val = Qt::compareThreeWay(lhs: lhs.r, rhs: rhs.r); !is_eq(o: val))
154 return val;
155 if (auto val = Qt::compareThreeWay(lhs: lhs.c, rhs: rhs.c); !is_eq(o: val))
156 return val;
157 if (auto val = Qt::compareThreeWay(lhs: lhs.i, rhs: rhs.i); !is_eq(o: val))
158 return val;
159 if (auto val = Qt::compareThreeWay(lhs: lhs.m, rhs: rhs.m); !is_eq(o: val))
160 return val;
161 return Qt::strong_ordering::equivalent;
162 }
163 Q_DECLARE_STRONGLY_ORDERED_LITERAL_TYPE(QModelIndex)
164private:
165 inline QModelIndex(int arow, int acolumn, const void *ptr, const QAbstractItemModel *amodel) noexcept
166 : r(arow), c(acolumn), i(reinterpret_cast<quintptr>(ptr)), m(amodel) {}
167 constexpr inline QModelIndex(int arow, int acolumn, quintptr id, const QAbstractItemModel *amodel) noexcept
168 : r(arow), c(acolumn), i(id), m(amodel) {}
169 int r, c;
170 quintptr i;
171 Qt::totally_ordered_wrapper<const QAbstractItemModel *> m;
172};
173Q_DECLARE_TYPEINFO(QModelIndex, Q_RELOCATABLE_TYPE);
174
175#ifndef QT_NO_DEBUG_STREAM
176Q_CORE_EXPORT QDebug operator<<(QDebug, const QModelIndex &);
177#endif
178
179class QPersistentModelIndexData;
180
181// qHash is a friend, but we can't use default arguments for friends (§8.3.6.4)
182size_t qHash(const QPersistentModelIndex &index, size_t seed = 0) noexcept;
183
184class Q_CORE_EXPORT QPersistentModelIndex
185{
186public:
187 QPersistentModelIndex();
188 QPersistentModelIndex(const QModelIndex &index);
189 QPersistentModelIndex(const QPersistentModelIndex &other);
190 ~QPersistentModelIndex();
191#if QT_CORE_REMOVED_SINCE(6, 8)
192 bool operator<(const QPersistentModelIndex &other) const noexcept;
193 bool operator==(const QPersistentModelIndex &other) const noexcept;
194 inline bool operator!=(const QPersistentModelIndex &other) const noexcept
195 { return !operator==(other); }
196#endif
197 QPersistentModelIndex &operator=(const QPersistentModelIndex &other);
198 inline QPersistentModelIndex(QPersistentModelIndex &&other) noexcept
199 : d(std::exchange(obj&: other.d, new_val: nullptr)) {}
200 QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_PURE_SWAP(QPersistentModelIndex)
201 void swap(QPersistentModelIndex &other) noexcept { qt_ptr_swap(lhs&: d, rhs&: other.d); }
202#if QT_CORE_REMOVED_SINCE(6, 8)
203 bool operator==(const QModelIndex &other) const noexcept;
204 bool operator!=(const QModelIndex &other) const noexcept;
205#endif
206 QPersistentModelIndex &operator=(const QModelIndex &other);
207 operator QModelIndex() const;
208 int row() const;
209 int column() const;
210 void *internalPointer() const;
211 const void *constInternalPointer() const;
212 quintptr internalId() const;
213 QModelIndex parent() const;
214 QModelIndex sibling(int row, int column) const;
215 QVariant data(int role = Qt::DisplayRole) const;
216 void multiData(QModelRoleDataSpan roleDataSpan) const;
217 Qt::ItemFlags flags() const;
218 const QAbstractItemModel *model() const;
219 bool isValid() const;
220private:
221 QPersistentModelIndexData *d;
222 friend size_t qHash(const QPersistentModelIndex &, size_t seed) noexcept;
223 friend bool qHashEquals(const QPersistentModelIndex &a, const QPersistentModelIndex &b) noexcept
224 { return a.d == b.d; }
225 friend Q_CORE_EXPORT bool
226 comparesEqual(const QPersistentModelIndex &lhs, const QPersistentModelIndex &rhs) noexcept;
227 friend Q_CORE_EXPORT bool
228 comparesEqual(const QPersistentModelIndex &lhs, const QModelIndex &rhs) noexcept;
229 friend Q_CORE_EXPORT Qt::strong_ordering // ### Qt 7: partial_ordering?
230 compareThreeWay(const QPersistentModelIndex &lhs, const QPersistentModelIndex &rhs) noexcept;
231 friend Q_CORE_EXPORT Qt::strong_ordering // ### Qt 7: partial_ordering?
232 compareThreeWay(const QPersistentModelIndex &lhs, const QModelIndex &rhs) noexcept;
233#if !QT_CORE_REMOVED_SINCE(6, 8)
234 Q_DECLARE_STRONGLY_ORDERED(QPersistentModelIndex)
235 Q_DECLARE_STRONGLY_ORDERED(QPersistentModelIndex, QModelIndex)
236#endif
237#ifndef QT_NO_DEBUG_STREAM
238 friend Q_CORE_EXPORT QDebug operator<<(QDebug, const QPersistentModelIndex &);
239#endif
240};
241Q_DECLARE_SHARED(QPersistentModelIndex)
242
243inline size_t qHash(const QPersistentModelIndex &index, size_t seed) noexcept
244{ return qHash(t: index.d, seed); }
245
246
247#ifndef QT_NO_DEBUG_STREAM
248Q_CORE_EXPORT QDebug operator<<(QDebug, const QPersistentModelIndex &);
249#endif
250
251typedef QList<QModelIndex> QModelIndexList;
252
253class QMimeData;
254class QAbstractItemModelPrivate;
255class QTransposeProxyModelPrivate;
256template <class Key, class T> class QMap;
257
258
259class Q_CORE_EXPORT QAbstractItemModel : public QObject
260{
261 Q_OBJECT
262
263 friend class QPersistentModelIndexData;
264 friend class QAbstractItemViewPrivate;
265 friend class QAbstractProxyModel;
266public:
267
268 explicit QAbstractItemModel(QObject *parent = nullptr);
269 virtual ~QAbstractItemModel();
270
271 Q_INVOKABLE bool hasIndex(int row, int column, const QModelIndex &parent = QModelIndex()) const;
272 Q_INVOKABLE virtual QModelIndex index(int row, int column,
273 const QModelIndex &parent = QModelIndex()) const = 0;
274 Q_INVOKABLE virtual QModelIndex parent(const QModelIndex &child) const = 0;
275
276 Q_INVOKABLE virtual QModelIndex sibling(int row, int column, const QModelIndex &idx) const;
277 Q_INVOKABLE virtual int rowCount(const QModelIndex &parent = QModelIndex()) const = 0;
278 Q_INVOKABLE virtual int columnCount(const QModelIndex &parent = QModelIndex()) const = 0;
279 Q_INVOKABLE virtual bool hasChildren(const QModelIndex &parent = QModelIndex()) const;
280
281 Q_INVOKABLE virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const = 0;
282 Q_INVOKABLE virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
283
284 Q_INVOKABLE virtual QVariant headerData(int section, Qt::Orientation orientation,
285 int role = Qt::DisplayRole) const;
286 virtual bool setHeaderData(int section, Qt::Orientation orientation, const QVariant &value,
287 int role = Qt::EditRole);
288
289 virtual QMap<int, QVariant> itemData(const QModelIndex &index) const;
290 virtual bool setItemData(const QModelIndex &index, const QMap<int, QVariant> &roles);
291 virtual bool clearItemData(const QModelIndex &index);
292
293 virtual QStringList mimeTypes() const;
294 virtual QMimeData *mimeData(const QModelIndexList &indexes) const;
295 virtual bool canDropMimeData(const QMimeData *data, Qt::DropAction action,
296 int row, int column, const QModelIndex &parent) const;
297 virtual bool dropMimeData(const QMimeData *data, Qt::DropAction action,
298 int row, int column, const QModelIndex &parent);
299 virtual Qt::DropActions supportedDropActions() const;
300 virtual Qt::DropActions supportedDragActions() const;
301
302 Q_INVOKABLE Q_REVISION(6, 4) virtual bool insertRows(int row, int count, const QModelIndex &parent = QModelIndex());
303 Q_INVOKABLE Q_REVISION(6, 4) virtual bool insertColumns(int column, int count, const QModelIndex &parent = QModelIndex());
304 Q_INVOKABLE Q_REVISION(6, 4) virtual bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex());
305 Q_INVOKABLE Q_REVISION(6, 4) virtual bool removeColumns(int column, int count, const QModelIndex &parent = QModelIndex());
306 Q_INVOKABLE Q_REVISION(6, 4) virtual bool moveRows(const QModelIndex &sourceParent, int sourceRow, int count,
307 const QModelIndex &destinationParent, int destinationChild);
308 Q_INVOKABLE Q_REVISION(6, 4) virtual bool moveColumns(const QModelIndex &sourceParent, int sourceColumn, int count,
309 const QModelIndex &destinationParent, int destinationChild);
310
311 Q_INVOKABLE Q_REVISION(6, 4) inline bool insertRow(int row, const QModelIndex &parent = QModelIndex());
312 Q_INVOKABLE Q_REVISION(6, 4) inline bool insertColumn(int column, const QModelIndex &parent = QModelIndex());
313 Q_INVOKABLE Q_REVISION(6, 4) inline bool removeRow(int row, const QModelIndex &parent = QModelIndex());
314 Q_INVOKABLE Q_REVISION(6, 4) inline bool removeColumn(int column, const QModelIndex &parent = QModelIndex());
315 Q_INVOKABLE Q_REVISION(6, 4) inline bool moveRow(const QModelIndex &sourceParent, int sourceRow,
316 const QModelIndex &destinationParent, int destinationChild);
317 Q_INVOKABLE Q_REVISION(6, 4) inline bool moveColumn(const QModelIndex &sourceParent, int sourceColumn,
318 const QModelIndex &destinationParent, int destinationChild);
319
320 Q_INVOKABLE virtual void fetchMore(const QModelIndex &parent);
321 Q_INVOKABLE virtual bool canFetchMore(const QModelIndex &parent) const;
322 Q_INVOKABLE virtual Qt::ItemFlags flags(const QModelIndex &index) const;
323 Q_INVOKABLE Q_REVISION(6, 4) virtual void sort(int column, Qt::SortOrder order = Qt::AscendingOrder);
324 virtual QModelIndex buddy(const QModelIndex &index) const;
325 Q_INVOKABLE virtual QModelIndexList match(const QModelIndex &start, int role,
326 const QVariant &value, int hits = 1,
327 Qt::MatchFlags flags =
328 Qt::MatchFlags(Qt::MatchStartsWith|Qt::MatchWrap)) const;
329 virtual QSize span(const QModelIndex &index) const;
330
331 virtual QHash<int,QByteArray> roleNames() const;
332
333 using QObject::parent;
334
335 enum LayoutChangeHint
336 {
337 NoLayoutChangeHint,
338 VerticalSortHint,
339 HorizontalSortHint
340 };
341 Q_ENUM(LayoutChangeHint)
342
343 enum class CheckIndexOption {
344 NoOption = 0x0000,
345 IndexIsValid = 0x0001,
346 DoNotUseParent = 0x0002,
347 ParentIsInvalid = 0x0004,
348 };
349 Q_ENUM(CheckIndexOption)
350 Q_DECLARE_FLAGS(CheckIndexOptions, CheckIndexOption)
351
352 [[nodiscard]] bool checkIndex(const QModelIndex &index, CheckIndexOptions options = CheckIndexOption::NoOption) const;
353
354 virtual void multiData(const QModelIndex &index, QModelRoleDataSpan roleDataSpan) const;
355
356Q_SIGNALS:
357 void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight,
358 const QList<int> &roles = QList<int>());
359 void headerDataChanged(Qt::Orientation orientation, int first, int last);
360 void layoutChanged(const QList<QPersistentModelIndex> &parents = QList<QPersistentModelIndex>(), QAbstractItemModel::LayoutChangeHint hint = QAbstractItemModel::NoLayoutChangeHint);
361 void layoutAboutToBeChanged(const QList<QPersistentModelIndex> &parents = QList<QPersistentModelIndex>(), QAbstractItemModel::LayoutChangeHint hint = QAbstractItemModel::NoLayoutChangeHint);
362
363 void rowsAboutToBeInserted(const QModelIndex &parent, int first, int last, QPrivateSignal);
364 void rowsInserted(const QModelIndex &parent, int first, int last, QPrivateSignal);
365
366 void rowsAboutToBeRemoved(const QModelIndex &parent, int first, int last, QPrivateSignal);
367 void rowsRemoved(const QModelIndex &parent, int first, int last, QPrivateSignal);
368
369 void columnsAboutToBeInserted(const QModelIndex &parent, int first, int last, QPrivateSignal);
370 void columnsInserted(const QModelIndex &parent, int first, int last, QPrivateSignal);
371
372 void columnsAboutToBeRemoved(const QModelIndex &parent, int first, int last, QPrivateSignal);
373 void columnsRemoved(const QModelIndex &parent, int first, int last, QPrivateSignal);
374
375 void modelAboutToBeReset(QPrivateSignal);
376 void modelReset(QPrivateSignal);
377
378 void rowsAboutToBeMoved( const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destinationParent, int destinationRow, QPrivateSignal);
379 void rowsMoved( const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destinationParent, int destinationRow, QPrivateSignal);
380
381 void columnsAboutToBeMoved( const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destinationParent, int destinationColumn, QPrivateSignal);
382 void columnsMoved( const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destinationParent, int destinationColumn, QPrivateSignal);
383
384public Q_SLOTS:
385 virtual bool submit();
386 virtual void revert();
387
388protected Q_SLOTS:
389 virtual void resetInternalData();
390
391protected:
392 QAbstractItemModel(QAbstractItemModelPrivate &dd, QObject *parent = nullptr);
393
394 inline QModelIndex createIndex(int row, int column, const void *data = nullptr) const;
395 inline QModelIndex createIndex(int row, int column, quintptr id) const;
396
397 void encodeData(const QModelIndexList &indexes, QDataStream &stream) const;
398 bool decodeData(int row, int column, const QModelIndex &parent, QDataStream &stream);
399
400 void beginInsertRows(const QModelIndex &parent, int first, int last);
401 void endInsertRows();
402
403 void beginRemoveRows(const QModelIndex &parent, int first, int last);
404 void endRemoveRows();
405
406 bool beginMoveRows(const QModelIndex &sourceParent, int sourceFirst, int sourceLast, const QModelIndex &destinationParent, int destinationRow);
407 void endMoveRows();
408
409 void beginInsertColumns(const QModelIndex &parent, int first, int last);
410 void endInsertColumns();
411
412 void beginRemoveColumns(const QModelIndex &parent, int first, int last);
413 void endRemoveColumns();
414
415 bool beginMoveColumns(const QModelIndex &sourceParent, int sourceFirst, int sourceLast, const QModelIndex &destinationParent, int destinationColumn);
416 void endMoveColumns();
417
418 void beginResetModel();
419 void endResetModel();
420
421 void changePersistentIndex(const QModelIndex &from, const QModelIndex &to);
422 void changePersistentIndexList(const QModelIndexList &from, const QModelIndexList &to);
423 QModelIndexList persistentIndexList() const;
424
425private:
426 Q_DECLARE_PRIVATE(QAbstractItemModel)
427 Q_DISABLE_COPY(QAbstractItemModel)
428};
429
430Q_DECLARE_OPERATORS_FOR_FLAGS(QAbstractItemModel::CheckIndexOptions)
431
432inline bool QAbstractItemModel::insertRow(int arow, const QModelIndex &aparent)
433{ return insertRows(row: arow, count: 1, parent: aparent); }
434inline bool QAbstractItemModel::insertColumn(int acolumn, const QModelIndex &aparent)
435{ return insertColumns(column: acolumn, count: 1, parent: aparent); }
436inline bool QAbstractItemModel::removeRow(int arow, const QModelIndex &aparent)
437{ return removeRows(row: arow, count: 1, parent: aparent); }
438inline bool QAbstractItemModel::removeColumn(int acolumn, const QModelIndex &aparent)
439{ return removeColumns(column: acolumn, count: 1, parent: aparent); }
440inline bool QAbstractItemModel::moveRow(const QModelIndex &sourceParent, int sourceRow,
441 const QModelIndex &destinationParent, int destinationChild)
442{ return moveRows(sourceParent, sourceRow, count: 1, destinationParent, destinationChild); }
443inline bool QAbstractItemModel::moveColumn(const QModelIndex &sourceParent, int sourceColumn,
444 const QModelIndex &destinationParent, int destinationChild)
445{ return moveColumns(sourceParent, sourceColumn, count: 1, destinationParent, destinationChild); }
446inline QModelIndex QAbstractItemModel::createIndex(int arow, int acolumn, const void *adata) const
447{ return QModelIndex(arow, acolumn, adata, this); }
448inline QModelIndex QAbstractItemModel::createIndex(int arow, int acolumn, quintptr aid) const
449{ return QModelIndex(arow, acolumn, aid, this); }
450
451class Q_CORE_EXPORT QAbstractTableModel : public QAbstractItemModel
452{
453 Q_OBJECT
454
455public:
456 explicit QAbstractTableModel(QObject *parent = nullptr);
457 ~QAbstractTableModel();
458
459 QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override;
460 QModelIndex sibling(int row, int column, const QModelIndex &idx) const override;
461 bool dropMimeData(const QMimeData *data, Qt::DropAction action,
462 int row, int column, const QModelIndex &parent) override;
463
464 Qt::ItemFlags flags(const QModelIndex &index) const override;
465
466 using QObject::parent;
467
468protected:
469 QAbstractTableModel(QAbstractItemModelPrivate &dd, QObject *parent);
470
471private:
472 Q_DISABLE_COPY(QAbstractTableModel)
473 QModelIndex parent(const QModelIndex &child) const override;
474 bool hasChildren(const QModelIndex &parent) const override;
475};
476
477class Q_CORE_EXPORT QAbstractListModel : public QAbstractItemModel
478{
479 Q_OBJECT
480
481public:
482 explicit QAbstractListModel(QObject *parent = nullptr);
483 ~QAbstractListModel();
484
485 QModelIndex index(int row, int column = 0, const QModelIndex &parent = QModelIndex()) const override;
486 QModelIndex sibling(int row, int column, const QModelIndex &idx) const override;
487 bool dropMimeData(const QMimeData *data, Qt::DropAction action,
488 int row, int column, const QModelIndex &parent) override;
489
490 Qt::ItemFlags flags(const QModelIndex &index) const override;
491
492 using QObject::parent;
493
494protected:
495 QAbstractListModel(QAbstractItemModelPrivate &dd, QObject *parent);
496
497private:
498 Q_DISABLE_COPY(QAbstractListModel)
499 QModelIndex parent(const QModelIndex &child) const override;
500 int columnCount(const QModelIndex &parent) const override;
501 bool hasChildren(const QModelIndex &parent) const override;
502};
503
504// inline implementations
505
506inline QModelIndex QModelIndex::parent() const
507{ return m ? m->parent(child: *this) : QModelIndex(); }
508
509inline QModelIndex QModelIndex::sibling(int arow, int acolumn) const
510{ return m ? (r == arow && c == acolumn) ? *this : m->sibling(row: arow, column: acolumn, idx: *this) : QModelIndex(); }
511
512inline QModelIndex QModelIndex::siblingAtColumn(int acolumn) const
513{ return m ? (c == acolumn) ? *this : m->sibling(row: r, column: acolumn, idx: *this) : QModelIndex(); }
514
515inline QModelIndex QModelIndex::siblingAtRow(int arow) const
516{ return m ? (r == arow) ? *this : m->sibling(row: arow, column: c, idx: *this) : QModelIndex(); }
517
518inline QVariant QModelIndex::data(int arole) const
519{ return m ? m->data(index: *this, role: arole) : QVariant(); }
520
521inline void QModelIndex::multiData(QModelRoleDataSpan roleDataSpan) const
522{ if (m) m->multiData(index: *this, roleDataSpan); }
523
524inline Qt::ItemFlags QModelIndex::flags() const
525{ return m ? m->flags(index: *this) : Qt::ItemFlags(); }
526
527inline size_t qHash(const QModelIndex &index, size_t seed = 0) noexcept
528{
529#if QT_VERSION >= QT_VERSION_CHECK(7, 0, 0)
530 return qHashMulti(seed, index.row(), index.column(), index.internalId());
531#else
532 return size_t((size_t(index.row()) << 4) + size_t(index.column()) + index.internalId()) ^ seed;
533#endif
534}
535
536QT_END_NAMESPACE
537
538QT_DECL_METATYPE_EXTERN(QModelIndexList, Q_CORE_EXPORT)
539
540#endif // QABSTRACTITEMMODEL_H
541

source code of qtbase/src/corelib/itemmodels/qabstractitemmodel.h