summaryrefslogtreecommitdiffstats
path: root/src/declarative/qml/qdeclarativeproperty.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/declarative/qml/qdeclarativeproperty.cpp')
-rw-r--r--src/declarative/qml/qdeclarativeproperty.cpp222
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;