1 /****************************************************************************
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the QtDeclarative module of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** No Commercial Usage
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
16 ** GNU Lesser General Public License Usage
17 ** Alternatively, this file may be used under the terms of the GNU Lesser
18 ** General Public License version 2.1 as published by the Free Software
19 ** Foundation and appearing in the file LICENSE.LGPL included in the
20 ** packaging of this file. Please review the following information to
21 ** ensure the GNU Lesser General Public License version 2.1 requirements
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 ** In addition, as a special exception, Nokia gives you certain additional
25 ** rights. These rights are described in the Nokia Qt LGPL Exception
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
40 ****************************************************************************/
42 #include "private/qdeclarativevaluetypescriptclass_p.h"
44 #include "private/qdeclarativebinding_p.h"
45 #include "private/qdeclarativeproperty_p.h"
46 #include "private/qdeclarativeengine_p.h"
47 #include "private/qdeclarativeguard_p.h"
49 #include <QtScript/qscriptcontextinfo.h>
53 struct QDeclarativeValueTypeObject : public QScriptDeclarativeClass::Object {
54 enum Type { Reference, Copy };
55 QDeclarativeValueTypeObject(Type t) : objectType(t) {}
57 QDeclarativeValueType *type;
60 struct QDeclarativeValueTypeReference : public QDeclarativeValueTypeObject {
61 QDeclarativeValueTypeReference() : QDeclarativeValueTypeObject(Reference) {}
62 QDeclarativeGuard<QObject> object;
66 struct QDeclarativeValueTypeCopy : public QDeclarativeValueTypeObject {
67 QDeclarativeValueTypeCopy() : QDeclarativeValueTypeObject(Copy) {}
71 QDeclarativeValueTypeScriptClass::QDeclarativeValueTypeScriptClass(QDeclarativeEngine *bindEngine)
72 : QScriptDeclarativeClass(QDeclarativeEnginePrivate::getScriptEngine(bindEngine)), engine(bindEngine)
76 QDeclarativeValueTypeScriptClass::~QDeclarativeValueTypeScriptClass()
80 QScriptValue QDeclarativeValueTypeScriptClass::newObject(QObject *object, int coreIndex, QDeclarativeValueType *type)
82 QDeclarativeValueTypeReference *ref = new QDeclarativeValueTypeReference;
85 ref->property = coreIndex;
86 QScriptEngine *scriptEngine = QDeclarativeEnginePrivate::getScriptEngine(engine);
87 return QScriptDeclarativeClass::newObject(scriptEngine, this, ref);
90 QScriptValue QDeclarativeValueTypeScriptClass::newObject(const QVariant &v, QDeclarativeValueType *type)
92 QDeclarativeValueTypeCopy *copy = new QDeclarativeValueTypeCopy;
95 QScriptEngine *scriptEngine = QDeclarativeEnginePrivate::getScriptEngine(engine);
96 return QScriptDeclarativeClass::newObject(scriptEngine, this, copy);
99 QScriptClass::QueryFlags
100 QDeclarativeValueTypeScriptClass::queryProperty(Object *obj, const Identifier &name,
101 QScriptClass::QueryFlags)
103 QDeclarativeValueTypeObject *o = static_cast<QDeclarativeValueTypeObject *>(obj);
107 QByteArray propName = toString(name).toUtf8();
109 m_lastIndex = o->type->metaObject()->indexOfProperty(propName.constData());
110 if (m_lastIndex == -1)
113 QScriptClass::QueryFlags rv = 0;
115 if (o->objectType == QDeclarativeValueTypeObject::Reference) {
116 QDeclarativeValueTypeReference *ref = static_cast<QDeclarativeValueTypeReference *>(o);
121 QMetaProperty prop = ref->object->metaObject()->property(m_lastIndex);
123 rv = QScriptClass::HandlesReadAccess;
124 if (prop.isWritable())
125 rv |= QScriptClass::HandlesWriteAccess;
127 rv = QScriptClass::HandlesReadAccess | QScriptClass::HandlesWriteAccess;
133 QDeclarativeValueTypeScriptClass::Value QDeclarativeValueTypeScriptClass::property(Object *obj, const Identifier &)
135 QDeclarativeValueTypeObject *o = static_cast<QDeclarativeValueTypeObject *>(obj);
138 if (o->objectType == QDeclarativeValueTypeObject::Reference) {
139 QDeclarativeValueTypeReference *ref = static_cast<QDeclarativeValueTypeReference *>(obj);
141 QMetaProperty p = ref->type->metaObject()->property(m_lastIndex);
142 ref->type->read(ref->object, ref->property);
143 rv = p.read(ref->type);
145 QDeclarativeValueTypeCopy *copy = static_cast<QDeclarativeValueTypeCopy *>(obj);
147 QMetaProperty p = copy->type->metaObject()->property(m_lastIndex);
148 copy->type->setValue(copy->value);
149 rv = p.read(copy->type);
152 QScriptEngine *scriptEngine = QDeclarativeEnginePrivate::getScriptEngine(engine);
153 return Value(scriptEngine, static_cast<QDeclarativeEnginePrivate *>(QObjectPrivate::get(engine))->scriptValueFromVariant(rv));
156 void QDeclarativeValueTypeScriptClass::setProperty(Object *obj, const Identifier &,
157 const QScriptValue &value)
159 QDeclarativeValueTypeObject *o = static_cast<QDeclarativeValueTypeObject *>(obj);
161 QVariant v = QDeclarativeEnginePrivate::get(engine)->scriptValueToVariant(value);
163 if (o->objectType == QDeclarativeValueTypeObject::Reference) {
164 QDeclarativeValueTypeReference *ref = static_cast<QDeclarativeValueTypeReference *>(obj);
166 ref->type->read(ref->object, ref->property);
167 QMetaProperty p = ref->type->metaObject()->property(m_lastIndex);
169 QDeclarativeBinding *newBinding = 0;
170 if (value.isFunction() && !value.isRegExp()) {
171 QDeclarativeContextData *ctxt = QDeclarativeEnginePrivate::get(engine)->getContext(context());
173 QDeclarativePropertyCache::Data cacheData;
174 cacheData.flags = QDeclarativePropertyCache::Data::IsWritable;
175 cacheData.propType = ref->object->metaObject()->property(ref->property).userType();
176 cacheData.coreIndex = ref->property;
178 QDeclarativePropertyCache::ValueTypeData valueTypeData;
179 valueTypeData.valueTypeCoreIdx = m_lastIndex;
180 valueTypeData.valueTypePropType = p.userType();
182 newBinding = new QDeclarativeBinding(value, ref->object, ctxt);
183 QScriptContextInfo ctxtInfo(context());
184 newBinding->setSourceLocation(ctxtInfo.fileName(), ctxtInfo.functionStartLineNumber());
185 QDeclarativeProperty prop = QDeclarativePropertyPrivate::restore(cacheData, valueTypeData, ref->object, ctxt);
186 newBinding->setTarget(prop);
187 if (newBinding->expression().contains(QLatin1String("this")))
188 newBinding->setEvaluateFlags(newBinding->evaluateFlags() | QDeclarativeBinding::RequiresThisObject);
191 QDeclarativeAbstractBinding *delBinding =
192 QDeclarativePropertyPrivate::setBinding(ref->object, ref->property, m_lastIndex, newBinding);
194 delBinding->destroy();
196 if (p.isEnumType() && (QMetaType::Type)v.type() == QMetaType::Double)
198 p.write(ref->type, v);
199 ref->type->write(ref->object, ref->property, 0);
202 QDeclarativeValueTypeCopy *copy = static_cast<QDeclarativeValueTypeCopy *>(obj);
203 copy->type->setValue(copy->value);
204 QMetaProperty p = copy->type->metaObject()->property(m_lastIndex);
205 p.write(copy->type, v);
206 copy->value = copy->type->value();
210 QVariant QDeclarativeValueTypeScriptClass::toVariant(Object *obj, bool *ok)
212 QDeclarativeValueTypeObject *o = static_cast<QDeclarativeValueTypeObject *>(obj);
214 if (o->objectType == QDeclarativeValueTypeObject::Reference) {
215 QDeclarativeValueTypeReference *ref = static_cast<QDeclarativeValueTypeReference *>(obj);
220 ref->type->read(ref->object, ref->property);
221 return ref->type->value();
224 QDeclarativeValueTypeCopy *copy = static_cast<QDeclarativeValueTypeCopy *>(obj);
234 QVariant QDeclarativeValueTypeScriptClass::toVariant(const QScriptValue &value)
236 Q_ASSERT(scriptClass(value) == this);
238 return toVariant(object(value), 0);