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
262
264QQmlObjectModel::QQmlObjectModel(QObject *parent)
265 : QQmlInstanceModel(*(
new QQmlObjectModelPrivate), parent)
269QQmlObjectModel::~QQmlObjectModel() =
default;
272
273
274
275
276
278QQmlListProperty<QObject> QQmlObjectModel::children()
280 Q_D(QQmlObjectModel);
281 return QQmlListProperty<QObject>(
this, d,
282 QQmlObjectModelPrivate::children_append,
283 QQmlObjectModelPrivate::children_count,
284 QQmlObjectModelPrivate::children_at,
285 QQmlObjectModelPrivate::children_clear,
286 QQmlObjectModelPrivate::children_replace,
287 QQmlObjectModelPrivate::children_removeLast);
291
292
293
294
295int QQmlObjectModel::count()
const
297 Q_D(
const QQmlObjectModel);
298 return d->children.size();
301bool QQmlObjectModel::isValid()
const
306QObject *QQmlObjectModel::object(
int index, QQmlIncubator::IncubationMode)
308 Q_D(QQmlObjectModel);
309 QQmlObjectModelPrivate::Item &item = d->children[index];
311 QObject *obj = item.item();
312 if (item.refCount() == 1) {
313 emit initItem(index, obj);
314 emit createdItem(index, obj);
319QQmlInstanceModel::ReleaseFlags QQmlObjectModel::release(QObject *item, ReusableFlag)
321 Q_D(QQmlObjectModel);
322 int idx = d->indexOf(item);
324 if (!d->children[idx].deref())
325 return QQmlInstanceModel::Referenced;
330QVariant QQmlObjectModel::variantValue(
int index,
const QString &role)
332 Q_D(QQmlObjectModel);
333 if (index < 0 || index >= d->children.size())
335 if (QObject *item = d->children.at(index).item())
336 return item->property(role.toUtf8().constData());
340QQmlIncubator::Status QQmlObjectModel::incubationStatus(
int)
342 return QQmlIncubator::Ready;
345int QQmlObjectModel::indexOf(QObject *item, QObject *)
const
347 Q_D(
const QQmlObjectModel);
348 return d->indexOf(item);
351QQmlObjectModelAttached *QQmlObjectModel::qmlAttachedProperties(QObject *obj)
353 return new QQmlObjectModelAttached(obj);
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375QObject *QQmlObjectModel::get(
int index)
const
377 Q_D(
const QQmlObjectModel);
378 if (index < 0 || index >= d->children.size())
380 return d->children.at(index).item();
384
385
386
387
388
389
390
391
392
393
394
395void QQmlObjectModel::append(QObject *object)
397 Q_D(QQmlObjectModel);
398 d->insert(count(), object);
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416void QQmlObjectModel::insert(
int index, QObject *object)
418 Q_D(QQmlObjectModel);
419 if (index < 0 || index > count()) {
420 qmlWarning(
this) << tr(
"insert: index %1 out of range").arg(index);
423 d->insert(index, object);
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441void QQmlObjectModel::move(
int from,
int to,
int n)
443 Q_D(QQmlObjectModel);
444 if (n <= 0 || from == to)
446 if (from < 0 || to < 0 || from + n > count() || to + n > count()) {
447 qmlWarning(
this) << tr(
"move: out of range");
450 d->move(from, to, n);
454
455
456
457
458
459
460
461void QQmlObjectModel::remove(
int index,
int n)
463 Q_D(QQmlObjectModel);
464 if (index < 0 || n <= 0 || index + n > count()) {
465 qmlWarning(
this) << tr(
"remove: indices [%1 - %2] out of range [0 - %3]").arg(index).arg(index+n).arg(count());
472
473
474
475
476
477
478
479void QQmlObjectModel::clear()
481 Q_D(QQmlObjectModel);
485bool QQmlInstanceModel::setRequiredProperty(
int index,
const QString &name,
const QVariant &value)
492 Q_UNREACHABLE_RETURN(
false);
497#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)
Combined button and popup list for selecting options.
DEFINE_OBJECT_VTABLE(QV4::QQmlObjectModelWrapper)
static void markObjects(Base *that, MarkStack *markStack)