Qt 4.8
qdeclarativecontextscriptclass.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the QtDeclarative module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #include "private/qdeclarativecontextscriptclass_p.h"
43 
44 #include "private/qdeclarativeengine_p.h"
45 #include "private/qdeclarativecontext_p.h"
46 #include "private/qdeclarativetypenamescriptclass_p.h"
47 #include "private/qdeclarativelistscriptclass_p.h"
48 #include "private/qdeclarativeguard_p.h"
49 
51 
55  : context(c), scopeObject(o), overrideObject(0), isSharedContext(false), isUrlContext(false) {}
60  bool isUrlContext:1;
61 
63  if (isSharedContext) {
65  } else {
66  return context.contextData();
67  }
68  }
69 
71  if (isSharedContext) {
73  } else {
74  return scopeObject.data();
75  }
76  }
77 };
78 
79 struct UrlContextData : public ContextData {
81  : ContextData(c, o), url(u) {
82  isUrlContext = true;
83  }
85  : ContextData(0, 0), url(u) {
86  isUrlContext = true;
87  }
89 };
90 
91 /*
92  The QDeclarativeContextScriptClass handles property access for a QDeclarativeContext
93  via QtScript.
94  */
96 : QScriptDeclarativeClass(QDeclarativeEnginePrivate::getScriptEngine(bindEngine)), engine(bindEngine),
97  lastScopeObject(0), lastContext(0), lastData(0), lastPropertyIndex(-1)
98 {
99 }
100 
102 {
103 }
104 
106 {
108 
109  return newObject(scriptEngine, this, new ContextData(context, scopeObject));
110 }
111 
113  const QString &url)
114 {
116 
117  return newObject(scriptEngine, this, new UrlContextData(context, scopeObject, url));
118 }
119 
121 {
123 
124  return newObject(scriptEngine, this, new UrlContextData(url));
125 }
126 
128 {
130 
131  return newObject(scriptEngine, this, new ContextData());
132 }
133 
135 {
136  if (scriptClass(v) != this)
137  return 0;
138 
139  ContextData *data = (ContextData *)object(v);
140  return data->getContext(engine);
141 }
142 
144 {
145  if (scriptClass(v) != this)
146  return QUrl();
147 
148  ContextData *data = (ContextData *)object(v);
149  if (data->isUrlContext) {
150  return QUrl(static_cast<UrlContextData *>(data)->url);
151  } else {
152  return QUrl();
153  }
154 }
155 
157 {
158  if (scriptClass(v) != this)
159  return 0;
160 
161  ContextData *data = (ContextData *)object(v);
162  QObject *rv = data->overrideObject;
163  data->overrideObject = override;
164  return rv;
165 }
166 
167 QScriptClass::QueryFlags
169  QScriptClass::QueryFlags flags)
170 {
171  Q_UNUSED(flags);
172 
173  lastScopeObject = 0;
174  lastContext = 0;
175  lastData = 0;
176  lastPropertyIndex = -1;
177 
178  QDeclarativeContextData *bindContext = ((ContextData *)object)->getContext(engine);
179  QObject *scopeObject = ((ContextData *)object)->getScope(engine);
180  if (!bindContext)
181  return 0;
182 
183  QObject *overrideObject = ((ContextData *)object)->overrideObject;
184  if (overrideObject) {
186  QScriptClass::QueryFlags rv =
187  ep->objectClass->queryProperty(overrideObject, name, flags, bindContext,
190  if (rv) {
191  lastScopeObject = overrideObject;
192  lastContext = bindContext;
193  return rv;
194  }
195  }
196 
197  bool includeTypes = true;
198  while (bindContext) {
199  QScriptClass::QueryFlags rv =
200  queryProperty(bindContext, scopeObject, name, flags, includeTypes);
201  scopeObject = 0; // Only applies to the first context
202  includeTypes = false; // Only applies to the first context
203  if (rv) return rv;
204  bindContext = bindContext->parent;
205  }
206 
207  return 0;
208 }
209 
210 QScriptClass::QueryFlags
212  const Identifier &name,
213  QScriptClass::QueryFlags flags,
214  bool includeTypes)
215 {
217 
218  lastPropertyIndex = bindContext->propertyNames?bindContext->propertyNames->value(name):-1;
219  if (lastPropertyIndex != -1) {
220  lastContext = bindContext;
222  }
223 
224  if (includeTypes && bindContext->imports) {
225  QDeclarativeTypeNameCache::Data *data = bindContext->imports->data(name);
226 
227  if (data) {
228  lastData = data;
229  lastContext = bindContext;
230  lastScopeObject = scopeObject;
232  }
233  }
234 
235  if (scopeObject) {
236  QScriptClass::QueryFlags rv =
237  ep->objectClass->queryProperty(scopeObject, name, flags, bindContext,
239  if (rv) {
240  lastScopeObject = scopeObject;
241  lastContext = bindContext;
242  return rv;
243  }
244  }
245 
246  if (bindContext->contextObject) {
247  QScriptClass::QueryFlags rv =
248  ep->objectClass->queryProperty(bindContext->contextObject, name, flags, bindContext,
250 
251  if (rv) {
252  lastScopeObject = bindContext->contextObject;
253  lastContext = bindContext;
254  return rv;
255  }
256  }
257 
258  return 0;
259 }
260 
263 {
264  Q_UNUSED(object);
265 
266  QDeclarativeContextData *bindContext = lastContext;
267  Q_ASSERT(bindContext);
268 
271 
272  if (lastData) {
273 
274  if (lastData->type) {
275  return Value(scriptEngine, ep->typeNameClass->newObject(lastScopeObject, lastData->type));
276  } else if (lastData->typeNamespace) {
277  return Value(scriptEngine, ep->typeNameClass->newObject(lastScopeObject, lastData->typeNamespace));
278  } else {
280  if (index < bindContext->importedScripts.count()) {
281  return Value(scriptEngine, bindContext->importedScripts.at(index));
282  } else {
283  return Value();
284  }
285  }
286 
287  } else if (lastScopeObject) {
288 
289  return ep->objectClass->property(lastScopeObject, name);
290 
291  } else if (lastPropertyIndex != -1) {
292 
293  QScriptValue rv;
294  if (lastPropertyIndex < bindContext->idValueCount) {
295  rv = ep->objectClass->newQObject(bindContext->idValues[lastPropertyIndex].data());
296 
297  if (ep->captureProperties)
299  } else {
301  const QVariant &value = cp->propertyValues.at(lastPropertyIndex);
302  if (value.userType() == qMetaTypeId<QList<QObject*> >()) {
304  } else {
305  rv = ep->scriptValueFromVariant(value);
306  }
307 
308  if (ep->captureProperties)
310  }
311 
312  return Value(scriptEngine, rv);
313 
314  } else {
315 
316  return Value(scriptEngine, lastFunction);
317 
318  }
319 }
320 
322  const QScriptValue &value)
323 {
324  Q_UNUSED(object);
326 
327  QDeclarativeContextData *bindContext = lastContext;
328  Q_ASSERT(bindContext);
329 
331 
332  ep->objectClass->setProperty(lastScopeObject, name, value, context(), bindContext);
333 }
334 
The QVariant class acts like a union for the most common Qt data types.
Definition: qvariant.h:92
static QScriptEngine * getScriptEngine(QDeclarativeEngine *e)
QScriptValue newUrlContext(QDeclarativeContextData *, QObject *, const QString &)
QDeclarativeTypeNameScriptClass * typeNameClass
UrlContextData(QDeclarativeContextData *c, QObject *o, const QString &u)
QDeclarativeContextData * getContext(QDeclarativeEngine *engine)
unsigned char c[8]
Definition: qnumeric_p.h:62
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
virtual void setProperty(Object *, const Identifier &name, const QScriptValue &)
QObject * setOverrideObject(QScriptValue &, QObject *)
static QScriptValue newObject(QScriptEngine *, QScriptDeclarativeClass *, Object *)
QScriptClass::QueryFlags queryProperty(QObject *, const Identifier &, QScriptClass::QueryFlags flags, QDeclarativeContextData *evalContext, QueryHints hints=0)
quint16 u
virtual Value property(Object *, const Identifier &)
static int context_count(QDeclarativeListProperty< QObject > *)
QDeclarativeContextData * contextFromValue(const QScriptValue &)
The QUrl class provides a convenient interface for working with URLs.
Definition: qurl.h:61
The QString class provides a Unicode character string.
Definition: qstring.h:83
QDeclarativeContextData * parent
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
The QObject class is the base class of all Qt objects.
Definition: qobject.h:111
static QDeclarativeEnginePrivate * get(QDeclarativeEngine *e)
The QScriptDeclarativeClass::Value class acts as a container for JavaScript data types.
QDeclarativeTypeNameCache * imports
QScriptValue newQObject(QObject *, int type=QMetaType::QObjectStar)
The QScriptEngine class provides an environment for evaluating Qt Script code.
QDeclarativeContextPrivate * asQDeclarativeContextPrivate()
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
QScriptValue newObject(QObject *, QDeclarativeType *, TypeNameMode=IncludeEnums)
QDeclarativeTypeNameCache::Data * lastData
const char * name
QScriptEngine * engine() const
const T & at(int i) const
Returns the item at index position i in the list.
Definition: qlist.h:468
virtual QScriptClass::QueryFlags queryProperty(Object *, const Identifier &, QScriptClass::QueryFlags flags)
QScriptValue scriptValueFromVariant(const QVariant &)
static const char * data(const QByteArray &arr)
QObject * getScope(QDeclarativeEngine *engine)
QScriptValue newContext(QDeclarativeContextData *, QObject *=0)
QDeclarativeContextData * sharedContext
QDeclarativeIntegerCache * propertyNames
QDeclarativeObjectScriptClass * objectClass
int userType() const
Returns the storage type of the value stored in the variant.
Definition: qvariant.cpp:1913
The QDeclarativeEngine class provides an environment for instantiating QML components.
QDeclarativeListScriptClass * listClass
QDeclarativeContext * asQDeclarativeContext()
QDeclarativeTypeNameCache * typeNamespace
quint16 index
static QObject * context_at(QDeclarativeListProperty< QObject > *, int)
static QScriptDeclarativeClass * scriptClass(const QScriptValue &)
QDeclarativeContextData * contextData()
QDeclarativeGuardedContextData context
void setProperty(QObject *, const Identifier &name, const QScriptValue &, QScriptContext *context, QDeclarativeContextData *evalContext=0)
Data * data(const QString &) const
QScriptValue newList(QObject *, int, int)
QDeclarativeGuard< QObject > scopeObject
QScriptContext * context() const
QList< QScriptValue > importedScripts
The QScriptValue class acts as a container for the Qt Script data types.
Definition: qscriptvalue.h:57
#define Q_UNUSED(x)
Indicates to the compiler that the parameter with the specified name is not used in the body of a fun...
Definition: qglobal.h:1729
Value property(QObject *, const Identifier &)
QPODVector< CapturedProperty, 16 > capturedProperties
ContextData(QDeclarativeContextData *c, QObject *o)