diff options
Diffstat (limited to 'src/declarative/qml/qdeclarativeproperty.cpp')
-rw-r--r-- | src/declarative/qml/qdeclarativeproperty.cpp | 222 |
1 files changed, 172 insertions, 50 deletions
diff --git a/src/declarative/qml/qdeclarativeproperty.cpp b/src/declarative/qml/qdeclarativeproperty.cpp index 7ead1b5..e1ec2cd 100644 --- a/src/declarative/qml/qdeclarativeproperty.cpp +++ b/src/declarative/qml/qdeclarativeproperty.cpp @@ -63,10 +63,30 @@ QT_BEGIN_NAMESPACE /*! - \class QDeclarativeProperty - \brief The QDeclarativeProperty class abstracts accessing QML properties. - \internal - */ +\class QDeclarativeProperty +\brief The QDeclarativeProperty class abstracts accessing properties on objects created from QML. + +As QML uses Qt's meta-type system all of the existing QMetaObject classes can be used to introspect +and interact with objects created by QML. However, some of the new features provided by QML - such +as type safety and attached properties - are most easily used through the QDeclarativeProperty class +that simplifies some of their natural complexity. + +Unlike QMetaProperty which represents a property on a class type, QDeclarativeProperty encapsulates +a property on a specific object instance. To read a property's value, programmers create a +QDeclarativeProperty instance and call the read() method. Likewise to write a property value the +write() method is used. + +\code + +QObject *object = declarativeComponent.create(); + +QDeclarativeProperty property(object, "font.pixelSize"); +qWarning() << "Current pixel size:" << property.read().toInt(); +property.write(24); +qWarning() << "Pixel size should now be 24:" << property.read().toInt(); + +\endcode +*/ /*! Create an invalid QDeclarativeProperty. @@ -95,7 +115,6 @@ QDeclarativeProperty::QDeclarativeProperty(QObject *obj) } /*! - \internal Creates a QDeclarativeProperty for the default property of \a obj. If there is no default property, an invalid QDeclarativeProperty will be created. */ @@ -104,6 +123,20 @@ QDeclarativeProperty::QDeclarativeProperty(QObject *obj, QDeclarativeContext *ct { d->q = this; d->context = ctxt; + d->engine = ctxt?ctxt->engine():0; + d->initDefault(obj); +} + +/*! + Creates a QDeclarativeProperty for the default property of \a obj. If there is no + default property, an invalid QDeclarativeProperty will be created. + */ +QDeclarativeProperty::QDeclarativeProperty(QObject *obj, QDeclarativeEngine *engine) +: d(new QDeclarativePropertyPrivate) +{ + d->q = this; + d->context = 0; + d->engine = engine; d->initDefault(obj); } @@ -117,10 +150,8 @@ void QDeclarativePropertyPrivate::initDefault(QObject *obj) QMetaProperty p = QDeclarativeMetaType::defaultProperty(obj); core.load(p); - if (core.isValid()) { - isDefaultProperty = true; + if (core.isValid()) object = obj; - } } /*! @@ -135,7 +166,6 @@ QDeclarativeProperty::QDeclarativeProperty(QObject *obj, const QString &name) } /*! - \internal Creates a QDeclarativeProperty for the property \a name of \a obj. */ QDeclarativeProperty::QDeclarativeProperty(QObject *obj, const QString &name, QDeclarativeContext *ctxt) @@ -143,8 +173,22 @@ QDeclarativeProperty::QDeclarativeProperty(QObject *obj, const QString &name, QD { d->q = this; d->context = ctxt; + d->engine = ctxt?ctxt->engine():0; + d->initProperty(obj, name); + if (!isValid()) { d->object = 0; d->context = 0; d->engine = 0; } +} + +/*! + Creates a QDeclarativeProperty for the property \a name of \a obj. + */ +QDeclarativeProperty::QDeclarativeProperty(QObject *obj, const QString &name, QDeclarativeEngine *engine) +: d(new QDeclarativePropertyPrivate) +{ + d->q = this; + d->context = 0; + d->engine = engine; d->initProperty(obj, name); - if (!isValid()) { d->object = 0; d->context = 0; } + if (!isValid()) { d->object = 0; d->context = 0; d->engine = 0; } } Q_GLOBAL_STATIC(QDeclarativeValueTypeFactory, qmlValueTypes); @@ -153,7 +197,6 @@ void QDeclarativePropertyPrivate::initProperty(QObject *obj, const QString &name { if (!obj) return; - QDeclarativeEngine *engine = context?context->engine():0; QDeclarativeTypeNameCache *typeNameCache = context?QDeclarativeContextPrivate::get(context)->imports:0; QStringList path = name.split(QLatin1Char('.')); @@ -247,7 +290,7 @@ void QDeclarativePropertyPrivate::initProperty(QObject *obj, const QString &name // Property QDeclarativePropertyCache::Data local; QDeclarativePropertyCache::Data *property = - QDeclarativePropertyCache::property(context?context->engine():0, currentObject, terminal, local); + QDeclarativePropertyCache::property(engine, currentObject, terminal, local); if (property && !(property->flags & QDeclarativePropertyCache::Data::IsFunction)) { object = currentObject; core = *property; @@ -268,10 +311,10 @@ QDeclarativeProperty::QDeclarativeProperty(const QDeclarativeProperty &other) This enum specifies a category of QML property. - \value InvalidCategory The property is invalid. - \value List The property is a QList pointer + \value InvalidCategory The property is invalid, or is a signal property. + \value List The property is a QDeclarativeListProperty list property \value Object The property is a QObject derived type pointer - \value Normal The property is none of the above. + \value Normal The property is a normal value property. */ /*! @@ -282,7 +325,6 @@ QDeclarativeProperty::QDeclarativeProperty(const QDeclarativeProperty &other) \value Invalid The property is invalid. \value Property The property is a regular Qt property. \value SignalProperty The property is a signal property. - \value Default The property is the default property. */ /*! @@ -298,7 +340,7 @@ QDeclarativePropertyPrivate::propertyTypeCategory() const { uint type = q->type(); - if (type & QDeclarativeProperty::ValueTypeProperty) { + if (isValueType()) { return QDeclarativeProperty::Normal; } else if (type & QDeclarativeProperty::Property) { int type = propertyType(); @@ -323,7 +365,7 @@ QDeclarativePropertyPrivate::propertyTypeCategory() const */ const char *QDeclarativeProperty::propertyTypeName() const { - if (type() & ValueTypeProperty) { + if (d->isValueType()) { QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(d->context); QDeclarativeValueType *valueType = 0; @@ -365,10 +407,15 @@ int QDeclarativeProperty::propertyType() const return d->propertyType(); } +bool QDeclarativePropertyPrivate::isValueType() const +{ + return valueType.valueTypeCoreIdx != -1; +} + int QDeclarativePropertyPrivate::propertyType() const { uint type = q->type(); - if (type & QDeclarativeProperty::ValueTypeProperty) { + if (isValueType()) { return valueType.valueTypePropType; } else if (type & QDeclarativeProperty::Property) { if (core.propType == (int)QVariant::LastType) @@ -387,10 +434,8 @@ QDeclarativeProperty::Type QDeclarativeProperty::type() const { if (d->core.flags & QDeclarativePropertyCache::Data::IsFunction) return SignalProperty; - else if (d->valueType.valueTypeCoreIdx != -1) - return (Type)(Property | ValueTypeProperty); else if (d->core.isValid()) - return (Type)(Property | ((d->isDefaultProperty)?Default:0)); + return Property; else return Invalid; } @@ -404,11 +449,11 @@ bool QDeclarativeProperty::isProperty() const } /*! - Returns true if this QDeclarativeProperty represents a default property. + Returns true if this QDeclarativeProperty represents a QML signal property. */ -bool QDeclarativeProperty::isDefault() const +bool QDeclarativeProperty::isSignalProperty() const { - return type() & Default; + return type() & SignalProperty; } /*! @@ -425,9 +470,9 @@ QObject *QDeclarativeProperty::object() const QDeclarativeProperty &QDeclarativeProperty::operator=(const QDeclarativeProperty &other) { d->context = other.d->context; + d->engine = other.d->engine; d->object = other.d->object; - d->isDefaultProperty = other.d->isDefaultProperty; d->isNameCached = other.d->isNameCached; d->core = other.d->core; d->nameCache = other.d->nameCache; @@ -495,10 +540,10 @@ QString QDeclarativeProperty::name() const if (!d->isNameCached) { // ### if (!d->object) { - } else if (type() & ValueTypeProperty) { + } else if (d->isValueType()) { QString rv = d->core.name(d->object) + QLatin1Char('.'); - QDeclarativeEnginePrivate *ep = d->context?QDeclarativeEnginePrivate::get(d->context->engine()):0; + QDeclarativeEnginePrivate *ep = d->engine?QDeclarativeEnginePrivate::get(d->engine):0; QDeclarativeValueType *valueType = 0; if (ep) valueType = ep->valueTypes[d->core.propType]; else valueType = QDeclarativeValueTypeFactory::valueType(d->core.propType); @@ -646,7 +691,7 @@ QDeclarativePropertyPrivate::signalExpression(const QDeclarativeProperty &that) QObject *child = children.at(ii); QDeclarativeBoundSignal *signal = QDeclarativeBoundSignal::cast(child); - if (signal && signal->index() == that.coreIndex()) + if (signal && signal->index() == that.index()) return signal->expression(); } @@ -675,7 +720,7 @@ QDeclarativePropertyPrivate::setSignalExpression(const QDeclarativeProperty &tha QObject *child = children.at(ii); QDeclarativeBoundSignal *signal = QDeclarativeBoundSignal::cast(child); - if (signal && signal->index() == that.coreIndex()) + if (signal && signal->index() == that.index()) return signal->setExpression(expr); } @@ -707,10 +752,48 @@ QVariant QDeclarativeProperty::read() const return QVariant(); } +/*! +Return the \a name property value of \a object. This method is equivalent to: +\code + QDeclarativeProperty p(object, name); + p.read(); +\endcode +*/ +QVariant QDeclarativeProperty::read(QObject *object, const QString &name) +{ + QDeclarativeProperty p(object, name); + return p.read(); +} + +/*! +Return the \a name property value of \a object. This method is equivalent to: +\code + QDeclarativeProperty p(object, name, context); + p.read(); +\endcode +*/ +QVariant QDeclarativeProperty::read(QObject *object, const QString &name, QDeclarativeContext *ctxt) +{ + QDeclarativeProperty p(object, name, ctxt); + return p.read(); +} + +/*! +Return the \a name property value of \a object. This method is equivalent to: +\code + QDeclarativeProperty p(object, name, engine); + p.read(); +\endcode +*/ +QVariant QDeclarativeProperty::read(QObject *object, const QString &name, QDeclarativeEngine *engine) +{ + QDeclarativeProperty p(object, name, engine); + return p.read(); +} + QVariant QDeclarativePropertyPrivate::readValueProperty() { - uint type = q->type(); - if(type & QDeclarativeProperty::ValueTypeProperty) { + if(isValueType()) { QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(context); QDeclarativeValueType *valueType = 0; @@ -731,7 +814,7 @@ QVariant QDeclarativePropertyPrivate::readValueProperty() QDeclarativeListProperty<QObject> prop; void *args[] = { &prop, 0 }; QMetaObject::metacall(object, QMetaObject::ReadProperty, core.coreIndex, args); - return QVariant::fromValue(QDeclarativeListReferencePrivate::init(prop, core.propType, context?context->engine():0)); + return QVariant::fromValue(QDeclarativeListReferencePrivate::init(prop, core.propType, engine)); } else { @@ -740,9 +823,7 @@ QVariant QDeclarativePropertyPrivate::readValueProperty() } } -//### //writeEnumProperty MIRRORS the relelvant bit of QMetaProperty::write AND MUST BE KEPT IN SYNC! -//### bool QDeclarativePropertyPrivate::writeEnumProperty(const QMetaProperty &prop, int idx, QObject *object, const QVariant &value, int flags) { if (!object || !prop.isWritable()) @@ -789,8 +870,7 @@ bool QDeclarativePropertyPrivate::writeValueProperty(const QVariant &value, Writ } bool rv = false; - uint type = q->type(); - if (type & QDeclarativeProperty::ValueTypeProperty) { + if (isValueType()) { QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(context); QDeclarativeValueType *writeBack = 0; @@ -931,13 +1011,13 @@ bool QDeclarativePropertyPrivate::write(QObject *object, const QDeclarativePrope for (int ii = 0; ii < list.count(); ++ii) { QObject *o = list.at(ii); - if (!canConvert(o->metaObject(), listType)) + if (o && !canConvert(o->metaObject(), listType)) o = 0; prop.append(&prop, (void *)o); } } else { QObject *o = enginePriv?enginePriv->toQObject(value):QDeclarativeMetaType::toQObject(value); - if (!canConvert(o->metaObject(), listType)) + if (o && !canConvert(o->metaObject(), listType)) o = 0; prop.append(&prop, (void *)o); } @@ -994,6 +1074,47 @@ bool QDeclarativeProperty::write(const QVariant &value) const } /*! +Writes \a value to the \a name property of \a object. This method is equivalent to: +\code + QDeclarativeProperty p(object, name); + p.write(value); +\endcode +*/ +bool QDeclarativeProperty::write(QObject *object, const QString &name, const QVariant &value) +{ + QDeclarativeProperty p(object, name); + return p.write(value); +} + +/*! +Writes \a value to the \a name property of \a object. This method is equivalent to: +\code + QDeclarativeProperty p(object, name, ctxt); + p.write(value); +\endcode +*/ +bool QDeclarativeProperty::write(QObject *object, const QString &name, const QVariant &value, + QDeclarativeContext *ctxt) +{ + QDeclarativeProperty p(object, name, ctxt); + return p.write(value); +} + +/*! +Writes \a value to the \a name property of \a object. This method is equivalent to: +\code + QDeclarativeProperty p(object, name, engine); + p.write(value); +\endcode +*/ +bool QDeclarativeProperty::write(QObject *object, const QString &name, const QVariant &value, + QDeclarativeEngine *engine) +{ + QDeclarativeProperty p(object, name, engine); + return p.write(value); +} + +/*! Resets the property value. */ bool QDeclarativeProperty::reset() const @@ -1020,7 +1141,7 @@ bool QDeclarativePropertyPrivate::write(const QDeclarativeProperty &that, /*! Returns true if the property has a change notifier signal, otherwise false. */ -bool QDeclarativeProperty::hasChangedNotifier() const +bool QDeclarativeProperty::hasNotifySignal() const { if (type() & Property && d->object) { return d->object->metaObject()->property(d->core.coreIndex).hasNotifySignal(); @@ -1035,7 +1156,7 @@ bool QDeclarativeProperty::hasChangedNotifier() const Some properties, such as attached properties or those whose value never changes, do not require a change notifier. */ -bool QDeclarativeProperty::needsChangedNotifier() const +bool QDeclarativeProperty::needsNotifySignal() const { return type() & Property && !property().isConstant(); } @@ -1048,7 +1169,7 @@ bool QDeclarativeProperty::needsChangedNotifier() const change notifier signal, or if the \a dest object does not have the specified \a method. */ -bool QDeclarativeProperty::connectNotifier(QObject *dest, int method) const +bool QDeclarativeProperty::connectNotifySignal(QObject *dest, int method) const { if (!(type() & Property) || !d->object) return false; @@ -1069,7 +1190,7 @@ bool QDeclarativeProperty::connectNotifier(QObject *dest, int method) const change notifier signal, or if the \a dest object does not have the specified \a slot. */ -bool QDeclarativeProperty::connectNotifier(QObject *dest, const char *slot) const +bool QDeclarativeProperty::connectNotifySignal(QObject *dest, const char *slot) const { if (!(type() & Property) || !d->object) return false; @@ -1086,7 +1207,7 @@ bool QDeclarativeProperty::connectNotifier(QObject *dest, const char *slot) cons /*! Return the Qt metaobject index of the property. */ -int QDeclarativeProperty::coreIndex() const +int QDeclarativeProperty::index() const { return d->core.coreIndex; } @@ -1097,7 +1218,7 @@ int QDeclarativePropertyPrivate::valueTypeCoreIndex(const QDeclarativeProperty & } struct SerializedData { - QDeclarativeProperty::Type type; + bool isValueType; QDeclarativePropertyCache::Data core; }; @@ -1112,7 +1233,7 @@ QByteArray QDeclarativePropertyPrivate::saveValueType(const QMetaObject *metaObj QMetaProperty subProp = subObject->property(subIndex); ValueTypeSerializedData sd; - sd.type = QDeclarativeProperty::ValueTypeProperty; + sd.isValueType = true; sd.core.load(metaObject->property(index)); sd.valueType.flags = QDeclarativePropertyCache::Data::flagsForProperty(subProp); sd.valueType.valueTypeCoreIdx = subIndex; @@ -1126,7 +1247,7 @@ QByteArray QDeclarativePropertyPrivate::saveValueType(const QMetaObject *metaObj QByteArray QDeclarativePropertyPrivate::saveProperty(const QMetaObject *metaObject, int index) { SerializedData sd; - sd.type = QDeclarativeProperty::Property; + sd.isValueType = false; sd.core.load(metaObject->property(index)); QByteArray rv((const char *)&sd, sizeof(sd)); @@ -1143,14 +1264,15 @@ QDeclarativePropertyPrivate::restore(const QByteArray &data, QObject *object, QD prop.d->object = object; prop.d->context = ctxt; + prop.d->engine = ctxt?ctxt->engine():0; const SerializedData *sd = (const SerializedData *)data.constData(); - if (sd->type == QDeclarativeProperty::Property) { - prop.d->core = sd->core; - } else if(sd->type == QDeclarativeProperty::ValueTypeProperty) { + if (sd->isValueType) { const ValueTypeSerializedData *vt = (const ValueTypeSerializedData *)sd; prop.d->core = vt->core; prop.d->valueType = vt->valueType; + } else { + prop.d->core = sd->core; } return prop; |