summaryrefslogtreecommitdiffstats
path: root/src/declarative/qml/qmlmetaproperty.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/declarative/qml/qmlmetaproperty.cpp')
-rw-r--r--src/declarative/qml/qmlmetaproperty.cpp1230
1 files changed, 0 insertions, 1230 deletions
diff --git a/src/declarative/qml/qmlmetaproperty.cpp b/src/declarative/qml/qmlmetaproperty.cpp
deleted file mode 100644
index 7c273dc..0000000
--- a/src/declarative/qml/qmlmetaproperty.cpp
+++ /dev/null
@@ -1,1230 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtDeclarative module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** No Commercial Usage
-** This file contains pre-release code and may not be distributed.
-** You may use this file in accordance with the terms and conditions
-** contained in the Technology Preview License Agreement accompanying
-** this package.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, 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.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at qt-info@nokia.com.
-**
-**
-**
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qmlmetaproperty.h"
-#include "qmlmetaproperty_p.h"
-
-#include "qmlcompositetypedata_p.h"
-#include "qml.h"
-#include "qmlbinding.h"
-#include "qmlcontext.h"
-#include "qmlcontext_p.h"
-#include "qmlboundsignal_p.h"
-#include "qmlengine.h"
-#include "qmlengine_p.h"
-#include "qmldeclarativedata_p.h"
-#include "qmlstringconverters_p.h"
-#include "qmllist_p.h"
-
-#include <QStringList>
-#include <QtCore/qdebug.h>
-
-#include <math.h>
-
-QT_BEGIN_NAMESPACE
-
-/*!
- \class QmlMetaProperty
- \brief The QmlMetaProperty class abstracts accessing QML properties.
- \internal
- */
-
-/*!
- Create an invalid QmlMetaProperty.
-*/
-QmlMetaProperty::QmlMetaProperty()
-: d(new QmlMetaPropertyPrivate)
-{
- d->q = this;
-}
-
-/*! \internal */
-QmlMetaProperty::~QmlMetaProperty()
-{
- delete d; d = 0;
-}
-
-/*!
- Creates a QmlMetaProperty for the default property of \a obj. If there is no
- default property, an invalid QmlMetaProperty will be created.
- */
-QmlMetaProperty::QmlMetaProperty(QObject *obj)
-: d(new QmlMetaPropertyPrivate)
-{
- d->q = this;
- d->initDefault(obj);
-}
-
-/*!
- \internal
- Creates a QmlMetaProperty for the default property of \a obj. If there is no
- default property, an invalid QmlMetaProperty will be created.
- */
-QmlMetaProperty::QmlMetaProperty(QObject *obj, QmlContext *ctxt)
-: d(new QmlMetaPropertyPrivate)
-{
- d->q = this;
- d->context = ctxt;
- d->initDefault(obj);
-}
-
-/*!
- Initialize from the default property of \a obj
-*/
-void QmlMetaPropertyPrivate::initDefault(QObject *obj)
-{
- if (!obj)
- return;
-
- QMetaProperty p = QmlMetaType::defaultProperty(obj);
- core.load(p);
- if (core.isValid()) {
- isDefaultProperty = true;
- object = obj;
- }
-}
-
-/*!
- Creates a QmlMetaProperty for the property \a name of \a obj.
- */
-QmlMetaProperty::QmlMetaProperty(QObject *obj, const QString &name)
-: d(new QmlMetaPropertyPrivate)
-{
- d->q = this;
- d->initProperty(obj, name);
- if (!isValid()) d->object = 0;
-}
-
-/*!
- \internal
- Creates a QmlMetaProperty for the property \a name of \a obj.
- */
-QmlMetaProperty::QmlMetaProperty(QObject *obj, const QString &name, QmlContext *ctxt)
-: d(new QmlMetaPropertyPrivate)
-{
- d->q = this;
- d->context = ctxt;
- d->initProperty(obj, name);
- if (!isValid()) { d->object = 0; d->context = 0; }
-}
-
-void QmlMetaPropertyPrivate::initProperty(QObject *obj, const QString &name)
-{
- QmlEnginePrivate *enginePrivate = 0;
- if (context && context->engine())
- enginePrivate = QmlEnginePrivate::get(context->engine());
-
- object = obj;
-
- if (name.isEmpty() || !obj)
- return;
-
- if (enginePrivate && name.at(0).isUpper()) {
- // Attached property
- // ### What about qualified types?
- QmlTypeNameCache *tnCache = QmlContextPrivate::get(context)->imports;
- if (tnCache) {
- QmlTypeNameCache::Data *d = tnCache->data(name);
- if (d && d->type && d->type->attachedPropertiesFunction()) {
- attachedFunc = d->type->index();
- }
- }
- return;
-
- } else if (name.count() >= 3 &&
- name.at(0) == QChar(QLatin1Char('o')) &&
- name.at(1) == QChar(QLatin1Char('n')) &&
- name.at(2).isUpper()) {
- // Signal
- QString signalName = name.mid(2);
- signalName[0] = signalName.at(0).toLower();
-
- QMetaMethod method = findSignal(obj, signalName);
- if (method.signature()) {
- core.load(method);
- return;
- }
- }
-
- // Property
- QmlPropertyCache::Data local;
- QmlPropertyCache::Data *property =
- QmlPropertyCache::property(context?context->engine():0, obj, name, local);
- if (property && !(property->flags & QmlPropertyCache::Data::IsFunction))
- core = *property;
-}
-
-/*!
- Create a copy of \a other.
-*/
-QmlMetaProperty::QmlMetaProperty(const QmlMetaProperty &other)
-: d(new QmlMetaPropertyPrivate(*other.d))
-{
- d->q = this;
-}
-
-/*!
- \enum QmlMetaProperty::PropertyCategory
-
- This enum specifies a category of QML property.
-
- \value Unknown The category is unknown. This will never be returned from propertyCategory()
- \value InvalidProperty The property is invalid.
- \value Bindable The property is a QmlBinding.
- \value List The property is a QList pointer
- \value Object The property is a QObject derived type pointer
- \value Normal The property is none of the above.
- */
-
-/*!
- \enum QmlMetaProperty::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.
- \value Default The property is the default property.
- \value Attached The property is an attached property.
-*/
-
-/*!
- Returns the property category.
-*/
-QmlMetaProperty::PropertyCategory QmlMetaProperty::propertyCategory() const
-{
- return d->propertyCategory();
-}
-
-QmlMetaProperty::PropertyCategory
-QmlMetaPropertyPrivate::propertyCategory() const
-{
- uint type = q->type();
-
- if (type & QmlMetaProperty::ValueTypeProperty) {
- return QmlMetaProperty::Normal;
- } else if (type & QmlMetaProperty::Attached) {
- return QmlMetaProperty::Object;
- } else if (type & QmlMetaProperty::Property) {
- int type = propertyType();
- if (type == QVariant::Invalid)
- return QmlMetaProperty::InvalidProperty;
- else if ((uint)type < QVariant::UserType)
- return QmlMetaProperty::Normal;
- else if (type == qMetaTypeId<QmlBinding *>())
- return QmlMetaProperty::Bindable;
- else if (core.flags & QmlPropertyCache::Data::IsQObjectDerived)
- return QmlMetaProperty::Object;
- else if (core.flags & QmlPropertyCache::Data::IsQList)
- return QmlMetaProperty::List;
- else
- return QmlMetaProperty::Normal;
- } else {
- return QmlMetaProperty::InvalidProperty;
- }
-}
-
-/*!
- Returns the type name of the property, or 0 if the property has no type
- name.
-*/
-const char *QmlMetaProperty::propertyTypeName() const
-{
- if (type() & ValueTypeProperty) {
-
- QmlEnginePrivate *ep = QmlEnginePrivate::get(d->context);
- QmlValueType *valueType = 0;
- if (ep) valueType = ep->valueTypes[d->core.propType];
- else valueType = QmlValueTypeFactory::valueType(d->core.propType);
- Q_ASSERT(valueType);
-
- const char *rv = valueType->metaObject()->property(d->valueType.valueTypeCoreIdx).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 QmlMetaProperty represent the same
- property.
-*/
-bool QmlMetaProperty::operator==(const QmlMetaProperty &other) const
-{
- // category is intentially omitted here as it is generated
- // from the other members
- return d->object == other.d->object &&
- d->core == other.d->core &&
- d->valueType == other.d->valueType &&
- d->attachedFunc == other.d->attachedFunc;
-}
-
-/*!
- Returns the QVariant type of the property, or QVariant::Invalid if the
- property has no QVariant type.
-*/
-int QmlMetaProperty::propertyType() const
-{
- return d->propertyType();
-}
-
-int QmlMetaPropertyPrivate::propertyType() const
-{
- uint type = q->type();
- if (type & QmlMetaProperty::ValueTypeProperty) {
- return valueType.valueTypePropType;
- } else if (type & QmlMetaProperty::Attached) {
- return qMetaTypeId<QObject *>();
- } else if (type & QmlMetaProperty::Property) {
- if (core.propType == (int)QVariant::LastType)
- return qMetaTypeId<QVariant>();
- else
- return core.propType;
- } else {
- return QVariant::Invalid;
- }
-}
-
-/*!
- Returns the type of the property.
-*/
-QmlMetaProperty::Type QmlMetaProperty::type() const
-{
- if (d->core.flags & QmlPropertyCache::Data::IsFunction)
- return SignalProperty;
- else if (d->attachedFunc != -1)
- return Attached;
- else if (d->valueType.valueTypeCoreIdx != -1)
- return (Type)(Property | ValueTypeProperty);
- else if (d->core.isValid())
- return (Type)(Property | ((d->isDefaultProperty)?Default:0));
- else
- return Invalid;
-}
-
-/*!
- Returns true if this QmlMetaProperty represents a regular Qt property.
-*/
-bool QmlMetaProperty::isProperty() const
-{
- return type() & Property;
-}
-
-/*!
- Returns true if this QmlMetaProperty represents a default property.
-*/
-bool QmlMetaProperty::isDefault() const
-{
- return type() & Default;
-}
-
-/*!
- Returns the QmlMetaProperty's QObject.
-*/
-QObject *QmlMetaProperty::object() const
-{
- return d->object;
-}
-
-/*!
- Assign \a other to this QmlMetaProperty.
-*/
-QmlMetaProperty &QmlMetaProperty::operator=(const QmlMetaProperty &other)
-{
- d->context = other.d->context;
- d->object = other.d->object;
-
- d->isDefaultProperty = other.d->isDefaultProperty;
- d->core = other.d->core;
-
- d->valueType = other.d->valueType;
-
- d->attachedFunc = other.d->attachedFunc;
- return *this;
-}
-
-/*!
- Returns true if the property is writable, otherwise false.
-*/
-bool QmlMetaProperty::isWritable() const
-{
- QmlMetaProperty::PropertyCategory category = propertyCategory();
-
- if (!d->object)
- return false;
- if (category == List)
- return true;
- else if (type() & SignalProperty)
- return false;
- else if (d->core.isValid() && d->object)
- return d->core.flags & QmlPropertyCache::Data::IsWritable;
- else
- return false;
-}
-
-/*!
- Returns true if the property is designable, otherwise false.
-*/
-bool QmlMetaProperty::isDesignable() const
-{
- 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 QmlMetaProperty::isResettable() const
-{
- if (type() & Property && d->core.isValid() && d->object)
- return d->core.flags & QmlPropertyCache::Data::IsResettable;
- else
- return false;
-}
-
-/*!
- Returns true if the QmlMetaProperty refers to a valid property, otherwise
- false.
-*/
-bool QmlMetaProperty::isValid() const
-{
- return type() != Invalid;
-}
-
-/*!
- Return the name of this QML property.
-*/
-QString QmlMetaProperty::name() const
-{
- if (!d->isNameCached) {
- // ###
- if (!d->object) {
- } else if (type() & ValueTypeProperty) {
- QString rv = d->core.name(d->object) + QLatin1Char('.');
-
- QmlEnginePrivate *ep = d->context?QmlEnginePrivate::get(d->context->engine()):0;
- QmlValueType *valueType = 0;
- if (ep) valueType = ep->valueTypes[d->core.propType];
- else valueType = QmlValueTypeFactory::valueType(d->core.propType);
- Q_ASSERT(valueType);
-
- rv += QString::fromUtf8(valueType->metaObject()->property(d->valueType.valueTypeCoreIdx).name());
-
- 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 QmlMetaProperty::property() const
-{
- 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 QmlMetaProperty::method() const
-{
- 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.
-*/
-QmlAbstractBinding *QmlMetaProperty::binding() const
-{
- if (!isProperty() || (type() & Attached) || !d->object)
- return 0;
-
- QmlDeclarativeData *data = QmlDeclarativeData::get(d->object);
- if (!data)
- return 0;
-
- if (!data->hasBindingBit(d->core.coreIndex))
- return 0;
-
- QmlAbstractBinding *binding = data->bindings;
- while (binding) {
- // ### This wont work for value types
- if (binding->propertyIndex() == d->core.coreIndex)
- return binding;
- binding = binding->m_nextBinding;
- }
- return 0;
-}
-
-/*!
- 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 intial value, it will use these flags for the write).
-*/
-QmlAbstractBinding *
-QmlMetaProperty::setBinding(QmlAbstractBinding *newBinding, QmlMetaProperty::WriteFlags flags) const
-{
- if (!isProperty() || (type() & Attached) || !d->object) {
- if (newBinding)
- newBinding->destroy();
- return 0;
- }
-
- return d->setBinding(d->object, d->core, newBinding, flags);
-}
-
-QmlAbstractBinding *
-QmlMetaPropertyPrivate::setBinding(QObject *object, const QmlPropertyCache::Data &core,
- QmlAbstractBinding *newBinding, QmlMetaProperty::WriteFlags flags)
-{
- QmlDeclarativeData *data = QmlDeclarativeData::get(object, 0 != newBinding);
-
- if (data && data->hasBindingBit(core.coreIndex)) {
- QmlAbstractBinding *binding = data->bindings;
- while (binding) {
- // ### This wont work for value types
- if (binding->propertyIndex() == core.coreIndex) {
- binding->setEnabled(false);
-
- if (newBinding)
- newBinding->setEnabled(true, flags);
-
- return binding; // ### QmlAbstractBinding;
- }
-
- binding = binding->m_nextBinding;
- }
- }
-
- if (newBinding)
- newBinding->setEnabled(true, flags);
-
- return 0;
-}
-/*!
- Returns the expression associated with this signal property, or 0 if no
- signal expression exists.
-*/
-QmlExpression *QmlMetaProperty::signalExpression() const
-{
- if (!(type() & SignalProperty))
- return 0;
-
- const QObjectList &children = d->object->children();
-
- for (int ii = 0; ii < children.count(); ++ii) {
- QObject *child = children.at(ii);
-
- QmlBoundSignal *signal = QmlBoundSignal::cast(child);
- if (signal && signal->index() == coreIndex())
- 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.
-*/
-QmlExpression *QmlMetaProperty::setSignalExpression(QmlExpression *expr) const
-{
- if (!(type() & SignalProperty)) {
- delete expr;
- return 0;
- }
-
- const QObjectList &children = d->object->children();
-
- for (int ii = 0; ii < children.count(); ++ii) {
- QObject *child = children.at(ii);
-
- QmlBoundSignal *signal = QmlBoundSignal::cast(child);
- if (signal && signal->index() == coreIndex())
- return signal->setExpression(expr);
- }
-
- if (expr) {
- QmlBoundSignal *signal = new QmlBoundSignal(d->object, method(), d->object);
- return signal->setExpression(expr);
- } else {
- return 0;
- }
-}
-
-QMetaMethod QmlMetaPropertyPrivate::findSignal(QObject *obj, const QString &name)
-{
- const QMetaObject *mo = obj->metaObject();
-
- int methods = mo->methodCount();
- for (int ii = methods - 1; ii >= 0; --ii) {
- QMetaMethod method = mo->method(ii);
- QString methodName = QString::fromUtf8(method.signature());
- int idx = methodName.indexOf(QLatin1Char('('));
- methodName = methodName.left(idx);
-
- if (methodName == name)
- return method;
- }
- return QMetaMethod();
-}
-
-QObject *QmlMetaPropertyPrivate::attachedObject() const
-{
- if (attachedFunc == -1)
- return 0;
- else
- return qmlAttachedPropertiesObjectById(attachedFunc, object);
-}
-
-/*!
- Returns the property value.
-*/
-QVariant QmlMetaProperty::read() const
-{
- if (!d->object)
- return QVariant();
-
- if (type() & SignalProperty) {
-
- return QVariant();
-
- } else if (type() & Property || type() & Attached) {
-
- return d->readValueProperty();
-
- }
- return QVariant();
-}
-
-QVariant QmlMetaPropertyPrivate::readValueProperty()
-{
- uint type = q->type();
- if (type & QmlMetaProperty::Attached) {
-
- return QVariant::fromValue(attachedObject());
-
- } else if(type & QmlMetaProperty::ValueTypeProperty) {
-
- QmlEnginePrivate *ep = QmlEnginePrivate::get(context);
- QmlValueType *valueType = 0;
- if (ep) valueType = ep->valueTypes[core.propType];
- else valueType = QmlValueTypeFactory::valueType(core.propType);
- Q_ASSERT(valueType);
-
- valueType->read(object, core.coreIndex);
-
- QVariant rv =
- valueType->metaObject()->property(this->valueType.valueTypeCoreIdx).read(valueType);
-
- if (!ep) delete valueType;
- return rv;
-
- } else if(core.flags & QmlPropertyCache::Data::IsQList) {
-
- QmlListProperty<QObject> prop;
- void *args[] = { &prop, 0 };
- QMetaObject::metacall(object, QMetaObject::ReadProperty, core.coreIndex, args);
- return QVariant::fromValue(QmlListReferencePrivate::init(prop, core.propType, context?context->engine():0));
-
- } else {
-
- return object->metaObject()->property(core.coreIndex).read(object.data());
-
- }
-}
-
-//###
-//writeEnumProperty MIRRORS the relelvant bit of QMetaProperty::write AND MUST BE KEPT IN SYNC!
-//###
-bool QmlMetaPropertyPrivate::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
- ) {
- if (prop.isFlagType())
- v = QVariant(menum.keysToValue(value.toByteArray()));
- else
- v = QVariant(menum.keyToValue(value.toByteArray()));
- } else if (v.userType() != QVariant::Int && v.userType() != QVariant::UInt) {
- int enumMetaTypeId = QMetaType::type(QByteArray(menum.scope()) + "::" + 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 QmlMetaPropertyPrivate::writeValueProperty(const QVariant &value,
- QmlMetaProperty::WriteFlags flags)
-{
- // Remove any existing bindings on this property
- if (!(flags & QmlMetaProperty::DontRemoveBinding)) {
- QmlAbstractBinding *binding = q->setBinding(0);
- if (binding) binding->destroy();
- }
-
- bool rv = false;
- uint type = q->type();
- if (type & QmlMetaProperty::ValueTypeProperty) {
- QmlEnginePrivate *ep = QmlEnginePrivate::get(context);
-
- QmlValueType *writeBack = 0;
- if (ep) {
- writeBack = ep->valueTypes[core.propType];
- } else {
- writeBack = QmlValueTypeFactory::valueType(core.propType);
- }
-
- writeBack->read(object, core.coreIndex);
-
- QmlPropertyCache::Data data = core;
- data.coreIndex = valueType.valueTypeCoreIdx;
- data.propType = valueType.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 QmlMetaPropertyPrivate::write(QObject *object, const QmlPropertyCache::Data &property,
- const QVariant &value, QmlContext *context,
- QmlMetaProperty::WriteFlags flags)
-{
- int coreIdx = property.coreIndex;
- int status = -1; //for dbus
-
- if (property.flags & QmlPropertyCache::Data::IsEnumType) {
- 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 t = property.propType;
- int vt = value.userType();
-
- QmlEnginePrivate *enginePriv = QmlEnginePrivate::get(context);
-
- if (t == QVariant::Url) {
-
- QUrl u;
- bool found = false;
- if (vt == QVariant::Url) {
- u = value.toUrl();
- found = true;
- } else if (vt == QVariant::ByteArray) {
- u = QUrl(QString::fromUtf8(value.toByteArray()));
- found = true;
- } else if (vt == QVariant::String) {
- u = QUrl(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 (vt == t) {
-
- void *a[] = { (void *)value.constData(), 0, &status, &flags };
- QMetaObject::metacall(object, QMetaObject::WriteProperty, coreIdx, a);
-
- } else if (qMetaTypeId<QVariant>() == t) {
-
- void *a[] = { (void *)&value, 0, &status, &flags };
- QMetaObject::metacall(object, QMetaObject::WriteProperty, coreIdx, a);
-
- } else if (property.flags & QmlPropertyCache::Data::IsQObjectDerived) {
-
- const QMetaObject *valMo = rawMetaObjectForType(enginePriv, value.userType());
-
- if (!valMo)
- return false;
-
- QObject *o = *(QObject **)value.constData();
- const QMetaObject *propMo = rawMetaObjectForType(enginePriv, t);
-
- 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.flags & QmlPropertyCache::Data::IsQList) {
-
- const QMetaObject *listType = 0;
- if (enginePriv) {
- listType = enginePriv->rawMetaObjectForType(enginePriv->listType(property.propType));
- } else {
- QmlType *type = QmlMetaType::qmlType(QmlMetaType::listType(property.propType));
- if (!type) return false;
- listType = type->baseMetaObject();
- }
- if (!listType) return false;
-
- QmlListProperty<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<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 (!canConvert(o->metaObject(), listType))
- o = 0;
- prop.append(&prop, (void *)o);
- }
- } else {
- QObject *o = enginePriv?enginePriv->toQObject(value):QmlMetaType::toQObject(value);
- if (!canConvert(o->metaObject(), listType))
- o = 0;
- prop.append(&prop, (void *)o);
- }
-
- } else {
- Q_ASSERT(vt != t);
-
- QVariant v = value;
- if (v.convert((QVariant::Type)t)) {
- void *a[] = { (void *)v.constData(), 0, &status, &flags};
- QMetaObject::metacall(object, QMetaObject::WriteProperty, coreIdx, a);
- } else if ((uint)t >= QVariant::UserType && vt == QVariant::String) {
- QmlMetaType::StringConverter con = QmlMetaType::customStringConverter(t);
- if (!con)
- return false;
-
- QVariant v = con(value.toString());
- if (v.userType() == t) {
- void *a[] = { (void *)v.constData(), 0, &status, &flags};
- QMetaObject::metacall(object, QMetaObject::WriteProperty, coreIdx, a);
- }
- } else if (vt == QVariant::String) {
- bool ok = false;
- QVariant v = QmlStringConverters::variantFromString(value.toString(), t, &ok);
- if (!ok)
- return false;
-
- void *a[] = { (void *)v.constData(), 0, &status, &flags};
- QMetaObject::metacall(object, QMetaObject::WriteProperty, coreIdx, a);
- } else {
- return false;
- }
- }
-
- return true;
-}
-
-const QMetaObject *QmlMetaPropertyPrivate::rawMetaObjectForType(QmlEnginePrivate *engine, int userType)
-{
- if (engine) {
- return engine->rawMetaObjectForType(userType);
- } else {
- QmlType *type = QmlMetaType::qmlType(userType);
- return type?type->baseMetaObject():0;
- }
-}
-
-/*!
- Set the property value to \a value.
-*/
-bool QmlMetaProperty::write(const QVariant &value) const
-{
- return write(value, 0);
-}
-
-/*!
- Resets the property value.
-*/
-bool QmlMetaProperty::reset() const
-{
- if (isResettable()) {
- void *args[] = { 0 };
- QMetaObject::metacall(d->object, QMetaObject::ResetProperty, d->core.coreIndex, args);
- return true;
- } else {
- return false;
- }
-}
-
-bool QmlMetaProperty::write(const QVariant &value, QmlMetaProperty::WriteFlags flags) const
-{
- if (d->object && type() & Property && d->core.isValid() && isWritable())
- return d->writeValueProperty(value, flags);
- else
- return false;
-}
-
-/*!
- Returns true if the property has a change notifier signal, otherwise false.
-*/
-bool QmlMetaProperty::hasChangedNotifier() const
-{
- if (type() & Property && !(type() & Attached) && 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 QmlMetaProperty::needsChangedNotifier() const
-{
- return type() & Property && !(type() & Attached) &&
- !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 QmlMetaProperty::connectNotifier(QObject *dest, int method) const
-{
- if (!(type() & Property) || (type() & Attached) || !d->object)
- return false;
-
- QMetaProperty prop = d->object->metaObject()->property(d->core.coreIndex);
- if (prop.hasNotifySignal()) {
- return QMetaObject::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 QmlMetaProperty::connectNotifier(QObject *dest, const char *slot) const
-{
- if (!(type() & Property) || (type() & Attached) || !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 QmlMetaProperty::coreIndex() const
-{
- return d->core.coreIndex;
-}
-
-/*! \internal */
-int QmlMetaProperty::valueTypeCoreIndex() const
-{
- return d->valueType.valueTypeCoreIdx;
-}
-
-Q_GLOBAL_STATIC(QmlValueTypeFactory, qmlValueTypes);
-
-
-struct SerializedData {
- QmlMetaProperty::Type type;
- QmlPropertyCache::Data core;
-};
-
-struct ValueTypeSerializedData : public SerializedData {
- QmlPropertyCache::ValueTypeData valueType;
-};
-
-QByteArray QmlMetaPropertyPrivate::saveValueType(const QMetaObject *metaObject, int index,
- int subIndex, int subType)
-{
- ValueTypeSerializedData sd;
- sd.type = QmlMetaProperty::ValueTypeProperty;
- sd.core.load(metaObject->property(index));
- sd.valueType.valueTypeCoreIdx = subIndex;
- sd.valueType.valueTypePropType = subType;
-
- QByteArray rv((const char *)&sd, sizeof(sd));
- return rv;
-}
-
-QByteArray QmlMetaPropertyPrivate::saveProperty(const QMetaObject *metaObject, int index)
-{
- SerializedData sd;
- sd.type = QmlMetaProperty::Property;
- sd.core.load(metaObject->property(index));
-
- QByteArray rv((const char *)&sd, sizeof(sd));
- return rv;
-}
-
-QmlMetaProperty
-QmlMetaPropertyPrivate::restore(const QByteArray &data, QObject *object, QmlContext *ctxt)
-{
- QmlMetaProperty prop;
-
- if (data.isEmpty())
- return prop;
-
- prop.d->object = object;
- prop.d->context = ctxt;
-
- const SerializedData *sd = (const SerializedData *)data.constData();
- if (sd->type == QmlMetaProperty::Property) {
- prop.d->core = sd->core;
- } else if(sd->type == QmlMetaProperty::ValueTypeProperty) {
- const ValueTypeSerializedData *vt = (const ValueTypeSerializedData *)sd;
- prop.d->core = vt->core;
- prop.d->valueType = vt->valueType;
- }
-
- return prop;
-}
-
-/*!
- \internal
-
- Creates a QmlMetaProperty for the property \a name of \a obj. Unlike
- the QmlMetaProperty(QObject*, QString, QmlContext*) constructor, this static function
- will correctly handle dot properties, including value types and attached properties.
-*/
-QmlMetaProperty QmlMetaProperty::createProperty(QObject *obj,
- const QString &name,
- QmlContext *context)
-{
- QmlTypeNameCache *typeNameCache = context?QmlContextPrivate::get(context)->imports:0;
-
- QStringList path = name.split(QLatin1Char('.'));
- QObject *object = obj;
-
- for (int jj = 0; jj < path.count() - 1; ++jj) {
- const QString &pathName = path.at(jj);
-
- if (QmlTypeNameCache::Data *data = typeNameCache?typeNameCache->data(pathName):0) {
- if (data->type) {
- QmlAttachedPropertiesFunc func = data->type->attachedPropertiesFunction();
- if (!func)
- return QmlMetaProperty();
- object = qmlAttachedPropertiesObjectById(data->type->index(), object);
- if (!object)
- return QmlMetaProperty();
- continue;
- } else {
- Q_ASSERT(data->typeNamespace);
- ++jj;
- data = data->typeNamespace->data(path.at(jj));
- if (!data || !data->type)
- return QmlMetaProperty();
- QmlAttachedPropertiesFunc func = data->type->attachedPropertiesFunction();
- if (!func)
- return QmlMetaProperty();
- object = qmlAttachedPropertiesObjectById(data->type->index(), object);
- if (!object)
- return QmlMetaProperty();
- continue;
- }
- }
-
- QmlMetaProperty prop(object, pathName, context);
-
- if (jj == path.count() - 2 && prop.propertyType() < (int)QVariant::UserType &&
- qmlValueTypes()->valueTypes[prop.propertyType()]) {
- // 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()->valueTypes[prop.propertyType()];
- int idx = typeObject->metaObject()->indexOfProperty(path.last().toUtf8().constData());
- if (idx == -1)
- return QmlMetaProperty();
- QMetaProperty vtProp = typeObject->metaObject()->property(idx);
-
- QmlMetaProperty p = prop;
- p.d->valueType.valueTypeCoreIdx = idx;
- p.d->valueType.valueTypePropType = vtProp.userType();
- return p;
- }
-
- QObject *objVal = QmlMetaType::toQObject(prop.read());
- if (!objVal)
- return QmlMetaProperty();
- object = objVal;
- }
-
- const QString &propName = path.last();
- QmlMetaProperty prop(object, propName, context);
- if (!prop.isValid())
- return QmlMetaProperty();
- else
- return prop;
-}
-
-/*!
- Returns true if lhs and rhs refer to the same metaobject data
-*/
-bool QmlMetaPropertyPrivate::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 QmlMetaPropertyPrivate::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;
-}
-
-QT_END_NAMESPACE