1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the QtQml module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40#ifndef QQMLLIST_H
41#define QQMLLIST_H
42
43#include <QtQml/qtqmlglobal.h>
44#include <QtCore/qlist.h>
45#include <QtCore/qvariant.h>
46
47QT_BEGIN_NAMESPACE
48
49
50class QObject;
51struct QMetaObject;
52
53#ifndef QQMLLISTPROPERTY
54#define QQMLLISTPROPERTY
55template<typename T>
56class QQmlListProperty {
57public:
58 using AppendFunction = void (*)(QQmlListProperty<T> *, T *);
59 using CountFunction = int (*)(QQmlListProperty<T> *);
60 using AtFunction = T *(*)(QQmlListProperty<T> *, int);
61 using ClearFunction = void (*)(QQmlListProperty<T> *);
62 using ReplaceFunction = void (*)(QQmlListProperty<T> *, int, T *);
63 using RemoveLastFunction = void (*)(QQmlListProperty<T> *);
64
65 QQmlListProperty() = default;
66
67#if QT_DEPRECATED_SINCE(5,15)
68 QT_DEPRECATED_X("Use constructor taking QList pointer, and gain improved performance")
69 QQmlListProperty(QObject *o, QList<T *> &list)
70 : object(o), data(&list), append(qlist_append), count(qlist_count), at(qlist_at),
71 clear(qlist_clear), replace(qslow_replace), removeLast(qslow_removeLast)
72 {}
73#endif
74
75 QQmlListProperty(QObject *o, QList<T *> *list)
76 : object(o), data(list), append(qlist_append), count(qlist_count), at(qlist_at),
77 clear(qlist_clear), replace(qlist_replace), removeLast(qlist_removeLast)
78 {}
79
80 QQmlListProperty(QObject *o, void *d, AppendFunction a, CountFunction c, AtFunction t,
81 ClearFunction r )
82 : object(o),
83 data(d),
84 append(a),
85 count(c),
86 at(t),
87 clear(r),
88 replace((a && c && t && r) ? qslow_replace : nullptr),
89 removeLast((a && c && t && r) ? qslow_removeLast : nullptr)
90 {}
91
92 QQmlListProperty(QObject *o, void *d, AppendFunction a, CountFunction c, AtFunction t,
93 ClearFunction r, ReplaceFunction s, RemoveLastFunction p)
94 : object(o),
95 data(d),
96 append(a),
97 count(c),
98 at(t),
99 clear((!r && p && c) ? qslow_clear : r),
100 replace((!s && a && c && t && (r || p)) ? qslow_replace : s),
101 removeLast((!p && a && c && t && r) ? qslow_removeLast : p)
102 {}
103
104 QQmlListProperty(QObject *o, void *d, CountFunction c, AtFunction a)
105 : object(o), data(d), count(c), at(a)
106 {}
107
108 bool operator==(const QQmlListProperty &o) const {
109 return object == o.object &&
110 data == o.data &&
111 append == o.append &&
112 count == o.count &&
113 at == o.at &&
114 clear == o.clear &&
115 replace == o.replace &&
116 removeLast == o.removeLast;
117 }
118
119 QObject *object = nullptr;
120 void *data = nullptr;
121
122 AppendFunction append = nullptr;
123 CountFunction count = nullptr;
124 AtFunction at = nullptr;
125 ClearFunction clear = nullptr;
126 ReplaceFunction replace = nullptr;
127 RemoveLastFunction removeLast = nullptr;
128
129private:
130 static void qlist_append(QQmlListProperty *p, T *v) {
131 reinterpret_cast<QList<T *> *>(p->data)->append(v);
132 }
133 static int qlist_count(QQmlListProperty *p) {
134 return reinterpret_cast<QList<T *> *>(p->data)->count();
135 }
136 static T *qlist_at(QQmlListProperty *p, int idx) {
137 return reinterpret_cast<QList<T *> *>(p->data)->at(idx);
138 }
139 static void qlist_clear(QQmlListProperty *p) {
140 return reinterpret_cast<QList<T *> *>(p->data)->clear();
141 }
142 static void qlist_replace(QQmlListProperty *p, int idx, T *v) {
143 return reinterpret_cast<QList<T *> *>(p->data)->replace(idx, v);
144 }
145 static void qlist_removeLast(QQmlListProperty *p) {
146 return reinterpret_cast<QList<T *> *>(p->data)->removeLast();
147 }
148
149 static void qslow_replace(QQmlListProperty<T> *list, int idx, T *v)
150 {
151 const int length = list->count(list);
152 if (idx < 0 || idx >= length)
153 return;
154
155 QVector<T *> stash;
156 if (list->clear != qslow_clear) {
157 stash.reserve(length);
158 for (int i = 0; i < length; ++i)
159 stash.append(i == idx ? v : list->at(list, i));
160 list->clear(list);
161 for (T *item : qAsConst(stash))
162 list->append(list, item);
163 } else {
164 stash.reserve(length - idx - 1);
165 for (int i = length - 1; i > idx; --i) {
166 stash.append(list->at(list, i));
167 list->removeLast(list);
168 }
169 list->removeLast(list);
170 list->append(list, v);
171 while (!stash.isEmpty())
172 list->append(list, stash.takeLast());
173 }
174 }
175
176 static void qslow_clear(QQmlListProperty<T> *list)
177 {
178 for (int i = 0, end = list->count(list); i < end; ++i)
179 list->removeLast(list);
180 }
181
182 static void qslow_removeLast(QQmlListProperty<T> *list)
183 {
184 const int length = list->count(list) - 1;
185 if (length < 0)
186 return;
187 QVector<T *> stash;
188 stash.reserve(length);
189 for (int i = 0; i < length; ++i)
190 stash.append(list->at(list, i));
191 list->clear(list);
192 for (T *item : qAsConst(stash))
193 list->append(list, item);
194 }
195};
196#endif
197
198class QQmlEngine;
199class QQmlListReferencePrivate;
200class Q_QML_EXPORT QQmlListReference
201{
202public:
203 QQmlListReference();
204 QQmlListReference(QObject *, const char *property, QQmlEngine * = nullptr);
205 QQmlListReference(const QQmlListReference &);
206 QQmlListReference &operator=(const QQmlListReference &);
207 ~QQmlListReference();
208
209 bool isValid() const;
210
211 QObject *object() const;
212 const QMetaObject *listElementType() const;
213
214 bool canAppend() const;
215 bool canAt() const;
216 bool canClear() const;
217 bool canCount() const;
218 bool canReplace() const;
219 bool canRemoveLast() const;
220
221 bool isManipulable() const;
222 bool isReadable() const;
223
224 bool append(QObject *) const;
225 QObject *at(int) const;
226 bool clear() const;
227 int count() const;
228 bool replace(int, QObject *) const;
229 bool removeLast() const;
230
231private:
232 friend class QQmlListReferencePrivate;
233 QQmlListReferencePrivate* d;
234};
235
236QT_END_NAMESPACE
237
238Q_DECLARE_METATYPE(QQmlListReference)
239
240#endif // QQMLLIST_H
241

source code of qtdeclarative/src/qml/qml/qqmllist.h