Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qqmlobjectmodel.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 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 "qqmlobjectmodel_p.h"
5
6#include <QtCore/qcoreapplication.h>
7#include <QtQml/qqmlcontext.h>
8#include <QtQml/qqmlengine.h>
9#include <QtQml/qqmlinfo.h>
10
11#include <private/qqmlchangeset_p.h>
12#include <private/qqmlglobal_p.h>
13#include <private/qobject_p.h>
14#include <private/qpodvector_p.h>
15
16#include <QtCore/qhash.h>
17#include <QtCore/qlist.h>
18
20
21QHash<QObject*, QQmlObjectModelAttached*> QQmlObjectModelAttached::attachedProperties;
22
23
25{
26 Q_DECLARE_PUBLIC(QQmlObjectModel)
27public:
28 class Item {
29 public:
30 Item(QObject *i) : item(i), ref(0) {}
31
32 void addRef() { ++ref; }
33 bool deref() { return --ref == 0; }
34
36 int ref;
37 };
38
40
41 static void children_append(QQmlListProperty<QObject> *prop, QObject *item) {
42 qsizetype index = static_cast<QQmlObjectModelPrivate *>(prop->data)->children.size();
43 static_cast<QQmlObjectModelPrivate *>(prop->data)->insert(index, item);
44 }
45
46 static qsizetype children_count(QQmlListProperty<QObject> *prop) {
47 return static_cast<QQmlObjectModelPrivate *>(prop->data)->children.size();
48 }
49
50 static QObject *children_at(QQmlListProperty<QObject> *prop, qsizetype index) {
51 return static_cast<QQmlObjectModelPrivate *>(prop->data)->children.at(index).item;
52 }
53
54 static void children_clear(QQmlListProperty<QObject> *prop) {
55 static_cast<QQmlObjectModelPrivate *>(prop->data)->clear();
56 }
57
58 static void children_replace(QQmlListProperty<QObject> *prop, qsizetype index, QObject *item) {
59 static_cast<QQmlObjectModelPrivate *>(prop->data)->replace(index, item);
60 }
61
62 static void children_removeLast(QQmlListProperty<QObject> *prop) {
63 auto data = static_cast<QQmlObjectModelPrivate *>(prop->data);
64 data->remove(data->children.size() - 1, 1);
65 }
66
67 void insert(int index, QObject *item) {
68 Q_Q(QQmlObjectModel);
69 children.insert(index, Item(item));
70 for (int i = index; i < children.size(); ++i) {
72 attached->setIndex(i);
73 }
74 QQmlChangeSet changeSet;
75 changeSet.insert(index, 1);
76 emit q->modelUpdated(changeSet, false);
77 emit q->countChanged();
78 emit q->childrenChanged();
79 }
80
81 void replace(int index, QObject *item) {
82 Q_Q(QQmlObjectModel);
83 auto *attached = QQmlObjectModelAttached::properties(children.at(index).item);
84 attached->setIndex(-1);
85 children.replace(index, Item(item));
87 QQmlChangeSet changeSet;
88 changeSet.change(index, 1);
89 emit q->modelUpdated(changeSet, false);
90 emit q->childrenChanged();
91 }
92
93 void move(int from, int to, int n) {
94 Q_Q(QQmlObjectModel);
95 if (from > to) {
96 // Only move forwards - flip if backwards moving
97 int tfrom = from;
98 int tto = to;
99 from = tto;
100 to = tto+n;
101 n = tfrom-tto;
102 }
103
104 QPODVector<QQmlObjectModelPrivate::Item, 4> store;
105 for (int i = 0; i < to - from; ++i)
106 store.append(children[from + n + i]);
107 for (int i = 0; i < n; ++i)
108 store.append(children[from + i]);
109
110 for (int i = 0; i < store.count(); ++i) {
111 children[from + i] = store[i];
113 attached->setIndex(from + i);
114 }
115
116 QQmlChangeSet changeSet;
117 changeSet.move(from, to, n, ++moveId);
118 emit q->modelUpdated(changeSet, false);
119 emit q->childrenChanged();
120 }
121
122 void remove(int index, int n) {
123 Q_Q(QQmlObjectModel);
124 for (int i = index; i < index + n; ++i) {
126 attached->setIndex(-1);
127 }
128 children.erase(children.begin() + index, children.begin() + index + n);
129 for (int i = index; i < children.size(); ++i) {
131 attached->setIndex(i);
132 }
133 QQmlChangeSet changeSet;
134 changeSet.remove(index, n);
135 emit q->modelUpdated(changeSet, false);
136 emit q->countChanged();
137 emit q->childrenChanged();
138 }
139
140 void clear() {
141 Q_Q(QQmlObjectModel);
142 const auto copy = children;
143 for (const Item &child : copy)
144 emit q->destroyingItem(child.item);
145 remove(0, children.size());
146 }
147
148 int indexOf(QObject *item) const {
149 for (int i = 0; i < children.size(); ++i)
150 if (children.at(i).item == item)
151 return i;
152 return -1;
153 }
154
156 QList<Item> children;
157};
158
160
161
206
214QQmlListProperty<QObject> QQmlObjectModel::children()
215{
216 Q_D(QQmlObjectModel);
217 return QQmlListProperty<QObject>(this, d,
224}
225
232{
233 Q_D(const QQmlObjectModel);
234 return d->children.size();
235}
236
238{
239 return true;
240}
241
243{
244 Q_D(QQmlObjectModel);
246 item.addRef();
247 if (item.ref == 1) {
248 emit initItem(index, item.item);
249 emit createdItem(index, item.item);
250 }
251 return item.item;
252}
253
254QQmlInstanceModel::ReleaseFlags QQmlObjectModel::release(QObject *item, ReusableFlag)
255{
256 Q_D(QQmlObjectModel);
257 int idx = d->indexOf(item);
258 if (idx >= 0) {
259 if (!d->children[idx].deref())
261 }
262 return {};
263}
264
266{
267 Q_D(QQmlObjectModel);
268 if (index < 0 || index >= d->children.size())
269 return QString();
270 return d->children.at(index).item->property(role.toUtf8().constData());
271}
272
277
279{
280 Q_D(const QQmlObjectModel);
281 return d->indexOf(item);
282}
283
288
308QObject *QQmlObjectModel::get(int index) const
309{
310 Q_D(const QQmlObjectModel);
311 if (index < 0 || index >= d->children.size())
312 return nullptr;
313 return d->children.at(index).item;
314}
315
328void QQmlObjectModel::append(QObject *object)
329{
330 Q_D(QQmlObjectModel);
331 d->insert(count(), object);
332}
333
349void QQmlObjectModel::insert(int index, QObject *object)
350{
351 Q_D(QQmlObjectModel);
352 if (index < 0 || index > count()) {
353 qmlWarning(this) << tr("insert: index %1 out of range").arg(index);
354 return;
355 }
356 d->insert(index, object);
357}
358
374void QQmlObjectModel::move(int from, int to, int n)
375{
376 Q_D(QQmlObjectModel);
377 if (n <= 0 || from == to)
378 return;
379 if (from < 0 || to < 0 || from + n > count() || to + n > count()) {
380 qmlWarning(this) << tr("move: out of range");
381 return;
382 }
383 d->move(from, to, n);
384}
385
394void QQmlObjectModel::remove(int index, int n)
395{
396 Q_D(QQmlObjectModel);
397 if (index < 0 || n <= 0 || index + n > count()) {
398 qmlWarning(this) << tr("remove: indices [%1 - %2] out of range [0 - %3]").arg(index).arg(index+n).arg(count());
399 return;
400 }
401 d->remove(index, n);
402}
403
412void QQmlObjectModel::clear()
413{
414 Q_D(QQmlObjectModel);
415 d->clear();
416}
417
419{
421 Q_UNUSED(name);
423 // The view should not call this function, unless
424 // it's actually handled in a subclass.
425 Q_UNREACHABLE_RETURN(false);
426}
427
429
430#include "moc_qqmlobjectmodel_p.cpp"
const char * constData() const noexcept
Returns a pointer to the const data stored in the byte array.
Definition qbytearray.h:124
\inmodule QtCore
Definition qobject.h:103
The QQmlChangeSet class stores an ordered list of notifications about changes to a linear data set.
void remove(int index, int count)
Appends a notification that count items were removed at index.
void change(int index, int count)
Appends a notification that count items were changed at index.
void move(int from, int to, int count, int moveId)
Appends a notification that count items were moved from one index to another.
void insert(int index, int count)
Appends a notification that count items were inserted at index.
IncubationMode
Specifies the mode the incubator operates in.
Status
Specifies the status of the QQmlIncubator.
void createdItem(int index, QObject *object)
virtual bool setRequiredProperty(int index, const QString &name, const QVariant &value)
void initItem(int index, QObject *object)
static QHash< QObject *, QQmlObjectModelAttached * > attachedProperties
static QQmlObjectModelAttached * properties(QObject *obj)
static void children_replace(QQmlListProperty< QObject > *prop, qsizetype index, QObject *item)
static QObject * children_at(QQmlListProperty< QObject > *prop, qsizetype index)
int indexOf(QObject *item) const
void move(int from, int to, int n)
void replace(int index, QObject *item)
static void children_append(QQmlListProperty< QObject > *prop, QObject *item)
static void children_clear(QQmlListProperty< QObject > *prop)
static qsizetype children_count(QQmlListProperty< QObject > *prop)
static void children_removeLast(QQmlListProperty< QObject > *prop)
void insert(int index, QObject *item)
void remove(int index, int n)
QQmlListProperty< QObject > children
\qmlattachedproperty int QtQml.Models::ObjectModel::index This attached property holds the index of t...
static QQmlObjectModelAttached * qmlAttachedProperties(QObject *obj)
int count() const override
\qmlproperty int QtQml.Models::ObjectModel::count
QVariant variantValue(int index, const QString &role) override
QQmlObjectModel(QObject *parent=nullptr)
\qmltype ObjectModel \instantiates QQmlObjectModel \inqmlmodule QtQml.Models
QQmlIncubator::Status incubationStatus(int index) override
bool isValid() const override
ReleaseFlags release(QObject *object, ReusableFlag reusable=NotReusable) override
int indexOf(QObject *object, QObject *objectContext) const override
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
QByteArray toUtf8() const &
Definition qstring.h:634
\inmodule QtCore
Definition qvariant.h:65
Combined button and popup list for selecting options.
static jboolean copy(JNIEnv *, jobject)
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
GLuint index
[2]
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLint ref
GLuint name
GLfloat n
GLhandleARB obj
[2]
GLdouble GLdouble GLdouble GLdouble q
Definition qopenglext.h:259
Q_QML_EXPORT QQmlInfo qmlWarning(const QObject *me)
#define tr(X)
#define emit
#define Q_UNUSED(x)
@ Q_PRIMITIVE_TYPE
Definition qtypeinfo.h:157
#define Q_DECLARE_TYPEINFO(TYPE, FLAGS)
Definition qtypeinfo.h:180
ptrdiff_t qsizetype
Definition qtypes.h:165
unsigned int uint
Definition qtypes.h:34
QGraphicsItem * item
QLayoutItem * child
[0]