QScriptDeclarativeClass::Value MetaCallArgument::toValue(QDeclarativeEngine *e) { QScriptEngine *engine = QDeclarativeEnginePrivate::getScriptEngine(e); if (type == qMetaTypeId<QScriptValue>()) { return QScriptDeclarativeClass::Value(engine, *qscriptValuePtr); } else if (type == QMetaType::Int) { return QScriptDeclarativeClass::Value(engine, int(intValue)); } else if (type == QMetaType::UInt) { return QScriptDeclarativeClass::Value(engine, uint(intValue)); } else if (type == QMetaType::Bool) { return QScriptDeclarativeClass::Value(engine, boolValue); } else if (type == QMetaType::Double) { return QScriptDeclarativeClass::Value(engine, doubleValue); } else if (type == QMetaType::Float) { return QScriptDeclarativeClass::Value(engine, floatValue); } else if (type == QMetaType::QString) { return QScriptDeclarativeClass::Value(engine, *qstringPtr); } else if (type == QMetaType::QObjectStar) { if (qobjectPtr) QDeclarativeData::get(qobjectPtr, true)->setImplicitDestructible(); QDeclarativeEnginePrivate *priv = QDeclarativeEnginePrivate::get(e); return QScriptDeclarativeClass::Value(engine, priv->objectClass->newQObject(qobjectPtr)); } else if (type == qMetaTypeId<QList<QObject *> >()) { QList<QObject *> &list = *qlistPtr; QScriptValue rv = engine->newArray(list.count()); QDeclarativeEnginePrivate *priv = QDeclarativeEnginePrivate::get(e); for (int ii = 0; ii < list.count(); ++ii) { QObject *object = list.at(ii); QDeclarativeData::get(object, true)->setImplicitDestructible(); rv.setProperty(ii, priv->objectClass->newQObject(object)); } return QScriptDeclarativeClass::Value(engine, rv); } else if (type == -1 || type == qMetaTypeId<QVariant>()) { QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(e); QScriptValue rv = ep->scriptValueFromVariant(*qvariantPtr); if (rv.isQObject()) { QObject *object = rv.toQObject(); if (object) QDeclarativeData::get(object, true)->setImplicitDestructible(); } return QScriptDeclarativeClass::Value(engine, rv); } else { return QScriptDeclarativeClass::Value(); } }
int QDeclarativeVMEMetaObject::metaCall(QMetaObject::Call c, int _id, void **a) { int id = _id; if(c == QMetaObject::WriteProperty) { int flags = *reinterpret_cast<int*>(a[3]); if (!(flags & QDeclarativePropertyPrivate::BypassInterceptor) && !aInterceptors.isEmpty() && aInterceptors.testBit(id)) { QPair<int, QDeclarativePropertyValueInterceptor*> pair = interceptors.value(id); int valueIndex = pair.first; QDeclarativePropertyValueInterceptor *vi = pair.second; int type = property(id).userType(); if (type != QVariant::Invalid) { if (valueIndex != -1) { QDeclarativeEnginePrivate *ep = ctxt?QDeclarativeEnginePrivate::get(ctxt->engine):0; QDeclarativeValueType *valueType = 0; if (ep) valueType = ep->valueTypes[type]; else valueType = QDeclarativeValueTypeFactory::valueType(type); Q_ASSERT(valueType); valueType->setValue(QVariant(type, a[0])); QMetaProperty valueProp = valueType->metaObject()->property(valueIndex); vi->write(valueProp.read(valueType)); if (!ep) delete valueType; return -1; } else { vi->write(QVariant(type, a[0])); return -1; } } } } if(c == QMetaObject::ReadProperty || c == QMetaObject::WriteProperty) { if (id >= propOffset) { id -= propOffset; if (id < metaData->propertyCount) { int t = (metaData->propertyData() + id)->propertyType; bool needActivate = false; if (t == -1) { if (c == QMetaObject::ReadProperty) { *reinterpret_cast<QVariant *>(a[0]) = readVarPropertyAsVariant(id); } else if (c == QMetaObject::WriteProperty) { writeVarProperty(id, *reinterpret_cast<QVariant *>(a[0])); } } else { if (c == QMetaObject::ReadProperty) { switch(t) { case QVariant::Int: *reinterpret_cast<int *>(a[0]) = data[id].asInt(); break; case QVariant::Bool: *reinterpret_cast<bool *>(a[0]) = data[id].asBool(); break; case QVariant::Double: *reinterpret_cast<double *>(a[0]) = data[id].asDouble(); break; case QVariant::String: *reinterpret_cast<QString *>(a[0]) = data[id].asQString(); break; case QVariant::Url: *reinterpret_cast<QUrl *>(a[0]) = data[id].asQUrl(); break; case QVariant::Color: *reinterpret_cast<QColor *>(a[0]) = data[id].asQColor(); break; case QVariant::Date: *reinterpret_cast<QDate *>(a[0]) = data[id].asQDate(); break; case QVariant::DateTime: *reinterpret_cast<QDateTime *>(a[0]) = data[id].asQDateTime(); break; case QMetaType::QObjectStar: *reinterpret_cast<QObject **>(a[0]) = data[id].asQObject(); break; default: break; } if (t == qMetaTypeId<QDeclarativeListProperty<QObject> >()) { int listIndex = data[id].asInt(); const List *list = &listProperties.at(listIndex); *reinterpret_cast<QDeclarativeListProperty<QObject> *>(a[0]) = QDeclarativeListProperty<QObject>(object, (void *)list, list_append, list_count, list_at, list_clear); } } else if (c == QMetaObject::WriteProperty) { switch(t) { case QVariant::Int: needActivate = *reinterpret_cast<int *>(a[0]) != data[id].asInt(); data[id].setValue(*reinterpret_cast<int *>(a[0])); break; case QVariant::Bool: needActivate = *reinterpret_cast<bool *>(a[0]) != data[id].asBool(); data[id].setValue(*reinterpret_cast<bool *>(a[0])); break; case QVariant::Double: needActivate = *reinterpret_cast<double *>(a[0]) != data[id].asDouble(); data[id].setValue(*reinterpret_cast<double *>(a[0])); break; case QVariant::String: needActivate = *reinterpret_cast<QString *>(a[0]) != data[id].asQString(); data[id].setValue(*reinterpret_cast<QString *>(a[0])); break; case QVariant::Url: needActivate = *reinterpret_cast<QUrl *>(a[0]) != data[id].asQUrl(); data[id].setValue(*reinterpret_cast<QUrl *>(a[0])); break; case QVariant::Color: needActivate = *reinterpret_cast<QColor *>(a[0]) != data[id].asQColor(); data[id].setValue(*reinterpret_cast<QColor *>(a[0])); break; case QVariant::Date: needActivate = *reinterpret_cast<QDate *>(a[0]) != data[id].asQDate(); data[id].setValue(*reinterpret_cast<QDate *>(a[0])); break; case QVariant::DateTime: needActivate = *reinterpret_cast<QDateTime *>(a[0]) != data[id].asQDateTime(); data[id].setValue(*reinterpret_cast<QDateTime *>(a[0])); break; case QMetaType::QObjectStar: needActivate = *reinterpret_cast<QObject **>(a[0]) != data[id].asQObject(); data[id].setValue(*reinterpret_cast<QObject **>(a[0])); break; default: break; } } } if (c == QMetaObject::WriteProperty && needActivate) { activate(object, methodOffset + id, 0); } return -1; } id -= metaData->propertyCount; if (id < metaData->aliasCount) { QDeclarativeVMEMetaData::AliasData *d = metaData->aliasData() + id; if (d->flags & QML_ALIAS_FLAG_PTR && c == QMetaObject::ReadProperty) *reinterpret_cast<void **>(a[0]) = 0; if (!ctxt) return -1; QDeclarativeContext *context = ctxt->asQDeclarativeContext(); QDeclarativeContextPrivate *ctxtPriv = QDeclarativeContextPrivate::get(context); QObject *target = ctxtPriv->data->idValues[d->contextIdx].data(); if (!target) return -1; connectAlias(id); if (d->isObjectAlias()) { *reinterpret_cast<QObject **>(a[0]) = target; return -1; } // Remove binding (if any) on write if(c == QMetaObject::WriteProperty) { int flags = *reinterpret_cast<int*>(a[3]); if (flags & QDeclarativePropertyPrivate::RemoveBindingOnAliasWrite) { QDeclarativeData *targetData = QDeclarativeData::get(target); if (targetData && targetData->hasBindingBit(d->propertyIndex())) { QDeclarativeAbstractBinding *binding = QDeclarativePropertyPrivate::setBinding(target, d->propertyIndex(), d->isValueTypeAlias()?d->valueTypeIndex():-1, 0); if (binding) binding->destroy(); } } } if (d->isValueTypeAlias()) { // Value type property QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(ctxt->engine); QDeclarativeValueType *valueType = ep->valueTypes[d->valueType()]; Q_ASSERT(valueType); valueType->read(target, d->propertyIndex()); int rv = QMetaObject::metacall(valueType, c, d->valueTypeIndex(), a); if (c == QMetaObject::WriteProperty) valueType->write(target, d->propertyIndex(), 0x00); return rv; } else { return QMetaObject::metacall(target, c, d->propertyIndex(), a); } } return -1; } } else if(c == QMetaObject::InvokeMetaMethod) { if (id >= methodOffset) { id -= methodOffset; int plainSignals = metaData->signalCount + metaData->propertyCount + metaData->aliasCount; if (id < plainSignals) { QMetaObject::activate(object, _id, a); return -1; } id -= plainSignals; if (id < metaData->methodCount) { if (!ctxt->engine) return -1; // We can't run the method QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(ctxt->engine); QScriptValue function = method(id); QScriptValueList args; QDeclarativeVMEMetaData::MethodData *data = metaData->methodData() + id; if (data->parameterCount) { for (int ii = 0; ii < data->parameterCount; ++ii) { args << ep->scriptValueFromVariant(*(QVariant *)a[ii + 1]); } } QScriptValue rv = function.call(ep->objectClass->newQObject(object), args); if (a[0]) *reinterpret_cast<QVariant *>(a[0]) = ep->scriptValueToVariant(rv); return -1; } return -1; } } if (parent) return parent->metaCall(c, _id, a); else return object->qt_metacall(c, _id, a); }
QDeclarativeObjectScriptClass::Value QDeclarativeObjectScriptClass::property(QObject *obj, const Identifier &name) { QScriptEngine *scriptEngine = QDeclarativeEnginePrivate::getScriptEngine(engine); if (name == m_destroyId.identifier) return Value(scriptEngine, m_destroy); else if (name == m_toStringId.identifier) return Value(scriptEngine, m_toString); if (lastData && !lastData->isValid()) return Value(); Q_ASSERT(obj); QDeclarativeEnginePrivate *enginePriv = QDeclarativeEnginePrivate::get(engine); if (lastTNData) { if (lastTNData->type) return Value(scriptEngine, enginePriv->typeNameClass->newObject(obj, lastTNData->type)); else return Value(scriptEngine, enginePriv->typeNameClass->newObject(obj, lastTNData->typeNamespace)); } else if (lastData->flags & QDeclarativePropertyCache::Data::IsFunction) { if (lastData->flags & QDeclarativePropertyCache::Data::IsVMEFunction) { return Value(scriptEngine, ((QDeclarativeVMEMetaObject *)(obj->metaObject()))->vmeMethod(lastData->coreIndex)); } else { // Uncomment to use QtScript method call logic // QScriptValue sobj = scriptEngine->newQObject(obj); // return Value(scriptEngine, sobj.property(toString(name))); return Value(scriptEngine, methods.newMethod(obj, lastData)); } } else { if (enginePriv->captureProperties && !(lastData->flags & QDeclarativePropertyCache::Data::IsConstant)) { enginePriv->capturedProperties << QDeclarativeEnginePrivate::CapturedProperty(obj, lastData->coreIndex, lastData->notifyIndex); } if (QDeclarativeValueTypeFactory::isValueType((uint)lastData->propType)) { QDeclarativeValueType *valueType = enginePriv->valueTypes[lastData->propType]; if (valueType) return Value(scriptEngine, enginePriv->valueTypeClass->newObject(obj, lastData->coreIndex, valueType)); } if (lastData->flags & QDeclarativePropertyCache::Data::IsQList) { return Value(scriptEngine, enginePriv->listClass->newList(obj, lastData->coreIndex, lastData->propType)); } else if (lastData->flags & QDeclarativePropertyCache::Data::IsQObjectDerived) { QObject *rv = 0; void *args[] = { &rv, 0 }; QMetaObject::metacall(obj, QMetaObject::ReadProperty, lastData->coreIndex, args); return Value(scriptEngine, newQObject(rv, lastData->propType)); } else if (lastData->flags & QDeclarativePropertyCache::Data::IsQScriptValue) { QScriptValue rv = scriptEngine->nullValue(); void *args[] = { &rv, 0 }; QMetaObject::metacall(obj, QMetaObject::ReadProperty, lastData->coreIndex, args); return Value(scriptEngine, rv); } else if (lastData->propType == QMetaType::QReal) { qreal rv = 0; void *args[] = { &rv, 0 }; QMetaObject::metacall(obj, QMetaObject::ReadProperty, lastData->coreIndex, args); return Value(scriptEngine, rv); } else if (lastData->propType == QMetaType::Int) { int rv = 0; void *args[] = { &rv, 0 }; QMetaObject::metacall(obj, QMetaObject::ReadProperty, lastData->coreIndex, args); return Value(scriptEngine, rv); } else if (lastData->propType == QMetaType::Bool) { bool rv = false; void *args[] = { &rv, 0 }; QMetaObject::metacall(obj, QMetaObject::ReadProperty, lastData->coreIndex, args); return Value(scriptEngine, rv); } else if (lastData->propType == QMetaType::QString) { QString rv; void *args[] = { &rv, 0 }; QMetaObject::metacall(obj, QMetaObject::ReadProperty, lastData->coreIndex, args); return Value(scriptEngine, rv); } else if (lastData->propType == QMetaType::UInt) { uint rv = 0; void *args[] = { &rv, 0 }; QMetaObject::metacall(obj, QMetaObject::ReadProperty, lastData->coreIndex, args); return Value(scriptEngine, rv); } else if (lastData->propType == QMetaType::Float) { float rv = 0; void *args[] = { &rv, 0 }; QMetaObject::metacall(obj, QMetaObject::ReadProperty, lastData->coreIndex, args); return Value(scriptEngine, rv); } else if (lastData->propType == QMetaType::Double) { double rv = 0; void *args[] = { &rv, 0 }; QMetaObject::metacall(obj, QMetaObject::ReadProperty, lastData->coreIndex, args); return Value(scriptEngine, rv); } else { QVariant var = obj->metaObject()->property(lastData->coreIndex).read(obj); return Value(scriptEngine, enginePriv->scriptValueFromVariant(var)); } } }