void tst_qqmllistreference::isManipulable() { TestType *tt = new TestType; { QQmlListReference ref; QVERIFY(ref.isManipulable() == false); } { QQmlListReference ref(tt, "blah"); QVERIFY(ref.isManipulable() == false); } { QQmlListReference ref(tt, "data"); QVERIFY(ref.isManipulable() == true); delete tt; QVERIFY(ref.isManipulable() == false); } { TestType tt; tt.property.count = 0; QQmlListReference ref(&tt, "data"); QVERIFY(ref.isManipulable() == false); } }
void tst_qqmllistreference::canCount() { TestType *tt = new TestType; { QQmlListReference ref; QVERIFY(!ref.canCount()); } { QQmlListReference ref(tt, "blah"); QVERIFY(!ref.canCount()); } { QQmlListReference ref(tt, "data"); QVERIFY(ref.canCount()); delete tt; QVERIFY(!ref.canCount()); } { TestType tt; tt.property.count = 0; QQmlListReference ref(&tt, "data"); QVERIFY(!ref.canCount()); } }
void tst_qqmllistreference::count() { TestType *tt = new TestType; tt->data.append(tt); tt->data.append(0); tt->data.append(tt); { QQmlListReference ref; QVERIFY(ref.count() == 0); } { QQmlListReference ref(tt, "blah"); QVERIFY(ref.count() == 0); } { QQmlListReference ref(tt, "data"); QVERIFY(ref.count() == 3); tt->data.removeAt(1); QVERIFY(ref.count() == 2); delete tt; QVERIFY(ref.count() == 0); } { TestType tt; tt.data.append(&tt); tt.property.count = 0; QQmlListReference ref(&tt, "data"); QVERIFY(ref.count() == 0); } }
void tst_qqmllistreference::at() { TestType *tt = new TestType; tt->data.append(tt); tt->data.append(0); tt->data.append(tt); { QQmlListReference ref; QVERIFY(ref.at(0) == 0); } { QQmlListReference ref(tt, "blah"); QVERIFY(ref.at(0) == 0); } { QQmlListReference ref(tt, "data"); QVERIFY(ref.at(0) == tt); QVERIFY(ref.at(1) == 0); QVERIFY(ref.at(2) == tt); delete tt; QVERIFY(ref.at(0) == 0); } { TestType tt; tt.data.append(&tt); tt.property.at = 0; QQmlListReference ref(&tt, "data"); QVERIFY(ref.at(0) == 0); } }
void tst_qqmllistreference::clear() { TestType *tt = new TestType; tt->data.append(tt); tt->data.append(0); tt->data.append(tt); { QQmlListReference ref; QVERIFY(ref.clear() == false); } { QQmlListReference ref(tt, "blah"); QVERIFY(ref.clear() == false); } { QQmlListReference ref(tt, "data"); QVERIFY(ref.clear() == true); QVERIFY(tt->data.count() == 0); delete tt; QVERIFY(ref.clear() == false); } { TestType tt; tt.property.clear = 0; QQmlListReference ref(&tt, "data"); QVERIFY(ref.clear() == false); } }
void tst_qqmllistreference::canClear() { TestType *tt = new TestType; { QQmlListReference ref; QVERIFY(ref.canClear() == false); } { QQmlListReference ref(tt, "blah"); QVERIFY(ref.canClear() == false); } { QQmlListReference ref(tt, "data"); QVERIFY(ref.canClear() == true); delete tt; QVERIFY(ref.canClear() == false); } { TestType tt; tt.property.clear = 0; QQmlListReference ref(&tt, "data"); QVERIFY(ref.canClear() == false); } }
void ObjectNodeInstance::addToNewProperty(QObject *object, QObject *newParent, const PropertyName &newParentProperty) { QQmlProperty property(newParent, QString::fromUtf8(newParentProperty), context()); if (object) object->setParent(newParent); if (isList(property)) { QQmlListReference list = qvariant_cast<QQmlListReference>(property.read()); if (!QmlPrivateGate::hasFullImplementedListInterface(list)) { qWarning() << "Property list interface not fully implemented for Class " << property.property().typeName() << " in property " << property.name() << "!"; return; } list.append(object); } else if (isObject(property)) { property.write(objectToVariant(object)); if (QQuickItem *item = qobject_cast<QQuickItem *>(object)) if (QQuickItem *newParentItem = qobject_cast<QQuickItem *>(newParent)) item->setParentItem(newParentItem); } Q_ASSERT(objectToVariant(object).isValid()); }
void tst_qqmllistreference::qmlmetaproperty() { TestType tt; tt.data.append(&tt); tt.data.append(0); tt.data.append(&tt); QQmlProperty prop(&tt, QLatin1String("data")); QVariant v = prop.read(); QVERIFY(v.userType() == qMetaTypeId<QQmlListReference>()); QQmlListReference ref = qvariant_cast<QQmlListReference>(v); QVERIFY(ref.count() == 3); QVERIFY(ref.listElementType() == &TestType::staticMetaObject); }
void ObjectNodeInstance::deleteObjectsInList(const QQmlProperty &property) { QObjectList objectList; QQmlListReference list = qvariant_cast<QQmlListReference>(property.read()); if (!QmlPrivateGate::hasFullImplementedListInterface(list)) { qWarning() << "Property list interface not fully implemented for Class " << property.property().typeName() << " in property " << property.name() << "!"; return; } for (int i = 0; i < list.count(); i++) { objectList += list.at(i); } list.clear(); }
bool DataVizAdapter::bars3DHasSeries(QBar3DSeries* series) { qDebug() << "DataVizAdapter::bars3DHasSeries(): series=" << series << "\tgetBars3D()=" << getBars3D(); bool hasSeries{false}; if ( getBars3D() != nullptr ) { QQmlProperty seriesListQmlProperty(getBars3D(), "seriesList"); if ( seriesListQmlProperty.isValid() ) { QQmlListReference seriesList = qvariant_cast<QQmlListReference>( seriesListQmlProperty.read() ); if (seriesList.isValid()) for ( int s = 0; s < seriesList.count(); s++ ) if ( seriesList.at(s) == series ) { hasSeries = true; break; } } } return hasSeries; }
void tst_qqmllistreference::listElementType() { TestType *tt = new TestType; { QQmlListReference ref; QVERIFY(ref.listElementType() == 0); } { QQmlListReference ref(tt, "blah"); QVERIFY(ref.listElementType() == 0); } { QQmlListReference ref(tt, "data"); QVERIFY(ref.listElementType() == &TestType::staticMetaObject); delete tt; QVERIFY(ref.listElementType() == 0); } }
void tst_qqmllistreference::object() { TestType *tt = new TestType; { QQmlListReference ref; QVERIFY(ref.object() == 0); } { QQmlListReference ref(tt, "blah"); QVERIFY(ref.object() == 0); } { QQmlListReference ref(tt, "data"); QVERIFY(ref.object() == tt); delete tt; QVERIFY(ref.object() == 0); } }
void tst_qqmllistreference::isValid() { TestType *tt = new TestType; { QQmlListReference ref; QVERIFY(ref.isValid() == false); } { QQmlListReference ref(tt, "blah"); QVERIFY(ref.isValid() == false); } { QQmlListReference ref(tt, "data"); QVERIFY(ref.isValid() == true); delete tt; QVERIFY(ref.isValid() == false); } }
void tst_qqmllistreference::engineTypes() { QQmlEngine engine; QQmlComponent component(&engine, testFileUrl("engineTypes.qml")); QObject *o = component.create(); QVERIFY(o); QQmlProperty p1(o, QLatin1String("myList")); QVERIFY(p1.propertyTypeCategory() == QQmlProperty::List); QQmlProperty p2(o, QLatin1String("myList"), engine.rootContext()); QVERIFY(p2.propertyTypeCategory() == QQmlProperty::List); QVariant v = p2.read(); QVERIFY(v.userType() == qMetaTypeId<QQmlListReference>()); QQmlListReference ref = qvariant_cast<QQmlListReference>(v); QVERIFY(ref.count() == 2); QVERIFY(ref.listElementType()); QVERIFY(ref.listElementType() != &QObject::staticMetaObject); delete o; }
void tst_qqmllistreference::append() { TestType *tt = new TestType; QObject object; { QQmlListReference ref; QVERIFY(!ref.append(tt)); } { QQmlListReference ref(tt, "blah"); QVERIFY(!ref.append(tt)); } { QQmlListReference ref(tt, "data"); QVERIFY(ref.append(tt)); QCOMPARE(tt->data.count(), 1); QCOMPARE(tt->data.at(0), tt); QVERIFY(!ref.append(&object)); QCOMPARE(tt->data.count(), 1); QCOMPARE(tt->data.at(0), tt); QVERIFY(ref.append(0)); QCOMPARE(tt->data.count(), 2); QCOMPARE(tt->data.at(0), tt); QVERIFY(!tt->data.at(1)); delete tt; QVERIFY(!ref.append(0)); } { TestType tt; tt.property.append = 0; QQmlListReference ref(&tt, "data"); QVERIFY(!ref.append(&tt)); } }
void tst_qqmllistreference::append() { TestType *tt = new TestType; QObject object; { QQmlListReference ref; QVERIFY(ref.append(tt) == false); } { QQmlListReference ref(tt, "blah"); QVERIFY(ref.append(tt) == false); } { QQmlListReference ref(tt, "data"); QVERIFY(ref.append(tt) == true); QVERIFY(tt->data.count() == 1); QVERIFY(tt->data.at(0) == tt); QVERIFY(ref.append(&object) == false); QVERIFY(tt->data.count() == 1); QVERIFY(tt->data.at(0) == tt); QVERIFY(ref.append(0) == true); QVERIFY(tt->data.count() == 2); QVERIFY(tt->data.at(0) == tt); QVERIFY(tt->data.at(1) == 0); delete tt; QVERIFY(ref.append(0) == false); } { TestType tt; tt.property.append = 0; QQmlListReference ref(&tt, "data"); QVERIFY(ref.append(&tt) == false); } }
void tst_qqmllistreference::qmllistreference_invalid() { TestType tt; // Invalid { QQmlListReference r; QVERIFY(r.isValid() == false); QVERIFY(r.object() == 0); QVERIFY(r.listElementType() == 0); QVERIFY(r.canAt() == false); QVERIFY(r.canClear() == false); QVERIFY(r.canCount() == false); QVERIFY(r.append(0) == false); QVERIFY(r.at(10) == 0); QVERIFY(r.clear() == false); QVERIFY(r.count() == 0); QVERIFY(r.isReadable() == false); QVERIFY(r.isManipulable() == false); } // Non-property { QQmlListReference r(&tt, "blah"); QVERIFY(r.isValid() == false); QVERIFY(r.object() == 0); QVERIFY(r.listElementType() == 0); QVERIFY(r.canAt() == false); QVERIFY(r.canClear() == false); QVERIFY(r.canCount() == false); QVERIFY(r.append(0) == false); QVERIFY(r.at(10) == 0); QVERIFY(r.clear() == false); QVERIFY(r.count() == 0); QVERIFY(r.isReadable() == false); QVERIFY(r.isManipulable() == false); } // Non-list property { QQmlListReference r(&tt, "intProperty"); QVERIFY(r.isValid() == false); QVERIFY(r.object() == 0); QVERIFY(r.listElementType() == 0); QVERIFY(r.canAt() == false); QVERIFY(r.canClear() == false); QVERIFY(r.canCount() == false); QVERIFY(r.append(0) == false); QVERIFY(r.at(10) == 0); QVERIFY(r.clear() == false); QVERIFY(r.count() == 0); QVERIFY(r.isReadable() == false); QVERIFY(r.isManipulable() == false); } }
static bool hasFullImplementedListInterface(const QQmlListReference &list) { return list.isValid() && list.canCount() && list.canAt() && list.canAppend() && list.canClear(); }
void packDataValue(QVariant_ *var, DataValue *value) { QVariant *qvar = reinterpret_cast<QVariant *>(var); // Some assumptions are made below regarding the size of types. // There's apparently no better way to handle this since that's // how the types with well defined sizes (qint64) are mapped to // meta-types (QMetaType::LongLong). switch ((int)qvar->type()) { case QVariant::Invalid: value->dataType = DTInvalid; break; case QMetaType::QUrl: *qvar = qvar->value<QUrl>().toString(); // fallthrough case QMetaType::QString: { value->dataType = DTString; QByteArray ba = qvar->toByteArray(); *(char**)(value->data) = local_strdup(ba.constData()); value->len = ba.size(); break; } case QMetaType::Bool: value->dataType = DTBool; *(qint8*)(value->data) = (qint8)qvar->toInt(); break; case QMetaType::LongLong: // Some of these entries will have to be fixed when handling platforms // where sizeof(long long) != 8 or sizeof(int) != 4. value->dataType = DTInt64; *(qint64*)(value->data) = qvar->toLongLong(); break; case QMetaType::ULongLong: value->dataType = DTUint64; *(quint64*)(value->data) = qvar->toLongLong(); break; case QMetaType::Int: value->dataType = DTInt32; *(qint32*)(value->data) = qvar->toInt(); break; case QMetaType::UInt: value->dataType = DTUint32; *(quint32*)(value->data) = qvar->toUInt(); break; case QMetaType::VoidStar: value->dataType = DTUintptr; *(uintptr_t*)(value->data) = (uintptr_t)qvar->value<void *>(); break; case QMetaType::Double: value->dataType = DTFloat64; *(double*)(value->data) = qvar->toDouble(); break; case QMetaType::Float: value->dataType = DTFloat32; *(float*)(value->data) = qvar->toFloat(); break; case QMetaType::QColor: value->dataType = DTColor; *(unsigned int*)(value->data) = qvar->value<QColor>().rgba(); break; case QMetaType::QVariantList: { QVariantList varlist = qvar->toList(); int len = varlist.size(); DataValue *dvlist = (DataValue *) malloc(sizeof(DataValue) * len); for (int i = 0; i < len; i++) { packDataValue((void*)&varlist.at(i), &dvlist[i]); } value->dataType = DTValueList; value->len = len; *(DataValue**)(value->data) = dvlist; } break; case QMetaType::QVariantMap: { QVariantMap varmap = qvar->toMap(); int len = varmap.size() * 2; DataValue *dvlist = (DataValue *) malloc(sizeof(DataValue) * len); QMapIterator<QString, QVariant> it(varmap); for (int i = 0; i < len; i += 2) { if (!it.hasNext()) { panicf("QVariantMap mutated during iteration"); } it.next(); QVariant key = it.key(); QVariant val = it.value(); packDataValue((void*)&key, &dvlist[i]); packDataValue((void*)&val, &dvlist[i+1]); } value->dataType = DTValueMap; value->len = len; *(DataValue**)(value->data) = dvlist; } break; default: if (qvar->type() == (int)QMetaType::QObjectStar || qvar->canConvert<QObject *>()) { QObject *qobject = qvar->value<QObject *>(); GoValue *goValue = dynamic_cast<GoValue *>(qobject); if (goValue) { value->dataType = DTGoAddr; *(void **)(value->data) = goValue->addr; break; } GoPaintedValue *goPaintedValue = dynamic_cast<GoPaintedValue *>(qobject); if (goPaintedValue) { value->dataType = DTGoAddr; *(void **)(value->data) = goPaintedValue->addr; break; } value->dataType = DTObject; *(void **)(value->data) = qobject; break; } { QQmlListReference ref = qvar->value<QQmlListReference>(); if (ref.isValid() && ref.canCount() && ref.canAt()) { int len = ref.count(); DataValue *dvlist = (DataValue *) malloc(sizeof(DataValue) * len); QVariant elem; for (int i = 0; i < len; i++) { elem.setValue(ref.at(i)); packDataValue(&elem, &dvlist[i]); } value->dataType = DTValueList; value->len = len; *(DataValue**)(value->data) = dvlist; break; } } if (qstrncmp(qvar->typeName(), "QQmlListProperty<", 17) == 0) { QQmlListProperty<QObject> *list = reinterpret_cast<QQmlListProperty<QObject>*>(qvar->data()); if (list->count && list->at) { int len = list->count(list); DataValue *dvlist = (DataValue *) malloc(sizeof(DataValue) * len); QVariant elem; for (int i = 0; i < len; i++) { elem.setValue(list->at(list, i)); packDataValue(&elem, &dvlist[i]); } value->dataType = DTValueList; value->len = len; *(DataValue**)(value->data) = dvlist; break; } } panicf("unsupported variant type: %d (%s)", qvar->type(), qvar->typeName()); break; } }