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