6#include <private/qqmlopenmetaobject_p.h>
7#include <private/qqmljsast_p.h>
8#include <private/qqmljsengine_p.h>
9#include <private/qjsvalue_p.h>
11#include <private/qqmlcustomparser_p.h>
12#include <private/qqmlengine_p.h>
13#include <private/qqmlnotifier_p.h>
15#include <private/qv4object_p.h>
16#include <private/qv4dateobject_p.h>
17#include <private/qv4urlobject_p.h>
18#include <private/qv4objectiterator_p.h>
19#include <private/qv4alloca_p.h>
20#include <private/qv4lookup_p.h>
21#include <private/qv4qmlcontext_p.h>
26#include <QtCore/qdebug.h>
27#include <QtCore/qstack.h>
28#include <QXmlStreamReader>
29#include <QtCore/qdatetime.h>
30#include <QScopedValueRollback>
44 for (
size_t i=0 ;
i <
sizeof(T) ; ++
i) {
54 static const QString roleTypeNames[] = {
61 return roleTypeNames[
t];
91 return createRole(qkey,
type);
96 const int dataSizes[] = {
107 const int dataAlignments[] = {
126 r->subLayout =
nullptr;
130 int dataAlignment = dataAlignments[
type];
132 int dataOffset = (currentBlockOffset + dataAlignment-1) & ~(dataAlignment-1);
134 r->blockIndex = ++currentBlock;
138 r->blockIndex = currentBlock;
139 r->blockOffset = dataOffset;
140 currentBlockOffset = dataOffset +
dataSize;
143 int roleIndex = roles.size();
144 r->index = roleIndex;
147 roleHash.insert(
key,
r);
154 const int otherRolesCount =
other->roles.size();
155 roles.reserve(otherRolesCount);
156 for (
int i=0 ;
i < otherRolesCount; ++
i) {
159 roleHash.insert(role->
name, role);
161 currentBlockOffset =
other->currentBlockOffset;
162 currentBlock =
other->currentBlock;
172 int roleOffset =
target->roles.size();
173 int newRoleCount =
src->roles.size() - roleOffset;
175 for (
int i=0 ;
i < newRoleCount ; ++
i) {
177 target->roles.append(role);
181 target->currentBlockOffset =
src->currentBlockOffset;
182 target->currentBlock =
src->currentBlock;
192 if (
other->subLayout)
207 switch (
data.userType()) {
216 if (
data.userType() == qMetaTypeId<QJSValue>() &&
220 }
else if (
data.userType() == qMetaTypeId<const QV4::CompiledData::Binding*>()
235 qmlWarning(
nullptr) <<
"Can't create role for unsupported data type";
272 arrayData = dataPointer->
d_ptr();
274 stringSize = mutableString.
size();
282 this->binding = binding;
305void StringOrTranslation::clear()
307 if (arrayData && !arrayData->deref())
318 if (
e->m_objectCache ==
nullptr) {
330 return e->m_objectCache;
337 bool hasChanges =
false;
341 for (
int i = 0;
i <
target->elements.count(); ++
i) {
343 int uid =
e->getUid();
346 sync.targetIndex =
i;
349 for (
int i = 0;
i <
src->elements.count(); ++
i) {
351 int uid =
e->getUid();
354 if (
it == elementHash.
end()) {
360 ElementSync &
sync =
it.value();
370 for (
int i = 0 ;
i <
target->elements.count() ; ++
i) {
372 ElementSync &
s = elementHash.
find(element->getUid()).
value();
375 s.targetIndex -= rowsRemoved;
376 if (
s.src ==
nullptr) {
381 s.target->destroy(
target->m_layout);
382 target->elements.removeOne(
s.target);
397 for (
int i = 0;
i <
src->elements.count(); ++
i) {
399 ElementSync &
s = elementHash.
find(srcElement->getUid()).
value();
402 if (targetElement ==
nullptr) {
403 targetElement =
new ListElement(srcElement->getUid());
406 target->elements.append(targetElement);
409 target->updateCacheIndices();
412 for (
int i=0 ;
i <
target->elements.count() ; ++
i) {
423 int rowsInserted = 0;
424 const int targetElementCount =
target->elements.count();
425 for (
int i = 0 ;
i < targetElementCount ; ++
i) {
427 ElementSync &
s = elementHash.
find(element->getUid()).
value();
429 s.srcIndex += rowsInserted;
430 if (
s.srcIndex !=
s.targetIndex) {
432 if (
s.targetIndex == -1) {
441 for (
int j=
i+1;
j < targetElementCount; ++
j) {
443 ElementSync &sToFix = elementHash.
find(eToFix->getUid()).
value();
444 if (
i <
s.targetIndex) {
446 if (sToFix.targetIndex >
s.targetIndex || sToFix.targetIndex <
i)
449 sToFix.targetIndex += 1;
452 if (sToFix.targetIndex <
s.targetIndex || sToFix.targetIndex >
i)
455 sToFix.targetIndex -= 1;
462 if (
s.targetIndex != -1 && !
s.changedRoles.isEmpty()) {
478 for (
const auto &destroyer :
remove(0, elements.
count()))
482 if (m_modelCache && m_modelCache->m_primary ==
false)
484 m_modelCache =
nullptr;
489 int elementIndex = elements.
count();
490 newElement(elementIndex);
497 updateCacheIndices(
index);
512 for (
int i=0 ;
i < (to-from) ; ++
i)
514 for (
int i=0 ;
i <
n ; ++
i)
515 store.
append(elements[from+
i]);
516 for (
int i=0 ;
i < store.
count() ; ++
i)
517 elements[from+
i] = store[
i];
519 updateCacheIndices(from, to +
n);
522void ListModel::newElement(
int index)
528void ListModel::updateCacheIndices(
int start,
int end)
532 if (end < 0 || end >
count)
538 mo->m_elementIndex =
i;
548 return e->getProperty(
r, owner, eng);
554 return e->getListProperty(role);
563 cache->updateValues();
580 propertyName =
it.nextPropertyNameAsString(propertyValue);
590 roleIndex =
e->setStringProperty(
r,
s->toQString());
591 }
else if (propertyValue->
isNumber()) {
593 roleIndex =
e->setDoubleProperty(
r, propertyValue->
asDouble());
604 roleIndex =
e->setListProperty(
r, subModel);
611 roleIndex =
e->setDateTimeProperty(
r, dt);
615 roleIndex =
e->setUrlProperty(
r, qurl);
621 roleIndex =
e->setFunctionProperty(
r, jsv);
626 roleIndex =
e->setQObjectProperty(role,
wrapper);
628 o->asReturnedValue(), QMetaType::fromType<QUrl>(),
true);
629 maybeUrl.metaType() == QMetaType::fromType<QUrl>()) {
631 QUrl qurl = maybeUrl.toUrl();
632 roleIndex =
e->setUrlProperty(
r, qurl);
637 roleIndex =
e->setVariantMapProperty(role,
obj);
643 e->clearProperty(*
r);
651 mo->updateValues(*roles);
669 propertyName =
it.nextPropertyNameAsString(propertyValue);
677 e->setStringPropertyFast(
r,
s->toQString());
678 }
else if (propertyValue->
isNumber()) {
681 e->setDoublePropertyFast(
r, propertyValue->
asDouble());
694 e->setListPropertyFast(
r, subModel);
705 e->setDateTimePropertyFast(
r, dt);
711 e->setUrlPropertyFast(
r, qurl);
720 o->asReturnedValue(), QMetaType::fromType<QUrl>(),
true);
721 if (maybeUrl.
metaType() == QMetaType::fromType<QUrl>()) {
725 e->setUrlPropertyFast(
r, qurl);
729 e->setVariantMapFast(role,
o);
735 auto memberName = propertyName->toString(v4)->toQString();
741 e->clearProperty(*
r);
752 auto element = elements[
index+
i];
759 updateCacheIndices(
index);
780 if (elementIndex >= 0 && elementIndex < elements.
count()) {
785 roleIndex =
e->setVariantProperty(*
r,
data);
789 if (roleIndex != -1 &&
cache)
801 if (elementIndex >= 0 && elementIndex < elements.
count()) {
805 roleIndex =
e->setJsProperty(*
r,
data, eng);
816 if (
e->next ==
nullptr) {
837 char *mem = getPropertyMemory(role);
844 char *mem = getPropertyMemory(role);
853 char *mem = getPropertyMemory(role);
854 if (isMemoryUsed<QVariantMap>(mem))
864 char *mem = getPropertyMemory(role);
865 if (isMemoryUsed<QDateTime>(mem))
875 char *mem = getPropertyMemory(role);
876 if (isMemoryUsed<QUrl>(mem))
877 url =
reinterpret_cast<QUrl *
>(mem);
886 char *mem = getPropertyMemory(role);
887 if (isMemoryUsed<QJSValue>(mem))
896 char *mem = getPropertyMemory(role);
898 bool existingGuard =
false;
902 existingGuard =
true;
917 char *mem = getPropertyMemory(role);
924 char *mem = getPropertyMemory(role);
931 double *
value =
reinterpret_cast<double *
>(mem);
946 bool *
value =
reinterpret_cast<bool *
>(mem);
956 if (
model->m_modelCache ==
nullptr) {
974 if (isMemoryUsed<QVariantMap>(mem)) {
982 if (isMemoryUsed<QDateTime>(mem)) {
990 if (isMemoryUsed<QUrl>(mem)) {
998 if (isMemoryUsed<QJSValue>(mem)) {
1016 char *mem = getPropertyMemory(role);
1019 if (!
c->isSet() ||
c->isTranslation())
1025 roleIndex = role.
index;
1036 char *mem = getPropertyMemory(role);
1037 double *
value =
reinterpret_cast<double *
>(mem);
1038 bool changed = *
value !=
d;
1041 roleIndex = role.
index;
1052 char *mem = getPropertyMemory(role);
1053 bool *
value =
reinterpret_cast<bool *
>(mem);
1054 bool changed = *
value !=
b;
1057 roleIndex = role.
index;
1068 char *mem = getPropertyMemory(role);
1075 roleIndex = role.
index;
1086 char *mem = getPropertyMemory(role);
1087 if (isMemoryUsed<QVariantMap>(mem))
1091 roleIndex = role.
index;
1102 char *mem = getPropertyMemory(role);
1103 if (isMemoryUsed<QVariantMap>(mem)) {
1108 roleIndex = role.
index;
1119 char *mem = getPropertyMemory(role);
1120 if (isMemoryUsed<QVariantMap>(mem)) {
1132 roleIndex = role.
index;
1143 char *mem = getPropertyMemory(role);
1144 if (isMemoryUsed<QDateTime>(mem)) {
1149 roleIndex = role.
index;
1160 char *mem = getPropertyMemory(role);
1161 if (isMemoryUsed<QUrl>(mem)) {
1162 QUrl *qurl =
reinterpret_cast<QUrl *
>(mem);
1166 roleIndex = role.
index;
1177 char *mem = getPropertyMemory(role);
1178 if (isMemoryUsed<QJSValue>(mem)) {
1183 roleIndex = role.
index;
1194 char *mem = getPropertyMemory(role);
1197 roleIndex = role.
index;
1206 char *mem = getPropertyMemory(role);
1212 char *mem = getPropertyMemory(role);
1213 double *
value =
new (mem)
double;
1219 char *mem = getPropertyMemory(role);
1220 bool *
value =
new (mem)
bool;
1226 char *mem = getPropertyMemory(role);
1232 char *mem = getPropertyMemory(role);
1239 char *mem = getPropertyMemory(role);
1241 *
map =
o->engine()->variantMapFromJS(
o);
1246 char *mem = getPropertyMemory(role);
1252 char *mem = getPropertyMemory(role);
1258 char *mem = getPropertyMemory(role);
1264 switch (role.
type) {
1266 setStringProperty(role,
QString());
1269 setDoubleProperty(role, 0.0);
1272 setBoolProperty(role,
false);
1275 setListProperty(role,
nullptr);
1278 setQObjectProperty(role,
nullptr);
1284 setUrlProperty(role,
QUrl());
1287 setVariantMapProperty(role, (
QVariantMap *)
nullptr);
1290 setFunctionProperty(role,
QJSValue());
1299 m_objectCache =
nullptr;
1307 m_objectCache =
nullptr;
1326 switch (srcRole.
type) {
1333 if (targetSubModel ==
nullptr) {
1335 target->setListPropertyFast(targetRole, targetSubModel);
1338 roleIndex = targetRole.
index;
1345 roleIndex =
target->setQObjectProperty(targetRole,
object);
1354 QVariant v =
src->getProperty(srcRole,
nullptr,
nullptr);
1355 roleIndex =
target->setVariantProperty(targetRole,
v);
1361 roleIndex =
target->setVariantMapProperty(targetRole,
map);
1368 changedRoles << roleIndex;
1371 return changedRoles;
1377 for (
int i=0 ;
i <
layout->roleCount() ; ++
i) {
1385 string->~StringOrTranslation();
1400 guard->~PersistentValue();
1437 if (m_objectCache) {
1439 operator delete(m_objectCache);
1444 next->destroy(
nullptr);
1452 switch (role.
type) {
1454 roleIndex = setDoubleProperty(role,
d.toDouble());
1457 if (
d.userType() == qMetaTypeId<const QV4::CompiledData::Binding *>())
1460 roleIndex = setStringProperty(role,
d.toString());
1463 roleIndex = setBoolProperty(role,
d.toBool());
1466 roleIndex = setListProperty(role,
d.value<
ListModel *>());
1470 roleIndex = setVariantMapProperty(role, &
map);
1474 roleIndex = setDateTimeProperty(role,
d.toDateTime());
1477 roleIndex = setUrlProperty(role,
d.toUrl());
1480 roleIndex = setFunctionProperty(role,
d.value<
QJSValue>());
1499 roleIndex = setStringProperty(role, qstr);
1500 }
else if (
d.isNumber()) {
1501 roleIndex = setDoubleProperty(role,
d.asDouble());
1514 roleIndex = setListProperty(role, subModel);
1518 }
else if (
d.isBoolean()) {
1519 roleIndex = setBoolProperty(role,
d.booleanValue());
1523 roleIndex = setDateTimeProperty(role, dt);
1527 roleIndex = setUrlProperty(role, qurl);
1532 roleIndex = setFunctionProperty(role, jsv);
1533 }
else if (
d.isObject()) {
1537 roleIndex = setQObjectProperty(role,
wrapper);
1539 roleIndex = setVariantMapProperty(role,
o);
1542 o.asReturnedValue(), QMetaType::fromType<QUrl>(),
true);
1543 if (maybeUrl.
metaType() == QMetaType::fromType<QUrl>()) {
1544 roleIndex = setUrlProperty(role, maybeUrl.
toUrl());
1547 }
else if (
d.isNullOrUndefined()) {
1548 clearProperty(role);
1558void ModelNodeMetaObject::initialize()
1563 for (
int i = 0 ;
i < roleCount ; ++
i) {
1579 if (!m_initialized) {
1580 m_initialized =
true;
1595 if (!m_initialized) {
1597 Q_ALLOCA_VAR(
int, changedRoles, roleCount *
sizeof(
int));
1598 for (
int i = 0;
i < roleCount; ++
i)
1599 changedRoles[
i] =
i;
1600 emitDirectNotifies(changedRoles, roleCount);
1604 for (
int i=0 ;
i < roleCount ; ++
i) {
1614 if (!m_initialized) {
1618 int roleCount = roles.
size();
1619 for (
int i=0 ;
i < roleCount ; ++
i) {
1620 int roleIndex = roles.
at(
i);
1640 if (roleIndex != -1)
1645void ModelNodeMetaObject::emitDirectNotifies(
const int *changedRoles,
int roleCount)
1654 for (
int i = 0;
i < roleCount; ++
i) {
1655 const int changedRole = changedRoles[
i];
1666 QString propName =
id.toQString();
1671 const int elementIndex = that->d()->elementIndex();
1672 int roleIndex = that->d()->m_model->m_listModel->setExistingProperty(elementIndex, propName,
value, eng);
1673 if (roleIndex != -1)
1674 that->d()->m_model->emitItemsChanged(elementIndex, 1,
QVector<int>(1, roleIndex));
1677 if (
mo->initialized())
1678 mo->emitPropertyNotification(propName.
toUtf8());
1702 const int elementIndex = that->d()->elementIndex();
1726 if (roleNameIndex < that->listModel()->roleCount()) {
1736 if (
auto recursiveListModel = qvariant_cast<QQmlListModel*>(
value)) {
1737 auto size = recursiveListModel->count();
1739 for (
auto i = 0;
i <
size;
i++) {
1741 v4, recursiveListModel->get(
i)));
1748 return roleName->toPropertyKey();
1776 object->updateValues(
obj, roles);
1783 for (
int i = 0;
i <
src->m_meta->count(); ++
i) {
1790 bool modelHasChanges =
false;
1792 if (targetModel ==
nullptr)
1793 targetModel = QQmlListModel::createWithOwner(
target->m_owner);
1797 QObject *targetModelObject = targetModel;
1799 }
else if (targetModel) {
1806 return changedRoles;
1811 for (
auto it =
object.cbegin(),
end =
object.cend();
it !=
end; ++
it) {
1814 int roleIndex = m_owner->m_roles.indexOf(
key);
1815 if (roleIndex == -1) {
1816 roleIndex = m_owner->m_roles.size();
1817 m_owner->m_roles.append(
key);
1824 if (
value.userType() == qMetaTypeId<QJSValue>())
1827 if (
value.userType() == QMetaType::QVariantList) {
1828 QQmlListModel *subModel = QQmlListModel::createWithOwner(m_owner);
1831 QVariantList::const_iterator subIt = subArray.
cbegin();
1832 QVariantList::const_iterator subEnd = subArray.
cend();
1833 while (subIt != subEnd) {
1839 QObject *subModelObject = subModel;
1846 delete existingModel;
1860 for (
int i=0 ;
i <
count() ; ++
i) {
1887 if (
v.userType() == qMetaTypeId<QJSValue>())
1890 if (
v.userType() == QMetaType::QVariantList) {
1891 QQmlListModel *subModel = QQmlListModel::createWithOwner(parentModel);
1894 QVariantList::const_iterator subIt = subArray.
cbegin();
1895 QVariantList::const_iterator subEnd = subArray.
cend();
1896 while (subIt != subEnd) {
1902 QObject *subModelObject = subModel;
1908 int elementIndex = parentModel->m_modelObjects.indexOf(m_owner);
1909 if (elementIndex != -1) {
1911 if (roleIndex != -1)
1912 parentModel->emitItemsChanged(elementIndex, 1,
QVector<int>(1, roleIndex));
2013 m_mainThread =
true;
2016 m_dynamicRoles =
false;
2019 m_listModel =
new ListModel(m_layout,
this);
2027 m_mainThread = owner->m_mainThread;
2029 m_agent = owner->m_agent;
2031 Q_ASSERT(owner->m_dynamicRoles ==
false);
2032 m_dynamicRoles =
false;
2037 m_compilationUnit = owner->m_compilationUnit;
2043 m_mainThread =
false;
2046 m_dynamicRoles = orig->m_dynamicRoles;
2049 m_listModel =
new ListModel(m_layout,
this);
2057 m_compilationUnit = orig->m_compilationUnit;
2068 if (m_mainThread && m_agent) {
2074 m_listModel =
nullptr;
2084 model->m_mainThread = newOwner->m_mainThread;
2085 model->m_engine = newOwner->m_engine;
2086 model->m_agent = newOwner->m_agent;
2087 model->m_dynamicRoles = newOwner->m_dynamicRoles;
2090 model->m_agent->addref();
2099 if (m_engine ==
nullptr) {
2110 bool hasChanges =
false;
2116 for (
int i = 0 ;
i <
target->m_modelObjects.size(); ++
i) {
2118 int uid =
e->getUid();
2121 sync.targetIndex =
i;
2124 for (
int i = 0 ;
i <
src->m_modelObjects.size(); ++
i) {
2126 int uid =
e->getUid();
2129 if (
it == elementHash.
end()) {
2135 ElementSync &
sync =
it.value();
2143 for (
int i = 0 ;
i <
target->m_modelObjects.size() ; ++
i) {
2149 if (
s.src ==
nullptr) {
2153 target->m_modelObjects.remove(
i, 1);
2163 target->m_modelObjects.clear();
2164 for (
int i = 0 ;
i <
src->m_modelObjects.size() ; ++
i) {
2169 if (targetElement ==
nullptr) {
2173 target->m_modelObjects.append(targetElement);
2182 for (
int i = 0 ;
i <
target->m_modelObjects.size() ; ++
i) {
2187 if (
s.srcIndex !=
s.targetIndex) {
2188 if (
s.targetIndex == -1) {
2198 if (
s.targetIndex != -1 && !
s.changedRoles.isEmpty()) {
2200 emit target->dataChanged(idx, idx,
s.changedRoles);
2216void QQmlListModel::emitItemsAboutToBeInserted(
int index,
int count)
2223void QQmlListModel::emitItemsInserted()
2263 if (m_dynamicRoles) {
2264 const QByteArray property = m_roles.at(role).toUtf8();
2272 if (roleIndex != -1) {
2289 v = m_modelObjects[
index]->getValue(m_roles[role]);
2300 if (m_dynamicRoles) {
2301 for (
int i = 0 ;
i < m_roles.size() ; ++
i)
2341 if (m_mainThread && m_agent ==
nullptr) {
2342 if (enableDynamicRoles) {
2344 qmlWarning(
this) <<
tr(
"unable to enable dynamic roles as this model is not empty");
2346 m_dynamicRoles =
true;
2348 if (m_roles.size()) {
2349 qmlWarning(
this) <<
tr(
"unable to enable static roles as this model is not empty");
2351 m_dynamicRoles =
false;
2355 qmlWarning(
this) <<
tr(
"dynamic role setting must be made from the main thread, before any worker scripts are created");
2365 return m_dynamicRoles ? m_modelObjects.size() : m_listModel->
elementCount();
2377 removeElements(0,
count());
2391 if (argLength == 1 || argLength == 2) {
2396 if (index < 0 || index+removeCount >
count() || removeCount <= 0) {
2401 removeElements(
index, removeCount);
2403 qmlWarning(
this) <<
tr(
"remove: incorrect number of arguments");
2407void QQmlListModel::removeElements(
int index,
int removeCount)
2418 if (m_dynamicRoles) {
2419 for (
int i=0 ;
i < removeCount ; ++
i) {
2420 auto modelObject = m_modelObjects[
index+
i];
2421 toDestroy.append([modelObject](){
2425 m_modelObjects.remove(
index, removeCount);
2427 toDestroy = m_listModel->
remove(
index, removeCount);
2434 for (
const auto &destroyer : toDestroy)
2438void QQmlListModel::updateTranslations()
2482 if (index < 0 || index >
count()) {
2492 int objectArrayLength = objectArray->getLength();
2493 emitItemsAboutToBeInserted(
index, objectArrayLength);
2494 for (
int i=0 ;
i < objectArrayLength ; ++
i) {
2495 argObject = objectArray->get(
i);
2497 if (m_dynamicRoles) {
2503 emitItemsInserted();
2504 }
else if (argObject) {
2505 emitItemsAboutToBeInserted(
index, 1);
2507 if (m_dynamicRoles) {
2513 emitItemsInserted();
2515 qmlWarning(
this) <<
tr(
"insert: value is not an object");
2518 qmlWarning(
this) <<
tr(
"insert: value is not an object");
2538 if (
n == 0 || from == to)
2540 if (!canMove(from, to,
n)) {
2548 if (m_dynamicRoles) {
2550 int realFrom = from;
2564 for (
int i=0 ;
i < (realTo-realFrom) ; ++
i)
2565 store.
append(m_modelObjects[realFrom+realN+
i]);
2566 for (
int i=0 ;
i < realN ; ++
i)
2567 store.
append(m_modelObjects[realFrom+
i]);
2568 for (
int i=0 ;
i < store.
count() ; ++
i)
2569 m_modelObjects[realFrom+
i] = store[
i];
2572 m_listModel->
move(from, to,
n);
2601 int objectArrayLength = objectArray->getLength();
2602 if (objectArrayLength > 0) {
2604 emitItemsAboutToBeInserted(
index, objectArrayLength);
2606 for (
int i=0 ;
i < objectArrayLength ; ++
i) {
2607 argObject = objectArray->get(
i);
2609 if (m_dynamicRoles) {
2612 m_listModel->
append(argObject);
2616 emitItemsInserted();
2618 }
else if (argObject) {
2621 if (m_dynamicRoles) {
2622 index = m_modelObjects.size();
2623 emitItemsAboutToBeInserted(
index, 1);
2627 emitItemsAboutToBeInserted(
index, 1);
2628 m_listModel->
append(argObject);
2631 emitItemsInserted();
2633 qmlWarning(
this) <<
tr(
"append: value is not an object");
2636 qmlWarning(
this) <<
tr(
"append: value is not an object");
2678 if (m_dynamicRoles) {
2729 emitItemsAboutToBeInserted(
index, 1);
2731 if (m_dynamicRoles) {
2737 emitItemsInserted();
2742 if (m_dynamicRoles) {
2745 m_listModel->
set(
index,
object, &roles);
2749 emitItemsChanged(
index, 1, roles);
2773 if (m_dynamicRoles) {
2774 int roleIndex = m_roles.indexOf(
property);
2775 if (roleIndex == -1) {
2776 roleIndex = m_roles.size();
2783 if (roleIndex != -1)
2799 qmlWarning(
this) <<
"List sync() can only be called from a WorkerScript";
2807 QString objName = compilationUnit->stringAt(
target->inheritedTypeNameIndex);
2808 if (objName != listElementTypeName) {
2810 if (
mo != &QQmlListElement::staticMetaObject) {
2811 error(
target, QQmlListModel::tr(
"ListElement: cannot contain nested elements"));
2814 listElementTypeName = objName;
2817 if (!compilationUnit->stringAt(
target->idNameIndex).isEmpty()) {
2818 error(
target->locationOfIdProperty, QQmlListModel::tr(
"ListElement: cannot use reserved \"id\" property"));
2826 error(binding, QQmlListModel::tr(
"ListElement: cannot contain nested elements"));
2829 if (!verifyProperty(compilationUnit, binding))
2833 QString scriptStr = compilationUnit->bindingValueAsScriptString(binding);
2838 error(binding, QQmlListModel::tr(
"ListElement: cannot use script for property value"));
2847bool QQmlListModelParser::applyProperty(
2853 bool roleSet =
false;
2860 if (outterElementIndex == -1) {
2865 subModel =
model->getListProperty(outterElementIndex, role);
2866 if (subModel ==
nullptr) {
2869 model->setOrCreateProperty(outterElementIndex, elementName, vModel);
2874 int elementIndex = subModel ? subModel->
appendElement() : -1;
2878 roleSet |= applyProperty(compilationUnit, subBinding, subModel, elementIndex);
2885 if (isTranslationBinding) {
2886 value = QVariant::fromValue<const QV4::CompiledData::Binding*>(binding);
2888 value = compilationUnit->bindingValueAsString(binding);
2890 value = compilationUnit->bindingValueAsNumber(binding);
2896 QString scriptStr = compilationUnit->bindingValueAsScriptString(binding);
2897 if (definesEmptyList(scriptStr)) {
2905 auto v4 = compilationUnit->engine;
2913 if (v4->hasException)
2914 v4->catchException();
2928 model->setOrCreateProperty(outterElementIndex, elementName,
value);
2929 auto listModel =
model->m_modelCache;
2930 if (isTranslationBinding && listModel) {
2931 if (!listModel->translationChangeHandler) {
2933 model->m_modelCache->translationChangeHandler = std::make_unique<QPropertyNotifier>(
2934 ep->translationLanguage.addNotifier([listModel](){ listModel->updateTranslations(); }));
2944 listElementTypeName =
QString();
2949 error(binding, QQmlListModel::tr(
"ListModel: undefined property '%1'").
arg(propName));
2952 if (!verifyProperty(compilationUnit, binding))
2962 rv->m_compilationUnit = compilationUnit;
2964 bool setRoles =
false;
2969 setRoles |= applyProperty(compilationUnit, binding, rv->m_listModel, -1);
2972 if (setRoles ==
false)
2973 qmlWarning(
obj) <<
"All ListElement declarations are empty, no roles can be created unless dynamicRoles is set.";
2976bool QQmlListModelParser::definesEmptyList(
const QString &
s)
2979 for (
int i=1;
i<
s.size()-1;
i++) {
2980 if (!
s[
i].isSpace())
3037#include "moc_qqmllistmodel_p_p.cpp"
3039#include "moc_qqmllistmodel_p.cpp"
static QVector< int > sync(DynamicRoleModelNode *src, DynamicRoleModelNode *target)
static DynamicRoleModelNode * create(const QVariantMap &obj, QQmlListModel *owner)
DynamicRoleModelNode(QQmlListModel *owner, int uid)
void setNodeUpdatesEnabled(bool enable)
void updateValues(const QVariantMap &object, QVector< int > &roles)
static QVector< int > sync(ListElement *src, ListLayout *srcLayout, ListElement *target, ListLayout *targetLayout)
const Role * getRoleOrCreate(const QString &key, const QVariant &data)
static void sync(ListLayout *src, ListLayout *target)
const Role & getExistingRole(int index) const
Q_REQUIRED_RESULT QVector< std::function< void()> > remove(int index, int count)
static bool sync(ListModel *src, ListModel *target)
int append(QV4::Object *object)
QVariant getProperty(int elementIndex, int roleIndex, const QQmlListModel *owner, QV4::ExecutionEngine *eng)
void move(int from, int to, int n)
void insertElement(int index)
ListModel(ListLayout *layout, QQmlListModel *modelCache)
void insert(int elementIndex, QV4::Object *object)
int setExistingProperty(int uid, const QString &key, const QV4::Value &data, QV4::ExecutionEngine *eng)
void updateTranslations()
QObject * getOrCreateModelObject(QQmlListModel *model, int elementIndex)
void set(int elementIndex, QV4::Object *object, QVector< int > *roles)
ListModel * getListProperty(int elementIndex, const ListLayout::Role &role)
int setOrCreateProperty(int elementIndex, const QString &key, const QVariant &data)
const ListLayout::Role & getExistingRole(int index) const
bool beginMoveRows(const QModelIndex &sourceParent, int sourceFirst, int sourceLast, const QModelIndex &destinationParent, int destinationRow)
void endRemoveRows()
Ends a row removal operation.
void endMoveRows()
Ends a row move operation.
void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QList< int > &roles=QList< int >())
This signal is emitted whenever the data in an existing item changes.
void endInsertRows()
Ends a row insertion operation.
void rowsInserted(const QModelIndex &parent, int first, int last, QPrivateSignal)
This signal is emitted after rows have been inserted into the model.
QModelIndex createIndex(int row, int column, const void *data=nullptr) const
Creates a model index for the given row and column with the internal pointer ptr.
void beginRemoveRows(const QModelIndex &parent, int first, int last)
Begins a row removal operation.
void beginInsertRows(const QModelIndex &parent, int first, int last)
Begins a row insertion operation.
void rowsRemoved(const QModelIndex &parent, int first, int last, QPrivateSignal)
This signal is emitted after rows have been removed from the model.
QObject * parent() const
Returns a pointer to the parent object.
T fetchAndAddOrdered(T valueToAdd) noexcept
\inmodule QtCore\reentrant
~QDateTime()
Destroys the datetime.
T & value() const noexcept
Returns a modifiable reference to the current item's value.
iterator find(const Key &key)
Returns an iterator pointing to the item with the key in the hash.
iterator end() noexcept
Returns an \l{STL-style iterators}{STL-style iterator} pointing to the imaginary item after the last ...
iterator insert(const Key &key, const T &value)
Inserts a new item with the key and a value of value.
QV4::ExecutionEngine * handle() const
static QJSValue fromReturnedValue(QV4::ReturnedValue d)
static QV4::ReturnedValue asReturnedValue(const QJSValue *jsval)
static QV4::ReturnedValue convertToReturnedValue(QV4::ExecutionEngine *e, const QJSValue &jsval)
static void setValue(QJSValue *jsval, const QV4::Value &v)
The QJSValue class acts as a container for Qt/JavaScript data types.
bool isCallable() const
Returns true if this QJSValue is a function, otherwise returns false.
~QJSValue()
Destroys this QJSValue.
qsizetype size() const noexcept
const_pointer constData() const noexcept
bool isEmpty() const noexcept
QList< T > toList() const noexcept
qsizetype length() const noexcept
const_reference at(qsizetype i) const noexcept
const_iterator cend() const noexcept
void append(parameter_type t)
const_iterator cbegin() const noexcept
bool isSharedWith(const QMap< Key, T > &other) const noexcept
QDynamicMetaObjectData * metaObject
static QObjectPrivate * get(QObject *o)
QAbstractDeclarativeData * declarativeData
virtual ~QObject()
Destroys the object, deleting all its child objects.
void remove(int idx, int count=1)
void insert(int idx, const T &v)
const T & at(int idx) const
static QQmlRefPointer< QQmlContextData > get(QQmlContext *context)
const QMetaObject * resolveType(const QString &) const
Resolves name to a type, or 0 if it is not a type.
int evaluateEnum(const QString &, bool *ok) const
If script is a simple enumeration expression (eg.
static QQmlData * get(QObjectPrivate *priv, bool create)
QQmlPropertyCapture * propertyCapture
static QQmlEnginePrivate * get(QQmlEngine *e)
The QQmlEngine class provides an environment for instantiating QML components.
static QQmlContext * contextForObject(const QObject *)
Returns the QQmlContext for the object, or nullptr if no context has been set.
static void setContextForObject(QObject *, QQmlContext *)
Sets the QQmlContext for the object to context.
The QQmlError class encapsulates a QML error.
void setDescription(const QString &)
Sets the error description.
void verifyBindings(const QQmlRefPointer< QV4::ExecutableCompilationUnit > &compilationUnit, const QList< const QV4::CompiledData::Binding * > &bindings) override
void applyBindings(QObject *obj, const QQmlRefPointer< QV4::ExecutableCompilationUnit > &compilationUnit, const QList< const QV4::CompiledData::Binding * > &bindings) override
Q_INVOKABLE void release()
Q_INVOKABLE void insert(QQmlV4Function *args)
\qmlmethod ListModel::insert(int index, jsobject dict)
Q_INVOKABLE void sync()
\qmlmethod ListModel::sync()
Q_INVOKABLE void clear()
\qmlmethod ListModel::clear()
friend class QQmlListModelWorkerAgent
Q_INVOKABLE void append(QQmlV4Function *args)
\qmlmethod ListModel::append(jsobject dict)
QVariant data(const QModelIndex &index, int role) const override
Returns the data stored under the given role for the item referred to by the index.
void setDynamicRoles(bool enableDynamicRoles)
\qmlproperty bool ListModel::dynamicRoles
QModelIndex index(int row, int column, const QModelIndex &parent) const override
Returns the index of the data in row and column with parent.
Q_INVOKABLE void setProperty(int index, const QString &property, const QVariant &value)
\qmlmethod ListModel::setProperty(int index, string property, variant value)
Q_INVOKABLE QJSValue get(int index) const
\qmlmethod object ListModel::get(int index)
Q_INVOKABLE void move(int from, int to, int count)
\qmlmethod ListModel::move(int from, int to, int n)
int rowCount(const QModelIndex &parent) const override
Returns the number of rows under the given parent.
bool setData(const QModelIndex &index, const QVariant &value, int role=Qt::EditRole) override
Sets the role data for the item at index to value.
Q_INVOKABLE void remove(QQmlV4Function *args)
\qmlmethod ListModel::remove(int index, int count = 1)
QHash< int, QByteArray > roleNames() const override
friend class DynamicRoleModelNode
QQmlListModel(QObject *parent=nullptr)
\qmltype ListModel \instantiates QQmlListModel \inqmlmodule QtQml.Models
Q_INVOKABLE void set(int index, const QJSValue &value)
\qmlmethod ListModel::set(int index, jsobject dict)
void captureProperty(QQmlNotifier *)
\macro QT_RESTRICTED_CAST_FROM_ASCII
static QString fromLatin1(QByteArrayView ba)
This is an overloaded member function, provided for convenience. It differs from the above function o...
qsizetype size() const
Returns the number of characters in this string.
static QString fromUtf8(QByteArrayView utf8)
This is an overloaded member function, provided for convenience. It differs from the above function o...
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
int compare(const QString &s, Qt::CaseSensitivity cs=Qt::CaseSensitive) const noexcept
QByteArray toUtf8() const &
~QUrl()
Destructor; called immediately before the object is deleted.
QString bindingValueAsString(const CompiledData::Binding *binding) const
ObjectType::Data * allocate(Args &&... args)
ReturnedValue value() const
bool isNullOrUndefined() const
void set(ExecutionEngine *engine, const Value &value)
static auto fromValue(T &&value) noexcept(std::is_nothrow_copy_constructible_v< T > &&Private::CanUseInternalSpace< T >) -> std::enable_if_t< std::conjunction_v< std::is_copy_constructible< T >, std::is_destructible< T > >, QVariant >
QMetaType metaType() const
QUrl toUrl() const
Returns the variant as a QUrl if the variant has userType() \l QMetaType::QUrl; otherwise returns an ...
QMap< QString, QString > map
[6]
qDeleteAll(list.begin(), list.end())
QCache< int, Employee > cache
[0]
QSet< QString >::iterator it
Combined button and popup list for selecting options.
\qmltype Particle \inqmlmodule QtQuick.Particles
static int arrayLength(const QString &rawType)
QMap< QString, QVariant > QVariantMap
static const QCssKnownValue properties[NumProperties - 1]
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
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction function
DBusConnection const char DBusError * error
static struct AttrInfo attrs[]
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
GLboolean GLboolean GLboolean b
GLsizei const GLfloat * v
[13]
GLboolean GLboolean GLboolean GLboolean a
[7]
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLenum GLenum GLsizei count
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLsizei GLenum GLsizei GLsizei GLuint memory
GLenum GLenum GLsizei void GLsizei void * column
GLenum GLenum GLsizei void * row
QQmlEngine * qmlEngine(const QObject *obj)
QQmlContext * qmlContext(const QObject *obj)
Q_QML_EXPORT QQmlInfo qmlWarning(const QObject *me)
static QAtomicInt uidCounter(MIN_LISTMODEL_UID)
static bool isMemoryUsed(const char *mem)
static QString roleTypeName(ListLayout::Role::DataType t)
QLatin1StringView QLatin1String
#define QStringLiteral(str)
QArrayDataPointer< char16_t > QStringPrivate
static const QTextHtmlElement elements[Html_NumElements]
#define Q_ALLOCA_VAR(type, name, size)
static QVariant toVariant(const QV4::Value &value, QMetaType typeHint, bool createJSValueForObjectsAndSymbols, V4ObjectSet *visitedObjects)
#define DEFINE_OBJECT_VTABLE(classname)
QSqlQueryModel * model
[16]
QFuture< QSet< QChar > > set
[10]
settings setValue("DataPump/bgcolor", color)
QUrl url("example.com")
[constructor-url-reference]
\inmodule QtCore \reentrant
qsizetype indexOf(const AT &t, qsizetype from=0) const noexcept
static void deallocate(QArrayData *data) noexcept
quint32_le propertyNameIndex
bool isFunctionExpression() const
bool evaluatesToString() const
union QV4::CompiledData::Binding::@543 value
bool isTranslationBinding() const
bool valueAsBoolean() const
quint32_le compiledScriptIndex
MemoryManager * memoryManager
Heap::String * newString(const QString &s=QString())
QV4::ReturnedValue fromVariant(const QVariant &)
static QVariantMap variantMapFromJS(const QV4::Object *o)
static QVariant toVariant(const QV4::Value &value, QMetaType typeHint, bool createJSValueForObjectsAndSymbols=true)
QQmlEngine * qmlEngine() const
Heap::ArrayObject * newArrayObject(int count=0)
static Heap::FunctionObject * createScriptFunction(ExecutionContext *scope, Function *function)
ReturnedValue(* getter)(Lookup *l, ExecutionEngine *engine, const Value &object)
static ReturnedValue getterFallback(Lookup *l, ExecutionEngine *engine, const Value &object)
ExecutionEngine * engine() const
PropertyKey next(const Object *o, Property *pd=nullptr, PropertyAttributes *attrs=nullptr) override
~ModelObjectOwnPropertyKeyIterator() override=default
V4_NEEDS_DESTROY ListModel * listModel() const
PropertyKey next(const Object *o, Property *pd=nullptr, PropertyAttributes *attrs=nullptr) override
bool hasProperty(PropertyKey id) const
bool arrayPut(uint index, const Value &value)
static ReturnedValue wrap(ExecutionEngine *engine, QObject *object)
static Heap::QmlContext * create(QV4::ExecutionContext *parent, QQmlRefPointer< QQmlContextData > context, QObject *scopeObject)
bool isNullOrUndefined() const
bool booleanValue() const
static constexpr VTable::OwnPropertyKeys virtualOwnPropertyKeys
static constexpr VTable::Get virtualGet
static constexpr VTable::Put virtualPut
static constexpr VTable::ResolveLookupGetter virtualResolveLookupGetter
QML_NEARLY_ALWAYS_INLINE String * stringValue() const
static constexpr Value undefinedValue()
void setString(const QString &s)
QString toString(const QQmlListModel *owner) const
void setTranslation(const QV4::CompiledData::Binding *binding)
IUIAutomationTreeWalker __RPC__deref_out_opt IUIAutomationElement ** parent