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
qqmlinstantiator.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 Research In Motion.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
6#include <QtQml/QQmlContext>
7#include <QtQml/QQmlComponent>
8#include <QtQml/QQmlInfo>
9#include <QtQml/QQmlError>
10#include <QtQmlModels/private/qqmlobjectmodel_p.h>
11#if QT_CONFIG(qml_delegate_model)
12#include <QtQmlModels/private/qqmldelegatemodel_p.h>
13#endif
14
16
18 : componentComplete(true)
19 , effectiveReset(false)
20 , active(true)
21 , async(false)
22#if QT_CONFIG(qml_delegate_model)
23 , ownModel(false)
24#endif
25 , requestedIndex(-1)
26 , model(QVariant(1))
27 , instanceModel(nullptr)
28 , delegate(nullptr)
29{
30}
31
33{
35 if (!instanceModel)
36 return;
37
38 if (objects.isEmpty())
39 return;
40
41 for (int i=0; i < objects.size(); i++) {
42 QObject *object = objects[i];
43 emit q->objectRemoved(i, object);
44 instanceModel->release(object);
45 if (object && object->parent() == q)
46 object->setParent(nullptr);
47 }
48
49 objects.clear();
50 emit q->objectChanged();
51}
52
60
61
63{
66 return;
67
68 int prevCount = q->count();
69
70 clear();
71
73 if (prevCount)
74 q->countChanged();
75 return;
76 }
77
78 for (int i = 0; i < instanceModel->count(); i++) {
79 QObject *object = modelObject(i, async);
80 // If the item was already created we won't get a createdItem
81 if (object)
82 _q_createdItem(i, object);
83 }
84 if (q->count() != prevCount)
85 q->countChanged();
86}
87
89{
91 if (objects.contains(item)) //Case when it was created synchronously in regenerate
92 return;
93 if (requestedIndex != idx) // Asynchronous creation, reference the object
95 if (!item->parent())
96 item->setParent(q);
97 if (objects.size() < idx + 1) {
98 int modelCount = instanceModel->count();
99 if (objects.capacity() < modelCount)
100 objects.reserve(modelCount);
101 objects.resize(idx + 1);
102 }
103 if (QObject *o = objects.at(idx))
105 objects.replace(idx, item);
106 if (objects.size() == 1)
107 q->objectChanged();
108 q->objectAdded(idx, item);
109}
110
112{
113 Q_Q(QQmlInstantiator);
114
116 return;
117
118 if (reset) {
119 regenerate();
120 if (changeSet.difference() != 0)
121 q->countChanged();
122 return;
123 }
124
125 int difference = 0;
126 QHash<int, QVector<QPointer<QObject> > > moved;
127 const QVector<QQmlChangeSet::Change> &removes = changeSet.removes();
128 for (const QQmlChangeSet::Change &remove : removes) {
129 int index = qMin(remove.index, objects.size());
130 int count = qMin(remove.index + remove.count, objects.size()) - index;
131 if (remove.isMove()) {
132 moved.insert(remove.moveId, objects.mid(index, count));
133 objects.erase(
134 objects.begin() + index,
135 objects.begin() + index + count);
136 } else while (count--) {
137 QObject *obj = objects.at(index);
138 objects.remove(index);
139 q->objectRemoved(index, obj);
140 if (obj)
142 }
143
144 difference -= remove.count;
145 }
146
147 const QVector<QQmlChangeSet::Change> &inserts = changeSet.inserts();
148 for (const QQmlChangeSet::Change &insert : inserts) {
149 int index = qMin(insert.index, objects.size());
150 if (insert.isMove()) {
151 QVector<QPointer<QObject> > movedObjects = moved.value(insert.moveId);
152 objects = objects.mid(0, index) + movedObjects + objects.mid(index);
153 } else {
154 if (insert.index <= objects.size())
155 objects.insert(insert.index, insert.count, nullptr);
156 for (int i = 0; i < insert.count; ++i) {
157 int modelIndex = index + i;
158 QObject* obj = modelObject(modelIndex, async);
159 if (obj)
160 _q_createdItem(modelIndex, obj);
161 }
162 }
163 difference += insert.count;
164 }
165
166 if (difference != 0)
167 q->countChanged();
168}
169
170#if QT_CONFIG(qml_delegate_model)
171void QQmlInstantiatorPrivate::makeModel()
172{
173 Q_Q(QQmlInstantiator);
174 QQmlDelegateModel* delegateModel = new QQmlDelegateModel(qmlContext(q), q);
175 instanceModel = delegateModel;
176 ownModel = true;
177 delegateModel->setDelegate(delegate);
178 delegateModel->classBegin(); //Pretend it was made in QML
180 delegateModel->componentComplete();
181}
182#endif
183
184
207
209{
210 Q_D(QQmlInstantiator);
211 d->clear();
212}
213
242{
243 Q_D(const QQmlInstantiator);
244 return d->active;
245}
246
248{
249 Q_D(QQmlInstantiator);
250 if (newVal == d->active)
251 return;
252 d->active = newVal;
254 d->regenerate();
255}
256
269{
270 Q_D(const QQmlInstantiator);
271 return d->async;
272}
273
275{
276 Q_D(QQmlInstantiator);
277 if (newVal == d->async)
278 return;
279 d->async = newVal;
281}
282
283
291{
292 Q_D(const QQmlInstantiator);
293 return d->objects.size();
294}
295
310{
311 Q_D(QQmlInstantiator);
312 return d->delegate;
313}
314
316{
317 Q_D(QQmlInstantiator);
318 if (c == d->delegate)
319 return;
320
321 d->delegate = c;
323
324#if QT_CONFIG(qml_delegate_model)
325 if (!d->ownModel)
326 return;
327
328 if (QQmlDelegateModel *dModel = qobject_cast<QQmlDelegateModel*>(d->instanceModel))
329 dModel->setDelegate(c);
330 if (d->componentComplete)
331 d->regenerate();
332#endif
333}
334
355{
356 Q_D(const QQmlInstantiator);
357 return d->model;
358}
359
361{
362 Q_D(QQmlInstantiator);
363 if (d->model == v)
364 return;
365
366 d->model = v;
367 //Don't actually set model until componentComplete in case it wants to create its delegates immediately
368 if (!d->componentComplete)
369 return;
370
371 QQmlInstanceModel *prevModel = d->instanceModel;
372 QObject *object = qvariant_cast<QObject*>(v);
373 QQmlInstanceModel *vim = nullptr;
374 if (object && (vim = qobject_cast<QQmlInstanceModel *>(object))) {
375#if QT_CONFIG(qml_delegate_model)
376 if (d->ownModel) {
377 delete d->instanceModel;
378 prevModel = nullptr;
379 d->ownModel = false;
380 }
381#endif
382 d->instanceModel = vim;
383#if QT_CONFIG(qml_delegate_model)
384 } else if (v != QVariant(0)){
385 if (!d->ownModel)
386 d->makeModel();
387
388 if (QQmlDelegateModel *dataModel = qobject_cast<QQmlDelegateModel *>(d->instanceModel)) {
389 d->effectiveReset = true;
390 dataModel->setModel(v);
391 d->effectiveReset = false;
392 }
393#endif
394 }
395
396 if (d->instanceModel != prevModel) {
397 if (prevModel) {
398 disconnect(prevModel, SIGNAL(modelUpdated(QQmlChangeSet,bool)),
399 this, SLOT(_q_modelUpdated(QQmlChangeSet,bool)));
400 disconnect(prevModel, SIGNAL(createdItem(int,QObject*)), this, SLOT(_q_createdItem(int,QObject*)));
401 //disconnect(prevModel, SIGNAL(initItem(int,QObject*)), this, SLOT(initItem(int,QObject*)));
402 }
403
404 if (d->instanceModel) {
405 connect(d->instanceModel, SIGNAL(modelUpdated(QQmlChangeSet,bool)),
406 this, SLOT(_q_modelUpdated(QQmlChangeSet,bool)));
407 connect(d->instanceModel, SIGNAL(createdItem(int,QObject*)), this, SLOT(_q_createdItem(int,QObject*)));
408 //connect(d->instanceModel, SIGNAL(initItem(int,QObject*)), this, SLOT(initItem(int,QObject*)));
409 }
410 }
411
412 d->regenerate();
414}
415
423{
424 Q_D(const QQmlInstantiator);
425 if (d->objects.size())
426 return d->objects[0];
427 return nullptr;
428}
429
436{
437 Q_D(const QQmlInstantiator);
438 if (index >= 0 && index < d->objects.size())
439 return d->objects[index];
440 return nullptr;
441}
442
447{
448 Q_D(QQmlInstantiator);
449 d->componentComplete = false;
450}
451
456{
457 Q_D(QQmlInstantiator);
458 d->componentComplete = true;
459#if QT_CONFIG(qml_delegate_model)
460 if (d->ownModel) {
461 static_cast<QQmlDelegateModel*>(d->instanceModel)->componentComplete();
462 d->regenerate();
463 } else
464#endif
465 {
466 QVariant realModel = d->model;
467 d->model = QVariant(0);
468 setModel(realModel); //If realModel == d->model this won't do anything, but that's fine since the model's 0
469 //setModel calls regenerate
470 }
471}
472
474
475#include "moc_qqmlinstantiator_p.cpp"
\inmodule QtCore
Definition qobject.h:103
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
Definition qobject.cpp:2960
The QQmlChangeSet class stores an ordered list of notifications about changes to a linear data set.
const QVector< Change > & removes() const
int difference() const
const QVector< Change > & inserts() const
The QQmlComponent class encapsulates a QML component definition.
void componentComplete() override
Invoked after the root component that caused this instantiation has completed construction.
void setDelegate(QQmlComponent *)
void classBegin() override
Invoked after class creation, but before any properties have been set.
virtual bool isValid() const =0
virtual ReleaseFlags release(QObject *object, ReusableFlag reusableFlag=NotReusable)=0
QQmlInstanceModel * instanceModel
void _q_createdItem(int, QObject *)
QObject * modelObject(int index, bool async)
void _q_modelUpdated(const QQmlChangeSet &, bool)
QVector< QPointer< QObject > > objects
QQmlComponent * delegate
\qmlproperty QtQml::Component QtQml.Models::Instantiator::delegate \qmldefault
void classBegin() override
void setDelegate(QQmlComponent *c)
bool isActive() const
\qmlsignal QtQml.Models::Instantiator::objectAdded(int index, QtObject object)
void setAsync(bool newVal)
QQmlInstantiator(QObject *parent=nullptr)
\qmltype Instantiator \instantiates QQmlInstantiator \inqmlmodule QtQml.Models
void setModel(const QVariant &v)
bool isAsync() const
\qmlproperty bool QtQml.Models::Instantiator::asynchronous
void asynchronousChanged()
void setActive(bool newVal)
void delegateChanged()
Q_INVOKABLE QObject * objectAt(int index) const
\qmlmethod QtObject QtQml.Models::Instantiator::objectAt(int index)
void componentComplete() override
\inmodule QtCore
Definition qvariant.h:65
cache insert(employee->id(), employee)
Combined button and popup list for selecting options.
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter int const void return DBusMessageIter DBusMessageIter return DBusMessageIter void DBusMessageIter void int return DBusMessage DBusMessageIter return DBusMessageIter return DBusMessageIter DBusMessageIter const char const char const char const char return DBusMessage return DBusMessage const char return DBusMessage dbus_bool_t return DBusMessage dbus_uint32_t return DBusMessage void
constexpr const T & qMin(const T &a, const T &b)
Definition qminmax.h:40
#define SLOT(a)
Definition qobjectdefs.h:52
#define SIGNAL(a)
Definition qobjectdefs.h:53
GLsizei const GLfloat * v
[13]
GLuint index
[2]
GLenum GLenum GLsizei count
GLuint object
[3]
GLhandleARB obj
[2]
GLboolean reset
const GLubyte * c
GLdouble GLdouble GLdouble GLdouble q
Definition qopenglext.h:259
QQmlContext * qmlContext(const QObject *obj)
Definition qqml.cpp:75
#define QT_CONFIG(feature)
#define emit
QSqlQueryModel * model
[16]
if(qFloatDistance(a, b)<(1<< 7))
[0]
settings remove("monkey")
QObject::connect nullptr
myObject disconnect()
[26]
QGraphicsItem * item