Merge branch 'kinetic-declarativeui' of scm.dev.nokia.troll.no:qt/kinetic into kineti...
[qt:qt-palm-pre.git] / src / script / bridge / qscriptdeclarativeobject.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
6 **
7 ** This file is part of the QtDeclarative module of the Qt Toolkit.
8 **
9 ** $QT_BEGIN_LICENSE:LGPL-ONLY$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser
12 ** General Public License version 2.1 as published by the Free Software
13 ** Foundation and appearing in the file LICENSE.LGPL included in the
14 ** packaging of this file.  Please review the following information to
15 ** ensure the GNU Lesser General Public License version 2.1 requirements
16 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 **
18 ** If you have questions regarding the use of this file, please contact
19 ** Nokia at qt-info@nokia.com.
20 ** $QT_END_LICENSE$
21 **
22 ****************************************************************************/
23
24 #include "config.h"
25 #include "qscriptdeclarativeobject_p.h"
26
27 #include "../api/qscriptengine.h"
28 #include "../api/qscriptengine_p.h"
29 #include "../api/qscriptcontext.h"
30 #include "../api/qscriptcontext_p.h"
31 #include "../api/qscriptclass.h"
32 #include "../api/qscriptclasspropertyiterator.h"
33
34 #include "Error.h"
35 #include "PropertyNameArray.h"
36
37 #include <QtCore/qstringlist.h>
38
39 Q_DECLARE_METATYPE(QScriptContext*)
40 Q_DECLARE_METATYPE(QScriptValue)
41 Q_DECLARE_METATYPE(QScriptValueList)
42
43 QT_BEGIN_NAMESPACE
44
45 namespace QScript
46 {
47
48 DeclarativeObjectDelegate::DeclarativeObjectDelegate(QScriptDeclarativeClass *c, 
49                                                      QScriptDeclarativeClass::Object *o)
50 : m_class(c), m_object(o)
51 {
52 }
53
54 DeclarativeObjectDelegate::~DeclarativeObjectDelegate()
55 {
56     delete m_object;
57 }
58
59 QScriptObjectDelegate::Type DeclarativeObjectDelegate::type() const
60 {
61     return DeclarativeClassObject;
62 }
63
64 bool DeclarativeObjectDelegate::getOwnPropertySlot(QScriptObject* object,
65                                                    JSC::ExecState *exec,
66                                                    const JSC::Identifier &propertyName,
67                                                    JSC::PropertySlot &slot)
68 {
69     QScriptEnginePrivate *engine = scriptEngineFromExec(exec);
70     QScriptDeclarativeClass::Identifier identifier = (void *)propertyName.ustring().rep();
71
72     QScriptDeclarativeClassPrivate *p = QScriptDeclarativeClassPrivate::get(m_class);
73     p->context = reinterpret_cast<QScriptContext *>(exec);
74     QScriptClass::QueryFlags flags = 
75         m_class->queryProperty(m_object, identifier, QScriptClass::HandlesReadAccess);
76     if (flags & QScriptClass::HandlesReadAccess) {
77         QScriptDeclarativeClass::Value val = m_class->property(m_object, identifier);
78         p->context = 0;
79         slot.setValue((const JSC::JSValue &)val);
80         return true;
81     }
82     p->context = 0;
83
84     return QScriptObjectDelegate::getOwnPropertySlot(object, exec, propertyName, slot);
85 }
86
87 void DeclarativeObjectDelegate::put(QScriptObject* object, JSC::ExecState *exec,
88                                     const JSC::Identifier &propertyName,
89                                     JSC::JSValue value, JSC::PutPropertySlot &slot)
90 {
91     QScriptEnginePrivate *engine = scriptEngineFromExec(exec);
92     QScriptDeclarativeClass::Identifier identifier = (void *)propertyName.ustring().rep();
93
94     QScriptDeclarativeClassPrivate *p = QScriptDeclarativeClassPrivate::get(m_class);
95     p->context = reinterpret_cast<QScriptContext *>(exec);
96     QScriptClass::QueryFlags flags = 
97         m_class->queryProperty(m_object, identifier, QScriptClass::HandlesWriteAccess);
98     if (flags & QScriptClass::HandlesWriteAccess) {
99         m_class->setProperty(m_object, identifier, engine->scriptValueFromJSCValue(value));
100         p->context = 0;
101         return;
102     }
103     p->context = 0;
104
105     QScriptObjectDelegate::put(object, exec, propertyName, value, slot);
106 }
107
108 bool DeclarativeObjectDelegate::deleteProperty(QScriptObject* object, JSC::ExecState *exec,
109                                                const JSC::Identifier &propertyName,
110                                                bool checkDontDelete)
111 {
112     return QScriptObjectDelegate::deleteProperty(object, exec, propertyName, checkDontDelete);
113 }
114
115 bool DeclarativeObjectDelegate::getPropertyAttributes(const QScriptObject* object, 
116                                                       JSC::ExecState *exec,
117                                                       const JSC::Identifier &propertyName,
118                                                       unsigned &attribs) const
119 {
120     QScriptDeclarativeClass::Identifier identifier = (void *)propertyName.ustring().rep();
121
122     QScriptClass::QueryFlags flags = 
123         m_class->queryProperty(m_object, identifier, QScriptClass::HandlesReadAccess);
124     if (flags & QScriptClass::HandlesReadAccess) {
125         QScriptValue::PropertyFlags flags = m_class->propertyFlags(m_object, identifier);
126         attribs = 0;
127         if (flags & QScriptValue::ReadOnly)
128             attribs |= JSC::ReadOnly;
129         if (flags & QScriptValue::SkipInEnumeration)
130             attribs |= JSC::DontEnum;
131         if (flags & QScriptValue::Undeletable)
132             attribs |= JSC::DontDelete;
133         if (flags & QScriptValue::PropertyGetter)
134             attribs |= JSC::Getter;
135         if (flags & QScriptValue::PropertySetter)
136             attribs |= JSC::Setter;
137         attribs |= flags & QScriptValue::UserRange;
138         return true;
139     }
140     return QScriptObjectDelegate::getPropertyAttributes(object, exec, propertyName, attribs);
141 }
142
143 void DeclarativeObjectDelegate::getOwnPropertyNames(QScriptObject* object, JSC::ExecState *exec,
144                                                     JSC::PropertyNameArray &propertyNames,
145                                                     bool includeNonEnumerable)
146 {
147     QStringList properties = m_class->propertyNames(m_object);
148     for (int ii = 0; ii < properties.count(); ++ii) {
149         const QString &name = properties.at(ii);
150         propertyNames.add(JSC::Identifier(exec, name));
151     }
152
153     QScriptObjectDelegate::getOwnPropertyNames(object, exec, propertyNames, includeNonEnumerable);
154 }
155
156 JSC::CallType DeclarativeObjectDelegate::getCallData(QScriptObject *object, JSC::CallData &callData)
157 {
158     if (!QScriptDeclarativeClassPrivate::get(m_class)->supportsCall) 
159         return JSC::CallTypeNone;
160     callData.native.function = call;
161     return JSC::CallTypeHost;
162 }
163
164 JSC::JSValue DeclarativeObjectDelegate::call(JSC::ExecState *exec, JSC::JSObject *callee,
165                                              JSC::JSValue thisValue, const JSC::ArgList &args)
166 {
167     if (!callee->inherits(&QScriptObject::info))
168         return JSC::throwError(exec, JSC::TypeError, "callee is not a DeclarativeObject object");
169     QScriptObject *obj = static_cast<QScriptObject*>(callee);
170     QScriptObjectDelegate *delegate = obj->delegate();
171     if (!delegate || (delegate->type() != QScriptObjectDelegate::DeclarativeClassObject))
172         return JSC::throwError(exec, JSC::TypeError, "callee is not a DeclarativeObject object");
173
174     QScriptDeclarativeClass *scriptClass = static_cast<DeclarativeObjectDelegate*>(delegate)->m_class;
175     QScriptEnginePrivate *eng_p = scriptEngineFromExec(exec);
176
177     JSC::ExecState *oldFrame = eng_p->currentFrame;
178     eng_p->pushContext(exec, thisValue, args, callee);
179     QScriptContext *ctxt = eng_p->contextForFrame(eng_p->currentFrame);
180
181     QScriptValue scriptObject = eng_p->scriptValueFromJSCValue(obj);
182     QScriptDeclarativeClass::Value result = 
183         scriptClass->call(static_cast<DeclarativeObjectDelegate*>(delegate)->m_object, ctxt);
184
185     eng_p->popContext();
186     eng_p->currentFrame = oldFrame;
187     return (JSC::JSValue &)(result);
188 }
189
190 JSC::ConstructType DeclarativeObjectDelegate::getConstructData(QScriptObject* object, JSC::ConstructData &constructData)
191 {
192     return QScriptObjectDelegate::getConstructData(object, constructData);
193 }
194
195 bool DeclarativeObjectDelegate::hasInstance(QScriptObject* object, JSC::ExecState *exec,
196                                             JSC::JSValue value, JSC::JSValue proto)
197 {
198     return QScriptObjectDelegate::hasInstance(object, exec, value, proto);
199 }
200
201 } // namespace QScript
202
203 QT_END_NAMESPACE