diff options
Diffstat (limited to 'src/qml/qml/qqmlproperty.cpp')
-rw-r--r-- | src/qml/qml/qqmlproperty.cpp | 216 |
1 files changed, 119 insertions, 97 deletions
diff --git a/src/qml/qml/qqmlproperty.cpp b/src/qml/qml/qqmlproperty.cpp index 9a138dcf80..ebf296b29d 100644 --- a/src/qml/qml/qqmlproperty.cpp +++ b/src/qml/qml/qqmlproperty.cpp @@ -119,7 +119,7 @@ The \l {Qt Quick 1} version of this class was named QDeclarativeProperty. Create an invalid QQmlProperty. */ QQmlProperty::QQmlProperty() -: d(0) +: d(nullptr) { } @@ -128,7 +128,7 @@ QQmlProperty::~QQmlProperty() { if (d) d->release(); - d = 0; + d = nullptr; } /*! @@ -150,8 +150,8 @@ QQmlProperty::QQmlProperty(QObject *obj) QQmlProperty::QQmlProperty(QObject *obj, QQmlContext *ctxt) : d(new QQmlPropertyPrivate) { - d->context = ctxt?QQmlContextData::get(ctxt):0; - d->engine = ctxt?ctxt->engine():0; + d->context = ctxt?QQmlContextData::get(ctxt):nullptr; + d->engine = ctxt?ctxt->engine():nullptr; d->initDefault(obj); } @@ -164,7 +164,7 @@ QQmlProperty::QQmlProperty(QObject *obj, QQmlContext *ctxt) QQmlProperty::QQmlProperty(QObject *obj, QQmlEngine *engine) : d(new QQmlPropertyPrivate) { - d->context = 0; + d->context = nullptr; d->engine = engine; d->initDefault(obj); } @@ -190,7 +190,7 @@ QQmlProperty::QQmlProperty(QObject *obj, const QString &name) : d(new QQmlPropertyPrivate) { d->initProperty(obj, name); - if (!isValid()) d->object = 0; + if (!isValid()) d->object = nullptr; } /*! @@ -203,10 +203,10 @@ QQmlProperty::QQmlProperty(QObject *obj, const QString &name) QQmlProperty::QQmlProperty(QObject *obj, const QString &name, QQmlContext *ctxt) : d(new QQmlPropertyPrivate) { - d->context = ctxt?QQmlContextData::get(ctxt):0; - d->engine = ctxt?ctxt->engine():0; + d->context = ctxt?QQmlContextData::get(ctxt):nullptr; + d->engine = ctxt?ctxt->engine():nullptr; d->initProperty(obj, name); - if (!isValid()) { d->object = 0; d->context = 0; d->engine = 0; } + if (!isValid()) { d->object = nullptr; d->context = nullptr; d->engine = nullptr; } } /*! @@ -217,14 +217,30 @@ QQmlProperty::QQmlProperty(QObject *obj, const QString &name, QQmlContext *ctxt) QQmlProperty::QQmlProperty(QObject *obj, const QString &name, QQmlEngine *engine) : d(new QQmlPropertyPrivate) { - d->context = 0; + d->context = nullptr; d->engine = engine; d->initProperty(obj, name); - if (!isValid()) { d->object = 0; d->context = 0; d->engine = 0; } + if (!isValid()) { d->object = nullptr; d->context = nullptr; d->engine = nullptr; } +} + +QQmlProperty QQmlPropertyPrivate::create(QObject *target, const QString &propertyName, QQmlContextData *context) +{ + QQmlProperty result; + auto d = new QQmlPropertyPrivate; + result.d = d; + d->context = context; + d->engine = context ? context->engine : nullptr; + d->initProperty(target, propertyName); + if (!result.isValid()) { + d->object = nullptr; + d->context = nullptr; + d->engine = nullptr; + } + return result; } QQmlPropertyPrivate::QQmlPropertyPrivate() -: context(0), engine(0), object(0), isNameCached(false) +: context(nullptr), engine(nullptr), object(nullptr), isNameCached(false) { } @@ -232,98 +248,104 @@ QQmlContextData *QQmlPropertyPrivate::effectiveContext() const { if (context) return context; else if (engine) return QQmlContextData::get(engine->rootContext()); - else return 0; + else return nullptr; } void QQmlPropertyPrivate::initProperty(QObject *obj, const QString &name) { if (!obj) return; - QQmlTypeNameCache *typeNameCache = context?context->imports:0; - - const auto path = name.splitRef(QLatin1Char('.')); - if (path.isEmpty()) return; + QQmlTypeNameCache *typeNameCache = context?context->imports:nullptr; QObject *currentObject = obj; - - // Everything up to the last property must be an "object type" property - for (int ii = 0; ii < path.count() - 1; ++ii) { - const QStringRef &pathName = path.at(ii); - - if (typeNameCache) { - QQmlTypeNameCache::Result r = typeNameCache->query(pathName); - if (r.isValid()) { - if (r.type.isValid()) { - QQmlEnginePrivate *enginePrivate = QQmlEnginePrivate::get(engine); - QQmlAttachedPropertiesFunc func = r.type.attachedPropertiesFunction(enginePrivate); - if (!func) return; // Not an attachable type - - currentObject = qmlAttachedPropertiesObjectById(r.type.attachedPropertiesId(enginePrivate), currentObject); - if (!currentObject) return; // Something is broken with the attachable type - } else if (r.importNamespace) { - if ((ii + 1) == path.count()) return; // No type following the namespace - - ++ii; r = typeNameCache->query(path.at(ii), r.importNamespace); - if (!r.type.isValid()) return; // Invalid type in namespace - - QQmlEnginePrivate *enginePrivate = QQmlEnginePrivate::get(engine); - QQmlAttachedPropertiesFunc func = r.type.attachedPropertiesFunction(enginePrivate); - if (!func) return; // Not an attachable type - - currentObject = qmlAttachedPropertiesObjectById(r.type.attachedPropertiesId(enginePrivate), currentObject); - if (!currentObject) return; // Something is broken with the attachable type - - } else if (r.scriptIndex != -1) { - return; // Not a type - } else { - Q_ASSERT(!"Unreachable"); + QVector<QStringRef> path; + QStringRef terminal(&name); + + if (name.contains(QLatin1Char('.'))) { + path = name.splitRef(QLatin1Char('.')); + if (path.isEmpty()) return; + + // Everything up to the last property must be an "object type" property + for (int ii = 0; ii < path.count() - 1; ++ii) { + const QStringRef &pathName = path.at(ii); + + // Types must begin with an uppercase letter (see checkRegistration() + // in qqmlmetatype.cpp for the enforcement of this). + if (typeNameCache && !pathName.isEmpty() && pathName.at(0).isUpper()) { + QQmlTypeNameCache::Result r = typeNameCache->query(pathName); + if (r.isValid()) { + if (r.type.isValid()) { + QQmlEnginePrivate *enginePrivate = QQmlEnginePrivate::get(engine); + QQmlAttachedPropertiesFunc func = r.type.attachedPropertiesFunction(enginePrivate); + if (!func) return; // Not an attachable type + + currentObject = qmlAttachedPropertiesObjectById(r.type.attachedPropertiesId(enginePrivate), currentObject); + if (!currentObject) return; // Something is broken with the attachable type + } else if (r.importNamespace) { + if ((ii + 1) == path.count()) return; // No type following the namespace + + ++ii; r = typeNameCache->query(path.at(ii), r.importNamespace); + if (!r.type.isValid()) return; // Invalid type in namespace + + QQmlEnginePrivate *enginePrivate = QQmlEnginePrivate::get(engine); + QQmlAttachedPropertiesFunc func = r.type.attachedPropertiesFunction(enginePrivate); + if (!func) return; // Not an attachable type + + currentObject = qmlAttachedPropertiesObjectById(r.type.attachedPropertiesId(enginePrivate), currentObject); + if (!currentObject) return; // Something is broken with the attachable type + + } else if (r.scriptIndex != -1) { + return; // Not a type + } else { + Q_ASSERT(!"Unreachable"); + } + continue; } - continue; + } - } + QQmlPropertyData local; + QQmlPropertyData *property = + QQmlPropertyCache::property(engine, currentObject, pathName, context, local); - QQmlPropertyData local; - QQmlPropertyData *property = - QQmlPropertyCache::property(engine, currentObject, pathName, context, local); + if (!property) return; // Not a property + if (property->isFunction()) + return; // Not an object property - if (!property) return; // Not a property - if (property->isFunction()) - return; // Not an object property + if (ii == (path.count() - 2) && QQmlValueTypeFactory::isValueType(property->propType())) { + // We're now at a value type property + const QMetaObject *valueTypeMetaObject = QQmlValueTypeFactory::metaObjectForMetaType(property->propType()); + if (!valueTypeMetaObject) return; // Not a value type - if (ii == (path.count() - 2) && QQmlValueTypeFactory::isValueType(property->propType())) { - // We're now at a value type property - const QMetaObject *valueTypeMetaObject = QQmlValueTypeFactory::metaObjectForMetaType(property->propType()); - if (!valueTypeMetaObject) return; // Not a value type + int idx = valueTypeMetaObject->indexOfProperty(path.last().toUtf8().constData()); + if (idx == -1) return; // Value type property does not exist - int idx = valueTypeMetaObject->indexOfProperty(path.last().toUtf8().constData()); - if (idx == -1) return; // Value type property does not exist + QMetaProperty vtProp = valueTypeMetaObject->property(idx); - QMetaProperty vtProp = valueTypeMetaObject->property(idx); + Q_ASSERT(vtProp.userType() <= 0x0000FFFF); + Q_ASSERT(idx <= 0x0000FFFF); - Q_ASSERT(vtProp.userType() <= 0x0000FFFF); - Q_ASSERT(idx <= 0x0000FFFF); + object = currentObject; + core = *property; + valueTypeData.setFlags(QQmlPropertyData::flagsForProperty(vtProp)); + valueTypeData.setPropType(vtProp.userType()); + valueTypeData.setCoreIndex(idx); - object = currentObject; - core = *property; - valueTypeData.setFlags(QQmlPropertyData::flagsForProperty(vtProp)); - valueTypeData.setPropType(vtProp.userType()); - valueTypeData.setCoreIndex(idx); + return; + } else { + if (!property->isQObject()) + return; // Not an object property - return; - } else { - if (!property->isQObject()) - return; // Not an object property + property->readProperty(currentObject, ¤tObject); + if (!currentObject) return; // No value - property->readProperty(currentObject, ¤tObject); - if (!currentObject) return; // No value + } } + terminal = path.last(); } - const QStringRef &terminal = path.last(); - if (terminal.count() >= 3 && terminal.at(0) == QLatin1Char('o') && terminal.at(1) == QLatin1Char('n') && @@ -467,7 +489,7 @@ QQmlPropertyPrivate::propertyTypeCategory() const const char *QQmlProperty::propertyTypeName() const { if (!d) - return 0; + return nullptr; if (d->isValueType()) { const QMetaObject *valueTypeMetaObject = QQmlValueTypeFactory::metaObjectForMetaType(d->core.propType()); Q_ASSERT(valueTypeMetaObject); @@ -475,7 +497,7 @@ const char *QQmlProperty::propertyTypeName() const } else if (d->object && type() & Property && d->core.isValid()) { return d->object->metaObject()->property(d->core.coreIndex()).typeName(); } else { - return 0; + return nullptr; } } @@ -559,7 +581,7 @@ bool QQmlProperty::isSignalProperty() const */ QObject *QQmlProperty::object() const { - return d ? d->object : 0; + return d ? d->object : nullptr; } /*! @@ -697,7 +719,7 @@ QQmlAbstractBinding * QQmlPropertyPrivate::binding(const QQmlProperty &that) { if (!that.d || !that.isProperty() || !that.d->object) - return 0; + return nullptr; QQmlPropertyIndex thatIndex(that.d->core.coreIndex(), that.d->valueTypeData.coreIndex()); return binding(that.d->object, thatIndex); @@ -759,7 +781,7 @@ static void removeOldBinding(QObject *object, QQmlPropertyIndex index, QQmlPrope return; if (!(flags & QQmlPropertyPrivate::DontEnable)) - oldBinding->setEnabled(false, 0); + oldBinding->setEnabled(false, nullptr); oldBinding->removeFromObject(); } @@ -793,13 +815,13 @@ QQmlPropertyPrivate::binding(QObject *object, QQmlPropertyIndex index) QQmlData *data = QQmlData::get(object); if (!data) - return 0; + return nullptr; const int coreIndex = index.coreIndex(); const int valueTypeIndex = index.valueTypeIndex(); if (coreIndex < 0 || !data->hasBindingBit(coreIndex)) - return 0; + return nullptr; QQmlAbstractBinding *binding = data->bindings; while (binding && (binding->targetPropertyIndex().coreIndex() != coreIndex || @@ -825,11 +847,11 @@ void QQmlPropertyPrivate::findAliasTarget(QObject *object, QQmlPropertyIndex bin int valueTypeIndex = bindingIndex.valueTypeIndex(); QQmlPropertyData *propertyData = - data->propertyCache?data->propertyCache->property(coreIndex):0; + data->propertyCache?data->propertyCache->property(coreIndex):nullptr; if (propertyData && propertyData->isAlias()) { QQmlVMEMetaObject *vme = QQmlVMEMetaObject::getForProperty(object, coreIndex); - QObject *aObject = 0; int aCoreIndex = -1; int aValueTypeIndex = -1; + QObject *aObject = nullptr; int aCoreIndex = -1; int aValueTypeIndex = -1; if (vme->aliasTarget(coreIndex, &aObject, &aCoreIndex, &aValueTypeIndex)) { // This will either be a value type sub-reference or an alias to a value-type sub-reference not both Q_ASSERT(valueTypeIndex == -1 || aValueTypeIndex == -1); @@ -884,11 +906,11 @@ QQmlBoundSignalExpression * QQmlPropertyPrivate::signalExpression(const QQmlProperty &that) { if (!(that.type() & QQmlProperty::SignalProperty)) - return 0; + return nullptr; QQmlData *data = QQmlData::get(that.d->object); if (!data) - return 0; + return nullptr; QQmlBoundSignal *signalHandler = data->signalHandlers; @@ -898,7 +920,7 @@ QQmlPropertyPrivate::signalExpression(const QQmlProperty &that) if (signalHandler) return signalHandler->expression(); - return 0; + return nullptr; } /*! @@ -925,7 +947,7 @@ void QQmlPropertyPrivate::takeSignalExpression(const QQmlProperty &that, return; } - QQmlData *data = QQmlData::get(that.d->object, 0 != expr); + QQmlData *data = QQmlData::get(that.d->object, nullptr != expr); if (!data) return; @@ -1032,7 +1054,7 @@ QVariant QQmlPropertyPrivate::readValueProperty() } else if (core.isQObject()) { - QObject *rv = 0; + QObject *rv = nullptr; core.readProperty(object, &rv); return QVariant::fromValue(rv); @@ -1043,11 +1065,11 @@ QVariant QQmlPropertyPrivate::readValueProperty() QVariant value; int status = -1; - void *args[] = { 0, &value, &status }; + void *args[] = { nullptr, &value, &status }; if (core.propType() == QMetaType::QVariant) { args[0] = &value; } else { - value = QVariant(core.propType(), (void*)0); + value = QVariant(core.propType(), (void*)nullptr); args[0] = value.data(); } core.readPropertyWithArgs(object, args); @@ -1406,7 +1428,7 @@ QQmlMetaObject QQmlPropertyPrivate::rawMetaObjectForType(QQmlEnginePrivate *engi */ bool QQmlProperty::write(const QVariant &value) const { - return QQmlPropertyPrivate::write(*this, value, 0); + return QQmlPropertyPrivate::write(*this, value, nullptr); } /*! @@ -1475,7 +1497,7 @@ bool QQmlProperty::write(QObject *object, const QString &name, const QVariant &v bool QQmlProperty::reset() const { if (isResettable()) { - void *args[] = { 0 }; + void *args[] = { nullptr }; QMetaObject::metacall(d->object, QMetaObject::ResetProperty, d->core.coreIndex(), args); return true; } else { |