|
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$ |
|
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 |
|
14 ** this package. |
|
15 ** |
|
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. |
|
23 ** |
|
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. |
|
27 ** |
|
28 ** If you have questions regarding the use of this file, please contact |
|
29 ** Nokia at qt-info@nokia.com. |
|
30 ** |
|
31 ** |
|
32 ** |
|
33 ** |
|
34 ** |
|
35 ** |
|
36 ** |
|
37 ** |
|
38 ** $QT_END_LICENSE$ |
|
39 ** |
|
40 ****************************************************************************/ |
|
41 |
|
42 #include "private/qdeclarativevmemetaobject_p.h" |
|
43 |
|
44 #include "qdeclarative.h" |
|
45 #include "private/qdeclarativerefcount_p.h" |
|
46 #include "qdeclarativeexpression.h" |
|
47 #include "private/qdeclarativeexpression_p.h" |
|
48 #include "private/qdeclarativecontext_p.h" |
|
49 |
|
50 Q_DECLARE_METATYPE(QScriptValue); |
|
51 |
|
52 QT_BEGIN_NAMESPACE |
|
53 |
|
54 class QDeclarativeVMEVariant |
|
55 { |
|
56 public: |
|
57 inline QDeclarativeVMEVariant(); |
|
58 inline ~QDeclarativeVMEVariant(); |
|
59 |
|
60 inline const void *dataPtr() const; |
|
61 inline void *dataPtr(); |
|
62 inline int dataType() const; |
|
63 |
|
64 inline QObject *asQObject(); |
|
65 inline const QVariant &asQVariant(); |
|
66 inline int asInt(); |
|
67 inline bool asBool(); |
|
68 inline double asDouble(); |
|
69 inline const QString &asQString(); |
|
70 inline const QUrl &asQUrl(); |
|
71 inline const QColor &asQColor(); |
|
72 inline const QTime &asQTime(); |
|
73 inline const QDate &asQDate(); |
|
74 inline const QDateTime &asQDateTime(); |
|
75 inline const QScriptValue &asQScriptValue(); |
|
76 |
|
77 inline void setValue(QObject *); |
|
78 inline void setValue(const QVariant &); |
|
79 inline void setValue(int); |
|
80 inline void setValue(bool); |
|
81 inline void setValue(double); |
|
82 inline void setValue(const QString &); |
|
83 inline void setValue(const QUrl &); |
|
84 inline void setValue(const QColor &); |
|
85 inline void setValue(const QTime &); |
|
86 inline void setValue(const QDate &); |
|
87 inline void setValue(const QDateTime &); |
|
88 inline void setValue(const QScriptValue &); |
|
89 private: |
|
90 int type; |
|
91 void *data[4]; // Large enough to hold all types |
|
92 |
|
93 inline void cleanup(); |
|
94 }; |
|
95 |
|
96 QDeclarativeVMEVariant::QDeclarativeVMEVariant() |
|
97 : type(QVariant::Invalid) |
|
98 { |
|
99 } |
|
100 |
|
101 QDeclarativeVMEVariant::~QDeclarativeVMEVariant() |
|
102 { |
|
103 cleanup(); |
|
104 } |
|
105 |
|
106 void QDeclarativeVMEVariant::cleanup() |
|
107 { |
|
108 if (type == QVariant::Invalid) { |
|
109 } else if (type == QMetaType::Int || |
|
110 type == QMetaType::Bool || |
|
111 type == QMetaType::Double) { |
|
112 type = QVariant::Invalid; |
|
113 } else if (type == QMetaType::QObjectStar) { |
|
114 ((QDeclarativeGuard<QObject>*)dataPtr())->~QDeclarativeGuard<QObject>(); |
|
115 type = QVariant::Invalid; |
|
116 } else if (type == QMetaType::QString) { |
|
117 ((QString *)dataPtr())->~QString(); |
|
118 type = QVariant::Invalid; |
|
119 } else if (type == QMetaType::QUrl) { |
|
120 ((QUrl *)dataPtr())->~QUrl(); |
|
121 type = QVariant::Invalid; |
|
122 } else if (type == QMetaType::QColor) { |
|
123 ((QColor *)dataPtr())->~QColor(); |
|
124 type = QVariant::Invalid; |
|
125 } else if (type == QMetaType::QTime) { |
|
126 ((QTime *)dataPtr())->~QTime(); |
|
127 type = QVariant::Invalid; |
|
128 } else if (type == QMetaType::QDate) { |
|
129 ((QDate *)dataPtr())->~QDate(); |
|
130 type = QVariant::Invalid; |
|
131 } else if (type == QMetaType::QDateTime) { |
|
132 ((QDateTime *)dataPtr())->~QDateTime(); |
|
133 type = QVariant::Invalid; |
|
134 } else if (type == qMetaTypeId<QVariant>()) { |
|
135 ((QVariant *)dataPtr())->~QVariant(); |
|
136 type = QVariant::Invalid; |
|
137 } else if (type == qMetaTypeId<QScriptValue>()) { |
|
138 ((QScriptValue *)dataPtr())->~QScriptValue(); |
|
139 type = QVariant::Invalid; |
|
140 } |
|
141 |
|
142 } |
|
143 |
|
144 int QDeclarativeVMEVariant::dataType() const |
|
145 { |
|
146 return type; |
|
147 } |
|
148 |
|
149 const void *QDeclarativeVMEVariant::dataPtr() const |
|
150 { |
|
151 return &data; |
|
152 } |
|
153 |
|
154 void *QDeclarativeVMEVariant::dataPtr() |
|
155 { |
|
156 return &data; |
|
157 } |
|
158 |
|
159 QObject *QDeclarativeVMEVariant::asQObject() |
|
160 { |
|
161 if (type != QMetaType::QObjectStar) |
|
162 setValue((QObject *)0); |
|
163 |
|
164 return *(QDeclarativeGuard<QObject> *)(dataPtr()); |
|
165 } |
|
166 |
|
167 const QVariant &QDeclarativeVMEVariant::asQVariant() |
|
168 { |
|
169 if (type != QMetaType::QVariant) |
|
170 setValue(QVariant()); |
|
171 |
|
172 return *(QVariant *)(dataPtr()); |
|
173 } |
|
174 |
|
175 int QDeclarativeVMEVariant::asInt() |
|
176 { |
|
177 if (type != QMetaType::Int) |
|
178 setValue(int(0)); |
|
179 |
|
180 return *(int *)(dataPtr()); |
|
181 } |
|
182 |
|
183 bool QDeclarativeVMEVariant::asBool() |
|
184 { |
|
185 if (type != QMetaType::Bool) |
|
186 setValue(bool(false)); |
|
187 |
|
188 return *(bool *)(dataPtr()); |
|
189 } |
|
190 |
|
191 double QDeclarativeVMEVariant::asDouble() |
|
192 { |
|
193 if (type != QMetaType::Double) |
|
194 setValue(double(0)); |
|
195 |
|
196 return *(double *)(dataPtr()); |
|
197 } |
|
198 |
|
199 const QString &QDeclarativeVMEVariant::asQString() |
|
200 { |
|
201 if (type != QMetaType::QString) |
|
202 setValue(QString()); |
|
203 |
|
204 return *(QString *)(dataPtr()); |
|
205 } |
|
206 |
|
207 const QUrl &QDeclarativeVMEVariant::asQUrl() |
|
208 { |
|
209 if (type != QMetaType::QUrl) |
|
210 setValue(QUrl()); |
|
211 |
|
212 return *(QUrl *)(dataPtr()); |
|
213 } |
|
214 |
|
215 const QColor &QDeclarativeVMEVariant::asQColor() |
|
216 { |
|
217 if (type != QMetaType::QColor) |
|
218 setValue(QColor()); |
|
219 |
|
220 return *(QColor *)(dataPtr()); |
|
221 } |
|
222 |
|
223 const QTime &QDeclarativeVMEVariant::asQTime() |
|
224 { |
|
225 if (type != QMetaType::QTime) |
|
226 setValue(QTime()); |
|
227 |
|
228 return *(QTime *)(dataPtr()); |
|
229 } |
|
230 |
|
231 const QDate &QDeclarativeVMEVariant::asQDate() |
|
232 { |
|
233 if (type != QMetaType::QDate) |
|
234 setValue(QDate()); |
|
235 |
|
236 return *(QDate *)(dataPtr()); |
|
237 } |
|
238 |
|
239 const QDateTime &QDeclarativeVMEVariant::asQDateTime() |
|
240 { |
|
241 if (type != QMetaType::QDateTime) |
|
242 setValue(QDateTime()); |
|
243 |
|
244 return *(QDateTime *)(dataPtr()); |
|
245 } |
|
246 |
|
247 const QScriptValue &QDeclarativeVMEVariant::asQScriptValue() |
|
248 { |
|
249 if (type != qMetaTypeId<QScriptValue>()) |
|
250 setValue(QScriptValue()); |
|
251 |
|
252 return *(QScriptValue *)(dataPtr()); |
|
253 } |
|
254 |
|
255 void QDeclarativeVMEVariant::setValue(QObject *v) |
|
256 { |
|
257 if (type != QMetaType::QObjectStar) { |
|
258 cleanup(); |
|
259 type = QMetaType::QObjectStar; |
|
260 new (dataPtr()) QDeclarativeGuard<QObject>(); |
|
261 } |
|
262 *(QDeclarativeGuard<QObject>*)(dataPtr()) = v; |
|
263 } |
|
264 |
|
265 void QDeclarativeVMEVariant::setValue(const QVariant &v) |
|
266 { |
|
267 if (type != qMetaTypeId<QVariant>()) { |
|
268 cleanup(); |
|
269 type = qMetaTypeId<QVariant>(); |
|
270 new (dataPtr()) QVariant(v); |
|
271 } else { |
|
272 *(QVariant *)(dataPtr()) = v; |
|
273 } |
|
274 } |
|
275 |
|
276 void QDeclarativeVMEVariant::setValue(int v) |
|
277 { |
|
278 if (type != QMetaType::Int) { |
|
279 cleanup(); |
|
280 type = QMetaType::Int; |
|
281 } |
|
282 *(int *)(dataPtr()) = v; |
|
283 } |
|
284 |
|
285 void QDeclarativeVMEVariant::setValue(bool v) |
|
286 { |
|
287 if (type != QMetaType::Bool) { |
|
288 cleanup(); |
|
289 type = QMetaType::Bool; |
|
290 } |
|
291 *(bool *)(dataPtr()) = v; |
|
292 } |
|
293 |
|
294 void QDeclarativeVMEVariant::setValue(double v) |
|
295 { |
|
296 if (type != QMetaType::Double) { |
|
297 cleanup(); |
|
298 type = QMetaType::Double; |
|
299 } |
|
300 *(double *)(dataPtr()) = v; |
|
301 } |
|
302 |
|
303 void QDeclarativeVMEVariant::setValue(const QString &v) |
|
304 { |
|
305 if (type != QMetaType::QString) { |
|
306 cleanup(); |
|
307 type = QMetaType::QString; |
|
308 new (dataPtr()) QString(v); |
|
309 } else { |
|
310 *(QString *)(dataPtr()) = v; |
|
311 } |
|
312 } |
|
313 |
|
314 void QDeclarativeVMEVariant::setValue(const QUrl &v) |
|
315 { |
|
316 if (type != QMetaType::QUrl) { |
|
317 cleanup(); |
|
318 type = QMetaType::QUrl; |
|
319 new (dataPtr()) QUrl(v); |
|
320 } else { |
|
321 *(QUrl *)(dataPtr()) = v; |
|
322 } |
|
323 } |
|
324 |
|
325 void QDeclarativeVMEVariant::setValue(const QColor &v) |
|
326 { |
|
327 if (type != QMetaType::QColor) { |
|
328 cleanup(); |
|
329 type = QMetaType::QColor; |
|
330 new (dataPtr()) QColor(v); |
|
331 } else { |
|
332 *(QColor *)(dataPtr()) = v; |
|
333 } |
|
334 } |
|
335 |
|
336 void QDeclarativeVMEVariant::setValue(const QTime &v) |
|
337 { |
|
338 if (type != QMetaType::QTime) { |
|
339 cleanup(); |
|
340 type = QMetaType::QTime; |
|
341 new (dataPtr()) QTime(v); |
|
342 } else { |
|
343 *(QTime *)(dataPtr()) = v; |
|
344 } |
|
345 } |
|
346 |
|
347 void QDeclarativeVMEVariant::setValue(const QDate &v) |
|
348 { |
|
349 if (type != QMetaType::QDate) { |
|
350 cleanup(); |
|
351 type = QMetaType::QDate; |
|
352 new (dataPtr()) QDate(v); |
|
353 } else { |
|
354 *(QDate *)(dataPtr()) = v; |
|
355 } |
|
356 } |
|
357 |
|
358 void QDeclarativeVMEVariant::setValue(const QDateTime &v) |
|
359 { |
|
360 if (type != QMetaType::QDateTime) { |
|
361 cleanup(); |
|
362 type = QMetaType::QDateTime; |
|
363 new (dataPtr()) QDateTime(v); |
|
364 } else { |
|
365 *(QDateTime *)(dataPtr()) = v; |
|
366 } |
|
367 } |
|
368 |
|
369 void QDeclarativeVMEVariant::setValue(const QScriptValue &v) |
|
370 { |
|
371 if (type != qMetaTypeId<QScriptValue>()) { |
|
372 cleanup(); |
|
373 type = qMetaTypeId<QScriptValue>(); |
|
374 new (dataPtr()) QScriptValue(v); |
|
375 } else { |
|
376 *(QScriptValue *)(dataPtr()) = v; |
|
377 } |
|
378 } |
|
379 |
|
380 QDeclarativeVMEMetaObject::QDeclarativeVMEMetaObject(QObject *obj, |
|
381 const QMetaObject *other, |
|
382 const QDeclarativeVMEMetaData *meta, |
|
383 QDeclarativeCompiledData *cdata) |
|
384 : object(obj), compiledData(cdata), ctxt(QDeclarativeData::get(obj, true)->outerContext), |
|
385 metaData(meta), data(0), methods(0), parent(0) |
|
386 { |
|
387 compiledData->addref(); |
|
388 |
|
389 *static_cast<QMetaObject *>(this) = *other; |
|
390 this->d.superdata = obj->metaObject(); |
|
391 |
|
392 QObjectPrivate *op = QObjectPrivate::get(obj); |
|
393 if (op->metaObject) |
|
394 parent = static_cast<QAbstractDynamicMetaObject*>(op->metaObject); |
|
395 op->metaObject = this; |
|
396 |
|
397 propOffset = QAbstractDynamicMetaObject::propertyOffset(); |
|
398 methodOffset = QAbstractDynamicMetaObject::methodOffset(); |
|
399 |
|
400 data = new QDeclarativeVMEVariant[metaData->propertyCount]; |
|
401 |
|
402 aConnected.resize(metaData->aliasCount); |
|
403 int list_type = qMetaTypeId<QDeclarativeListProperty<QObject> >(); |
|
404 |
|
405 // ### Optimize |
|
406 for (int ii = 0; ii < metaData->propertyCount; ++ii) { |
|
407 int t = (metaData->propertyData() + ii)->propertyType; |
|
408 if (t == list_type) { |
|
409 listProperties.append(List(methodOffset + ii)); |
|
410 data[ii].setValue(listProperties.count() - 1); |
|
411 } |
|
412 } |
|
413 } |
|
414 |
|
415 QDeclarativeVMEMetaObject::~QDeclarativeVMEMetaObject() |
|
416 { |
|
417 compiledData->release(); |
|
418 delete parent; |
|
419 delete [] data; |
|
420 delete [] methods; |
|
421 } |
|
422 |
|
423 int QDeclarativeVMEMetaObject::metaCall(QMetaObject::Call c, int _id, void **a) |
|
424 { |
|
425 int id = _id; |
|
426 if(c == QMetaObject::WriteProperty) { |
|
427 int flags = *reinterpret_cast<int*>(a[3]); |
|
428 if (!(flags & QDeclarativePropertyPrivate::BypassInterceptor) |
|
429 && !aInterceptors.isEmpty() |
|
430 && aInterceptors.testBit(id)) { |
|
431 QPair<int, QDeclarativePropertyValueInterceptor*> pair = interceptors.value(id); |
|
432 int valueIndex = pair.first; |
|
433 QDeclarativePropertyValueInterceptor *vi = pair.second; |
|
434 int type = property(id).userType(); |
|
435 |
|
436 if (type != QVariant::Invalid) { |
|
437 if (valueIndex != -1) { |
|
438 QDeclarativeEnginePrivate *ep = ctxt?QDeclarativeEnginePrivate::get(ctxt->engine):0; |
|
439 QDeclarativeValueType *valueType = 0; |
|
440 if (ep) valueType = ep->valueTypes[type]; |
|
441 else valueType = QDeclarativeValueTypeFactory::valueType(type); |
|
442 Q_ASSERT(valueType); |
|
443 |
|
444 valueType->setValue(QVariant(type, a[0])); |
|
445 QMetaProperty valueProp = valueType->metaObject()->property(valueIndex); |
|
446 vi->write(valueProp.read(valueType)); |
|
447 |
|
448 if (!ep) delete valueType; |
|
449 return -1; |
|
450 } else { |
|
451 vi->write(QVariant(type, a[0])); |
|
452 return -1; |
|
453 } |
|
454 } |
|
455 } |
|
456 } |
|
457 if(c == QMetaObject::ReadProperty || c == QMetaObject::WriteProperty) { |
|
458 if (id >= propOffset) { |
|
459 id -= propOffset; |
|
460 |
|
461 if (id < metaData->propertyCount) { |
|
462 int t = (metaData->propertyData() + id)->propertyType; |
|
463 bool needActivate = false; |
|
464 |
|
465 if (t == -1) { |
|
466 |
|
467 if (c == QMetaObject::ReadProperty) { |
|
468 *reinterpret_cast<QVariant *>(a[0]) = readVarPropertyAsVariant(id); |
|
469 } else if (c == QMetaObject::WriteProperty) { |
|
470 writeVarProperty(id, *reinterpret_cast<QVariant *>(a[0])); |
|
471 } |
|
472 |
|
473 } else { |
|
474 |
|
475 if (c == QMetaObject::ReadProperty) { |
|
476 switch(t) { |
|
477 case QVariant::Int: |
|
478 *reinterpret_cast<int *>(a[0]) = data[id].asInt(); |
|
479 break; |
|
480 case QVariant::Bool: |
|
481 *reinterpret_cast<bool *>(a[0]) = data[id].asBool(); |
|
482 break; |
|
483 case QVariant::Double: |
|
484 *reinterpret_cast<double *>(a[0]) = data[id].asDouble(); |
|
485 break; |
|
486 case QVariant::String: |
|
487 *reinterpret_cast<QString *>(a[0]) = data[id].asQString(); |
|
488 break; |
|
489 case QVariant::Url: |
|
490 *reinterpret_cast<QUrl *>(a[0]) = data[id].asQUrl(); |
|
491 break; |
|
492 case QVariant::Color: |
|
493 *reinterpret_cast<QColor *>(a[0]) = data[id].asQColor(); |
|
494 break; |
|
495 case QVariant::Date: |
|
496 *reinterpret_cast<QDate *>(a[0]) = data[id].asQDate(); |
|
497 break; |
|
498 case QVariant::DateTime: |
|
499 *reinterpret_cast<QDateTime *>(a[0]) = data[id].asQDateTime(); |
|
500 break; |
|
501 case QMetaType::QObjectStar: |
|
502 *reinterpret_cast<QObject **>(a[0]) = data[id].asQObject(); |
|
503 break; |
|
504 default: |
|
505 break; |
|
506 } |
|
507 if (t == qMetaTypeId<QDeclarativeListProperty<QObject> >()) { |
|
508 int listIndex = data[id].asInt(); |
|
509 const List *list = &listProperties.at(listIndex); |
|
510 *reinterpret_cast<QDeclarativeListProperty<QObject> *>(a[0]) = |
|
511 QDeclarativeListProperty<QObject>(object, (void *)list, |
|
512 list_append, list_count, list_at, |
|
513 list_clear); |
|
514 } |
|
515 |
|
516 } else if (c == QMetaObject::WriteProperty) { |
|
517 |
|
518 switch(t) { |
|
519 case QVariant::Int: |
|
520 needActivate = *reinterpret_cast<int *>(a[0]) != data[id].asInt(); |
|
521 data[id].setValue(*reinterpret_cast<int *>(a[0])); |
|
522 break; |
|
523 case QVariant::Bool: |
|
524 needActivate = *reinterpret_cast<bool *>(a[0]) != data[id].asBool(); |
|
525 data[id].setValue(*reinterpret_cast<bool *>(a[0])); |
|
526 break; |
|
527 case QVariant::Double: |
|
528 needActivate = *reinterpret_cast<double *>(a[0]) != data[id].asDouble(); |
|
529 data[id].setValue(*reinterpret_cast<double *>(a[0])); |
|
530 break; |
|
531 case QVariant::String: |
|
532 needActivate = *reinterpret_cast<QString *>(a[0]) != data[id].asQString(); |
|
533 data[id].setValue(*reinterpret_cast<QString *>(a[0])); |
|
534 break; |
|
535 case QVariant::Url: |
|
536 needActivate = *reinterpret_cast<QUrl *>(a[0]) != data[id].asQUrl(); |
|
537 data[id].setValue(*reinterpret_cast<QUrl *>(a[0])); |
|
538 break; |
|
539 case QVariant::Color: |
|
540 needActivate = *reinterpret_cast<QColor *>(a[0]) != data[id].asQColor(); |
|
541 data[id].setValue(*reinterpret_cast<QColor *>(a[0])); |
|
542 break; |
|
543 case QVariant::Date: |
|
544 needActivate = *reinterpret_cast<QDate *>(a[0]) != data[id].asQDate(); |
|
545 data[id].setValue(*reinterpret_cast<QDate *>(a[0])); |
|
546 break; |
|
547 case QVariant::DateTime: |
|
548 needActivate = *reinterpret_cast<QDateTime *>(a[0]) != data[id].asQDateTime(); |
|
549 data[id].setValue(*reinterpret_cast<QDateTime *>(a[0])); |
|
550 break; |
|
551 case QMetaType::QObjectStar: |
|
552 needActivate = *reinterpret_cast<QObject **>(a[0]) != data[id].asQObject(); |
|
553 data[id].setValue(*reinterpret_cast<QObject **>(a[0])); |
|
554 break; |
|
555 default: |
|
556 break; |
|
557 } |
|
558 } |
|
559 |
|
560 } |
|
561 |
|
562 if (c == QMetaObject::WriteProperty && needActivate) { |
|
563 activate(object, methodOffset + id, 0); |
|
564 } |
|
565 |
|
566 return -1; |
|
567 } |
|
568 |
|
569 id -= metaData->propertyCount; |
|
570 |
|
571 if (id < metaData->aliasCount) { |
|
572 |
|
573 QDeclarativeVMEMetaData::AliasData *d = metaData->aliasData() + id; |
|
574 |
|
575 if (d->flags & QML_ALIAS_FLAG_PTR && c == QMetaObject::ReadProperty) |
|
576 *reinterpret_cast<void **>(a[0]) = 0; |
|
577 |
|
578 if (!ctxt) return -1; |
|
579 |
|
580 QDeclarativeContext *context = ctxt->asQDeclarativeContext(); |
|
581 QDeclarativeContextPrivate *ctxtPriv = QDeclarativeContextPrivate::get(context); |
|
582 |
|
583 QObject *target = ctxtPriv->data->idValues[d->contextIdx].data(); |
|
584 if (!target) |
|
585 return -1; |
|
586 |
|
587 if (c == QMetaObject::ReadProperty && !aConnected.testBit(id)) { |
|
588 int sigIdx = methodOffset + id + metaData->propertyCount; |
|
589 QMetaObject::connect(context, d->contextIdx + ctxtPriv->notifyIndex, object, sigIdx); |
|
590 |
|
591 if (d->propertyIdx != -1) { |
|
592 QMetaProperty prop = |
|
593 target->metaObject()->property(d->propertyIdx); |
|
594 if (prop.hasNotifySignal()) |
|
595 QMetaObject::connect(target, prop.notifySignalIndex(), |
|
596 object, sigIdx); |
|
597 } |
|
598 aConnected.setBit(id); |
|
599 } |
|
600 |
|
601 if (d->propertyIdx == -1) { |
|
602 *reinterpret_cast<QObject **>(a[0]) = target; |
|
603 return -1; |
|
604 } else { |
|
605 return QMetaObject::metacall(target, c, d->propertyIdx, a); |
|
606 } |
|
607 |
|
608 } |
|
609 return -1; |
|
610 |
|
611 } |
|
612 |
|
613 } else if(c == QMetaObject::InvokeMetaMethod) { |
|
614 |
|
615 if (id >= methodOffset) { |
|
616 |
|
617 id -= methodOffset; |
|
618 int plainSignals = metaData->signalCount + metaData->propertyCount + |
|
619 metaData->aliasCount; |
|
620 if (id < plainSignals) { |
|
621 QMetaObject::activate(object, _id, a); |
|
622 return -1; |
|
623 } |
|
624 |
|
625 id -= plainSignals; |
|
626 |
|
627 if (id < metaData->methodCount) { |
|
628 if (!ctxt->engine) |
|
629 return -1; // We can't run the method |
|
630 |
|
631 QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(ctxt->engine); |
|
632 |
|
633 QScriptValue function = method(id); |
|
634 |
|
635 QScriptValueList args; |
|
636 QDeclarativeVMEMetaData::MethodData *data = metaData->methodData() + id; |
|
637 if (data->parameterCount) { |
|
638 for (int ii = 0; ii < data->parameterCount; ++ii) { |
|
639 args << ep->scriptValueFromVariant(*(QVariant *)a[ii + 1]); |
|
640 } |
|
641 } |
|
642 QScriptValue rv = function.call(ep->objectClass->newQObject(object), args); |
|
643 |
|
644 if (a[0]) *reinterpret_cast<QVariant *>(a[0]) = ep->scriptValueToVariant(rv); |
|
645 |
|
646 return -1; |
|
647 } |
|
648 return -1; |
|
649 } |
|
650 } |
|
651 |
|
652 if (parent) |
|
653 return parent->metaCall(c, _id, a); |
|
654 else |
|
655 return object->qt_metacall(c, _id, a); |
|
656 } |
|
657 |
|
658 QScriptValue QDeclarativeVMEMetaObject::method(int index) |
|
659 { |
|
660 if (!methods) |
|
661 methods = new QScriptValue[metaData->methodCount]; |
|
662 |
|
663 if (!methods[index].isValid()) { |
|
664 QDeclarativeVMEMetaData::MethodData *data = metaData->methodData() + index; |
|
665 |
|
666 const QChar *body = |
|
667 (const QChar *)(((const char*)metaData) + data->bodyOffset); |
|
668 |
|
669 QString code = QString::fromRawData(body, data->bodyLength); |
|
670 |
|
671 // XXX Use QScriptProgram |
|
672 // XXX We should evaluate all methods in a single big script block to |
|
673 // improve the call time between dynamic methods defined on the same |
|
674 // object |
|
675 methods[index] = QDeclarativeExpressionPrivate::evalInObjectScope(ctxt, object, code, ctxt->url.toString(), |
|
676 data->lineNumber, 0); |
|
677 } |
|
678 |
|
679 return methods[index]; |
|
680 } |
|
681 |
|
682 QScriptValue QDeclarativeVMEMetaObject::readVarProperty(int id) |
|
683 { |
|
684 if (data[id].dataType() == qMetaTypeId<QScriptValue>()) |
|
685 return data[id].asQScriptValue(); |
|
686 else if (data[id].dataType() == QMetaType::QObjectStar) |
|
687 return QDeclarativeEnginePrivate::get(ctxt->engine)->objectClass->newQObject(data[id].asQObject()); |
|
688 else |
|
689 return QDeclarativeEnginePrivate::get(ctxt->engine)->scriptValueFromVariant(data[id].asQVariant()); |
|
690 } |
|
691 |
|
692 QVariant QDeclarativeVMEMetaObject::readVarPropertyAsVariant(int id) |
|
693 { |
|
694 if (data[id].dataType() == qMetaTypeId<QScriptValue>()) |
|
695 return QDeclarativeEnginePrivate::get(ctxt->engine)->scriptValueToVariant(data[id].asQScriptValue()); |
|
696 else if (data[id].dataType() == QMetaType::QObjectStar) |
|
697 return QVariant::fromValue(data[id].asQObject()); |
|
698 else |
|
699 return data[id].asQVariant(); |
|
700 } |
|
701 |
|
702 void QDeclarativeVMEMetaObject::writeVarProperty(int id, const QScriptValue &value) |
|
703 { |
|
704 data[id].setValue(value); |
|
705 activate(object, methodOffset + id, 0); |
|
706 } |
|
707 |
|
708 void QDeclarativeVMEMetaObject::writeVarProperty(int id, const QVariant &value) |
|
709 { |
|
710 if (value.userType() == QMetaType::QObjectStar) |
|
711 data[id].setValue(qvariant_cast<QObject *>(value)); |
|
712 else |
|
713 data[id].setValue(value); |
|
714 activate(object, methodOffset + id, 0); |
|
715 } |
|
716 |
|
717 void QDeclarativeVMEMetaObject::listChanged(int id) |
|
718 { |
|
719 activate(object, methodOffset + id, 0); |
|
720 } |
|
721 |
|
722 void QDeclarativeVMEMetaObject::list_append(QDeclarativeListProperty<QObject> *prop, QObject *o) |
|
723 { |
|
724 List *list = static_cast<List *>(prop->data); |
|
725 list->append(o); |
|
726 QMetaObject::activate(prop->object, list->notifyIndex, 0); |
|
727 } |
|
728 |
|
729 int QDeclarativeVMEMetaObject::list_count(QDeclarativeListProperty<QObject> *prop) |
|
730 { |
|
731 return static_cast<List *>(prop->data)->count(); |
|
732 } |
|
733 |
|
734 QObject *QDeclarativeVMEMetaObject::list_at(QDeclarativeListProperty<QObject> *prop, int index) |
|
735 { |
|
736 return static_cast<List *>(prop->data)->at(index); |
|
737 } |
|
738 |
|
739 void QDeclarativeVMEMetaObject::list_clear(QDeclarativeListProperty<QObject> *prop) |
|
740 { |
|
741 List *list = static_cast<List *>(prop->data); |
|
742 list->clear(); |
|
743 QMetaObject::activate(prop->object, list->notifyIndex, 0); |
|
744 } |
|
745 |
|
746 void QDeclarativeVMEMetaObject::registerInterceptor(int index, int valueIndex, QDeclarativePropertyValueInterceptor *interceptor) |
|
747 { |
|
748 if (aInterceptors.isEmpty()) |
|
749 aInterceptors.resize(propertyCount() + metaData->propertyCount); |
|
750 aInterceptors.setBit(index); |
|
751 interceptors.insert(index, qMakePair(valueIndex, interceptor)); |
|
752 } |
|
753 |
|
754 QScriptValue QDeclarativeVMEMetaObject::vmeMethod(int index) |
|
755 { |
|
756 if (index < methodOffset) { |
|
757 Q_ASSERT(parent); |
|
758 return static_cast<QDeclarativeVMEMetaObject *>(parent)->vmeMethod(index); |
|
759 } |
|
760 int plainSignals = metaData->signalCount + metaData->propertyCount + metaData->aliasCount; |
|
761 Q_ASSERT(index >= (methodOffset + plainSignals) && index < (methodOffset + plainSignals + metaData->methodCount)); |
|
762 return method(index - methodOffset - plainSignals); |
|
763 } |
|
764 |
|
765 QScriptValue QDeclarativeVMEMetaObject::vmeProperty(int index) |
|
766 { |
|
767 if (index < propOffset) { |
|
768 Q_ASSERT(parent); |
|
769 return static_cast<QDeclarativeVMEMetaObject *>(parent)->vmeProperty(index); |
|
770 } |
|
771 return readVarProperty(index - propOffset); |
|
772 } |
|
773 |
|
774 void QDeclarativeVMEMetaObject::setVMEProperty(int index, const QScriptValue &v) |
|
775 { |
|
776 if (index < propOffset) { |
|
777 Q_ASSERT(parent); |
|
778 static_cast<QDeclarativeVMEMetaObject *>(parent)->setVMEProperty(index, v); |
|
779 } |
|
780 return writeVarProperty(index - propOffset, v); |
|
781 } |
|
782 |
|
783 QT_END_NAMESPACE |