7#include <QtQml/qqmlcontext.h>
8#include <QtQml/qqmlengine.h>
9#include <QtQml/qqmlinfo.h>
11#include <private/qqmlchangeset_p.h>
12#include <private/qqmlglobal_p.h>
13#include <private/qobject_p.h>
14#include <private/qv4qobjectwrapper_p.h>
16#include <QtCore/qcoreapplication.h>
17#include <QtCore/qhash.h>
18#include <QtCore/qlist.h>
19#include <QtCore/qvarlengtharray.h>
25 Q_DECLARE_PUBLIC(QQmlObjectModel)
55 static QObject *
children_at(QQmlListProperty<QObject> *prop, qsizetype index) {
63 static void children_replace(QQmlListProperty<QObject> *prop, qsizetype index, QObject *item) {
69 data->remove(data->children.size() - 1, 1);
74 if (QJSEngine *engine = qjsEngine(q)) {
75 QV4::WriteBarrier::markCustom(engine->handle(), [&](QV4::MarkStack *markStack) {
76 QV4::QObjectWrapper::markWrapper(item, markStack);
81 void insert(
int index, QObject *item) {
83 children.insert(index, Item(item));
84 markNewChild(q, item);
85 for (
int i = index, end = children.size(); i < end; ++i)
87 QQmlChangeSet changeSet;
88 changeSet.insert(index, 1);
89 emit q->modelUpdated(changeSet,
false);
90 emit q->countChanged();
91 emit q->childrenChanged();
97 children.replace(index, Item(item));
98 markNewChild(q, item);
100 QQmlChangeSet changeSet;
101 changeSet.change(index, 1);
102 emit q->modelUpdated(changeSet,
false);
103 emit q->childrenChanged();
106 void move(
int from,
int to,
int n) {
107 Q_Q(QQmlObjectModel);
117 QVarLengthArray<QQmlObjectModelPrivate::Item, 4> store;
118 for (
int i = 0; i < to - from; ++i)
119 store.append(std::move(children[from + n + i]));
120 for (
int i = 0; i < n; ++i)
121 store.append(std::move(children[from + i]));
123 for (
int i = 0, end = store.count(); i < end; ++i) {
124 children[from + i] = std::move(store[i]);
128 QQmlChangeSet changeSet;
129 changeSet.move(from, to, n, ++moveId);
130 emit q->modelUpdated(changeSet,
false);
131 emit q->childrenChanged();
135 Q_Q(QQmlObjectModel);
136 for (
int i = index; i < index + n; ++i)
138 children.erase(children.begin() + index, children.begin() + index + n);
139 for (
int i = index, end = children.size(); i < end; ++i)
141 QQmlChangeSet changeSet;
142 changeSet.remove(index, n);
143 emit q->modelUpdated(changeSet,
false);
144 emit q->countChanged();
145 emit q->childrenChanged();
149 Q_Q(QQmlObjectModel);
150 const auto copy = children;
151 for (
const Item &child : copy)
152 emit q->destroyingItem(child.item());
153 remove(0, children.size());
157 for (
int i = 0; i < children.size(); ++i)
158 if (children.at(i).item() == item)
165 for (
const Item &child : children)
166 QV4::QObjectWrapper::markWrapper(child.item(), markStack);
172 void setIndex(
int child,
int index)
174 if (
auto *attached =
static_cast<QQmlObjectModelAttached *>(
175 qmlAttachedPropertiesObject<QQmlObjectModel>(children.at(child).item()))) {
176 attached->setIndex(index);
180 void setIndex(
int child) { setIndex(child, child); }
181 void clearIndex(
int child) { setIndex(child, -1); }
185 QList<Item> children;
193 Q_ASSERT(QV4::Value::fromHeapObject(that).as<QV4::QObjectWrapper>());
194 QObject *object =
static_cast<QObjectWrapper *>(that)->object();
198 Q_ASSERT(qobject_cast<QQmlObjectModel *>(object));
199 QQmlObjectModelPrivate::get(
static_cast<QQmlObjectModel *>(object))
200 ->markChildren(markStack);
202 QObjectWrapper::markObjects(that, markStack);
218 q_func()))->asReturnedValue();
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
263QQmlObjectModel::QQmlObjectModel(QObject *parent)
264 : QQmlInstanceModel(*(
new QQmlObjectModelPrivate), parent)
268QQmlObjectModel::~QQmlObjectModel() =
default;
271
272
273
274
275
277QQmlListProperty<QObject> QQmlObjectModel::children()
279 Q_D(QQmlObjectModel);
280 return QQmlListProperty<QObject>(
this, d,
281 QQmlObjectModelPrivate::children_append,
282 QQmlObjectModelPrivate::children_count,
283 QQmlObjectModelPrivate::children_at,
284 QQmlObjectModelPrivate::children_clear,
285 QQmlObjectModelPrivate::children_replace,
286 QQmlObjectModelPrivate::children_removeLast);
290
291
292
293
294int QQmlObjectModel::count()
const
296 Q_D(
const QQmlObjectModel);
297 return d->children.size();
300bool QQmlObjectModel::isValid()
const
305QObject *QQmlObjectModel::object(
int index, QQmlIncubator::IncubationMode)
307 Q_D(QQmlObjectModel);
308 QQmlObjectModelPrivate::Item &item = d->children[index];
310 QObject *obj = item.item();
311 if (item.refCount() == 1) {
312 emit initItem(index, obj);
313 emit createdItem(index, obj);
318QQmlInstanceModel::ReleaseFlags QQmlObjectModel::release(QObject *item, ReusableFlag)
320 Q_D(QQmlObjectModel);
321 int idx = d->indexOf(item);
323 if (!d->children[idx].deref())
324 return QQmlInstanceModel::Referenced;
329QVariant QQmlObjectModel::variantValue(
int index,
const QString &role)
331 Q_D(QQmlObjectModel);
332 if (index < 0 || index >= d->children.size())
334 if (QObject *item = d->children.at(index).item())
335 return item->property(role.toUtf8().constData());
339QQmlIncubator::Status QQmlObjectModel::incubationStatus(
int)
341 return QQmlIncubator::Ready;
344int QQmlObjectModel::indexOf(QObject *item, QObject *)
const
346 Q_D(
const QQmlObjectModel);
347 return d->indexOf(item);
350QQmlObjectModelAttached *QQmlObjectModel::qmlAttachedProperties(QObject *obj)
352 return new QQmlObjectModelAttached(obj);
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374QObject *QQmlObjectModel::get(
int index)
const
376 Q_D(
const QQmlObjectModel);
377 if (index < 0 || index >= d->children.size())
379 return d->children.at(index).item();
383
384
385
386
387
388
389
390
391
392
393
394void QQmlObjectModel::append(QObject *object)
396 Q_D(QQmlObjectModel);
397 d->insert(count(), object);
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415void QQmlObjectModel::insert(
int index, QObject *object)
417 Q_D(QQmlObjectModel);
418 if (index < 0 || index > count()) {
419 qmlWarning(
this) << tr(
"insert: index %1 out of range").arg(index);
422 d->insert(index, object);
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440void QQmlObjectModel::move(
int from,
int to,
int n)
442 Q_D(QQmlObjectModel);
443 if (n <= 0 || from == to)
445 if (from < 0 || to < 0 || from + n > count() || to + n > count()) {
446 qmlWarning(
this) << tr(
"move: out of range");
449 d->move(from, to, n);
453
454
455
456
457
458
459
460void QQmlObjectModel::remove(
int index,
int n)
462 Q_D(QQmlObjectModel);
463 if (index < 0 || n <= 0 || index + n > count()) {
464 qmlWarning(
this) << tr(
"remove: indices [%1 - %2] out of range [0 - %3]").arg(index).arg(index+n).arg(count());
471
472
473
474
475
476
477
478void QQmlObjectModel::clear()
480 Q_D(QQmlObjectModel);
484bool QQmlInstanceModel::setRequiredProperty(
int index,
const QString &name,
const QVariant &value)
491 Q_UNREACHABLE_RETURN(
false);
496#include "moc_qqmlobjectmodel_p.cpp"
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)
static QQmlObjectModelPrivate * get(QQmlObjectModel *q)
void remove(int index, int n)
void markChildren(QV4::MarkStack *markStack) const
void markNewChild(QQmlObjectModel *q, QObject *item)
quint64 _q_createJSWrapper(QQmlV4ExecutionEnginePtr engine)
DEFINE_OBJECT_VTABLE(QV4::QQmlObjectModelWrapper)
static void markObjects(Base *that, MarkStack *markStack)