aboutsummaryrefslogtreecommitdiffstats
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.cpp1917
1 files changed, 0 insertions, 1917 deletions
diff --git a/src/declarative/qml/qdeclarativeproperty.cpp b/src/declarative/qml/qdeclarativeproperty.cpp
deleted file mode 100644
index 7ba801d72f..0000000000
--- a/src/declarative/qml/qdeclarativeproperty.cpp
+++ /dev/null
@@ -1,1917 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/
-**
-** This file is part of the QtDeclarative module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qdeclarativeproperty.h"
-#include "qdeclarativeproperty_p.h"
-
-#include "qdeclarative.h"
-#include "qdeclarativebinding_p.h"
-#include "qdeclarativecontext.h"
-#include "qdeclarativecontext_p.h"
-#include "qdeclarativeboundsignal_p.h"
-#include "qdeclarativeengine.h"
-#include "qdeclarativeengine_p.h"
-#include "qdeclarativedata_p.h"
-#include "qdeclarativestringconverters_p.h"
-#include "qdeclarativelist_p.h"
-#include "qdeclarativecompiler_p.h"
-#include "qdeclarativevmemetaobject_p.h"
-#include "qdeclarativeexpression_p.h"
-
-#include <QStringList>
-#include <QtCore/qdebug.h>
-
-#include <math.h>
-
-Q_DECLARE_METATYPE(QList<int>)
-Q_DECLARE_METATYPE(QList<qreal>)
-Q_DECLARE_METATYPE(QList<bool>)
-Q_DECLARE_METATYPE(QList<QString>)
-Q_DECLARE_METATYPE(QList<QUrl>)
-
-QT_BEGIN_NAMESPACE
-
-/*!
-\class QDeclarativeProperty
-\since 4.7
-\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.
-
-For example, for the following QML code:
-
-\qml
-// MyItem.qml
-import QtQuick 2.0
-
-Text { text: "A bit of text" }
-\endqml
-
-The \l Text object's properties could be accessed using QDeclarativeProperty, like this:
-
-\code
-#include <QDeclarativeProperty>
-#include <QGraphicsObject>
-
-...
-
-QDeclarativeView view(QUrl::fromLocalFile("MyItem.qml"));
-QDeclarativeProperty property(view.rootObject(), "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.
-*/
-QDeclarativeProperty::QDeclarativeProperty()
-: d(0)
-{
-}
-
-/*! \internal */
-QDeclarativeProperty::~QDeclarativeProperty()
-{
- if (d)
- d->release();
- d = 0;
-}
-
-/*!
- 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)
-: d(new QDeclarativePropertyPrivate)
-{
- d->initDefault(obj);
-}
-
-/*!
- Creates a QDeclarativeProperty for the default property of \a obj
- using the \l{QDeclarativeContext} {context} \a ctxt. If there is
- no default property, an invalid QDeclarativeProperty will be
- created.
- */
-QDeclarativeProperty::QDeclarativeProperty(QObject *obj, QDeclarativeContext *ctxt)
-: d(new QDeclarativePropertyPrivate)
-{
- d->context = ctxt?QDeclarativeContextData::get(ctxt):0;
- d->engine = ctxt?ctxt->engine():0;
- d->initDefault(obj);
-}
-
-/*!
- Creates a QDeclarativeProperty for the default property of \a obj
- using the environment for instantiating QML components that is
- provided by \a engine. If there is no default property, an
- invalid QDeclarativeProperty will be created.
- */
-QDeclarativeProperty::QDeclarativeProperty(QObject *obj, QDeclarativeEngine *engine)
- : d(new QDeclarativePropertyPrivate)
-{
- d->context = 0;
- d->engine = engine;
- d->initDefault(obj);
-}
-
-/*!
- Initialize from the default property of \a obj
-*/
-void QDeclarativePropertyPrivate::initDefault(QObject *obj)
-{
- if (!obj)
- return;
-
- QMetaProperty p = QDeclarativeMetaType::defaultProperty(obj);
- core.load(p);
- if (core.isValid())
- object = obj;
-}
-
-/*!
- Creates a QDeclarativeProperty for the property \a name of \a obj.
- */
-QDeclarativeProperty::QDeclarativeProperty(QObject *obj, const QString &name)
-: d(new QDeclarativePropertyPrivate)
-{
- d->initProperty(obj, name);
- if (!isValid()) d->object = 0;
-}
-
-/*!
- Creates a QDeclarativeProperty for the property \a name of \a obj
- using the \l{QDeclarativeContext} {context} \a ctxt.
-
- Creating a QDeclarativeProperty without a context will render some
- properties - like attached properties - inaccessible.
-*/
-QDeclarativeProperty::QDeclarativeProperty(QObject *obj, const QString &name, QDeclarativeContext *ctxt)
-: d(new QDeclarativePropertyPrivate)
-{
- d->context = ctxt?QDeclarativeContextData::get(ctxt):0;
- 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
- using the environment for instantiating QML components that is
- provided by \a engine.
- */
-QDeclarativeProperty::QDeclarativeProperty(QObject *obj, const QString &name, QDeclarativeEngine *engine)
-: d(new QDeclarativePropertyPrivate)
-{
- d->context = 0;
- d->engine = engine;
- d->initProperty(obj, name);
- if (!isValid()) { d->object = 0; d->context = 0; d->engine = 0; }
-}
-
-Q_GLOBAL_STATIC(QDeclarativeValueTypeFactory, qmlValueTypes);
-
-QDeclarativePropertyPrivate::QDeclarativePropertyPrivate()
-: context(0), engine(0), object(0), isNameCached(false)
-{
-}
-
-QDeclarativeContextData *QDeclarativePropertyPrivate::effectiveContext() const
-{
- if (context) return context;
- else if (engine) return QDeclarativeContextData::get(engine->rootContext());
- else return 0;
-}
-
-void QDeclarativePropertyPrivate::initProperty(QObject *obj, const QString &name)
-{
- if (!obj) return;
-
- QDeclarativeTypeNameCache *typeNameCache = context?context->imports:0;
-
- QStringList path = name.split(QLatin1Char('.'));
- if (path.isEmpty()) return;
-
- 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 QString &pathName = path.at(ii);
-
- if (typeNameCache) {
- QDeclarativeTypeNameCache::Result r = typeNameCache->query(pathName);
- if (r.isValid()) {
- if (r.type) {
- QDeclarativeAttachedPropertiesFunc func = r.type->attachedPropertiesFunction();
- if (!func) return; // Not an attachable type
-
- currentObject = qmlAttachedPropertiesObjectById(r.type->attachedPropertiesId(), 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) return; // Invalid type in namespace
-
- QDeclarativeAttachedPropertiesFunc func = r.type->attachedPropertiesFunction();
- if (!func) return; // Not an attachable type
-
- currentObject = qmlAttachedPropertiesObjectById(r.type->attachedPropertiesId(), 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;
- }
-
- }
-
- QDeclarativePropertyData local;
- QDeclarativePropertyData *property =
- QDeclarativePropertyCache::property(engine, obj, pathName, local);
-
- if (!property) return; // Not a property
- if (property->isFunction())
- return; // Not an object property
-
- if (ii == (path.count() - 2) && QDeclarativeValueTypeFactory::isValueType(property->propType)) {
- // We're now at a value type property. We can use a global valuetypes array as we
- // never actually use the objects, just look up their properties.
- QObject *typeObject = (*qmlValueTypes())[property->propType];
- if (!typeObject) return; // Not a value type
-
- int idx = typeObject->metaObject()->indexOfProperty(path.last().toUtf8().constData());
- if (idx == -1) return; // Value type property does not exist
-
- QMetaProperty vtProp = typeObject->metaObject()->property(idx);
-
- typedef QDeclarativePropertyData PCD;
-
- Q_ASSERT(PCD::flagsForProperty(vtProp) <= PCD::ValueTypeFlagMask);
- Q_ASSERT(vtProp.userType() <= 0xFF);
- Q_ASSERT(idx <= 0xFF);
-
- object = currentObject;
- core = *property;
- core.setFlags(core.getFlags() | PCD::IsValueTypeVirtual);
- core.valueTypeFlags = PCD::flagsForProperty(vtProp);
- core.valueTypePropType = vtProp.userType();
- core.valueTypeCoreIndex = idx;
-
- return;
- } else {
- if (!property->isQObject())
- return; // Not an object property
-
- void *args[] = { &currentObject, 0 };
- QMetaObject::metacall(currentObject, QMetaObject::ReadProperty, property->coreIndex, args);
- if (!currentObject) return; // No value
-
- }
-
- }
-
- const QString &terminal = path.last();
-
- if (terminal.count() >= 3 &&
- terminal.at(0) == QLatin1Char('o') &&
- terminal.at(1) == QLatin1Char('n') &&
- terminal.at(2).isUpper()) {
-
- QString signalName = terminal.mid(2);
- signalName[0] = signalName.at(0).toLower();
-
- QMetaMethod method = findSignalByName(currentObject->metaObject(), signalName.toLatin1().constData());
- if (method.signature()) {
- object = currentObject;
- core.load(method);
- return;
- }
- }
-
- // Property
- QDeclarativePropertyData local;
- QDeclarativePropertyData *property =
- QDeclarativePropertyCache::property(engine, currentObject, terminal, local);
- if (property && !property->isFunction()) {
- object = currentObject;
- core = *property;
- nameCache = terminal;
- isNameCached = true;
- }
-}
-
-/*!
- Create a copy of \a other.
-*/
-QDeclarativeProperty::QDeclarativeProperty(const QDeclarativeProperty &other)
-{
- d = other.d;
- if (d)
- d->addref();
-}
-
-/*!
- \enum QDeclarativeProperty::PropertyTypeCategory
-
- This enum specifies a category of QML property.
-
- \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 a normal value property.
- */
-
-/*!
- \enum QDeclarativeProperty::Type
-
- This enum specifies a type of QML property.
-
- \value Invalid The property is invalid.
- \value Property The property is a regular Qt property.
- \value SignalProperty The property is a signal property.
-*/
-
-/*!
- Returns the property category.
-*/
-QDeclarativeProperty::PropertyTypeCategory QDeclarativeProperty::propertyTypeCategory() const
-{
- return d ? d->propertyTypeCategory() : InvalidCategory;
-}
-
-QDeclarativeProperty::PropertyTypeCategory
-QDeclarativePropertyPrivate::propertyTypeCategory() const
-{
- uint type = this->type();
-
- if (isValueType()) {
- return QDeclarativeProperty::Normal;
- } else if (type & QDeclarativeProperty::Property) {
- int type = propertyType();
- if (type == QVariant::Invalid)
- return QDeclarativeProperty::InvalidCategory;
- else if (QDeclarativeValueTypeFactory::isValueType((uint)type))
- return QDeclarativeProperty::Normal;
- else if (core.isQObject())
- return QDeclarativeProperty::Object;
- else if (core.isQList())
- return QDeclarativeProperty::List;
- else
- return QDeclarativeProperty::Normal;
- } else {
- return QDeclarativeProperty::InvalidCategory;
- }
-}
-
-/*!
- Returns the type name of the property, or 0 if the property has no type
- name.
-*/
-const char *QDeclarativeProperty::propertyTypeName() const
-{
- if (!d)
- return 0;
- if (d->isValueType()) {
-
- 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);
- Q_ASSERT(valueType);
-
- const char *rv = valueType->metaObject()->property(d->core.valueTypeCoreIndex).typeName();
-
- if (!ep) delete valueType;
-
- return rv;
- } else if (d->object && type() & Property && d->core.isValid()) {
- return d->object->metaObject()->property(d->core.coreIndex).typeName();
- } else {
- return 0;
- }
-}
-
-/*!
- Returns true if \a other and this QDeclarativeProperty represent the same
- property.
-*/
-bool QDeclarativeProperty::operator==(const QDeclarativeProperty &other) const
-{
- if (!d || !other.d)
- return false;
- // category is intentially omitted here as it is generated
- // from the other members
- return d->object == other.d->object &&
- d->core.coreIndex == other.d->core.coreIndex &&
- d->core.isValueTypeVirtual() == other.d->core.isValueTypeVirtual() &&
- (!d->core.isValueTypeVirtual() ||
- (d->core.valueTypeCoreIndex == other.d->core.valueTypeCoreIndex &&
- d->core.valueTypePropType == other.d->core.valueTypePropType));
-}
-
-/*!
- Returns the QVariant type of the property, or QVariant::Invalid if the
- property has no QVariant type.
-*/
-int QDeclarativeProperty::propertyType() const
-{
- return d ? d->propertyType() : int(QVariant::Invalid);
-}
-
-bool QDeclarativePropertyPrivate::isValueType() const
-{
- return core.isValueTypeVirtual();
-}
-
-int QDeclarativePropertyPrivate::propertyType() const
-{
- uint type = this->type();
- if (isValueType()) {
- return core.valueTypePropType;
- } else if (type & QDeclarativeProperty::Property) {
- return core.propType;
- } else {
- return QVariant::Invalid;
- }
-}
-
-QDeclarativeProperty::Type QDeclarativePropertyPrivate::type() const
-{
- if (core.isFunction())
- return QDeclarativeProperty::SignalProperty;
- else if (core.isValid())
- return QDeclarativeProperty::Property;
- else
- return QDeclarativeProperty::Invalid;
-}
-
-/*!
- Returns the type of the property.
-*/
-QDeclarativeProperty::Type QDeclarativeProperty::type() const
-{
- return d ? d->type() : Invalid;
-}
-
-/*!
- Returns true if this QDeclarativeProperty represents a regular Qt property.
-*/
-bool QDeclarativeProperty::isProperty() const
-{
- return type() & Property;
-}
-
-/*!
- Returns true if this QDeclarativeProperty represents a QML signal property.
-*/
-bool QDeclarativeProperty::isSignalProperty() const
-{
- return type() & SignalProperty;
-}
-
-/*!
- Returns the QDeclarativeProperty's QObject.
-*/
-QObject *QDeclarativeProperty::object() const
-{
- return d ? d->object : 0;
-}
-
-/*!
- Assign \a other to this QDeclarativeProperty.
-*/
-QDeclarativeProperty &QDeclarativeProperty::operator=(const QDeclarativeProperty &other)
-{
- if (d)
- d->release();
- d = other.d;
- if (d)
- d->addref();
-
- return *this;
-}
-
-/*!
- Returns true if the property is writable, otherwise false.
-*/
-bool QDeclarativeProperty::isWritable() const
-{
- if (!d)
- return false;
- if (!d->object)
- return false;
- if (d->core.isQList()) //list
- return true;
- else if (d->core.isFunction()) //signal handler
- return false;
- else if (d->core.isValid()) //normal property
- return d->core.isWritable();
- else
- return false;
-}
-
-/*!
- Returns true if the property is designable, otherwise false.
-*/
-bool QDeclarativeProperty::isDesignable() const
-{
- if (!d)
- return false;
- if (type() & Property && d->core.isValid() && d->object)
- return d->object->metaObject()->property(d->core.coreIndex).isDesignable();
- else
- return false;
-}
-
-/*!
- Returns true if the property is resettable, otherwise false.
-*/
-bool QDeclarativeProperty::isResettable() const
-{
- if (!d)
- return false;
- if (type() & Property && d->core.isValid() && d->object)
- return d->core.isResettable();
- else
- return false;
-}
-
-/*!
- Returns true if the QDeclarativeProperty refers to a valid property, otherwise
- false.
-*/
-bool QDeclarativeProperty::isValid() const
-{
- if (!d)
- return false;
- return type() != Invalid;
-}
-
-/*!
- Return the name of this QML property.
-*/
-QString QDeclarativeProperty::name() const
-{
- if (!d)
- return QString();
- if (!d->isNameCached) {
- // ###
- if (!d->object) {
- } else if (d->isValueType()) {
- QString rv = d->core.name(d->object) + QLatin1Char('.');
-
- 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);
- Q_ASSERT(valueType);
-
- const char *vtName = valueType->metaObject()->property(d->core.valueTypeCoreIndex).name();
- rv += QString::fromUtf8(vtName);
-
- if (!ep) delete valueType;
-
- d->nameCache = rv;
- } else if (type() & SignalProperty) {
- QString name = QLatin1String("on") + d->core.name(d->object);
- name[2] = name.at(2).toUpper();
- d->nameCache = name;
- } else {
- d->nameCache = d->core.name(d->object);
- }
- d->isNameCached = true;
- }
-
- return d->nameCache;
-}
-
-/*!
- Returns the \l{QMetaProperty} {Qt property} associated with
- this QML property.
- */
-QMetaProperty QDeclarativeProperty::property() const
-{
- if (!d)
- return QMetaProperty();
- if (type() & Property && d->core.isValid() && d->object)
- return d->object->metaObject()->property(d->core.coreIndex);
- else
- return QMetaProperty();
-}
-
-/*!
- Return the QMetaMethod for this property if it is a SignalProperty,
- otherwise returns an invalid QMetaMethod.
-*/
-QMetaMethod QDeclarativeProperty::method() const
-{
- if (!d)
- return QMetaMethod();
- if (type() & SignalProperty && d->object)
- return d->object->metaObject()->method(d->core.coreIndex);
- else
- return QMetaMethod();
-}
-
-/*!
- Returns the binding associated with this property, or 0 if no binding
- exists.
-*/
-QDeclarativeAbstractBinding *
-QDeclarativePropertyPrivate::binding(const QDeclarativeProperty &that)
-{
- if (!that.d || !that.isProperty() || !that.d->object)
- return 0;
-
- return binding(that.d->object, that.d->core.coreIndex,
- that.d->core.getValueTypeCoreIndex());
-}
-
-/*!
- Set the binding associated with this property to \a newBinding. Returns
- the existing binding (if any), otherwise 0.
-
- \a newBinding will be enabled, and the returned binding (if any) will be
- disabled.
-
- Ownership of \a newBinding transfers to QML. Ownership of the return value
- is assumed by the caller.
-
- \a flags is passed through to the binding and is used for the initial update (when
- the binding sets the initial value, it will use these flags for the write).
-*/
-QDeclarativeAbstractBinding *
-QDeclarativePropertyPrivate::setBinding(const QDeclarativeProperty &that,
- QDeclarativeAbstractBinding *newBinding,
- WriteFlags flags)
-{
- if (!that.d || !that.isProperty() || !that.d->object) {
- if (newBinding)
- newBinding->destroy();
- return 0;
- }
-
- if (newBinding) {
- // In the case that the new binding is provided, we must target the property it
- // is associated with. If we don't do this, retargetBinding() can fail.
- QObject *object = newBinding->object();
- int pi = newBinding->propertyIndex();
-
- int core = pi & 0xFFFFFF;
- int vt = (pi & 0xFF000000)?(pi >> 24):-1;
-
- return setBinding(object, core, vt, newBinding, flags);
- } else {
- return setBinding(that.d->object, that.d->core.coreIndex,
- that.d->core.getValueTypeCoreIndex(),
- newBinding, flags);
- }
-}
-
-QDeclarativeAbstractBinding *
-QDeclarativePropertyPrivate::binding(QObject *object, int coreIndex, int valueTypeIndex)
-{
- QDeclarativeData *data = QDeclarativeData::get(object);
- if (!data)
- return 0;
-
- QDeclarativePropertyData *propertyData =
- data->propertyCache?data->propertyCache->property(coreIndex):0;
- if (propertyData && propertyData->isAlias()) {
- const QDeclarativeVMEMetaObject *vme =
- static_cast<const QDeclarativeVMEMetaObject *>(metaObjectForProperty(object->metaObject(), coreIndex));
-
- QObject *aObject = 0; int aCoreIndex = -1; int aValueTypeIndex = -1;
- if (!vme->aliasTarget(coreIndex, &aObject, &aCoreIndex, &aValueTypeIndex) || aCoreIndex == -1)
- return 0;
-
- // 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);
- aValueTypeIndex = (valueTypeIndex == -1)?aValueTypeIndex:valueTypeIndex;
- return binding(aObject, aCoreIndex, aValueTypeIndex);
- }
-
- if (!data->hasBindingBit(coreIndex))
- return 0;
-
- QDeclarativeAbstractBinding *binding = data->bindings;
- while (binding && binding->propertyIndex() != coreIndex)
- binding = binding->m_nextBinding;
-
- if (binding && valueTypeIndex != -1) {
- if (binding->bindingType() == QDeclarativeAbstractBinding::ValueTypeProxy) {
- int index = coreIndex | (valueTypeIndex << 24);
- binding = static_cast<QDeclarativeValueTypeProxyBinding *>(binding)->binding(index);
- }
- }
-
- return binding;
-}
-
-void QDeclarativePropertyPrivate::findAliasTarget(QObject *object, int bindingIndex,
- QObject **targetObject, int *targetBindingIndex)
-{
- int coreIndex = bindingIndex & 0xFFFFFF;
- int valueTypeIndex = bindingIndex >> 24;
- if (valueTypeIndex == 0) valueTypeIndex = -1;
-
- QDeclarativeData *data = QDeclarativeData::get(object, false);
- if (data) {
- QDeclarativePropertyData *propertyData =
- data->propertyCache?data->propertyCache->property(coreIndex):0;
- if (propertyData && propertyData->isAlias()) {
- const QDeclarativeVMEMetaObject *vme =
- static_cast<const QDeclarativeVMEMetaObject *>(metaObjectForProperty(object->metaObject(), coreIndex));
- QObject *aObject = 0; 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);
-
- int aBindingIndex = aCoreIndex;
- if (aValueTypeIndex != -1)
- aBindingIndex |= aValueTypeIndex << 24;
- else if (valueTypeIndex != -1)
- aBindingIndex |= valueTypeIndex << 24;
-
- findAliasTarget(aObject, aBindingIndex, targetObject, targetBindingIndex);
- return;
- }
- }
- }
-
- *targetObject = object;
- *targetBindingIndex = bindingIndex;
-}
-
-QDeclarativeAbstractBinding *
-QDeclarativePropertyPrivate::setBinding(QObject *object, int coreIndex, int valueTypeIndex,
- QDeclarativeAbstractBinding *newBinding, WriteFlags flags)
-{
- QDeclarativeData *data = QDeclarativeData::get(object, 0 != newBinding);
- QDeclarativeAbstractBinding *binding = 0;
-
- if (data) {
- QDeclarativePropertyData *propertyData =
- data->propertyCache?data->propertyCache->property(coreIndex):0;
- if (propertyData && propertyData->isAlias()) {
- const QDeclarativeVMEMetaObject *vme =
- static_cast<const QDeclarativeVMEMetaObject *>(metaObjectForProperty(object->metaObject(), coreIndex));
-
- QObject *aObject = 0; int aCoreIndex = -1; int aValueTypeIndex = -1;
- if (!vme->aliasTarget(coreIndex, &aObject, &aCoreIndex, &aValueTypeIndex)) {
- if (newBinding) newBinding->destroy();
- return 0;
- }
-
- // 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);
- aValueTypeIndex = (valueTypeIndex == -1)?aValueTypeIndex:valueTypeIndex;
- return setBinding(aObject, aCoreIndex, aValueTypeIndex, newBinding, flags);
- }
- }
-
- if (data && data->hasBindingBit(coreIndex)) {
- binding = data->bindings;
-
- while (binding && binding->propertyIndex() != coreIndex)
- binding = binding->m_nextBinding;
- }
-
- int index = coreIndex;
- if (valueTypeIndex != -1)
- index |= (valueTypeIndex << 24);
-
- if (binding && valueTypeIndex != -1 && binding->bindingType() == QDeclarativeAbstractBinding::ValueTypeProxy)
- binding = static_cast<QDeclarativeValueTypeProxyBinding *>(binding)->binding(index);
-
- if (binding) {
- binding->removeFromObject();
- binding->setEnabled(false, 0);
- }
-
- if (newBinding) {
- if (newBinding->propertyIndex() != index || newBinding->object() != object)
- newBinding->retargetBinding(object, index);
-
- Q_ASSERT(newBinding->propertyIndex() == index);
- Q_ASSERT(newBinding->object() == object);
-
- newBinding->addToObject();
- newBinding->setEnabled(true, flags);
- }
-
- return binding;
-}
-
-QDeclarativeAbstractBinding *
-QDeclarativePropertyPrivate::setBindingNoEnable(QObject *object, int coreIndex, int valueTypeIndex,
- QDeclarativeAbstractBinding *newBinding)
-{
- QDeclarativeData *data = QDeclarativeData::get(object, 0 != newBinding);
- QDeclarativeAbstractBinding *binding = 0;
-
- if (data) {
- QDeclarativePropertyData *propertyData =
- data->propertyCache?data->propertyCache->property(coreIndex):0;
- if (propertyData && propertyData->isAlias()) {
- const QDeclarativeVMEMetaObject *vme =
- static_cast<const QDeclarativeVMEMetaObject *>(metaObjectForProperty(object->metaObject(), coreIndex));
-
- QObject *aObject = 0; int aCoreIndex = -1; int aValueTypeIndex = -1;
- if (!vme->aliasTarget(coreIndex, &aObject, &aCoreIndex, &aValueTypeIndex)) {
- if (newBinding) newBinding->destroy();
- return 0;
- }
-
- // 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);
- aValueTypeIndex = (valueTypeIndex == -1)?aValueTypeIndex:valueTypeIndex;
- return setBindingNoEnable(aObject, aCoreIndex, aValueTypeIndex, newBinding);
- }
- }
-
- if (data && data->hasBindingBit(coreIndex)) {
- binding = data->bindings;
-
- while (binding && binding->propertyIndex() != coreIndex)
- binding = binding->m_nextBinding;
- }
-
- int index = coreIndex;
- if (valueTypeIndex != -1)
- index |= (valueTypeIndex << 24);
-
- if (binding && valueTypeIndex != -1 && binding->bindingType() == QDeclarativeAbstractBinding::ValueTypeProxy)
- binding = static_cast<QDeclarativeValueTypeProxyBinding *>(binding)->binding(index);
-
- if (binding)
- binding->removeFromObject();
-
- if (newBinding) {
- if (newBinding->propertyIndex() != index || newBinding->object() != object)
- newBinding->retargetBinding(object, index);
-
- Q_ASSERT(newBinding->propertyIndex() == index);
- Q_ASSERT(newBinding->object() == object);
-
- newBinding->addToObject();
- }
-
- return binding;
-}
-
-/*!
- Returns the expression associated with this signal property, or 0 if no
- signal expression exists.
-*/
-QDeclarativeExpression *
-QDeclarativePropertyPrivate::signalExpression(const QDeclarativeProperty &that)
-{
- if (!(that.type() & QDeclarativeProperty::SignalProperty))
- return 0;
-
- const QObjectList &children = that.d->object->children();
-
- for (int ii = 0; ii < children.count(); ++ii) {
- QObject *child = children.at(ii);
-
- QDeclarativeBoundSignal *signal = QDeclarativeBoundSignal::cast(child);
- if (signal && signal->index() == that.index())
- return signal->expression();
- }
-
- return 0;
-}
-
-/*!
- Set the signal expression associated with this signal property to \a expr.
- Returns the existing signal expression (if any), otherwise 0.
-
- Ownership of \a expr transfers to QML. Ownership of the return value is
- assumed by the caller.
-*/
-QDeclarativeExpression *
-QDeclarativePropertyPrivate::setSignalExpression(const QDeclarativeProperty &that,
- QDeclarativeExpression *expr)
-{
- if (!(that.type() & QDeclarativeProperty::SignalProperty)) {
- delete expr;
- return 0;
- }
-
- const QObjectList &children = that.d->object->children();
-
- for (int ii = 0; ii < children.count(); ++ii) {
- QObject *child = children.at(ii);
-
- QDeclarativeBoundSignal *signal = QDeclarativeBoundSignal::cast(child);
- if (signal && signal->index() == that.index())
- return signal->setExpression(expr);
- }
-
- if (expr) {
- QDeclarativeBoundSignal *signal = new QDeclarativeBoundSignal(that.d->object, that.method(), that.d->object);
- return signal->setExpression(expr);
- } else {
- return 0;
- }
-}
-
-/*!
- Returns the property value.
-*/
-QVariant QDeclarativeProperty::read() const
-{
- if (!d)
- return QVariant();
- if (!d->object)
- return QVariant();
-
- if (type() & SignalProperty) {
-
- return QVariant();
-
- } else if (type() & Property) {
-
- return d->readValueProperty();
-
- }
- 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 using the
- \l{QDeclarativeContext} {context} \a ctxt. 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 using the environment
- for instantiating QML components that is provided by \a engine. .
- 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()
-{
- if (isValueType()) {
-
- QDeclarativeEnginePrivate *ep = engine?QDeclarativeEnginePrivate::get(engine):0;
- QDeclarativeValueType *valueType = 0;
- if (ep) valueType = ep->valueTypes[core.propType];
- else valueType = QDeclarativeValueTypeFactory::valueType(core.propType);
- Q_ASSERT(valueType);
-
- valueType->read(object, core.coreIndex);
-
- QVariant rv = valueType->metaObject()->property(core.valueTypeCoreIndex).read(valueType);
-
- if (!ep) delete valueType;
- return rv;
-
- } else if (core.isQList()) {
-
- QDeclarativeListProperty<QObject> prop;
- void *args[] = { &prop, 0 };
- QMetaObject::metacall(object, QMetaObject::ReadProperty, core.coreIndex, args);
- return QVariant::fromValue(QDeclarativeListReferencePrivate::init(prop, core.propType, engine));
-
- } else if (core.isQObject()) {
-
- QObject *rv = 0;
- void *args[] = { &rv, 0 };
- QMetaObject::metacall(object, QMetaObject::ReadProperty, core.coreIndex, args);
- return QVariant::fromValue(rv);
-
- } else {
-
- return object->metaObject()->property(core.coreIndex).read(object.data());
-
- }
-}
-
-static QUrl urlFromUserString(const QByteArray &data)
-{
- QUrl u;
- if (!data.isEmpty())
- {
- // Preserve any valid percent-encoded octets supplied by the source
- u.setEncodedUrl(data, QUrl::TolerantMode);
- }
- return u;
-}
-
-static QUrl urlFromUserString(const QString &data)
-{
- return urlFromUserString(data.toUtf8());
-}
-
-// helper function to allow assignment / binding to QList<QUrl> properties.
-static QVariant resolvedUrlSequence(const QVariant &value, QDeclarativeContextData *context)
-{
- QList<QUrl> urls;
- if (value.userType() == qMetaTypeId<QUrl>()) {
- urls.append(value.toUrl());
- } else if (value.userType() == qMetaTypeId<QString>()) {
- urls.append(urlFromUserString(value.toString()));
- } else if (value.userType() == qMetaTypeId<QByteArray>()) {
- urls.append(urlFromUserString(value.toByteArray()));
- } else if (value.userType() == qMetaTypeId<QList<QUrl> >()) {
- urls = value.value<QList<QUrl> >();
- } else if (value.userType() == qMetaTypeId<QStringList>()) {
- QStringList urlStrings = value.value<QStringList>();
- for (int i = 0; i < urlStrings.size(); ++i)
- urls.append(urlFromUserString(urlStrings.at(i)));
- } else if (value.userType() == qMetaTypeId<QList<QString> >()) {
- QList<QString> urlStrings = value.value<QList<QString> >();
- for (int i = 0; i < urlStrings.size(); ++i)
- urls.append(urlFromUserString(urlStrings.at(i)));
- } // note: QList<QByteArray> is not currently supported.
-
- QList<QUrl> resolvedUrls;
- for (int i = 0; i < urls.size(); ++i) {
- QUrl u = urls.at(i);
- if (context && u.isRelative() && !u.isEmpty())
- u = context->resolvedUrl(u);
- resolvedUrls.append(u);
- }
-
- return QVariant::fromValue<QList<QUrl> >(resolvedUrls);
-}
-
-//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())
- return false;
-
- QVariant v = value;
- if (prop.isEnumType()) {
- QMetaEnum menum = prop.enumerator();
- if (v.userType() == QVariant::String
-#ifdef QT3_SUPPORT
- || v.userType() == QVariant::CString
-#endif
- ) {
- bool ok;
- if (prop.isFlagType())
- v = QVariant(menum.keysToValue(value.toByteArray(), &ok));
- else
- v = QVariant(menum.keyToValue(value.toByteArray(), &ok));
- if (!ok)
- return false;
- } else if (v.userType() != QVariant::Int && v.userType() != QVariant::UInt) {
- int enumMetaTypeId = QMetaType::type(QByteArray(menum.scope() + QByteArray("::") + menum.name()));
- if ((enumMetaTypeId == 0) || (v.userType() != enumMetaTypeId) || !v.constData())
- return false;
- v = QVariant(*reinterpret_cast<const int *>(v.constData()));
- }
- v.convert(QVariant::Int);
- }
-
- // the status variable is changed by qt_metacall to indicate what it did
- // this feature is currently only used by QtDBus and should not be depended
- // upon. Don't change it without looking into QDBusAbstractInterface first
- // -1 (unchanged): normal qt_metacall, result stored in argv[0]
- // changed: result stored directly in value, return the value of status
- int status = -1;
- void *argv[] = { v.data(), &v, &status, &flags };
- QMetaObject::metacall(object, QMetaObject::WriteProperty, idx, argv);
- return status;
-}
-
-bool QDeclarativePropertyPrivate::writeValueProperty(const QVariant &value, WriteFlags flags)
-{
- return writeValueProperty(object, engine, core, value, effectiveContext(), flags);
-}
-
-bool
-QDeclarativePropertyPrivate::writeValueProperty(QObject *object, QDeclarativeEngine *engine,
- const QDeclarativePropertyData &core,
- const QVariant &value,
- QDeclarativeContextData *context, WriteFlags flags)
-{
- // Remove any existing bindings on this property
- if (!(flags & DontRemoveBinding) && object) {
- QDeclarativeAbstractBinding *binding = setBinding(object, core.coreIndex,
- core.getValueTypeCoreIndex(),
- 0, flags);
- if (binding) binding->destroy();
- }
-
- bool rv = false;
- if (core.isValueTypeVirtual()) {
- QDeclarativeEnginePrivate *ep = engine?QDeclarativeEnginePrivate::get(engine):0;
-
- QDeclarativeValueType *writeBack = 0;
- if (ep) {
- writeBack = ep->valueTypes[core.propType];
- } else {
- writeBack = QDeclarativeValueTypeFactory::valueType(core.propType);
- }
-
- writeBack->read(object, core.coreIndex);
-
- QDeclarativePropertyData data = core;
- data.setFlags(QDeclarativePropertyData::Flag(core.valueTypeFlags));
- data.coreIndex = core.valueTypeCoreIndex;
- data.propType = core.valueTypePropType;
-
- rv = write(writeBack, data, value, context, flags);
-
- writeBack->write(object, core.coreIndex, flags);
- if (!ep) delete writeBack;
-
- } else {
-
- rv = write(object, core, value, context, flags);
-
- }
-
- return rv;
-}
-
-bool QDeclarativePropertyPrivate::write(QObject *object,
- const QDeclarativePropertyData &property,
- const QVariant &value, QDeclarativeContextData *context,
- WriteFlags flags)
-{
- int coreIdx = property.coreIndex;
- int status = -1; //for dbus
-
- if (property.isEnum()) {
- QMetaProperty prop = object->metaObject()->property(property.coreIndex);
- QVariant v = value;
- // Enum values come through the script engine as doubles
- if (value.userType() == QVariant::Double) {
- double integral;
- double fractional = modf(value.toDouble(), &integral);
- if (qFuzzyIsNull(fractional))
- v.convert(QVariant::Int);
- }
- return writeEnumProperty(prop, coreIdx, object, v, flags);
- }
-
- int propertyType = property.propType;
- int variantType = value.userType();
-
- QDeclarativeEnginePrivate *enginePriv = QDeclarativeEnginePrivate::get(context);
-
- if (propertyType == QVariant::Url) {
-
- QUrl u;
- bool found = false;
- if (variantType == QVariant::Url) {
- u = value.toUrl();
- found = true;
- } else if (variantType == QVariant::ByteArray) {
- u = urlFromUserString(value.toByteArray());
- found = true;
- } else if (variantType == QVariant::String) {
- u = urlFromUserString(value.toString());
- found = true;
- }
-
- if (!found)
- return false;
-
- if (context && u.isRelative() && !u.isEmpty())
- u = context->resolvedUrl(u);
- int status = -1;
- void *argv[] = { &u, 0, &status, &flags };
- QMetaObject::metacall(object, QMetaObject::WriteProperty, coreIdx, argv);
-
- } else if (propertyType == qMetaTypeId<QList<QUrl> >()) {
- QList<QUrl> urlSeq = resolvedUrlSequence(value, context).value<QList<QUrl> >();
- int status = -1;
- void *argv[] = { &urlSeq, 0, &status, &flags };
- QMetaObject::metacall(object, QMetaObject::WriteProperty, coreIdx, argv);
- } else if (variantType == propertyType) {
-
- void *a[] = { (void *)value.constData(), 0, &status, &flags };
- QMetaObject::metacall(object, QMetaObject::WriteProperty, coreIdx, a);
-
- } else if (qMetaTypeId<QVariant>() == propertyType) {
-
- void *a[] = { (void *)&value, 0, &status, &flags };
- QMetaObject::metacall(object, QMetaObject::WriteProperty, coreIdx, a);
-
- } else if (property.isQObject()) {
-
- const QMetaObject *valMo = rawMetaObjectForType(enginePriv, value.userType());
-
- if (!valMo)
- return false;
-
- QObject *o = *(QObject **)value.constData();
- const QMetaObject *propMo = rawMetaObjectForType(enginePriv, propertyType);
-
- if (o) valMo = o->metaObject();
-
- if (canConvert(valMo, propMo)) {
- void *args[] = { &o, 0, &status, &flags };
- QMetaObject::metacall(object, QMetaObject::WriteProperty, coreIdx,
- args);
- } else if (!o && canConvert(propMo, valMo)) {
- // In the case of a null QObject, we assign the null if there is
- // any change that the null variant type could be up or down cast to
- // the property type.
- void *args[] = { &o, 0, &status, &flags };
- QMetaObject::metacall(object, QMetaObject::WriteProperty, coreIdx,
- args);
- } else {
- return false;
- }
-
- } else if (property.isQList()) {
-
- const QMetaObject *listType = 0;
- if (enginePriv) {
- listType = enginePriv->rawMetaObjectForType(enginePriv->listType(property.propType));
- } else {
- QDeclarativeType *type = QDeclarativeMetaType::qmlType(QDeclarativeMetaType::listType(property.propType));
- if (!type) return false;
- listType = type->baseMetaObject();
- }
- if (!listType) return false;
-
- QDeclarativeListProperty<void> prop;
- void *args[] = { &prop, 0 };
- QMetaObject::metacall(object, QMetaObject::ReadProperty, coreIdx, args);
-
- if (!prop.clear) return false;
-
- prop.clear(&prop);
-
- if (value.userType() == qMetaTypeId<QDeclarativeListReference>()) {
- QDeclarativeListReference qdlr = value.value<QDeclarativeListReference>();
-
- for (int ii = 0; ii < qdlr.count(); ++ii) {
- QObject *o = qdlr.at(ii);
- if (o && !canConvert(o->metaObject(), listType))
- o = 0;
- prop.append(&prop, (void *)o);
- }
- } else if (value.userType() == qMetaTypeId<QList<QObject *> >()) {
- const QList<QObject *> &list = qvariant_cast<QList<QObject *> >(value);
-
- for (int ii = 0; ii < list.count(); ++ii) {
- QObject *o = list.at(ii);
- if (o && !canConvert(o->metaObject(), listType))
- o = 0;
- prop.append(&prop, (void *)o);
- }
- } else {
- QObject *o = enginePriv?enginePriv->toQObject(value):QDeclarativeMetaType::toQObject(value);
- if (o && !canConvert(o->metaObject(), listType))
- o = 0;
- prop.append(&prop, (void *)o);
- }
-
- } else {
- Q_ASSERT(variantType != propertyType);
-
- bool ok = false;
- QVariant v;
- if (variantType == QVariant::String)
- v = QDeclarativeStringConverters::variantFromString(value.toString(), propertyType, &ok);
- if (!ok) {
- v = value;
- if (v.convert((QVariant::Type)propertyType)) {
- ok = true;
- } else if ((uint)propertyType >= QVariant::UserType && variantType == QVariant::String) {
- QDeclarativeMetaType::StringConverter con = QDeclarativeMetaType::customStringConverter(propertyType);
- if (con) {
- v = con(value.toString());
- if (v.userType() == propertyType)
- ok = true;
- }
- }
- }
- if (!ok) {
- // the only other option is that they are assigning a single value
- // to a sequence type property (eg, an int to a QList<int> property).
- // Note that we've already handled single-value assignment to QList<QUrl> properties.
- if (variantType == QVariant::Int && propertyType == qMetaTypeId<QList<int> >()) {
- QList<int> list;
- list << value.toInt();
- v = QVariant::fromValue<QList<int> >(list);
- ok = true;
- } else if (variantType == QVariant::Double && propertyType == qMetaTypeId<QList<qreal> >()) {
- QList<qreal> list;
- list << value.toReal();
- v = QVariant::fromValue<QList<qreal> >(list);
- ok = true;
- } else if (variantType == QVariant::Bool && propertyType == qMetaTypeId<QList<bool> >()) {
- QList<bool> list;
- list << value.toBool();
- v = QVariant::fromValue<QList<bool> >(list);
- ok = true;
- } else if (variantType == QVariant::String && propertyType == qMetaTypeId<QList<QString> >()) {
- QList<QString> list;
- list << value.toString();
- v = QVariant::fromValue<QList<QString> >(list);
- ok = true;
- } else if (variantType == QVariant::String && propertyType == qMetaTypeId<QStringList>()) {
- QStringList list;
- list << value.toString();
- v = QVariant::fromValue<QStringList>(list);
- ok = true;
- }
- }
-
- if (ok) {
- void *a[] = { (void *)v.constData(), 0, &status, &flags};
- QMetaObject::metacall(object, QMetaObject::WriteProperty, coreIdx, a);
- } else {
- return false;
- }
- }
-
- return true;
-}
-
-// Returns true if successful, false if an error description was set on expression
-bool QDeclarativePropertyPrivate::writeBinding(QObject *object,
- const QDeclarativePropertyData &core,
- QDeclarativeContextData *context,
- QDeclarativeJavaScriptExpression *expression,
- v8::Handle<v8::Value> result, bool isUndefined,
- WriteFlags flags)
-{
- Q_ASSERT(object);
- Q_ASSERT(core.coreIndex != -1);
-
- QDeclarativeEngine *engine = context->engine;
- QV8Engine *v8engine = QDeclarativeEnginePrivate::getV8Engine(engine);
-
-#define QUICK_STORE(cpptype, conversion) \
- { \
- cpptype o = (conversion); \
- int status = -1; \
- void *argv[] = { &o, 0, &status, &flags }; \
- QMetaObject::metacall(object, QMetaObject::WriteProperty, core.coreIndex, argv); \
- return true; \
- } \
-
-
- if (!isUndefined && !core.isValueTypeVirtual()) {
- switch (core.propType) {
- case QMetaType::Int:
- if (result->IsInt32())
- QUICK_STORE(int, result->Int32Value())
- else if (result->IsNumber())
- QUICK_STORE(int, qRound(result->NumberValue()))
- break;
- case QMetaType::Double:
- if (result->IsNumber())
- QUICK_STORE(double, result->NumberValue())
- break;
- case QMetaType::Float:
- if (result->IsNumber())
- QUICK_STORE(float, result->NumberValue())
- break;
- case QMetaType::QString:
- if (result->IsString())
- QUICK_STORE(QString, v8engine->toString(result))
- break;
- default:
- break;
- }
- }
-#undef QUICK_STORE
-
- int type = core.isValueTypeVirtual()?core.valueTypePropType:core.propType;
-
- QDeclarativeJavaScriptExpression::DeleteWatcher watcher(expression);
-
- QVariant value;
- bool isVmeProperty = core.isVMEProperty();
-
- if (isUndefined) {
- } else if (core.isQList()) {
- value = v8engine->toVariant(result, qMetaTypeId<QList<QObject *> >());
- } else if (result->IsNull() && core.isQObject()) {
- value = QVariant::fromValue((QObject *)0);
- } else if (core.propType == qMetaTypeId<QList<QUrl> >()) {
- value = resolvedUrlSequence(v8engine->toVariant(result, qMetaTypeId<QList<QUrl> >()), context);
- } else if (!isVmeProperty) {
- value = v8engine->toVariant(result, type);
- }
-
- if (expression->hasError()) {
- return false;
- } else if (isUndefined && core.isResettable()) {
- void *args[] = { 0 };
- QMetaObject::metacall(object, QMetaObject::ResetProperty, core.coreIndex, args);
- } else if (isUndefined && type == qMetaTypeId<QVariant>()) {
- writeValueProperty(object, engine, core, QVariant(), context, flags);
- } else if (isUndefined) {
- expression->delayedError()->error.setDescription(QLatin1String("Unable to assign [undefined] to ") + QLatin1String(QMetaType::typeName(type)));
- return false;
- } else if (result->IsFunction()) {
- expression->delayedError()->error.setDescription(QLatin1String("Unable to assign a function to a property."));
- return false;
- } else if (isVmeProperty) {
- typedef QDeclarativeVMEMetaObject VMEMO;
- VMEMO *vmemo = static_cast<VMEMO *>(const_cast<QMetaObject *>(object->metaObject()));
- vmemo->setVMEProperty(core.coreIndex, result);
- } else if (!writeValueProperty(object, engine, core, value, context, flags)) {
-
- if (watcher.wasDeleted())
- return true;
-
- const char *valueType = 0;
- if (value.userType() == QVariant::Invalid) valueType = "null";
- else valueType = QMetaType::typeName(value.userType());
-
- expression->delayedError()->error.setDescription(QLatin1String("Unable to assign ") +
- QLatin1String(valueType) +
- QLatin1String(" to ") +
- QLatin1String(QMetaType::typeName(type)));
- return false;
- }
-
- return true;
-}
-
-bool QDeclarativePropertyPrivate::writeBinding(const QDeclarativeProperty &that,
- QDeclarativeContextData *context,
- QDeclarativeJavaScriptExpression *expression,
- v8::Handle<v8::Value> result, bool isUndefined,
- WriteFlags flags)
-{
- QDeclarativePropertyPrivate *pp = that.d;
-
- if (!pp)
- return true;
-
- QObject *object = that.object();
- if (!object)
- return true;
-
- return writeBinding(object, pp->core, context, expression, result, isUndefined, flags);
-}
-
-const QMetaObject *QDeclarativePropertyPrivate::rawMetaObjectForType(QDeclarativeEnginePrivate *engine, int userType)
-{
- if (engine) {
- return engine->rawMetaObjectForType(userType);
- } else {
- QDeclarativeType *type = QDeclarativeMetaType::qmlType(userType);
- return type?type->baseMetaObject():0;
- }
-}
-
-/*!
- Sets the property value to \a value and returns true.
- Returns false if the property can't be set because the
- \a value is the wrong type, for example.
- */
-bool QDeclarativeProperty::write(const QVariant &value) const
-{
- return QDeclarativePropertyPrivate::write(*this, value, 0);
-}
-
-/*!
- 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 using the
- \l{QDeclarativeContext} {context} \a ctxt. 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 using the
- environment for instantiating QML components that is provided by
- \a engine. 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 and returns true if the property is
- resettable. If the property is not resettable, nothing happens
- and false is returned.
-*/
-bool QDeclarativeProperty::reset() const
-{
- if (isResettable()) {
- void *args[] = { 0 };
- QMetaObject::metacall(d->object, QMetaObject::ResetProperty, d->core.coreIndex, args);
- return true;
- } else {
- return false;
- }
-}
-
-bool QDeclarativePropertyPrivate::write(const QDeclarativeProperty &that,
- const QVariant &value, WriteFlags flags)
-{
- if (!that.d)
- return false;
- if (that.d->object && that.type() & QDeclarativeProperty::Property &&
- that.d->core.isValid() && that.isWritable())
- return that.d->writeValueProperty(value, flags);
- else
- return false;
-}
-
-/*!
- Returns true if the property has a change notifier signal, otherwise false.
-*/
-bool QDeclarativeProperty::hasNotifySignal() const
-{
- if (type() & Property && d->object) {
- return d->object->metaObject()->property(d->core.coreIndex).hasNotifySignal();
- }
- return false;
-}
-
-/*!
- Returns true if the property needs a change notifier signal for bindings
- to remain upto date, false otherwise.
-
- Some properties, such as attached properties or those whose value never
- changes, do not require a change notifier.
-*/
-bool QDeclarativeProperty::needsNotifySignal() const
-{
- return type() & Property && !property().isConstant();
-}
-
-/*!
- Connects the property's change notifier signal to the
- specified \a method of the \a dest object and returns
- true. Returns false if this metaproperty does not
- represent a regular Qt property or if it has no
- change notifier signal, or if the \a dest object does
- not have the specified \a method.
-*/
-bool QDeclarativeProperty::connectNotifySignal(QObject *dest, int method) const
-{
- if (!(type() & Property) || !d->object)
- return false;
-
- QMetaProperty prop = d->object->metaObject()->property(d->core.coreIndex);
- if (prop.hasNotifySignal()) {
- return QDeclarativePropertyPrivate::connect(d->object, prop.notifySignalIndex(), dest, method, Qt::DirectConnection);
- } else {
- return false;
- }
-}
-
-/*!
- Connects the property's change notifier signal to the
- specified \a slot of the \a dest object and returns
- true. Returns false if this metaproperty does not
- represent a regular Qt property or if it has no
- change notifier signal, or if the \a dest object does
- not have the specified \a slot.
-*/
-bool QDeclarativeProperty::connectNotifySignal(QObject *dest, const char *slot) const
-{
- if (!(type() & Property) || !d->object)
- return false;
-
- QMetaProperty prop = d->object->metaObject()->property(d->core.coreIndex);
- if (prop.hasNotifySignal()) {
- QByteArray signal(QByteArray("2") + prop.notifySignal().signature());
- return QObject::connect(d->object, signal.constData(), dest, slot);
- } else {
- return false;
- }
-}
-
-/*!
- Return the Qt metaobject index of the property.
-*/
-int QDeclarativeProperty::index() const
-{
- return d ? d->core.coreIndex : -1;
-}
-
-int QDeclarativePropertyPrivate::valueTypeCoreIndex(const QDeclarativeProperty &that)
-{
- return that.d ? that.d->core.getValueTypeCoreIndex() : -1;
-}
-
-/*!
- Returns the "property index" for use in bindings. The top 8 bits are the value type
- offset, and 0 otherwise. The bottom 24-bits are the regular property index.
-*/
-int QDeclarativePropertyPrivate::bindingIndex(const QDeclarativeProperty &that)
-{
- if (!that.d)
- return -1;
- return bindingIndex(that.d->core);
-}
-
-int QDeclarativePropertyPrivate::bindingIndex(const QDeclarativePropertyData &that)
-{
- int rv = that.coreIndex;
- if (rv != -1 && that.isValueTypeVirtual())
- rv = rv | (that.valueTypeCoreIndex << 24);
- return rv;
-}
-
-QDeclarativePropertyData
-QDeclarativePropertyPrivate::saveValueType(const QMetaObject *metaObject, int index,
- const QMetaObject *subObject, int subIndex,
- QDeclarativeEngine *)
-{
- QMetaProperty subProp = subObject->property(subIndex);
-
- QDeclarativePropertyData core;
- core.load(metaObject->property(index));
- core.setFlags(core.getFlags() | QDeclarativePropertyData::IsValueTypeVirtual);
- core.valueTypeFlags = QDeclarativePropertyData::flagsForProperty(subProp);
- core.valueTypeCoreIndex = subIndex;
- core.valueTypePropType = subProp.userType();
-
- return core;
-}
-
-QDeclarativeProperty
-QDeclarativePropertyPrivate::restore(QObject *object, const QDeclarativePropertyData &data,
- QDeclarativeContextData *ctxt)
-{
- QDeclarativeProperty prop;
-
- prop.d = new QDeclarativePropertyPrivate;
- prop.d->object = object;
- prop.d->context = ctxt;
- prop.d->engine = ctxt?ctxt->engine:0;
-
- prop.d->core = data;
-
- return prop;
-}
-
-/*!
- Returns true if lhs and rhs refer to the same metaobject data
-*/
-bool QDeclarativePropertyPrivate::equal(const QMetaObject *lhs, const QMetaObject *rhs)
-{
- return lhs == rhs || (1 && lhs && rhs && lhs->d.stringdata == rhs->d.stringdata);
-}
-
-/*!
- Returns true if from inherits to.
-*/
-bool QDeclarativePropertyPrivate::canConvert(const QMetaObject *from, const QMetaObject *to)
-{
- if (from && to == &QObject::staticMetaObject)
- return true;
-
- while (from) {
- if (equal(from, to))
- return true;
- from = from->superClass();
- }
-
- return false;
-}
-
-/*!
- Return the signal corresponding to \a name
-*/
-QMetaMethod QDeclarativePropertyPrivate::findSignalByName(const QMetaObject *mo, const QByteArray &name)
-{
- Q_ASSERT(mo);
- int methods = mo->methodCount();
- for (int ii = methods - 1; ii >= 2; --ii) { // >= 2 to block the destroyed signal
- QMetaMethod method = mo->method(ii);
- QByteArray methodName = method.signature();
- int idx = methodName.indexOf('(');
- methodName = methodName.left(idx);
-
- if (methodName == name)
- return method;
- }
-
- // If no signal is found, but the signal is of the form "onBlahChanged",
- // return the notify signal for the property "Blah"
- if (name.endsWith("Changed")) {
- QByteArray propName = name.mid(0, name.length() - 7);
- int propIdx = mo->indexOfProperty(propName.constData());
- if (propIdx >= 0) {
- QMetaProperty prop = mo->property(propIdx);
- if (prop.hasNotifySignal())
- return prop.notifySignal();
- }
- }
-
- return QMetaMethod();
-}
-
-static inline int QMetaObject_methods(const QMetaObject *metaObject)
-{
- struct Private
- {
- int revision;
- int className;
- int classInfoCount, classInfoData;
- int methodCount, methodData;
- int propertyCount, propertyData;
- };
-
- return reinterpret_cast<const Private *>(metaObject->d.data)->methodCount;
-}
-
-static inline int QMetaObject_properties(const QMetaObject *metaObject)
-{
- struct Private
- {
- int revision;
- int className;
- int classInfoCount, classInfoData;
- int methodCount, methodData;
- int propertyCount, propertyData;
- };
-
- return reinterpret_cast<const Private *>(metaObject->d.data)->propertyCount;
-}
-
-static inline void flush_vme_signal(const QObject *object, int index)
-{
- QDeclarativeData *data = static_cast<QDeclarativeData *>(QObjectPrivate::get(const_cast<QObject *>(object))->declarativeData);
- if (data && data->propertyCache) {
- QDeclarativePropertyData *property = data->propertyCache->method(index);
-
- if (property && property->isVMESignal()) {
- const QMetaObject *metaObject = object->metaObject();
- int methodOffset = metaObject->methodOffset();
-
- while (methodOffset > index) {
- metaObject = metaObject->d.superdata;
- methodOffset -= QMetaObject_methods(metaObject);
- }
-
- QDeclarativeVMEMetaObject *vme =
- static_cast<QDeclarativeVMEMetaObject *>(const_cast<QMetaObject *>(metaObject));
-
- vme->connectAliasSignal(index);
- }
- }
-}
-
-/*!
-Connect \a sender \a signal_index to \a receiver \a method_index with the specified
-\a type and \a types. This behaves identically to QMetaObject::connect() except that
-it connects any lazy "proxy" signal connections set up by QML.
-
-It is possible that this logic should be moved to QMetaObject::connect().
-*/
-bool QDeclarativePropertyPrivate::connect(const QObject *sender, int signal_index,
- const QObject *receiver, int method_index,
- int type, int *types)
-{
- flush_vme_signal(sender, signal_index);
- flush_vme_signal(receiver, method_index);
-
- return QMetaObject::connect(sender, signal_index, receiver, method_index, type, types);
-}
-
-void QDeclarativePropertyPrivate::flushSignal(const QObject *sender, int signal_index)
-{
- flush_vme_signal(sender, signal_index);
-}
-
-/*!
-Return \a metaObject's [super] meta object that provides data for \a property.
-*/
-const QMetaObject *QDeclarativePropertyPrivate::metaObjectForProperty(const QMetaObject *metaObject, int property)
-{
- int propertyOffset = metaObject->propertyOffset();
-
- while (propertyOffset > property) {
- metaObject = metaObject->d.superdata;
- propertyOffset -= QMetaObject_properties(metaObject);
- }
-
- return metaObject;
-}
-
-QT_END_NAMESPACE