summaryrefslogtreecommitdiffstats
path: root/src/declarative/qml/qdeclarativevaluetypescriptclass.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/declarative/qml/qdeclarativevaluetypescriptclass.cpp')
-rw-r--r--src/declarative/qml/qdeclarativevaluetypescriptclass.cpp242
1 files changed, 242 insertions, 0 deletions
diff --git a/src/declarative/qml/qdeclarativevaluetypescriptclass.cpp b/src/declarative/qml/qdeclarativevaluetypescriptclass.cpp
new file mode 100644
index 00000000..b1d4221d
--- /dev/null
+++ b/src/declarative/qml/qdeclarativevaluetypescriptclass.cpp
@@ -0,0 +1,242 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 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$
+** 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 "private/qdeclarativevaluetypescriptclass_p.h"
+
+#include "private/qdeclarativebinding_p.h"
+#include "private/qdeclarativeproperty_p.h"
+#include "private/qdeclarativeengine_p.h"
+#include "private/qdeclarativeguard_p.h"
+
+#include <QtScript/qscriptcontextinfo.h>
+
+QT_BEGIN_NAMESPACE
+
+struct QDeclarativeValueTypeObject : public QScriptDeclarativeClass::Object {
+ enum Type { Reference, Copy };
+ QDeclarativeValueTypeObject(Type t) : objectType(t) {}
+ Type objectType;
+ QDeclarativeValueType *type;
+};
+
+struct QDeclarativeValueTypeReference : public QDeclarativeValueTypeObject {
+ QDeclarativeValueTypeReference() : QDeclarativeValueTypeObject(Reference) {}
+ QDeclarativeGuard<QObject> object;
+ int property;
+};
+
+struct QDeclarativeValueTypeCopy : public QDeclarativeValueTypeObject {
+ QDeclarativeValueTypeCopy() : QDeclarativeValueTypeObject(Copy) {}
+ QVariant value;
+};
+
+QDeclarativeValueTypeScriptClass::QDeclarativeValueTypeScriptClass(QDeclarativeEngine *bindEngine)
+: QScriptDeclarativeClass(QDeclarativeEnginePrivate::getScriptEngine(bindEngine)), engine(bindEngine)
+{
+}
+
+QDeclarativeValueTypeScriptClass::~QDeclarativeValueTypeScriptClass()
+{
+}
+
+QScriptValue QDeclarativeValueTypeScriptClass::newObject(QObject *object, int coreIndex, QDeclarativeValueType *type)
+{
+ QDeclarativeValueTypeReference *ref = new QDeclarativeValueTypeReference;
+ ref->type = type;
+ ref->object = object;
+ ref->property = coreIndex;
+ QScriptEngine *scriptEngine = QDeclarativeEnginePrivate::getScriptEngine(engine);
+ return QScriptDeclarativeClass::newObject(scriptEngine, this, ref);
+}
+
+QScriptValue QDeclarativeValueTypeScriptClass::newObject(const QVariant &v, QDeclarativeValueType *type)
+{
+ QDeclarativeValueTypeCopy *copy = new QDeclarativeValueTypeCopy;
+ copy->type = type;
+ copy->value = v;
+ QScriptEngine *scriptEngine = QDeclarativeEnginePrivate::getScriptEngine(engine);
+ return QScriptDeclarativeClass::newObject(scriptEngine, this, copy);
+}
+
+QScriptClass::QueryFlags
+QDeclarativeValueTypeScriptClass::queryProperty(Object *obj, const Identifier &name,
+ QScriptClass::QueryFlags)
+{
+ QDeclarativeValueTypeObject *o = static_cast<QDeclarativeValueTypeObject *>(obj);
+
+ m_lastIndex = -1;
+
+ QByteArray propName = toString(name).toUtf8();
+
+ m_lastIndex = o->type->metaObject()->indexOfProperty(propName.constData());
+ if (m_lastIndex == -1)
+ return 0;
+
+ QScriptClass::QueryFlags rv = 0;
+
+ if (o->objectType == QDeclarativeValueTypeObject::Reference) {
+ QDeclarativeValueTypeReference *ref = static_cast<QDeclarativeValueTypeReference *>(o);
+
+ if (!ref->object)
+ return 0;
+
+ QMetaProperty prop = ref->object->metaObject()->property(m_lastIndex);
+
+ rv = QScriptClass::HandlesReadAccess;
+ if (prop.isWritable())
+ rv |= QScriptClass::HandlesWriteAccess;
+ } else {
+ rv = QScriptClass::HandlesReadAccess | QScriptClass::HandlesWriteAccess;
+ }
+
+ return rv;
+}
+
+QDeclarativeValueTypeScriptClass::Value QDeclarativeValueTypeScriptClass::property(Object *obj, const Identifier &)
+{
+ QDeclarativeValueTypeObject *o = static_cast<QDeclarativeValueTypeObject *>(obj);
+
+ QVariant rv;
+ if (o->objectType == QDeclarativeValueTypeObject::Reference) {
+ QDeclarativeValueTypeReference *ref = static_cast<QDeclarativeValueTypeReference *>(obj);
+
+ QMetaProperty p = ref->type->metaObject()->property(m_lastIndex);
+ ref->type->read(ref->object, ref->property);
+ rv = p.read(ref->type);
+ } else {
+ QDeclarativeValueTypeCopy *copy = static_cast<QDeclarativeValueTypeCopy *>(obj);
+
+ QMetaProperty p = copy->type->metaObject()->property(m_lastIndex);
+ copy->type->setValue(copy->value);
+ rv = p.read(copy->type);
+ }
+
+ QScriptEngine *scriptEngine = QDeclarativeEnginePrivate::getScriptEngine(engine);
+ return Value(scriptEngine, static_cast<QDeclarativeEnginePrivate *>(QObjectPrivate::get(engine))->scriptValueFromVariant(rv));
+}
+
+void QDeclarativeValueTypeScriptClass::setProperty(Object *obj, const Identifier &,
+ const QScriptValue &value)
+{
+ QDeclarativeValueTypeObject *o = static_cast<QDeclarativeValueTypeObject *>(obj);
+
+ QVariant v = QDeclarativeEnginePrivate::get(engine)->scriptValueToVariant(value);
+
+ if (o->objectType == QDeclarativeValueTypeObject::Reference) {
+ QDeclarativeValueTypeReference *ref = static_cast<QDeclarativeValueTypeReference *>(obj);
+
+ ref->type->read(ref->object, ref->property);
+ QMetaProperty p = ref->type->metaObject()->property(m_lastIndex);
+
+ QDeclarativeBinding *newBinding = 0;
+ if (value.isFunction() && !value.isRegExp()) {
+ QDeclarativeContextData *ctxt = QDeclarativeEnginePrivate::get(engine)->getContext(context());
+
+ QDeclarativePropertyCache::Data cacheData;
+ cacheData.flags = QDeclarativePropertyCache::Data::IsWritable;
+ cacheData.propType = ref->object->metaObject()->property(ref->property).userType();
+ cacheData.coreIndex = ref->property;
+
+ QDeclarativePropertyCache::ValueTypeData valueTypeData;
+ valueTypeData.valueTypeCoreIdx = m_lastIndex;
+ valueTypeData.valueTypePropType = p.userType();
+
+ newBinding = new QDeclarativeBinding(value, ref->object, ctxt);
+ QScriptContextInfo ctxtInfo(context());
+ newBinding->setSourceLocation(ctxtInfo.fileName(), ctxtInfo.functionStartLineNumber());
+ QDeclarativeProperty prop = QDeclarativePropertyPrivate::restore(cacheData, valueTypeData, ref->object, ctxt);
+ newBinding->setTarget(prop);
+ if (newBinding->expression().contains(QLatin1String("this")))
+ newBinding->setEvaluateFlags(newBinding->evaluateFlags() | QDeclarativeBinding::RequiresThisObject);
+ }
+
+ QDeclarativeAbstractBinding *delBinding =
+ QDeclarativePropertyPrivate::setBinding(ref->object, ref->property, m_lastIndex, newBinding);
+ if (delBinding)
+ delBinding->destroy();
+
+ if (p.isEnumType() && (QMetaType::Type)v.type() == QMetaType::Double)
+ v = v.toInt();
+ p.write(ref->type, v);
+ ref->type->write(ref->object, ref->property, 0);
+
+ } else {
+ QDeclarativeValueTypeCopy *copy = static_cast<QDeclarativeValueTypeCopy *>(obj);
+ copy->type->setValue(copy->value);
+ QMetaProperty p = copy->type->metaObject()->property(m_lastIndex);
+ p.write(copy->type, v);
+ copy->value = copy->type->value();
+ }
+}
+
+QVariant QDeclarativeValueTypeScriptClass::toVariant(Object *obj, bool *ok)
+{
+ QDeclarativeValueTypeObject *o = static_cast<QDeclarativeValueTypeObject *>(obj);
+
+ if (o->objectType == QDeclarativeValueTypeObject::Reference) {
+ QDeclarativeValueTypeReference *ref = static_cast<QDeclarativeValueTypeReference *>(obj);
+
+ if (ok) *ok = true;
+
+ if (ref->object) {
+ ref->type->read(ref->object, ref->property);
+ return ref->type->value();
+ }
+ } else {
+ QDeclarativeValueTypeCopy *copy = static_cast<QDeclarativeValueTypeCopy *>(obj);
+
+ if (ok) *ok = true;
+
+ return copy->value;
+ }
+
+ return QVariant();
+}
+
+QVariant QDeclarativeValueTypeScriptClass::toVariant(const QScriptValue &value)
+{
+ Q_ASSERT(scriptClass(value) == this);
+
+ return toVariant(object(value), 0);
+}
+
+QT_END_NAMESPACE
+