void QJnextMainLoop::set(QObject *object, QVariantList& args, QByteArray* retval) { QByteArray property = args.takeFirst().toByteArray(); const QMetaObject * meta = object->metaObject(); int propertyIndex = meta->indexOfProperty(property); if (propertyIndex < 0) { retval->append("No such property " + property); return; } QMetaProperty metaprop = meta->property(propertyIndex); if (!metaprop.isWritable()) { retval->append("Property " + property + " is not writable"); return; } QVariant vValue = args.takeFirst(); /* handle enum inputs as text */ if (metaprop.isEnumType()) { int id; const QMetaEnum &enumerator = metaprop.enumerator(); QByteArray keys; for (int i = 0; i < enumerator.keyCount(); ++i) keys += enumerator.key(i) + QByteArray(" "); #ifdef DEBUG_QJnextMainLoop qDebug() << "[QJnextMainLoop]\tEnumerator" << enumerator.isFlag() << enumerator.scope() << enumerator.name() << keys; #endif if (enumerator.isFlag()) id = enumerator.keyToValue(vValue.toByteArray().constData()); else id = enumerator.keysToValue(vValue.toByteArray().constData()); if (id != -1) vValue = QVariant(id); } #ifdef DEBUG_QJnextMainLoop qDebug() << "[QJnextMainLoop]\tSET" << meta->className() << property << vValue << vValue.canConvert(metaprop.type()); #endif if (!vValue.convert(metaprop.type())) { retval->append( "Unable to convert \"" + vValue.toByteArray() + "\" to " + metaprop.typeName()); return; } if (!metaprop.write(object, vValue)) retval->append( QByteArray("Unable to set property ") + meta->className() + "." + property + " to " + vValue.toByteArray()); else *retval = QByteArray(); }
void SaxsviewProperty::setValue(QObject *obj) { if (!mProperty) { // // Find the meta-property information; the passed object must // provide the Q_PROPERTY name passed to the constructor. // int indexOfProperty = obj->metaObject()->indexOfProperty(qPrintable(mPropertyName)); QMetaProperty metaProperty = obj->metaObject()->property(indexOfProperty); if (metaProperty.isValid()) { // // Create an editor factory if and only if the property is writeable. // if (metaProperty.isWritable()) { mBrowser->setFactoryForManager(mManager, new QtVariantEditorFactory(this)); connect(mManager, SIGNAL(valueChanged(QtProperty*, const QVariant&)), this, SLOT(valueChanged(QtProperty*, const QVariant&))); } if (!mManager->isPropertyTypeSupported(metaProperty.type())) qFatal("internal error: property '%s', property type not supported: '%s'", metaProperty.name(), metaProperty.typeName()); // // Check if this is an enum and handle it specially if yes. // if (metaProperty.isEnumType()) { QStringList enumNames; QMetaEnum metaEnum = metaProperty.enumerator(); // // WARNING: This only builds a list of names in the order // as defined. The combobox to display these names // provides the selected index, not the actual enum // value. // for (int i = 0; i < metaEnum.keyCount(); ++i) enumNames << metaEnum.key(i); setEnumNames(enumNames); } if (mAttributes.contains("enumNames")) mProperty = mManager->addProperty(mManager->enumTypeId(), mPropertyLabel); else mProperty = mManager->addProperty(metaProperty.type(), mPropertyLabel); } else if (obj->dynamicPropertyNames().contains(qPrintable(mPropertyName))) {
void QDBusViewer::setProperty(const BusSignature &sig) { QDBusInterface iface(sig.mService, sig.mPath, sig.mInterface, c); QMetaProperty prop = iface.metaObject()->property(iface.metaObject()->indexOfProperty(sig.mName.toLatin1())); bool ok; QString input = QInputDialog::getText(this, tr("Arguments"), tr("Please enter the value of the property %1 (type %2)").arg( sig.mName, QString::fromLatin1(prop.typeName())), QLineEdit::Normal, QString(), &ok); if (!ok) return; QVariant value = input; if (!value.convert(prop.type())) { QMessageBox::warning(this, tr("Unable to marshall"), tr("Value conversion failed, unable to set property")); return; } QDBusMessage message = QDBusMessage::createMethodCall(sig.mService, sig.mPath, QLatin1String("org.freedesktop.DBus.Properties"), QLatin1String("Set")); QList<QVariant> arguments; arguments << sig.mInterface << sig.mName << qVariantFromValue(QDBusVariant(value)); message.setArguments(arguments); c.callWithCallback(message, this, SLOT(dumpMessage(QDBusMessage))); }
void SFIdentityData::deserializeFromMap(QVariantMap map){ const QMetaObject *metaObj = metaObject(); int count = metaObj->propertyCount(); for(int i=0; i<count; i++) { QMetaProperty property = metaObj->property(i); if (!property.isWritable()) { continue; } QVariant value; if (map.contains(property.name())){ value = map[property.name()]; }else if (map.contains("photos") && map["photos"].toMap().contains(property.name())){ value = map["photos"].toMap()[property.name()]; }else if(map.contains("urls") && map["urls"].toMap().contains(property.name())){ value = map["urls"].toMap()[property.name()]; }else if(map.contains("mobile_policy") && map["mobile_policy"].toMap().contains(property.name())){ value = map["mobile_policy"].toMap()[property.name()]; }else{ continue; } if (!const_cast<QVariant&>(value).canConvert(property.type())) { continue; } property.write(this, value); } }
ExpressionType type(const QByteArray& name, const QMetaProperty& prop) const { ExpressionType typeGet(ExpressionType::Lambda); typeGet.addParameter(ExpressionType(name)) .addParameter(toExpressionType(prop.type(), prop.typeName())); return typeGet; }
QList<QPair<QString, QVariant::Type> >QtMetaUtilities::getNamesNTypes(const QMetaObject &metaObject) { QList<QPair<QString, QVariant::Type> >retour; QString className = QLatin1String(metaObject.className()); if (className == "QObject") return retour; for (int idx = metaObject.propertyOffset(); idx < metaObject.propertyCount(); idx++) { QMetaProperty prop = metaObject.property(idx); retour.append(QPair<QString, QVariant::Type>(prop.name(), prop.type())); } return retour; }
static int writeProperty(QObject *obj, const QByteArray &property_name, QVariant value, int propFlags = QDBusConnection::ExportAllProperties) { const QMetaObject *mo = obj->metaObject(); int pidx = mo->indexOfProperty(property_name); if (pidx == -1) { // this object has no property by that name return PropertyNotFound; } QMetaProperty mp = mo->property(pidx); // check if this property is exported bool isScriptable = mp.isScriptable(); if (!(propFlags & QDBusConnection::ExportScriptableProperties) && isScriptable) return PropertyNotFound; if (!(propFlags & QDBusConnection::ExportNonScriptableProperties) && !isScriptable) return PropertyNotFound; // we found our property // do we have the right type? int id = mp.type(); if (id == QVariant::UserType) { // dynamic type id = qDBusNameToTypeId(mp.typeName()); if (id == -1) { // type not registered? qWarning("QDBusConnection: Unable to handle unregistered datatype '%s' for property '%s::%s'", mp.typeName(), mo->className(), property_name.constData()); return PropertyWriteFailed; } } if (id != 0xff && value.userType() == QDBusMetaTypeId::argument) { // we have to demarshall before writing void *null = 0; QVariant other(id, null); if (!QDBusMetaType::demarshall(qvariant_cast<QDBusArgument>(value), id, other.data())) { qWarning("QDBusConnection: type `%s' (%d) is not registered with QtDBus. " "Use qDBusRegisterMetaType to register it", mp.typeName(), id); return PropertyWriteFailed; } value = other; } // the property type here should match return mp.write(obj, value) ? PropertyWriteSuccess : PropertyWriteFailed; }
bool parseObject(const QVariant &source, QObject *target) { if (!source.isValid() || !source.canConvert(QVariant::Map)) { qDebug() << "[ObjectParser] Error: Invalid object... " << source.toByteArray(); return false; } const QVariantMap &map = source.toMap(); const QMetaObject *metaobject = target->metaObject(); QVariantMap::const_iterator it; QVariantMap::const_iterator end = map.constEnd(); for (it = map.constBegin(); it != end; ++it) { const int index = metaobject->indexOfProperty(it.key().toLatin1()); if (index < 0) { continue; } const QMetaProperty metaproperty = metaobject->property(index); const QVariant::Type type = metaproperty.type(); QVariant v = it.value(); if (v.canConvert(type)) { v.convert(type); metaproperty.write(target, v); } else if (QString(QLatin1String("QVariant")) .compare(QLatin1String(metaproperty.typeName())) == 0) { metaproperty.write(target, v); } else { qDebug() << "[ObjectParser] Warning: unable to map variable" << it.key() << "of type" << v.type() << "to type" << metaproperty.type() << "!"; metaproperty.write(target, QVariant()); } } return true; }
void parseToProperties(const QByteArray &json, QObject *obj) { QVariantMap map = parse(json).toMap(); const QMetaObject *meta = obj->metaObject(); for (int i = 0, size = meta->propertyCount(); i < size; i++) { QMetaProperty prop = meta->property(i); QVariantMap::iterator it = map.find(prop.name()); if (it != map.end()) { QVariant var = it.value(); if (var.canConvert(prop.type())) { prop.write(obj, var); } } } }
QVariant QDBusAbstractInterfacePrivate::property(const QMetaProperty &mp) const { if (!connection.isConnected()) // not connected return QVariant(); // try to read this property QDBusMessage msg = QDBusMessage::createMethodCall(service, path, QLatin1String(DBUS_INTERFACE_PROPERTIES), QLatin1String("Get")); msg << interface << QString::fromUtf8(mp.name()); QDBusMessage reply = connection.call(msg, QDBus::Block); if (reply.type() == QDBusMessage::ReplyMessage && reply.arguments().count() == 1 && reply.signature() == QLatin1String("v")) { QVariant value = qvariant_cast<QDBusVariant>(reply.arguments().at(0)).variant(); // make sure the type is right if (qstrcmp(mp.typeName(), value.typeName()) == 0) { if (mp.type() == QVariant::LastType) // QVariant is special in this context return qvariant_cast<QDBusVariant>(reply.arguments().at(0)).variant(); return value; } } // there was an error... if (reply.type() == QDBusMessage::ErrorMessage) lastError = reply; else if (reply.signature() != QLatin1String("v")) { QString errmsg = QLatin1String("Invalid signature `%1' in return from call to " DBUS_INTERFACE_PROPERTIES); lastError = QDBusError(QDBusError::InvalidSignature, errmsg.arg(reply.signature())); } else { QString errmsg = QLatin1String("Unexpected type `%1' when retrieving property " "`%2 %3.%4'"); lastError = QDBusError(QDBusError::InvalidSignature, errmsg.arg(QLatin1String(reply.arguments().at(0).typeName()), QLatin1String(mp.typeName()), interface, QString::fromUtf8(mp.name()))); } return QVariant(); }
QString QObjectWriter:: toString(const QVariant& val, const QMetaProperty& mprop) const { QString result; QVariant::Type t = mprop.type(); if (t == QVariant::Time) { QTime t = qVariantValue<QTime>(val); if (t.hour() > 0) { return t.toString("hh:mm:ss"); } else { return t.toString("m:ss"); } } if (mprop.isEnumType()) { int value = val.toInt(); QMetaEnum menum = mprop.enumerator(); if (mprop.isFlagType()) { QStringList selectedFlags; int kc = menum.keyCount(); for (int j=0; j<kc; ++j) { if (menum.value(j) == 0) continue; if ((value & menum.value(j)) == menum.value(j)) { selectedFlags << menum.key(j); } } result = selectedFlags.join("|") + QString(" (%1)").arg(val.toInt()); } else result = QString("%1 (%2)").arg(menum.valueToKey(value)).arg(val.toInt()); return result; } if (m_map.contains(t)) { VariantWriter* vw = m_map[t]; result = vw->toString(val, mprop); } else if (m_vwriter != 0 && result == QString()) result = m_vwriter->toString(val, mprop); if (result == QString()) result = Qt::escape(val.toString()); else result = Qt::escape(result); return result; }
void QDeclarativePropertyCache::Data::lazyLoad(const QMetaProperty &p, QDeclarativeEngine *engine) { Q_UNUSED(engine); coreIndex = p.propertyIndex(); notifyIndex = p.notifySignalIndex(); revision = p.revision(); flags = fastFlagsForProperty(p); int type = p.type(); if (type == QMetaType::QObjectStar || type == QMetaType::QWidgetStar) { propType = type; flags |= QDeclarativePropertyCache::Data::IsQObjectDerived; } else if (type == QVariant::UserType || type == -1) { propTypeName = p.typeName(); flags |= QDeclarativePropertyCache::Data::NotFullyResolved; } else { propType = type; } }
void DecorationShadowTest::testSizes() { using namespace KDecoration2; DecorationShadow shadow; QFETCH(QByteArray, propertyName); const int propertyIndex = shadow.metaObject()->indexOfProperty(propertyName.constData()); QVERIFY(propertyIndex != -1); QMetaProperty metaProperty = shadow.metaObject()->property(propertyIndex); QCOMPARE(metaProperty.isReadable(), true); QCOMPARE(metaProperty.hasNotifySignal(), true); QCOMPARE(metaProperty.type(), QVariant::Rect); QSignalSpy changedSpy(&shadow, SIGNAL(innerShadowRectChanged())); QVERIFY(changedSpy.isValid()); QCOMPARE(shadow.innerShadowRect(), QRect()); QCOMPARE(shadow.property(propertyName.constData()).isValid(), true); QCOMPARE(shadow.property(propertyName.constData()).toRect(), QRect()); QFETCH(QRect, innerShadowRect); QFETCH(QRect, shadowRect); QFETCH(QSize, shadowSize); shadow.setInnerShadowRect(innerShadowRect); QCOMPARE(shadow.innerShadowRect(), innerShadowRect); // property should still be invalid as the image is not yet set QCOMPARE(shadow.property(propertyName.constData()).toRect(), QRect()); shadow.setShadow(QImage(shadowSize, QImage::Format_ARGB32)); QCOMPARE(shadow.property(propertyName.constData()).toRect(), shadowRect); QCOMPARE(changedSpy.count(), 1); // trying to set to same value shouldn't emit the signal shadow.setInnerShadowRect(innerShadowRect); QCOMPARE(shadow.property(propertyName.constData()).toRect(), shadowRect); QCOMPARE(changedSpy.count(), 1); // changing to different value should emit signal shadow.setInnerShadowRect(innerShadowRect.adjusted(1, 1, 1, 1)); QCOMPARE(changedSpy.count(), 2); QCOMPARE(shadow.innerShadowRect(), innerShadowRect.adjusted(1, 1, 1, 1)); }
void QObjectHelper::qvariant2qobject(const QVariantMap& variant, QObject* object) { const QMetaObject *metaobject = object->metaObject(); QVariantMap::const_iterator iter; for (iter = variant.constBegin(); iter != variant.constEnd(); ++iter) { int pIdx = metaobject->indexOfProperty( iter.key().toUtf8() ); if ( pIdx < 0 ) { continue; } QMetaProperty metaproperty = metaobject->property( pIdx ); QVariant::Type type = metaproperty.type(); QVariant v( iter.value() ); if ( v.canConvert( type ) ) { v.convert( type ); metaproperty.write( object, v ); } else if (QString(QLatin1String("QVariant")).compare(QLatin1String(metaproperty.typeName())) == 0) { metaproperty.write( object, v ); } } }
void JsonToProperties::parse(const QString& json, QObject* object) throw(ParseException) { QVariantMap dataMap = JsonToVariant::parse(json).toMap(); const QMetaObject* meta = object->metaObject(); for( int i = 0; i < meta->propertyCount(); ++i ) { QMetaProperty property = meta->property(i); if(dataMap.contains(property.name())) { QVariant data = dataMap[property.name()]; if(data.canConvert(property.type())) property.write(object, data); else qDebug() << QObject::tr("Found property %1 with incompatible data type.").arg(property.name()); } } }
void DecorationShadowTest::testPadding() { using namespace KDecoration2; DecorationShadow shadow; QFETCH(QByteArray, propertyName); const int propertyIndex = shadow.metaObject()->indexOfProperty(propertyName.constData()); QVERIFY(propertyIndex != -1); QMetaProperty metaProperty = shadow.metaObject()->property(propertyIndex); QCOMPARE(metaProperty.isReadable(), true); QCOMPARE(metaProperty.hasNotifySignal(), true); QCOMPARE(metaProperty.type(), QVariant::Int); QSignalSpy changedSpy(&shadow, SIGNAL(paddingChanged())); QVERIFY(changedSpy.isValid()); QCOMPARE(shadow.property(propertyName.constData()).isValid(), true); QCOMPARE(shadow.property(propertyName.constData()).toInt(), 0); QFETCH(QMargins, padding); shadow.setPadding(padding); QCOMPARE(shadow.padding(), padding); QCOMPARE(shadow.property(propertyName.constData()).toInt(), 10); QCOMPARE(changedSpy.count(), 1); // trying to set to same value shouldn't emit the signal shadow.setPadding(padding); QCOMPARE(shadow.property(propertyName.constData()).toInt(), 10); QCOMPARE(changedSpy.count(), 1); // changing to different value should emit signal padding += 1; shadow.setPadding(padding); QCOMPARE(shadow.padding(), padding); QCOMPARE(shadow.property(propertyName.constData()).toInt(), 11); QCOMPARE(changedSpy.count(), 2); }
QVariant QDBusAbstractInterfacePrivate::property(const QMetaProperty &mp) const { if (!connection.isConnected()) // not connected return QVariant(); // is this metatype registered? int mid; const char *expectedSignature; if (mp.type() == QVariant::LastType) { // We're asking to read a QVariant mid = qMetaTypeId<QDBusVariant>(); expectedSignature = "v"; } else { mid = QMetaType::type(mp.typeName()); expectedSignature = QDBusMetaType::typeToSignature(mid); if (expectedSignature == 0) { qWarning("QDBusAbstractInterface: type %s must be registered with QtDBus before it can be " "used to read property %s.%s", mp.typeName(), qPrintable(interface), mp.name()); return QVariant(); } } // try to read this property QDBusMessage msg = QDBusMessage::createMethodCall(service, path, QLatin1String(DBUS_INTERFACE_PROPERTIES), QLatin1String("Get")); msg << interface << QString::fromUtf8(mp.name()); QDBusMessage reply = connection.call(msg, QDBus::Block); if (reply.type() != QDBusMessage::ReplyMessage) { lastError = reply; return QVariant(); } if (reply.signature() != QLatin1String("v")) { QString errmsg = QLatin1String("Invalid signature `%1' in return from call to " DBUS_INTERFACE_PROPERTIES); lastError = QDBusError(QDBusError::InvalidSignature, errmsg.arg(reply.signature())); return QVariant(); } QByteArray foundSignature; const char *foundType = 0; QVariant value = qvariant_cast<QDBusVariant>(reply.arguments().at(0)).variant(); if (value.userType() == mid) return value; // simple match if (value.userType() == qMetaTypeId<QDBusArgument>()) { QDBusArgument arg = qvariant_cast<QDBusArgument>(value); foundType = "user type"; foundSignature = arg.currentSignature().toLatin1(); if (foundSignature == expectedSignature) { void *null = 0; QVariant result(mid, null); QDBusMetaType::demarshall(arg, mid, result.data()); if (mp.type() == QVariant::LastType) // special case: QVariant return qvariant_cast<QDBusVariant>(result).variant(); return result; } } else { foundType = value.typeName(); foundSignature = QDBusMetaType::typeToSignature(value.userType()); } // there was an error... QString errmsg = QLatin1String("Unexpected `%1' (%2) when retrieving property `%3.%4' " "(expected type `%5' (%6))"); lastError = QDBusError(QDBusError::InvalidSignature, errmsg.arg(QString::fromLatin1(foundType), QString::fromLatin1(foundSignature), interface, QString::fromUtf8(mp.name()), QString::fromLatin1(mp.typeName()), QString::fromLatin1(expectedSignature))); return QVariant(); }
/*! Updates the corresponding record with the properties of the object. */ bool TSqlObject::update() { if (isNew()) { sqlError = QSqlError(QLatin1String("No record to update"), QString(), QSqlError::UnknownError); tWarn("Unable to update the '%s' object. Create it before!", metaObject()->className()); return false; } QSqlDatabase &database = Tf::currentSqlDatabase(databaseId()); QString where(" WHERE "); // Updates the value of 'updated_at' or 'modified_at' property bool updflag = false; int revIndex = -1; for (int i = metaObject()->propertyOffset(); i < metaObject()->propertyCount(); ++i) { const char *propName = metaObject()->property(i).name(); QByteArray prop = QByteArray(propName).toLower(); if (!updflag && (prop == UpdatedAt || prop == ModifiedAt)) { setProperty(propName, QDateTime::currentDateTime()); updflag = true; } else if (revIndex < 0 && prop == LockRevision) { bool ok; int oldRevision = property(propName).toInt(&ok); if (!ok || oldRevision <= 0) { sqlError = QSqlError(QLatin1String("Unable to convert the 'revision' property to an int"), QString(), QSqlError::UnknownError); tError("Unable to convert the 'revision' property to an int, %s", qPrintable(objectName())); return false; } setProperty(propName, oldRevision + 1); revIndex = i; where.append(QLatin1String(propName)); where.append("=").append(TSqlQuery::formatValue(oldRevision, QVariant::Int, database)); where.append(" AND "); } else { // continue } } QString upd; // UPDATE Statement upd.reserve(255); upd.append(QLatin1String("UPDATE ")).append(tableName()).append(QLatin1String(" SET ")); int pkidx = metaObject()->propertyOffset() + primaryKeyIndex(); QMetaProperty metaProp = metaObject()->property(pkidx); const char *pkName = metaProp.name(); if (primaryKeyIndex() < 0 || !pkName) { QString msg = QString("Primary key not found for table ") + tableName() + QLatin1String(". Create a primary key!"); sqlError = QSqlError(msg, QString(), QSqlError::StatementError); tError("%s", qPrintable(msg)); return false; } QVariant::Type pkType = metaProp.type(); QVariant origpkval = value(pkName); where.append(QLatin1String(pkName)); where.append("=").append(TSqlQuery::formatValue(origpkval, pkType, database)); // Restore the value of primary key QObject::setProperty(pkName, origpkval); for (int i = metaObject()->propertyOffset(); i < metaObject()->propertyCount(); ++i) { metaProp = metaObject()->property(i); const char *propName = metaProp.name(); QVariant newval = QObject::property(propName); QVariant recval = QSqlRecord::value(QLatin1String(propName)); if (i != pkidx && recval.isValid() && recval != newval) { upd.append(QLatin1String(propName)); upd.append(QLatin1Char('=')); upd.append(TSqlQuery::formatValue(newval, metaProp.type(), database)); upd.append(QLatin1String(", ")); } } if (!upd.endsWith(QLatin1String(", "))) { tSystemDebug("SQL UPDATE: Same values as that of the record. No need to update."); return true; } upd.chop(2); syncToSqlRecord(); upd.append(where); TSqlQuery query(database); bool ret = query.exec(upd); sqlError = query.lastError(); if (ret) { // Optimistic lock check if (revIndex >= 0 && query.numRowsAffected() != 1) { QString msg = QString("Row was updated or deleted from table ") + tableName() + QLatin1String(" by another transaction"); sqlError = QSqlError(msg, QString(), QSqlError::UnknownError); throw SqlException(msg, __FILE__, __LINE__); } } return ret; }
void tst_QQmlEngineDebugService::recursiveObjectTest( QObject *o, const QmlDebugObjectReference &oref, bool recursive) const { const QMetaObject *meta = o->metaObject(); QQmlType *type = QQmlMetaType::qmlType(meta); QString className = type ? QString(type->qmlTypeName()) : QString(meta->className()); className = className.mid(className.lastIndexOf(QLatin1Char('/'))+1); QCOMPARE(oref.debugId, QQmlDebugService::idForObject(o)); QCOMPARE(oref.name, o->objectName()); QCOMPARE(oref.className, className); QCOMPARE(oref.contextDebugId, QQmlDebugService::idForObject( qmlContext(o))); const QObjectList &children = o->children(); for (int i=0; i<children.count(); i++) { QObject *child = children[i]; if (!qmlContext(child)) continue; int debugId = QQmlDebugService::idForObject(child); QVERIFY(debugId >= 0); QmlDebugObjectReference cref; foreach (const QmlDebugObjectReference &ref, oref.children) { if (ref.debugId == debugId) { cref = ref; break; } } QVERIFY(cref.debugId >= 0); if (recursive) recursiveObjectTest(child, cref, true); } foreach (const QmlDebugPropertyReference &p, oref.properties) { QCOMPARE(p.objectDebugId, QQmlDebugService::idForObject(o)); // signal properties are fake - they are generated from QQmlAbstractBoundSignal children if (p.name.startsWith("on") && p.name.length() > 2 && p.name[2].isUpper()) { QString signal = p.value.toString(); QQmlBoundSignalExpression *expr = QQmlPropertyPrivate::signalExpression(QQmlProperty(o, p.name)); QVERIFY(expr && expr->expression() == signal); QVERIFY(p.valueTypeName.isEmpty()); QVERIFY(p.binding.isEmpty()); QVERIFY(!p.hasNotifySignal); continue; } QMetaProperty pmeta = meta->property(meta->indexOfProperty(p.name.toUtf8().constData())); QCOMPARE(p.name, QString::fromUtf8(pmeta.name())); if (pmeta.type() < QVariant::UserType && pmeta.userType() != QMetaType::QVariant) // TODO test complex types QCOMPARE(p.value , pmeta.read(o)); if (p.name == "parent") QVERIFY(p.valueTypeName == "QGraphicsObject*" || p.valueTypeName == "QQuickItem*"); else QCOMPARE(p.valueTypeName, QString::fromUtf8(pmeta.typeName())); QQmlAbstractBinding *binding = QQmlPropertyPrivate::binding( QQmlProperty(o, p.name)); if (binding) QCOMPARE(binding->expression(), p.binding); QCOMPARE(p.hasNotifySignal, pmeta.hasNotifySignal()); QVERIFY(pmeta.isValid()); } }
QWidget * BorderDrawersLoader::createEditor(BorderDrawerInterface * drawer, bool createCommands) { if (!drawer) return 0; QtTreePropertyBrowser * browser = new QtTreePropertyBrowser(); BorderChangeListener * listener = new BorderChangeListener(drawer, browser, createCommands); // QVariant type of property QtVariantPropertyManager * variantManager = 0; KVariantEditorFactory * variantFactory = 0; // Integer type of property QtIntPropertyManager * integerManager = 0; KSliderEditFactory * integerFactory = 0; // Double type of property QtDoublePropertyManager * doubleManager = 0; KDoubleSpinBoxFactory * doubleFactory = 0; const QMetaObject * meta = drawer->metaObject(); int propertiesCount = meta->propertyCount(); for (int i = 0; i < propertiesCount; ++i) { QMetaProperty metaProperty = meta->property(i); QString propertyName = drawer->propertyName(metaProperty); if (propertyName.isEmpty()) continue; QtProperty * property; switch (metaProperty.type()) { case QVariant::Int: { if (!integerManager || !integerFactory) { integerManager = new QtIntPropertyManager(browser); integerFactory = new KSliderEditFactory(browser); browser->setFactoryForManager(integerManager, integerFactory); } property = integerManager->addProperty(propertyName); integerManager->setValue(property, metaProperty.read(drawer).toInt()); integerManager->setMinimum(property, drawer->minimumValue(metaProperty).toInt()); integerManager->setMaximum(property, drawer->maximumValue(metaProperty).toInt()); } break; case QVariant::Double: { if (!doubleManager || !doubleFactory) { doubleManager = new QtDoublePropertyManager(browser); doubleFactory = new KDoubleSpinBoxFactory(browser); browser->setFactoryForManager(doubleManager, doubleFactory); } property = doubleManager->addProperty(propertyName); doubleManager->setValue(property, metaProperty.read(drawer).toDouble()); doubleManager->setMinimum(property, drawer->minimumValue(metaProperty).toDouble()); doubleManager->setMaximum(property, drawer->maximumValue(metaProperty).toDouble()); } break; case Enum: { } break; default: { if (!variantManager || !variantFactory) { variantManager = new QtVariantPropertyManager(browser); variantFactory = new KVariantEditorFactory(browser); browser->setFactoryForManager(variantManager, variantFactory); } property = variantManager->addProperty(metaProperty.type(), propertyName); variantManager->setValue(property, metaProperty.read(drawer)); } } browser->addProperty(property); } if (integerManager) { connect(integerFactory, SIGNAL(editingFinished()), listener, SLOT(editingFinished())); connect(integerManager, SIGNAL(propertyChanged(QtProperty*)), listener, SLOT(propertyChanged(QtProperty*))); } if (doubleManager) { connect(doubleFactory, SIGNAL(editingFinished()), listener, SLOT(editingFinished())); connect(doubleManager, SIGNAL(propertyChanged(QtProperty*)), listener, SLOT(propertyChanged(QtProperty*))); } if (variantManager) { connect(variantFactory, SIGNAL(editingFinished()), listener, SLOT(editingFinished())); connect(variantManager, SIGNAL(propertyChanged(QtProperty*)), listener, SLOT(propertyChanged(QtProperty*))); } return browser; }
/** * \brief Construct the property from a QMetaProperty * * \param metaProperty Qt meta property */ QtSimpleProperty(const QMetaProperty& metaProperty) : ponder::SimpleProperty(metaProperty.name(), metaProperty.isEnumType() ? ponder::enumType : QtHelper::type(metaProperty.type())) , m_metaProperty(metaProperty) { }
void tst_QQmlMetaObject::property() { QFETCH(QString, testFile); QFETCH(QByteArray, cppTypeName); QFETCH(int, cppType); QFETCH(bool, isDefault); QFETCH(QVariant, expectedValue); QFETCH(bool, isWritable); QFETCH(QVariant, newValue); QQmlEngine engine; QQmlComponent component(&engine, testFileUrl(testFile)); QObject *object = component.create(); QVERIFY(object != 0); const QMetaObject *mo = object->metaObject(); QVERIFY(mo->superClass() != 0); QVERIFY(QByteArray(mo->className()).contains("_QML_")); QCOMPARE(mo->propertyOffset(), mo->superClass()->propertyCount()); QCOMPARE(mo->propertyCount(), mo->superClass()->propertyCount() + 1); QMetaProperty prop = mo->property(mo->propertyOffset()); QCOMPARE(prop.name(), "test"); QCOMPARE(QByteArray(prop.typeName()), cppTypeName); if (prop.userType() < QMetaType::User) QCOMPARE(prop.type(), QVariant::Type(cppType)); else QCOMPARE(prop.type(), QVariant::UserType); QCOMPARE(prop.userType(), cppType); QVERIFY(!prop.isConstant()); QVERIFY(!prop.isDesignable()); QVERIFY(!prop.isEnumType()); QVERIFY(!prop.isFinal()); QVERIFY(!prop.isFlagType()); QVERIFY(prop.isReadable()); QVERIFY(!prop.isResettable()); QVERIFY(prop.isScriptable()); QVERIFY(!prop.isStored()); QVERIFY(!prop.isUser()); QVERIFY(prop.isValid()); QCOMPARE(prop.isWritable(), isWritable); QCOMPARE(mo->classInfoOffset(), mo->superClass()->classInfoCount()); QCOMPARE(mo->classInfoCount(), mo->superClass()->classInfoCount() + (isDefault ? 1 : 0)); if (isDefault) { QMetaClassInfo info = mo->classInfo(mo->classInfoOffset()); QCOMPARE(info.name(), "DefaultProperty"); QCOMPARE(info.value(), "test"); } QCOMPARE(mo->methodOffset(), mo->superClass()->methodCount()); QCOMPARE(mo->methodCount(), mo->superClass()->methodCount() + 1); // the signal QVERIFY(prop.notifySignalIndex() != -1); QMetaMethod signal = prop.notifySignal(); QCOMPARE(signal.methodType(), QMetaMethod::Signal); QCOMPARE(signal.name(), QByteArray("testChanged")); QCOMPARE(signal.methodSignature(), QByteArray("testChanged()")); QCOMPARE(signal.access(), QMetaMethod::Public); QCOMPARE(signal.parameterCount(), 0); QCOMPARE(signal.parameterTypes(), QList<QByteArray>()); QCOMPARE(signal.parameterNames(), QList<QByteArray>()); QCOMPARE(signal.tag(), ""); QCOMPARE(signal.typeName(), "void"); QCOMPARE(signal.returnType(), int(QMetaType::Void)); QSignalSpy changedSpy(object, SIGNAL(testChanged())); QObject::connect(object, SIGNAL(testChanged()), object, SLOT(deleteLater())); if (expectedValue.isValid()) QCOMPARE(prop.read(object), expectedValue); else QVERIFY(prop.read(object).isValid()); QCOMPARE(changedSpy.count(), 0); if (isWritable) { QVERIFY(prop.write(object, newValue)); QCOMPARE(changedSpy.count(), 1); QCOMPARE(prop.read(object), newValue); } else { QVERIFY(!prop.write(object, prop.read(object))); QCOMPARE(changedSpy.count(), 0); } delete object; }
QString PipelineLoader::serialize( Pipeline* pl ) throw(std::runtime_error) /*TODO checked exceptions*/ { //RefPtr<Pipeline> pl = pipeline; QDomDocument doc; QDomElement xmlPipeline = doc.createElement( "pipeline" ); doc.appendChild( xmlPipeline ); QDomElement xmlElements = doc.createElement( "elements" ); xmlPipeline.appendChild( xmlElements ); const Pipeline::PipelineElementMap& ples = pl->getChildren(); QMapIterator<int, RefPtr<PipelineElement> > itr( ples ); while( itr.hasNext() ) { itr.next(); RefPtr<PipelineElement> ple = itr.value(); QString className = ple->metaObject()->className(); int id = ple->getId(); QDomElement xmlElement = doc.createElement( "element" ); xmlElement.setAttribute( "id", id ); xmlElement.setAttribute( "name", className ); xmlElements.appendChild( xmlElement ); QDomElement xmlProperties = doc.createElement( "properties" ); xmlElement.appendChild( xmlProperties ); // first do static properties const QMetaObject* metaObject = ple->metaObject(); for(int i = metaObject->propertyOffset(); i < metaObject->propertyCount(); ++i) { QMetaProperty property = metaObject->property(i); QString propertyName = QString::fromLatin1( property.name() ); QString propertyValue; QVariant::Type propertyType = property.type(); // custom types are saved here if( propertyType == QVariant::UserType ) { // TODO: pass control here to pipeline element // to parse custom types? QVariant value = property.read( ple ); if( value.canConvert<plv::Enum>() ) { plv::Enum e = value.value<plv::Enum>(); propertyValue = e.getSelectedItemName(); } } // all other QVariant can easily be converted to string else { propertyValue = property.read( ple ).toString(); } QDomElement xmlProperty = doc.createElement( propertyName ); QDomText text = doc.createTextNode( propertyValue ); xmlProperty.appendChild( text ); xmlProperties.appendChild( xmlProperty ); } // now dynamic properties // these are not used by processor definitions { QVariant xVal = ple->property("sceneCoordX"); QVariant yVal = ple->property("sceneCoordY"); if( xVal.isValid() && yVal.isValid() ) { QDomElement xmlXValProperty = doc.createElement( "sceneCoordX" ); QDomText xValText = doc.createTextNode( xVal.toString() ); xmlXValProperty.appendChild( xValText ); xmlProperties.appendChild( xmlXValProperty ); QDomElement xmlYValProperty = doc.createElement( "sceneCoordY" ); QDomText yValText = doc.createTextNode( yVal.toString() ); xmlYValProperty.appendChild( yValText ); xmlProperties.appendChild( xmlYValProperty ); } } } QDomElement xmlConnections = doc.createElement( "connections" ); xmlPipeline.appendChild( xmlConnections ); const Pipeline::PipelineConnectionsList& connections = pl->getConnections(); foreach( RefPtr<PinConnection> connection, connections ) { QDomElement xmlConnection = doc.createElement( "connection" ); xmlConnections.appendChild( xmlConnection ); QDomElement xmlSink = doc.createElement("sink"); xmlConnection.appendChild( xmlSink ); QDomElement xmlSinkPinName = doc.createElement( "pinName" ); QDomElement xmlSinkId = doc.createElement( "processorId" ); xmlSink.appendChild( xmlSinkPinName ); xmlSink.appendChild( xmlSinkId ); QString sinkPinName = connection->toPin()->getName(); QString sinkId = QVariant( connection->toPin()->getOwner()->getId() ).toString(); QDomText xmlSinkNameText = doc.createTextNode( sinkPinName ); QDomText xmlSinkIdText = doc.createTextNode( sinkId ); xmlSinkPinName.appendChild( xmlSinkNameText ); xmlSinkId.appendChild( xmlSinkIdText ); QDomElement xmlSource = doc.createElement("source"); xmlConnection.appendChild( xmlSource ); QDomElement xmlSourcePinName = doc.createElement( "pinName" ); QDomElement xmlSourceId = doc.createElement( "processorId" ); xmlSource.appendChild( xmlSourcePinName ); xmlSource.appendChild( xmlSourceId ); QString sourcePinName = connection->fromPin()->getName(); QString sourceId = QVariant( connection->fromPin()->getOwner()->getId() ).toString(); QDomText xmlSourceNameText = doc.createTextNode( sourcePinName ); QDomText xmlSourceIdText = doc.createTextNode( sourceId ); xmlSourcePinName.appendChild( xmlSourceNameText ); xmlSourceId.appendChild( xmlSourceIdText ); }
QObject *QDeclarativeVME::run(QDeclarativeVMEObjectStack &stack, QDeclarativeContextData *ctxt, QDeclarativeCompiledData *comp, int start, int count, const QBitField &bindingSkipList) { Q_ASSERT(comp); Q_ASSERT(ctxt); const QList<QDeclarativeCompiledData::TypeReference> &types = comp->types; const QList<QString> &primitives = comp->primitives; const QList<QByteArray> &datas = comp->datas; const QList<QDeclarativeCompiledData::CustomTypeData> &customTypeData = comp->customTypeData; const QList<int> &intData = comp->intData; const QList<float> &floatData = comp->floatData; const QList<QDeclarativePropertyCache *> &propertyCaches = comp->propertyCaches; const QList<QDeclarativeParser::Object::ScriptBlock> &scripts = comp->scripts; const QList<QUrl> &urls = comp->urls; QDeclarativeEnginePrivate::SimpleList<QDeclarativeAbstractBinding> bindValues; QDeclarativeEnginePrivate::SimpleList<QDeclarativeParserStatus> parserStatus; QDeclarativeVMEStack<ListInstance> qliststack; vmeErrors.clear(); QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(ctxt->engine); int status = -1; //for dbus QDeclarativePropertyPrivate::WriteFlags flags = QDeclarativePropertyPrivate::BypassInterceptor | QDeclarativePropertyPrivate::RemoveBindingOnAliasWrite; for (int ii = start; !isError() && ii < (start + count); ++ii) { const QDeclarativeInstruction &instr = comp->bytecode.at(ii); switch(instr.type) { case QDeclarativeInstruction::Init: { if (instr.init.bindingsSize) bindValues = QDeclarativeEnginePrivate::SimpleList<QDeclarativeAbstractBinding>(instr.init.bindingsSize); if (instr.init.parserStatusSize) parserStatus = QDeclarativeEnginePrivate::SimpleList<QDeclarativeParserStatus>(instr.init.parserStatusSize); if (instr.init.contextCache != -1) ctxt->setIdPropertyData(comp->contextCaches.at(instr.init.contextCache)); if (instr.init.compiledBinding != -1) ctxt->optimizedBindings = new QDeclarativeCompiledBindings(datas.at(instr.init.compiledBinding).constData(), ctxt, comp); } break; case QDeclarativeInstruction::CreateObject: { QBitField bindings; if (instr.create.bindingBits != -1) { const QByteArray &bits = datas.at(instr.create.bindingBits); bindings = QBitField((const quint32*)bits.constData(), bits.size() * 8); } if (stack.isEmpty()) bindings = bindings.united(bindingSkipList); QObject *o = types.at(instr.create.type).createInstance(ctxt, bindings, &vmeErrors); if (!o) { VME_EXCEPTION(QCoreApplication::translate("QDeclarativeVME","Unable to create object of type %1").arg(QString::fromLatin1(types.at(instr.create.type).className))); } QDeclarativeData *ddata = QDeclarativeData::get(o); Q_ASSERT(ddata); if (stack.isEmpty()) { if (ddata->context) { Q_ASSERT(ddata->context != ctxt); Q_ASSERT(ddata->outerContext); Q_ASSERT(ddata->outerContext != ctxt); QDeclarativeContextData *c = ddata->context; while (c->linkedContext) c = c->linkedContext; c->linkedContext = ctxt; } else { ctxt->addObject(o); } ddata->ownContext = true; } else if (!ddata->context) { ctxt->addObject(o); } ddata->setImplicitDestructible(); ddata->outerContext = ctxt; ddata->lineNumber = instr.line; ddata->columnNumber = instr.create.column; if (instr.create.data != -1) { QDeclarativeCustomParser *customParser = types.at(instr.create.type).type->customParser(); customParser->setCustomData(o, datas.at(instr.create.data)); } if (!stack.isEmpty()) { QObject *parent = stack.top(); if (o->isWidgetType()) { QWidget *widget = static_cast<QWidget*>(o); if (parent->isWidgetType()) { QWidget *parentWidget = static_cast<QWidget*>(parent); widget->setParent(parentWidget); } else { // TODO: parent might be a layout } } else { QDeclarative_setParent_noEvent(o, parent); } } stack.push(o); } break; case QDeclarativeInstruction::CreateSimpleObject: { QObject *o = (QObject *)operator new(instr.createSimple.typeSize + sizeof(QDeclarativeData)); ::memset(static_cast<void *>(o), 0, instr.createSimple.typeSize + sizeof(QDeclarativeData)); instr.createSimple.create(o); QDeclarativeData *ddata = (QDeclarativeData *)(((const char *)o) + instr.createSimple.typeSize); const QDeclarativeCompiledData::TypeReference &ref = types.at(instr.createSimple.type); if (!ddata->propertyCache && ref.typePropertyCache) { ddata->propertyCache = ref.typePropertyCache; ddata->propertyCache->addref(); } ddata->lineNumber = instr.line; ddata->columnNumber = instr.createSimple.column; QObjectPrivate::get(o)->declarativeData = ddata; ddata->context = ddata->outerContext = ctxt; ddata->nextContextObject = ctxt->contextObjects; if (ddata->nextContextObject) ddata->nextContextObject->prevContextObject = &ddata->nextContextObject; ddata->prevContextObject = &ctxt->contextObjects; ctxt->contextObjects = ddata; QObject *parent = stack.top(); QDeclarative_setParent_noEvent(o, parent); stack.push(o); } break; case QDeclarativeInstruction::SetId: { QObject *target = stack.top(); ctxt->setIdProperty(instr.setId.index, target); } break; case QDeclarativeInstruction::SetDefault: { ctxt->contextObject = stack.top(); } break; case QDeclarativeInstruction::CreateComponent: { QDeclarativeComponent *qcomp = new QDeclarativeComponent(ctxt->engine, comp, ii + 1, instr.createComponent.count, stack.isEmpty() ? 0 : stack.top()); QDeclarativeData *ddata = QDeclarativeData::get(qcomp, true); Q_ASSERT(ddata); ctxt->addObject(qcomp); if (stack.isEmpty()) ddata->ownContext = true; ddata->setImplicitDestructible(); ddata->outerContext = ctxt; ddata->lineNumber = instr.line; ddata->columnNumber = instr.create.column; QDeclarativeComponentPrivate::get(qcomp)->creationContext = ctxt; stack.push(qcomp); ii += instr.createComponent.count; } break; case QDeclarativeInstruction::StoreMetaObject: { QObject *target = stack.top(); QMetaObject mo; const QByteArray &metadata = datas.at(instr.storeMeta.data); QMetaObjectBuilder::fromRelocatableData(&mo, 0, metadata); const QDeclarativeVMEMetaData *data = (const QDeclarativeVMEMetaData *)datas.at(instr.storeMeta.aliasData).constData(); (void)new QDeclarativeVMEMetaObject(target, &mo, data, comp); if (instr.storeMeta.propertyCache != -1) { QDeclarativeData *ddata = QDeclarativeData::get(target, true); if (ddata->propertyCache) ddata->propertyCache->release(); ddata->propertyCache = propertyCaches.at(instr.storeMeta.propertyCache); ddata->propertyCache->addref(); } } break; case QDeclarativeInstruction::StoreVariant: { QObject *target = stack.top(); CLEAN_PROPERTY(target, instr.storeString.propertyIndex); // XXX - can be more efficient QVariant v = QDeclarativeStringConverters::variantFromString(primitives.at(instr.storeString.value)); void *a[] = { &v, 0, &status, &flags }; QMetaObject::metacall(target, QMetaObject::WriteProperty, instr.storeString.propertyIndex, a); } break; case QDeclarativeInstruction::StoreVariantInteger: { QObject *target = stack.top(); CLEAN_PROPERTY(target, instr.storeString.propertyIndex); QVariant v(instr.storeInteger.value); void *a[] = { &v, 0, &status, &flags }; QMetaObject::metacall(target, QMetaObject::WriteProperty, instr.storeString.propertyIndex, a); } break; case QDeclarativeInstruction::StoreVariantDouble: { QObject *target = stack.top(); CLEAN_PROPERTY(target, instr.storeString.propertyIndex); QVariant v(instr.storeDouble.value); void *a[] = { &v, 0, &status, &flags }; QMetaObject::metacall(target, QMetaObject::WriteProperty, instr.storeString.propertyIndex, a); } break; case QDeclarativeInstruction::StoreVariantBool: { QObject *target = stack.top(); CLEAN_PROPERTY(target, instr.storeString.propertyIndex); QVariant v(instr.storeBool.value); void *a[] = { &v, 0, &status, &flags }; QMetaObject::metacall(target, QMetaObject::WriteProperty, instr.storeString.propertyIndex, a); } break; case QDeclarativeInstruction::StoreString: { QObject *target = stack.top(); CLEAN_PROPERTY(target, instr.storeString.propertyIndex); void *a[] = { (void *)&primitives.at(instr.storeString.value), 0, &status, &flags }; QMetaObject::metacall(target, QMetaObject::WriteProperty, instr.storeString.propertyIndex, a); } break; case QDeclarativeInstruction::StoreUrl: { QObject *target = stack.top(); CLEAN_PROPERTY(target, instr.storeUrl.propertyIndex); void *a[] = { (void *)&urls.at(instr.storeUrl.value), 0, &status, &flags }; QMetaObject::metacall(target, QMetaObject::WriteProperty, instr.storeUrl.propertyIndex, a); } break; case QDeclarativeInstruction::StoreFloat: { QObject *target = stack.top(); CLEAN_PROPERTY(target, instr.storeFloat.propertyIndex); float f = instr.storeFloat.value; void *a[] = { &f, 0, &status, &flags }; QMetaObject::metacall(target, QMetaObject::WriteProperty, instr.storeFloat.propertyIndex, a); } break; case QDeclarativeInstruction::StoreDouble: { QObject *target = stack.top(); CLEAN_PROPERTY(target, instr.storeDouble.propertyIndex); double d = instr.storeDouble.value; void *a[] = { &d, 0, &status, &flags }; QMetaObject::metacall(target, QMetaObject::WriteProperty, instr.storeDouble.propertyIndex, a); } break; case QDeclarativeInstruction::StoreBool: { QObject *target = stack.top(); CLEAN_PROPERTY(target, instr.storeBool.propertyIndex); void *a[] = { (void *)&instr.storeBool.value, 0, &status, &flags }; QMetaObject::metacall(target, QMetaObject::WriteProperty, instr.storeBool.propertyIndex, a); } break; case QDeclarativeInstruction::StoreInteger: { QObject *target = stack.top(); CLEAN_PROPERTY(target, instr.storeInteger.propertyIndex); void *a[] = { (void *)&instr.storeInteger.value, 0, &status, &flags }; QMetaObject::metacall(target, QMetaObject::WriteProperty, instr.storeInteger.propertyIndex, a); } break; case QDeclarativeInstruction::StoreColor: { QObject *target = stack.top(); CLEAN_PROPERTY(target, instr.storeColor.propertyIndex); QColor c = QColor::fromRgba(instr.storeColor.value); void *a[] = { &c, 0, &status, &flags }; QMetaObject::metacall(target, QMetaObject::WriteProperty, instr.storeColor.propertyIndex, a); } break; case QDeclarativeInstruction::StoreDate: { QObject *target = stack.top(); CLEAN_PROPERTY(target, instr.storeDate.propertyIndex); QDate d = QDate::fromJulianDay(instr.storeDate.value); void *a[] = { &d, 0, &status, &flags }; QMetaObject::metacall(target, QMetaObject::WriteProperty, instr.storeDate.propertyIndex, a); } break; case QDeclarativeInstruction::StoreTime: { QObject *target = stack.top(); CLEAN_PROPERTY(target, instr.storeTime.propertyIndex); QTime t; t.setHMS(intData.at(instr.storeTime.valueIndex), intData.at(instr.storeTime.valueIndex+1), intData.at(instr.storeTime.valueIndex+2), intData.at(instr.storeTime.valueIndex+3)); void *a[] = { &t, 0, &status, &flags }; QMetaObject::metacall(target, QMetaObject::WriteProperty, instr.storeTime.propertyIndex, a); } break; case QDeclarativeInstruction::StoreDateTime: { QObject *target = stack.top(); CLEAN_PROPERTY(target, instr.storeDateTime.propertyIndex); QTime t; t.setHMS(intData.at(instr.storeDateTime.valueIndex+1), intData.at(instr.storeDateTime.valueIndex+2), intData.at(instr.storeDateTime.valueIndex+3), intData.at(instr.storeDateTime.valueIndex+4)); QDateTime dt(QDate::fromJulianDay(intData.at(instr.storeDateTime.valueIndex)), t); void *a[] = { &dt, 0, &status, &flags }; QMetaObject::metacall(target, QMetaObject::WriteProperty, instr.storeDateTime.propertyIndex, a); } break; case QDeclarativeInstruction::StorePoint: { QObject *target = stack.top(); CLEAN_PROPERTY(target, instr.storeRealPair.propertyIndex); QPoint p = QPointF(floatData.at(instr.storeRealPair.valueIndex), floatData.at(instr.storeRealPair.valueIndex+1)).toPoint(); void *a[] = { &p, 0, &status, &flags }; QMetaObject::metacall(target, QMetaObject::WriteProperty, instr.storeRealPair.propertyIndex, a); } break; case QDeclarativeInstruction::StorePointF: { QObject *target = stack.top(); CLEAN_PROPERTY(target, instr.storeRealPair.propertyIndex); QPointF p(floatData.at(instr.storeRealPair.valueIndex), floatData.at(instr.storeRealPair.valueIndex+1)); void *a[] = { &p, 0, &status, &flags }; QMetaObject::metacall(target, QMetaObject::WriteProperty, instr.storeRealPair.propertyIndex, a); } break; case QDeclarativeInstruction::StoreSize: { QObject *target = stack.top(); CLEAN_PROPERTY(target, instr.storeRealPair.propertyIndex); QSize p = QSizeF(floatData.at(instr.storeRealPair.valueIndex), floatData.at(instr.storeRealPair.valueIndex+1)).toSize(); void *a[] = { &p, 0, &status, &flags }; QMetaObject::metacall(target, QMetaObject::WriteProperty, instr.storeRealPair.propertyIndex, a); } break; case QDeclarativeInstruction::StoreSizeF: { QObject *target = stack.top(); CLEAN_PROPERTY(target, instr.storeRealPair.propertyIndex); QSizeF s(floatData.at(instr.storeRealPair.valueIndex), floatData.at(instr.storeRealPair.valueIndex+1)); void *a[] = { &s, 0, &status, &flags }; QMetaObject::metacall(target, QMetaObject::WriteProperty, instr.storeRealPair.propertyIndex, a); } break; case QDeclarativeInstruction::StoreRect: { QObject *target = stack.top(); CLEAN_PROPERTY(target, instr.storeRect.propertyIndex); QRect r = QRectF(floatData.at(instr.storeRect.valueIndex), floatData.at(instr.storeRect.valueIndex+1), floatData.at(instr.storeRect.valueIndex+2), floatData.at(instr.storeRect.valueIndex+3)).toRect(); void *a[] = { &r, 0, &status, &flags }; QMetaObject::metacall(target, QMetaObject::WriteProperty, instr.storeRect.propertyIndex, a); } break; case QDeclarativeInstruction::StoreRectF: { QObject *target = stack.top(); CLEAN_PROPERTY(target, instr.storeRect.propertyIndex); QRectF r(floatData.at(instr.storeRect.valueIndex), floatData.at(instr.storeRect.valueIndex+1), floatData.at(instr.storeRect.valueIndex+2), floatData.at(instr.storeRect.valueIndex+3)); void *a[] = { &r, 0, &status, &flags }; QMetaObject::metacall(target, QMetaObject::WriteProperty, instr.storeRect.propertyIndex, a); } break; case QDeclarativeInstruction::StoreVector3D: { QObject *target = stack.top(); CLEAN_PROPERTY(target, instr.storeVector3D.propertyIndex); QVector3D p(floatData.at(instr.storeVector3D.valueIndex), floatData.at(instr.storeVector3D.valueIndex+1), floatData.at(instr.storeVector3D.valueIndex+2)); void *a[] = { &p, 0, &status, &flags }; QMetaObject::metacall(target, QMetaObject::WriteProperty, instr.storeVector3D.propertyIndex, a); } break; case QDeclarativeInstruction::StoreObject: { QObject *assignObj = stack.pop(); QObject *target = stack.top(); CLEAN_PROPERTY(target, instr.storeObject.propertyIndex); void *a[] = { (void *)&assignObj, 0, &status, &flags }; QMetaObject::metacall(target, QMetaObject::WriteProperty, instr.storeObject.propertyIndex, a); } break; case QDeclarativeInstruction::AssignCustomType: { QObject *target = stack.top(); CLEAN_PROPERTY(target, instr.assignCustomType.propertyIndex); QDeclarativeCompiledData::CustomTypeData data = customTypeData.at(instr.assignCustomType.valueIndex); const QString &primitive = primitives.at(data.index); QDeclarativeMetaType::StringConverter converter = QDeclarativeMetaType::customStringConverter(data.type); QVariant v = (*converter)(primitive); QMetaProperty prop = target->metaObject()->property(instr.assignCustomType.propertyIndex); if (v.isNull() || ((int)prop.type() != data.type && prop.userType() != data.type)) VME_EXCEPTION(QCoreApplication::translate("QDeclarativeVME","Cannot assign value %1 to property %2").arg(primitive).arg(QString::fromUtf8(prop.name()))); void *a[] = { (void *)v.data(), 0, &status, &flags }; QMetaObject::metacall(target, QMetaObject::WriteProperty, instr.assignCustomType.propertyIndex, a); } break; case QDeclarativeInstruction::AssignSignalObject: { // XXX optimize QObject *assign = stack.pop(); QObject *target = stack.top(); int sigIdx = instr.assignSignalObject.signal; const QByteArray &pr = datas.at(sigIdx); QDeclarativeProperty prop(target, QString::fromUtf8(pr)); if (prop.type() & QDeclarativeProperty::SignalProperty) { QMetaMethod method = QDeclarativeMetaType::defaultMethod(assign); if (method.signature() == 0) VME_EXCEPTION(QCoreApplication::translate("QDeclarativeVME","Cannot assign object type %1 with no default method").arg(QString::fromLatin1(assign->metaObject()->className()))); if (!QMetaObject::checkConnectArgs(prop.method().signature(), method.signature())) VME_EXCEPTION(QCoreApplication::translate("QDeclarativeVME","Cannot connect mismatched signal/slot %1 %vs. %2").arg(QString::fromLatin1(method.signature())).arg(QString::fromLatin1(prop.method().signature()))); QDeclarativePropertyPrivate::connect(target, prop.index(), assign, method.methodIndex()); } else { VME_EXCEPTION(QCoreApplication::translate("QDeclarativeVME","Cannot assign an object to signal property %1").arg(QString::fromUtf8(pr))); } } break; case QDeclarativeInstruction::StoreSignal: { QObject *target = stack.top(); QObject *context = stack.at(stack.count() - 1 - instr.storeSignal.context); QMetaMethod signal = target->metaObject()->method(instr.storeSignal.signalIndex); QDeclarativeBoundSignal *bs = new QDeclarativeBoundSignal(target, signal, target); QDeclarativeExpression *expr = new QDeclarativeExpression(ctxt, context, primitives.at(instr.storeSignal.value)); expr->setSourceLocation(comp->name, instr.line); static_cast<QDeclarativeExpressionPrivate *>(QObjectPrivate::get(expr))->name = datas.at(instr.storeSignal.name); bs->setExpression(expr); } break; case QDeclarativeInstruction::StoreImportedScript: { ctxt->addImportedScript(scripts.at(instr.storeScript.value)); } break; case QDeclarativeInstruction::StoreScriptString: { QObject *target = stack.top(); QObject *scope = stack.at(stack.count() - 1 - instr.storeScriptString.scope); QDeclarativeScriptString ss; ss.setContext(ctxt->asQDeclarativeContext()); ss.setScopeObject(scope); ss.setScript(primitives.at(instr.storeScriptString.value)); void *a[] = { &ss, 0, &status, &flags }; QMetaObject::metacall(target, QMetaObject::WriteProperty, instr.storeScriptString.propertyIndex, a); } break; case QDeclarativeInstruction::BeginObject: { QObject *target = stack.top(); QDeclarativeParserStatus *status = reinterpret_cast<QDeclarativeParserStatus *>(reinterpret_cast<char *>(target) + instr.begin.castValue); parserStatus.append(status); status->d = &parserStatus.values[parserStatus.count - 1]; status->classBegin(); } break; case QDeclarativeInstruction::StoreBinding: case QDeclarativeInstruction::StoreBindingOnAlias: { QObject *target = stack.at(stack.count() - 1 - instr.assignBinding.owner); QObject *context = stack.at(stack.count() - 1 - instr.assignBinding.context); QDeclarativeProperty mp = QDeclarativePropertyPrivate::restore(datas.at(instr.assignBinding.property), target, ctxt); int coreIndex = mp.index(); if ((stack.count() - instr.assignBinding.owner) == 1 && bindingSkipList.testBit(coreIndex)) break; QDeclarativeBinding *bind = new QDeclarativeBinding((void *)datas.at(instr.assignBinding.value).constData(), comp, context, ctxt, comp->name, instr.line, 0); bindValues.append(bind); bind->m_mePtr = &bindValues.values[bindValues.count - 1]; bind->setTarget(mp); if (instr.type == QDeclarativeInstruction::StoreBindingOnAlias) { QDeclarativeAbstractBinding *old = QDeclarativePropertyPrivate::setBindingNoEnable(target, coreIndex, QDeclarativePropertyPrivate::valueTypeCoreIndex(mp), bind); if (old) { old->destroy(); } } else { bind->addToObject(target, QDeclarativePropertyPrivate::bindingIndex(mp)); } } break; case QDeclarativeInstruction::StoreCompiledBinding: { QObject *target = stack.at(stack.count() - 1 - instr.assignBinding.owner); QObject *scope = stack.at(stack.count() - 1 - instr.assignBinding.context); int property = instr.assignBinding.property; if (stack.count() == 1 && bindingSkipList.testBit(property & 0xFFFF)) break; QDeclarativeAbstractBinding *binding = ctxt->optimizedBindings->configBinding(instr.assignBinding.value, target, scope, property); bindValues.append(binding); binding->m_mePtr = &bindValues.values[bindValues.count - 1]; binding->addToObject(target, property); } break; case QDeclarativeInstruction::StoreValueSource: { QObject *obj = stack.pop(); QDeclarativePropertyValueSource *vs = reinterpret_cast<QDeclarativePropertyValueSource *>(reinterpret_cast<char *>(obj) + instr.assignValueSource.castValue); QObject *target = stack.at(stack.count() - 1 - instr.assignValueSource.owner); QDeclarativeProperty prop = QDeclarativePropertyPrivate::restore(datas.at(instr.assignValueSource.property), target, ctxt); obj->setParent(target); vs->setTarget(prop); } break; case QDeclarativeInstruction::StoreValueInterceptor: { QObject *obj = stack.pop(); QDeclarativePropertyValueInterceptor *vi = reinterpret_cast<QDeclarativePropertyValueInterceptor *>(reinterpret_cast<char *>(obj) + instr.assignValueInterceptor.castValue); QObject *target = stack.at(stack.count() - 1 - instr.assignValueInterceptor.owner); QDeclarativeProperty prop = QDeclarativePropertyPrivate::restore(datas.at(instr.assignValueInterceptor.property), target, ctxt); obj->setParent(target); vi->setTarget(prop); QDeclarativeVMEMetaObject *mo = static_cast<QDeclarativeVMEMetaObject *>((QMetaObject*)target->metaObject()); mo->registerInterceptor(prop.index(), QDeclarativePropertyPrivate::valueTypeCoreIndex(prop), vi); } break; case QDeclarativeInstruction::StoreObjectQList: { QObject *assign = stack.pop(); const ListInstance &list = qliststack.top(); list.qListProperty.append((QDeclarativeListProperty<void>*)&list.qListProperty, assign); } break; case QDeclarativeInstruction::AssignObjectList: { // This is only used for assigning interfaces QObject *assign = stack.pop(); const ListInstance &list = qliststack.top(); int type = list.type; void *ptr = 0; const char *iid = QDeclarativeMetaType::interfaceIId(type); if (iid) ptr = assign->qt_metacast(iid); if (!ptr) VME_EXCEPTION(QCoreApplication::translate("QDeclarativeVME","Cannot assign object to list")); list.qListProperty.append((QDeclarativeListProperty<void>*)&list.qListProperty, ptr); } break; case QDeclarativeInstruction::StoreVariantObject: { QObject *assign = stack.pop(); QObject *target = stack.top(); CLEAN_PROPERTY(target, instr.storeObject.propertyIndex); QVariant v = QVariant::fromValue(assign); void *a[] = { &v, 0, &status, &flags }; QMetaObject::metacall(target, QMetaObject::WriteProperty, instr.storeObject.propertyIndex, a); } break; case QDeclarativeInstruction::StoreInterface: { QObject *assign = stack.pop(); QObject *target = stack.top(); CLEAN_PROPERTY(target, instr.storeObject.propertyIndex); int coreIdx = instr.storeObject.propertyIndex; QMetaProperty prop = target->metaObject()->property(coreIdx); int t = prop.userType(); const char *iid = QDeclarativeMetaType::interfaceIId(t); bool ok = false; if (iid) { void *ptr = assign->qt_metacast(iid); if (ptr) { void *a[] = { &ptr, 0, &status, &flags }; QMetaObject::metacall(target, QMetaObject::WriteProperty, coreIdx, a); ok = true; } } if (!ok) VME_EXCEPTION(QCoreApplication::translate("QDeclarativeVME","Cannot assign object to interface property")); } break; case QDeclarativeInstruction::FetchAttached: { QObject *target = stack.top(); QObject *qmlObject = qmlAttachedPropertiesObjectById(instr.fetchAttached.id, target); if (!qmlObject) VME_EXCEPTION(QCoreApplication::translate("QDeclarativeVME","Unable to create attached object")); stack.push(qmlObject); } break; case QDeclarativeInstruction::FetchQList: { QObject *target = stack.top(); qliststack.push(ListInstance(instr.fetchQmlList.type)); void *a[1]; a[0] = (void *)&(qliststack.top().qListProperty); QMetaObject::metacall(target, QMetaObject::ReadProperty, instr.fetchQmlList.property, a); } break; case QDeclarativeInstruction::FetchObject: { QObject *target = stack.top(); QObject *obj = 0; // NOTE: This assumes a cast to QObject does not alter the // object pointer void *a[1]; a[0] = &obj; QMetaObject::metacall(target, QMetaObject::ReadProperty, instr.fetch.property, a); if (!obj) VME_EXCEPTION(QCoreApplication::translate("QDeclarativeVME","Cannot set properties on %1 as it is null").arg(QString::fromUtf8(target->metaObject()->property(instr.fetch.property).name()))); stack.push(obj); } break; case QDeclarativeInstruction::PopQList: { qliststack.pop(); } break; case QDeclarativeInstruction::Defer: { if (instr.defer.deferCount) { QObject *target = stack.top(); QDeclarativeData *data = QDeclarativeData::get(target, true); comp->addref(); data->deferredComponent = comp; data->deferredIdx = ii; ii += instr.defer.deferCount; } } break; case QDeclarativeInstruction::PopFetchedObject: { stack.pop(); } break; case QDeclarativeInstruction::FetchValueType: { QObject *target = stack.top(); if (instr.fetchValue.bindingSkipList != 0) { // Possibly need to clear bindings QDeclarativeData *targetData = QDeclarativeData::get(target); if (targetData) { QDeclarativeAbstractBinding *binding = QDeclarativePropertyPrivate::binding(target, instr.fetchValue.property, -1); if (binding && binding->bindingType() != QDeclarativeAbstractBinding::ValueTypeProxy) { QDeclarativePropertyPrivate::setBinding(target, instr.fetchValue.property, -1, 0); binding->destroy(); } else if (binding) { QDeclarativeValueTypeProxyBinding *proxy = static_cast<QDeclarativeValueTypeProxyBinding *>(binding); proxy->removeBindings(instr.fetchValue.bindingSkipList); } } } QDeclarativeValueType *valueHandler = ep->valueTypes[instr.fetchValue.type]; valueHandler->read(target, instr.fetchValue.property); stack.push(valueHandler); } break; case QDeclarativeInstruction::PopValueType: { QDeclarativeValueType *valueHandler = static_cast<QDeclarativeValueType *>(stack.pop()); QObject *target = stack.top(); valueHandler->write(target, instr.fetchValue.property, QDeclarativePropertyPrivate::BypassInterceptor); } break; default: qFatal("QDeclarativeCompiledData: Internal error - unknown instruction %d", instr.type); break; } } if (isError()) { if (!stack.isEmpty()) { delete stack.at(0); // ### What about failures in deferred creation? } else { ctxt->destroy(); } QDeclarativeEnginePrivate::clear(bindValues); QDeclarativeEnginePrivate::clear(parserStatus); return 0; } if (bindValues.count) ep->bindValues << bindValues; else if (bindValues.values) bindValues.clear(); if (parserStatus.count) ep->parserStatus << parserStatus; else if (parserStatus.values) parserStatus.clear(); Q_ASSERT(stack.count() == 1); return stack.top(); }
void QDBusAbstractInterfacePrivate::property(const QMetaProperty &mp, QVariant &where) const { if (!isValid || !canMakeCalls()) { // can't make calls where.clear(); return; } // is this metatype registered? const char *expectedSignature = ""; if (mp.type() != 0xff) { expectedSignature = QDBusMetaType::typeToSignature(where.userType()); if (expectedSignature == 0) { qWarning("QDBusAbstractInterface: type %s must be registered with QtDBus before it can be " "used to read property %s.%s", mp.typeName(), qPrintable(interface), mp.name()); lastError = QDBusError(QDBusError::Failed, QString::fromLatin1("Unregistered type %1 cannot be handled") .arg(QLatin1String(mp.typeName()))); where.clear(); return; } } // try to read this property QDBusMessage msg = QDBusMessage::createMethodCall(service, path, QLatin1String(DBUS_INTERFACE_PROPERTIES), QLatin1String("Get")); QDBusMessagePrivate::setParametersValidated(msg, true); msg << interface << QString::fromUtf8(mp.name()); QDBusMessage reply = connection.call(msg, QDBus::Block); if (reply.type() != QDBusMessage::ReplyMessage) { lastError = reply; where.clear(); return; } if (reply.signature() != QLatin1String("v")) { QString errmsg = QLatin1String("Invalid signature `%1' in return from call to " DBUS_INTERFACE_PROPERTIES); lastError = QDBusError(QDBusError::InvalidSignature, errmsg.arg(reply.signature())); where.clear(); return; } QByteArray foundSignature; const char *foundType = 0; QVariant value = qvariant_cast<QDBusVariant>(reply.arguments().at(0)).variant(); if (value.userType() == where.userType() || mp.type() == 0xff || (expectedSignature[0] == 'v' && expectedSignature[1] == '\0')) { // simple match where = value; return; } if (value.userType() == qMetaTypeId<QDBusArgument>()) { QDBusArgument arg = qvariant_cast<QDBusArgument>(value); foundType = "user type"; foundSignature = arg.currentSignature().toLatin1(); if (foundSignature == expectedSignature) { // signatures match, we can demarshall QDBusMetaType::demarshall(arg, where.userType(), where.data()); return; } } else { foundType = value.typeName(); foundSignature = QDBusMetaType::typeToSignature(value.userType()); } // there was an error... QString errmsg = QLatin1String("Unexpected `%1' (%2) when retrieving property `%3.%4' " "(expected type `%5' (%6))"); lastError = QDBusError(QDBusError::InvalidSignature, errmsg.arg(QString::fromLatin1(foundType), QString::fromLatin1(foundSignature), interface, QString::fromUtf8(mp.name()), QString::fromLatin1(mp.typeName()), QString::fromLatin1(expectedSignature))); where.clear(); return; }
int QServiceProxy::qt_metacall(QMetaObject::Call c, int id, void **a) { #ifdef QT_SFW_ENDPOINT_DEBUG qDebug() << "QServiceProxy::qt_metacall: Start"; #endif id = QObject::qt_metacall(c, id, a); if (id < 0 || !d->meta) return id; //Let the object endpoint monitor keep track of the usage... #ifdef Q_OS_SYMBIAN ObjectEndPointMonitor aOem(d->endPoint); #endif //End Q_OS_SYMBIAN if(localSignals.at(id)){ QMetaObject::activate(this, d->meta, id, a); return id; } if (c == QMetaObject::InvokeMetaMethod) { const int mcount = d->meta->methodCount() - d->meta->methodOffset(); const int metaIndex = id + d->meta->methodOffset(); QMetaMethod method = d->meta->method(metaIndex); const int returnType = QMetaType::type(method.typeName()); //process arguments const QList<QByteArray> pTypes = method.parameterTypes(); const int pTypesCount = pTypes.count(); QVariantList args ; if (pTypesCount > 10) { qWarning() << "Cannot call" << method.signature() << ". More than 10 parameter."; return id; } for (int i=0; i < pTypesCount; i++) { const QByteArray& t = pTypes[i]; int variantType = QVariant::nameToType(t); if (variantType == QVariant::UserType) variantType = QMetaType::type(t); if (t == "QVariant") { //ignore whether QVariant is declared as metatype args << *reinterpret_cast<const QVariant(*)>(a[i+1]); } else if ( variantType == 0 ){ qWarning("%s: argument %s has unknown type. Use qRegisterMetaType to register it.", method.signature(), t.data()); return id; } else { args << QVariant(variantType, a[i+1]); } } //QVariant looks the same as Void type. we need to distinguish them if (returnType == QMetaType::Void && strcmp(method.typeName(),"QVariant") ) { d->endPoint->invokeRemote(metaIndex, args, returnType); } else { //TODO: ugly but works //add +1 if we have a variant return type to avoid triggering of void //code path //invokeRemote() parameter list needs review QVariant result = d->endPoint->invokeRemote(metaIndex, args, returnType==0 ? returnType+1: returnType); if(result.type() != QVariant::Invalid){ if (returnType != 0 && strcmp(method.typeName(),"QVariant")) { QByteArray buffer; QDataStream stream(&buffer, QIODevice::ReadWrite); QMetaType::save(stream, returnType, result.constData()); stream.device()->seek(0); QMetaType::load(stream, returnType, a[0]); } else { if (a[0]) *reinterpret_cast< QVariant*>(a[0]) = result; } } } id-=mcount; } else if ( c == QMetaObject::ReadProperty || c == QMetaObject::WriteProperty || c == QMetaObject::ResetProperty ) { const int pCount = d->meta->propertyCount() - d->meta->propertyOffset(); const int metaIndex = id + d->meta->propertyOffset(); QMetaProperty property = d->meta->property(metaIndex); if (property.isValid()) { int pType = property.type(); if (pType == QVariant::UserType) pType = QMetaType::type(property.typeName()); QVariant arg; if ( c == QMetaObject::WriteProperty ) { if (pType == QVariant::Invalid && QByteArray(property.typeName()) == "QVariant") arg = *reinterpret_cast<const QVariant(*)>(a[0]); else if (pType == 0) { qWarning("%s: property %s has unknown type", property.name(), property.typeName()); return id; } else { arg = QVariant(pType, a[0]); } } QVariant result; if (c == QMetaObject::ReadProperty) { result = d->endPoint->invokeRemoteProperty(metaIndex, arg, pType, c); //wrap result for client if (pType != 0) { QByteArray buffer; QDataStream stream(&buffer, QIODevice::ReadWrite); QMetaType::save(stream, pType, result.constData()); stream.device()->seek(0); QMetaType::load(stream, pType, a[0]); } else { if (a[0]) *reinterpret_cast< QVariant*>(a[0]) = result; } } else { d->endPoint->invokeRemoteProperty(metaIndex, arg, pType, c); } } id-=pCount; } else if ( c == QMetaObject::QueryPropertyDesignable || c == QMetaObject::QueryPropertyScriptable || c == QMetaObject::QueryPropertyStored || c == QMetaObject::QueryPropertyEditable || c == QMetaObject::QueryPropertyUser ) { //Nothing to do? //These values are part of the transferred meta object already } else { //TODO qWarning() << "MetaCall type" << c << "not yet handled"; } #ifdef QT_SFW_ENDPOINT_DEBUG qDebug() << "QServiceProxy::qt_metacall: End"; #endif return id; }