1 | // Copyright (C) 2018 The Qt Company Ltd. |
---|---|
2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only |
3 | |
4 | #include "qqmladaptormodel_p.h" |
5 | |
6 | #include <private/qqmldmabstractitemmodeldata_p.h> |
7 | #include <private/qqmldmlistaccessordata_p.h> |
8 | #include <private/qqmldmobjectdata_p.h> |
9 | |
10 | QT_BEGIN_NAMESPACE |
11 | |
12 | QQmlAdaptorModel::Accessors::~Accessors() |
13 | { |
14 | } |
15 | |
16 | QQmlAdaptorModel::QQmlAdaptorModel() |
17 | : QQmlGuard<QObject>(QQmlAdaptorModel::objectDestroyedImpl, nullptr) |
18 | , accessors(&m_nullAccessors) |
19 | { |
20 | } |
21 | |
22 | QQmlAdaptorModel::~QQmlAdaptorModel() |
23 | { |
24 | accessors->cleanup(*this); |
25 | } |
26 | |
27 | void QQmlAdaptorModel::setModel(const QVariant &variant) |
28 | { |
29 | accessors->cleanup(*this); |
30 | |
31 | // Don't use variant anymore after this. list may transform it. |
32 | list.setList(variant); |
33 | |
34 | modelStrongReference.clear(); |
35 | |
36 | if (QObject *object = qvariant_cast<QObject *>(v: list.list())) { |
37 | if (QQmlData *ddata = QQmlData::get(object)) |
38 | modelStrongReference = ddata->jsWrapper; |
39 | setObject(object); |
40 | if (qobject_cast<QAbstractItemModel *>(object)) |
41 | accessors = new VDMAbstractItemModelDataType(this); |
42 | else |
43 | accessors = new VDMObjectDelegateDataType; |
44 | } else if (list.type() == QQmlListAccessor::ListProperty) { |
45 | auto object = static_cast<const QQmlListReference *>(list.list().constData())->object(); |
46 | if (QQmlData *ddata = QQmlData::get(object)) |
47 | modelStrongReference = ddata->jsWrapper; |
48 | setObject(object); |
49 | accessors = new VDMObjectDelegateDataType; |
50 | } else if (list.type() == QQmlListAccessor::ObjectList) { |
51 | setObject(nullptr); |
52 | accessors = new VDMObjectDelegateDataType; |
53 | } else if (list.type() != QQmlListAccessor::Invalid |
54 | && list.type() != QQmlListAccessor::Instance) { // Null QObject |
55 | setObject(nullptr); |
56 | accessors = new VDMListDelegateDataType(this); |
57 | } else { |
58 | setObject(nullptr); |
59 | accessors = &m_nullAccessors; |
60 | } |
61 | } |
62 | |
63 | void QQmlAdaptorModel::invalidateModel() |
64 | { |
65 | accessors->cleanup(*this); |
66 | accessors = &m_nullAccessors; |
67 | // Don't clear the model object as we still need the guard to clear the list variant if the |
68 | // object is destroyed. |
69 | } |
70 | |
71 | bool QQmlAdaptorModel::isValid() const |
72 | { |
73 | return accessors != &m_nullAccessors; |
74 | } |
75 | |
76 | int QQmlAdaptorModel::count() const |
77 | { |
78 | return rowCount() * columnCount(); |
79 | } |
80 | |
81 | int QQmlAdaptorModel::rowCount() const |
82 | { |
83 | return qMax(a: 0, b: accessors->rowCount(*this)); |
84 | } |
85 | |
86 | int QQmlAdaptorModel::columnCount() const |
87 | { |
88 | return qMax(a: 0, b: accessors->columnCount(*this)); |
89 | } |
90 | |
91 | int QQmlAdaptorModel::rowAt(int index) const |
92 | { |
93 | int count = rowCount(); |
94 | return count <= 0 ? -1 : index % count; |
95 | } |
96 | |
97 | int QQmlAdaptorModel::columnAt(int index) const |
98 | { |
99 | int count = rowCount(); |
100 | return count <= 0 ? -1 : index / count; |
101 | } |
102 | |
103 | int QQmlAdaptorModel::indexAt(int row, int column) const |
104 | { |
105 | return column * rowCount() + row; |
106 | } |
107 | |
108 | void QQmlAdaptorModel::useImportVersion(QTypeRevision revision) |
109 | { |
110 | modelItemRevision = revision; |
111 | } |
112 | |
113 | void QQmlAdaptorModel::objectDestroyedImpl(QQmlGuardImpl *guard) |
114 | { |
115 | auto This = static_cast<QQmlAdaptorModel *>(guard); |
116 | This->setModel(QVariant()); |
117 | } |
118 | |
119 | QT_END_NAMESPACE |
120 |