void QJnextMainLoop::get(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.isReadable()) { retval->append("Property " + property + " is not readable"); return; } QVariant value = metaprop.read(object); if (value.isNull()) { qWarning() << "[QJnextMainLoop]\tNULL value ignored" << object->property(property); } #ifdef DEBUG_QJnextMainLoop qDebug() << "[QJnextMainLoop]\tVALUE" << value << object->property(property) << metaprop.isEnumType(); #endif if (metaprop.isEnumType()) { bool ok; int enumValue = value.toInt(&ok); if (!ok) { int status = -1; void *argv[] = { 0, &value, &status }; QMetaObject::metacall(const_cast<QObject*>(object), QMetaObject::ReadProperty, propertyIndex + meta->propertyOffset(), argv); const int * enumRaw = static_cast<const int *>(argv[0]); if (status == -1 && enumRaw != 0) { const QMetaEnum & iEnum = metaprop.enumerator(); if (iEnum.isFlag()) value = iEnum.valueToKeys(*enumRaw); else value = iEnum.valueToKey(*enumRaw); } else { // someone is evil and didn't register enumerations properly qDebug() << "[QJnextMainLoop]\t" << "!!!!!!!" << argv[0] << value; } } else if (metaprop.enumerator().isFlag()) { *retval = metaprop.enumerator().valueToKeys(enumValue); return; } else { *retval = metaprop.enumerator().valueToKey(enumValue); return; } } *retval = value.toByteArray(); }
void ObjectControllerPrivate::updateClassProperties(const QMetaObject *metaObject, bool recursive) { if (!metaObject) return; if (recursive) updateClassProperties(metaObject->superClass(), recursive); QtProperty *classProperty = m_classToProperty.value(metaObject); if (!classProperty) return; for (int idx = metaObject->propertyOffset(); idx < metaObject->propertyCount(); idx++) { QMetaProperty metaProperty = metaObject->property(idx); if (metaProperty.isReadable()) { if (m_classToIndexToProperty.contains(metaObject) && m_classToIndexToProperty[metaObject].contains(idx)) { QtVariantProperty *subProperty = m_classToIndexToProperty[metaObject][idx]; if (metaProperty.isEnumType()) { if (metaProperty.isFlagType()) subProperty->setValue(flagToInt(metaProperty.enumerator(), metaProperty.read(m_object).toInt())); else subProperty->setValue(enumToInt(metaProperty.enumerator(), metaProperty.read(m_object).toInt())); } else { subProperty->setValue(metaProperty.read(m_object)); } } } } }
QT_BEGIN_NAMESPACE QDeclarativePropertyCache::Data::Flags QDeclarativePropertyCache::Data::flagsForProperty(const QMetaProperty &p, QDeclarativeEngine *engine) { int propType = p.userType(); Flags flags; if (p.isConstant()) flags |= Data::IsConstant; if (p.isWritable()) flags |= Data::IsWritable; if (p.isResettable()) flags |= Data::IsResettable; if (propType == qMetaTypeId<QDeclarativeBinding *>()) { flags |= Data::IsQmlBinding; } else if (propType == qMetaTypeId<QScriptValue>()) { flags |= Data::IsQScriptValue; } else if (p.isEnumType()) { flags |= Data::IsEnumType; } else { QDeclarativeMetaType::TypeCategory cat = engine ? QDeclarativeEnginePrivate::get(engine)->typeCategory(propType) : QDeclarativeMetaType::typeCategory(propType); if (cat == QDeclarativeMetaType::Object) flags |= Data::IsQObjectDerived; else if (cat == QDeclarativeMetaType::List) flags |= Data::IsQList; } return flags; }
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 QDeclarativeValueTypeScriptClass::setProperty(Object *obj, const Identifier &, const QScriptValue &value) { QDeclarativeValueTypeObject *o = static_cast<QDeclarativeValueTypeObject *>(obj); QVariant v = QDeclarativeEnginePrivate::get(engine)->scriptValueToVariant(value); if (o->objectType == QDeclarativeValueTypeObject::Reference) { QDeclarativeValueTypeReference *ref = static_cast<QDeclarativeValueTypeReference *>(obj); ref->type->read(ref->object, ref->property); QMetaProperty p = ref->type->metaObject()->property(m_lastIndex); QDeclarativeBinding *newBinding = 0; if (value.isFunction() && !value.isRegExp()) { QDeclarativeContextData *ctxt = QDeclarativeEnginePrivate::get(engine)->getContext(context()); QDeclarativePropertyCache::Data cacheData; cacheData.flags = QDeclarativePropertyCache::Data::IsWritable; cacheData.propType = ref->object->metaObject()->property(ref->property).userType(); cacheData.coreIndex = ref->property; QDeclarativePropertyCache::ValueTypeData valueTypeData; valueTypeData.valueTypeCoreIdx = m_lastIndex; valueTypeData.valueTypePropType = p.userType(); newBinding = new QDeclarativeBinding(value, ref->object, ctxt); QScriptContextInfo ctxtInfo(context()); newBinding->setSourceLocation(ctxtInfo.fileName(), ctxtInfo.functionStartLineNumber()); QDeclarativeProperty prop = QDeclarativePropertyPrivate::restore(cacheData, valueTypeData, ref->object, ctxt); newBinding->setTarget(prop); if (newBinding->expression().contains(QLatin1String("this"))) newBinding->setEvaluateFlags(newBinding->evaluateFlags() | QDeclarativeBinding::RequiresThisObject); } QDeclarativeAbstractBinding *delBinding = QDeclarativePropertyPrivate::setBinding(ref->object, ref->property, m_lastIndex, newBinding); if (delBinding) delBinding->destroy(); if (p.isEnumType() && (QMetaType::Type)v.type() == QMetaType::Double) v = v.toInt(); p.write(ref->type, v); ref->type->write(ref->object, ref->property, 0); } else { QDeclarativeValueTypeCopy *copy = static_cast<QDeclarativeValueTypeCopy *>(obj); copy->type->setValue(copy->value); QMetaProperty p = copy->type->metaObject()->property(m_lastIndex); p.write(copy->type, v); copy->value = copy->type->value(); } }
void MetaInfoPrivate::parseProperties(NodeMetaInfo &nodeMetaInfo, const QMetaObject *qMetaObject) const { Q_ASSERT_X(qMetaObject, Q_FUNC_INFO, "invalid QMetaObject"); Q_ASSERT_X(nodeMetaInfo.isValid(), Q_FUNC_INFO, "invalid NodeMetaInfo"); for (int i = qMetaObject->propertyOffset(); i < qMetaObject->propertyCount(); ++i) { QMetaProperty qProperty = qMetaObject->property(i); PropertyMetaInfo propertyInfo; propertyInfo.setName(QLatin1String(qProperty.name())); QString typeName(qProperty.typeName()); QString noStar = typeName; bool star = false; while (noStar.contains('*')) {//strip star noStar.chop(1); star = true; } if (m_QtTypesToQmlTypes.contains(noStar)) { typeName = star ? m_QtTypesToQmlTypes.value(noStar) + '*' : m_QtTypesToQmlTypes.value(noStar); //### versions } propertyInfo.setType(typeName); propertyInfo.setValid(true); propertyInfo.setReadable(qProperty.isReadable()); propertyInfo.setWritable(qProperty.isWritable()); propertyInfo.setResettable(qProperty.isResettable()); propertyInfo.setEnumType(qProperty.isEnumType()); propertyInfo.setFlagType(qProperty.isFlagType()); if (propertyInfo.isEnumType()) { EnumeratorMetaInfo enumerator; QMetaEnum qEnumerator = qProperty.enumerator(); enumerator.setValid(qEnumerator.isValid()); enumerator.setIsFlagType(qEnumerator.isFlag()); enumerator.setScope(qEnumerator.scope()); enumerator.setName(qEnumerator.name()); for (int i = 0 ;i < qEnumerator.keyCount(); i++) { enumerator.addElement(qEnumerator.valueToKey(i), i); } propertyInfo.setEnumerator(enumerator); } nodeMetaInfo.addProperty(propertyInfo); } }
QMap<QString,QPair<QString,QVariant> > Modifier::serializeProperties() { QMap<QString,QPair<QString,QVariant> > result; for (int i = 0; i < metaObject()->propertyCount(); ++i) { QMetaProperty metaproperty = metaObject()->property(i); const char *name = metaproperty.name(); QVariant value = property(name); QString type(metaproperty.typeName()); if (metaproperty.isEnumType()) type = "int"; result.insert(name, QPair<QString,QVariant>(type, value)); } return result; }
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))) {
QVariant ObjectNodeInstance::convertEnumToValue(const QVariant &value, const PropertyName &name) { Q_ASSERT(value.canConvert<Enumeration>()); int propertyIndex = object()->metaObject()->indexOfProperty(name); QMetaProperty metaProperty = object()->metaObject()->property(propertyIndex); QVariant adjustedValue; Enumeration enumeration = value.value<Enumeration>(); if (metaProperty.isValid() && metaProperty.isEnumType()) { adjustedValue = metaProperty.enumerator().keyToValue(enumeration.name()); } else { QQmlExpression expression(context(), object(), enumeration.toString()); adjustedValue = expression.evaluate(); if (expression.hasError()) qDebug() << "Enumeration can not be evaluated:" << object() << name << enumeration; } return adjustedValue; }
void PropertyEditor::getProperties(QObject *obj) { mMetaProperties.clear(); mProperties.clear(); if (!obj) return; const QMetaObject *mo = obj->metaObject(); for (int i = 0; i < mo->propertyCount(); ++i) { QMetaProperty mp = mo->property(i); mMetaProperties.append(mp); QVariant v(mp.read(obj)); if (mp.isEnumType()) { mProperties.insert(mp.name(), v.toInt());//mp.enumerator().valueToKey(v.toInt())); //always use string } else { mProperties.insert(mp.name(), v); } } mProperties.remove("objectName"); }
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 ObjectControllerPrivate::slotValueChanged(QtProperty *property, const QVariant &value) { if (!m_propertyToIndex.contains(property)) return; int idx = m_propertyToIndex.value(property); const QMetaObject *metaObject = m_object->metaObject(); QMetaProperty metaProperty = metaObject->property(idx); if (metaProperty.isEnumType()) { if (metaProperty.isFlagType()) metaProperty.write(m_object, intToFlag(metaProperty.enumerator(), value.toInt())); else metaProperty.write(m_object, intToEnum(metaProperty.enumerator(), value.toInt())); } else { metaProperty.write(m_object, value); } updateClassProperties(metaObject, true); }
QT_BEGIN_NAMESPACE // Flags that do *NOT* depend on the property's QMetaProperty::userType() and thus are quick // to load static QDeclarativePropertyCache::Data::Flags fastFlagsForProperty(const QMetaProperty &p) { QDeclarativePropertyCache::Data::Flags flags; if (p.isConstant()) flags |= QDeclarativePropertyCache::Data::IsConstant; if (p.isWritable()) flags |= QDeclarativePropertyCache::Data::IsWritable; if (p.isResettable()) flags |= QDeclarativePropertyCache::Data::IsResettable; if (p.isFinal()) flags |= QDeclarativePropertyCache::Data::IsFinal; if (p.isEnumType()) flags |= QDeclarativePropertyCache::Data::IsEnumType; return flags; }
void PropertyEditor::getProperties(QObject *obj) { mMetaProperties.clear(); mProperties.clear(); mPropertyDetails.clear(); if (!obj) return; const QMetaObject *mo = obj->metaObject(); for (int i = 0; i < mo->propertyCount(); ++i) { QMetaProperty mp = mo->property(mo->propertyOffset()+i); mMetaProperties.append(mp); QVariant v(mp.read(obj)); if (mp.isEnumType()) { mProperties.insert(QString::fromLatin1(mp.name()), v.toInt());//mp.enumerator().valueToKey(v.toInt())); //always use string } else { mProperties.insert(QString::fromLatin1(mp.name()), v); } const QVariant detail = obj->property(QByteArray("detail_").append(mp.name()).constData()); if (!detail.isNull()) mPropertyDetails.insert(QString::fromLatin1(mp.name()), detail.toString()); } mProperties.remove(QString::fromLatin1("objectName")); }
//writeEnumProperty MIRRORS the relelvant bit of QMetaProperty::write AND MUST BE KEPT IN SYNC! bool QDeclarativePropertyPrivate::writeEnumProperty(const QMetaProperty &prop, int idx, QObject *object, const QVariant &value, int flags) { if (!object || !prop.isWritable()) return false; QVariant v = value; if (prop.isEnumType()) { QMetaEnum menum = prop.enumerator(); if (v.userType() == QVariant::String #ifdef QT3_SUPPORT || v.userType() == QVariant::CString #endif ) { if (prop.isFlagType()) v = QVariant(menum.keysToValue(value.toByteArray())); else v = QVariant(menum.keyToValue(value.toByteArray())); } else if (v.userType() != QVariant::Int && v.userType() != QVariant::UInt) { int enumMetaTypeId = QMetaType::type(QByteArray(menum.scope()) + "::" + menum.name()); if ((enumMetaTypeId == 0) || (v.userType() != enumMetaTypeId) || !v.constData()) return false; v = QVariant(*reinterpret_cast<const int *>(v.constData())); } v.convert(QVariant::Int); } // the status variable is changed by qt_metacall to indicate what it did // this feature is currently only used by QtDBus and should not be depended // upon. Don't change it without looking into QDBusAbstractInterface first // -1 (unchanged): normal qt_metacall, result stored in argv[0] // changed: result stored directly in value, return the value of status int status = -1; void *argv[] = { v.data(), &v, &status, &flags }; QMetaObject::metacall(object, QMetaObject::WriteProperty, idx, argv); return status; }
QString qax_generateDocumentation(QAxBase *that) { that->metaObject(); if (that->isNull()) return QString(); ITypeInfo *typeInfo = 0; IDispatch *dispatch = 0; that->queryInterface(IID_IDispatch, (void**)&dispatch); if (dispatch) dispatch->GetTypeInfo(0, LOCALE_SYSTEM_DEFAULT, &typeInfo); QString docu; QTextStream stream(&docu, QIODevice::WriteOnly); const QMetaObject *mo = that->metaObject(); QString coClass = QLatin1String(mo->classInfo(mo->indexOfClassInfo("CoClass")).value()); stream << "<h1 align=center>" << coClass << " Reference</h1>" << endl; stream << "<p>The " << coClass << " COM object is a " << that->qObject()->metaObject()->className(); stream << " with the CLSID " << that->control() << ".</p>" << endl; stream << "<h3>Interfaces</h3>" << endl; stream << "<ul>" << endl; const char *inter = 0; int interCount = 1; while ((inter = mo->classInfo(mo->indexOfClassInfo("Interface " + QByteArray::number(interCount))).value())) { stream << "<li>" << inter << endl; interCount++; } stream << "</ul>" << endl; stream << "<h3>Event Interfaces</h3>" << endl; stream << "<ul>" << endl; interCount = 1; while ((inter = mo->classInfo(mo->indexOfClassInfo("Event Interface " + QByteArray::number(interCount))).value())) { stream << "<li>" << inter << endl; interCount++; } stream << "</ul>" << endl; QList<QString> methodDetails, propDetails; const int slotCount = mo->methodCount(); if (slotCount) { stream << "<h2>Public Slots:</h2>" << endl; stream << "<ul>" << endl; int defArgCount = 0; for (int islot = mo->methodOffset(); islot < slotCount; ++islot) { const QMetaMethod slot = mo->method(islot); if (slot.methodType() != QMetaMethod::Slot) continue; if (slot.attributes() & QMetaMethod::Cloned) { ++defArgCount; continue; } QByteArray returntype(slot.typeName()); if (returntype.isEmpty()) returntype = "void"; QByteArray prototype = namedPrototype(slot.parameterTypes(), slot.parameterNames(), defArgCount); QByteArray signature = slot.methodSignature(); QByteArray name = signature.left(signature.indexOf('(')); stream << "<li>" << returntype << " <a href=\"#" << name << "\"><b>" << name << "</b></a>" << prototype << ";</li>" << endl; prototype = namedPrototype(slot.parameterTypes(), slot.parameterNames()); QString detail = QString::fromLatin1("<h3><a name=") + QString::fromLatin1(name.constData()) + QLatin1String("></a>") + QLatin1String(returntype.constData()) + QLatin1Char(' ') + QLatin1String(name.constData()) + QLatin1Char(' ') + QString::fromLatin1(prototype.constData()) + QLatin1String("<tt> [slot]</tt></h3>\n"); prototype = namedPrototype(slot.parameterTypes(), QList<QByteArray>()); detail += docuFromName(typeInfo, QString::fromLatin1(name.constData())); detail += QLatin1String("<p>Connect a signal to this slot:<pre>\n"); detail += QString::fromLatin1("\tQObject::connect(sender, SIGNAL(someSignal") + QString::fromLatin1(prototype.constData()) + QLatin1String("), object, SLOT(") + QString::fromLatin1(name.constData()) + QString::fromLatin1(prototype.constData()) + QLatin1String("));"); detail += QLatin1String("</pre>\n"); if (1) { detail += QLatin1String("<p>Or call the function directly:<pre>\n"); bool hasParams = slot.parameterTypes().count() != 0; if (hasParams) detail += QLatin1String("\tQVariantList params = ...\n"); detail += QLatin1String("\t"); QByteArray functionToCall = "dynamicCall"; if (returntype == "IDispatch*" || returntype == "IUnknown*") { functionToCall = "querySubObject"; returntype = "QAxObject *"; } if (returntype != "void") detail += QLatin1String(returntype.constData()) + QLatin1String(" result = "); detail += QLatin1String("object->") + QLatin1String(functionToCall.constData()) + QLatin1String("(\"" + name + prototype + '\"'); if (hasParams) detail += QLatin1String(", params"); detail += QLatin1Char(')'); if (returntype != "void" && returntype != "QAxObject *" && returntype != "QVariant") detail += QLatin1Char('.') + QLatin1String(toType(returntype)); detail += QLatin1String(";</pre>\n"); } else { detail += QLatin1String("<p>This function has parameters of unsupported types and cannot be called directly."); } methodDetails << detail; defArgCount = 0; } stream << "</ul>" << endl; } int signalCount = mo->methodCount(); if (signalCount) { ITypeLib *typeLib = 0; if (typeInfo) { UINT index = 0; typeInfo->GetContainingTypeLib(&typeLib, &index); typeInfo->Release(); } typeInfo = 0; stream << "<h2>Signals:</h2>" << endl; stream << "<ul>" << endl; for (int isignal = mo->methodOffset(); isignal < signalCount; ++isignal) { const QMetaMethod signal(mo->method(isignal)); if (signal.methodType() != QMetaMethod::Signal) continue; QByteArray prototype = namedPrototype(signal.parameterTypes(), signal.parameterNames()); QByteArray signature = signal.methodSignature(); QByteArray name = signature.left(signature.indexOf('(')); stream << "<li>void <a href=\"#" << name << "\"><b>" << name << "</b></a>" << prototype << ";</li>" << endl; QString detail = QLatin1String("<h3><a name=") + QLatin1String(name.constData()) + QLatin1String("></a>void ") + QLatin1String(name.constData()) + QLatin1Char(' ') + QLatin1String(prototype.constData()) + QLatin1String("<tt> [signal]</tt></h3>\n"); if (typeLib) { interCount = 0; do { if (typeInfo) typeInfo->Release(); typeInfo = 0; typeLib->GetTypeInfo(++interCount, &typeInfo); QString typeLibDocu = docuFromName(typeInfo, QString::fromLatin1(name.constData())); if (!typeLibDocu.isEmpty()) { detail += typeLibDocu; break; } } while (typeInfo); } prototype = namedPrototype(signal.parameterTypes(), QList<QByteArray>()); detail += QLatin1String("<p>Connect a slot to this signal:<pre>\n"); detail += QLatin1String("\tQObject::connect(object, SIGNAL(") + QString::fromLatin1(name.constData()) + QString::fromLatin1(prototype.constData()) + QLatin1String("), receiver, SLOT(someSlot") + QString::fromLatin1(prototype.constData()) + QLatin1String("));"); detail += QLatin1String("</pre>\n"); methodDetails << detail; if (typeInfo) typeInfo->Release(); typeInfo = 0; } stream << "</ul>" << endl; if (typeLib) typeLib->Release(); } const int propCount = mo->propertyCount(); if (propCount) { if (dispatch) dispatch->GetTypeInfo(0, LOCALE_SYSTEM_DEFAULT, &typeInfo); stream << "<h2>Properties:</h2>" << endl; stream << "<ul>" << endl; for (int iprop = 0; iprop < propCount; ++iprop) { const QMetaProperty prop = mo->property(iprop); QByteArray name(prop.name()); QByteArray type(prop.typeName()); stream << "<li>" << type << " <a href=\"#" << name << "\"><b>" << name << "</b></a>;</li>" << endl; QString detail = QLatin1String("<h3><a name=") + QString::fromLatin1(name.constData()) + QLatin1String("></a>") + QLatin1String(type.constData()) + QLatin1Char(' ') + QLatin1String(name.constData()) + QLatin1String("</h3>\n"); detail += docuFromName(typeInfo, QString::fromLatin1(name)); QVariant::Type vartype = QVariant::nameToType(type); if (!prop.isReadable()) continue; if (prop.isEnumType()) vartype = QVariant::Int; if (vartype != QVariant::Invalid) { detail += QLatin1String("<p>Read this property's value using QObject::property:<pre>\n"); if (prop.isEnumType()) detail += QLatin1String("\tint val = "); else detail += QLatin1Char('\t') + QLatin1String(type.constData()) + QLatin1String(" val = "); detail += QLatin1String("object->property(\"") + QLatin1String(name.constData()) + QLatin1String("\").") + QLatin1String(toType(type).constData()) + QLatin1String(";\n"); detail += QLatin1String("</pre>\n"); } else if (type == "IDispatch*" || type == "IUnknown*") { detail += QLatin1String("<p>Get the subobject using querySubObject:<pre>\n"); detail += QLatin1String("\tQAxObject *") + QLatin1String(name.constData()) + QLatin1String(" = object->querySubObject(\"") + QLatin1String(name.constData()) + QLatin1String("\");\n"); detail += QLatin1String("</pre>\n"); } else { detail += QLatin1String("<p>This property is of an unsupported type.\n"); } if (prop.isWritable()) { detail += QLatin1String("Set this property' value using QObject::setProperty:<pre>\n"); if (prop.isEnumType()) { detail += QLatin1String("\tint newValue = ... // string representation of values also supported\n"); } else { detail += QLatin1String("\t") + QString::fromLatin1(type.constData()) + QLatin1String(" newValue = ...\n"); } detail += QLatin1String("\tobject->setProperty(\"") + QString::fromLatin1(name) + QLatin1String("\", newValue);\n"); detail += QLatin1String("</pre>\n"); detail += QLatin1String("Or using the "); QByteArray setterSlot; if (isupper(name.at(0))) { setterSlot = "Set" + name; } else { QByteArray nameUp = name; nameUp[0] = toupper(nameUp.at(0)); setterSlot = "set" + nameUp; } detail += QLatin1String("<a href=\"#") + QString::fromLatin1(setterSlot) + QLatin1String("\">") + QString::fromLatin1(setterSlot.constData()) + QLatin1String("</a> slot.\n"); } if (prop.isEnumType()) { detail += QLatin1String("<p>See also <a href=\"#") + QString::fromLatin1(type) + QLatin1String("\">") + QString::fromLatin1(type) + QLatin1String("</a>.\n"); } propDetails << detail; } stream << "</ul>" << endl; } const int enumCount = mo->enumeratorCount(); if (enumCount) { stream << "<hr><h2>Member Type Documentation</h2>" << endl; for (int i = 0; i < enumCount; ++i) { const QMetaEnum enumdata = mo->enumerator(i); stream << "<h3><a name=" << enumdata.name() << "></a>" << enumdata.name() << "</h3>" << endl; stream << "<ul>" << endl; for (int e = 0; e < enumdata.keyCount(); ++e) { stream << "<li>" << enumdata.key(e) << "\t=" << enumdata.value(e) << "</li>" << endl; } stream << "</ul>" << endl; } } if (methodDetails.count()) { stream << "<hr><h2>Member Function Documentation</h2>" << endl; for (int i = 0; i < methodDetails.count(); ++i) stream << methodDetails.at(i) << endl; } if (propDetails.count()) { stream << "<hr><h2>Property Documentation</h2>" << endl; for (int i = 0; i < propDetails.count(); ++i) stream << propDetails.at(i) << endl; } if (typeInfo) typeInfo->Release(); if (dispatch) dispatch->Release(); return docu; }
/** * \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; }
void ChangeProperties::updateProperties() { bool hasControl = activex && !activex->isNull(); tabWidget->setEnabled(hasControl); listProperties->clear(); listEditRequests->clear(); if (hasControl) { const QMetaObject *mo = activex->metaObject(); const int numprops = mo->propertyCount(); for (int i = mo->propertyOffset(); i < numprops; ++i) { const QMetaProperty property = mo->property(i); QTreeWidgetItem *item = new QTreeWidgetItem(listProperties); item->setText(0, QString::fromLatin1(property.name())); item->setText(1, QString::fromLatin1(property.typeName())); if (!property.isDesignable()) { item->setTextColor(0, Qt::gray); item->setTextColor(1, Qt::gray); item->setTextColor(2, Qt::gray); } QVariant var = activex->property(property.name()); switch (var.type()) { case QVariant::Color: { QColor col = qvariant_cast<QColor>(var); item->setText(2, col.name()); } break; case QVariant::Font: { QFont fnt = qvariant_cast<QFont>(var); item->setText(2, fnt.toString()); } break; case QVariant::Bool: { item->setText(2, var.toBool() ? QLatin1String("true") : QLatin1String("false")); } break; case QVariant::Pixmap: { QPixmap pm = qvariant_cast<QPixmap>(var); item->setIcon(2, pm); } break; case QVariant::List: { QList<QVariant> varList = var.toList(); QStringList strList; for (int i = 0; i < varList.count(); ++i) { QVariant var = varList.at(i); strList << var.toString(); } item->setText(2, strList.join(QLatin1String(", "))); } break; case QVariant::Int: if (property.isEnumType()) { const QMetaEnum enumerator = mo->enumerator(mo->indexOfEnumerator(property.typeName())); item->setText(2, QString::fromLatin1(enumerator.valueToKey(var.toInt()))); break; } //FALLTHROUGH default: item->setText(2, var.toString()); break; } bool requesting = false; #if 0 { void *argv[] = { &requesting }; activex->qt_metacall(QMetaObject::Call(0x10000000) /*RequestingEdit*/, i, argv); } #endif if (requesting) { QTreeWidgetItem *check = new QTreeWidgetItem(listEditRequests); check->setText(0, QString::fromLatin1(property.name())); check->setCheckState(0, activex->propertyWritable(property.name()) ? Qt::Checked : Qt::Unchecked); } } listProperties->setCurrentItem(listProperties->topLevelItem(0)); } else { editValue->clear(); } }
void ObjectControllerPrivate::addClassProperties(const QMetaObject *metaObject) { if (!metaObject) return; addClassProperties(metaObject->superClass()); QtProperty *classProperty = m_classToProperty.value(metaObject); if (!classProperty) { QString className = QLatin1String(metaObject->className()); classProperty = m_manager->addProperty(QtVariantPropertyManager::groupTypeId(), className); m_classToProperty[metaObject] = classProperty; m_propertyToClass[classProperty] = metaObject; for (int idx = metaObject->propertyOffset(); idx < metaObject->propertyCount(); idx++) { QMetaProperty metaProperty = metaObject->property(idx); int type = metaProperty.userType(); QtVariantProperty *subProperty = 0; if (!metaProperty.isReadable()) { subProperty = m_readOnlyManager->addProperty(QVariant::String, QLatin1String(metaProperty.name())); subProperty->setValue(QLatin1String("< Non Readable >")); } else if (metaProperty.isEnumType()) { if (metaProperty.isFlagType()) { subProperty = m_manager->addProperty(QtVariantPropertyManager::flagTypeId(), QLatin1String(metaProperty.name())); QMetaEnum metaEnum = metaProperty.enumerator(); QMap<int, bool> valueMap; QStringList flagNames; for (int i = 0; i < metaEnum.keyCount(); i++) { int value = metaEnum.value(i); if (!valueMap.contains(value) && isPowerOf2(value)) { valueMap[value] = true; flagNames.append(QLatin1String(metaEnum.key(i))); } subProperty->setAttribute(QLatin1String("flagNames"), flagNames); subProperty->setValue(flagToInt(metaEnum, metaProperty.read(m_object).toInt())); } } else { subProperty = m_manager->addProperty(QtVariantPropertyManager::enumTypeId(), QLatin1String(metaProperty.name())); QMetaEnum metaEnum = metaProperty.enumerator(); QMap<int, bool> valueMap; // dont show multiple enum values which have the same values QStringList enumNames; for (int i = 0; i < metaEnum.keyCount(); i++) { int value = metaEnum.value(i); if (!valueMap.contains(value)) { valueMap[value] = true; enumNames.append(QLatin1String(metaEnum.key(i))); } } subProperty->setAttribute(QLatin1String("enumNames"), enumNames); subProperty->setValue(enumToInt(metaEnum, metaProperty.read(m_object).toInt())); } } else if (m_manager->isPropertyTypeSupported(type)) { if (!metaProperty.isWritable()) subProperty = m_readOnlyManager->addProperty(type, QLatin1String(metaProperty.name()) + QLatin1String(" (Non Writable)")); if (!metaProperty.isDesignable()) subProperty = m_readOnlyManager->addProperty(type, QLatin1String(metaProperty.name()) + QLatin1String(" (Non Designable)")); else subProperty = m_manager->addProperty(type, QLatin1String(metaProperty.name())); subProperty->setValue(metaProperty.read(m_object)); } else { subProperty = m_readOnlyManager->addProperty(QVariant::String, QLatin1String(metaProperty.name())); subProperty->setValue(QLatin1String("< Unknown Type >")); subProperty->setEnabled(false); } classProperty->addSubProperty(subProperty); m_propertyToIndex[subProperty] = idx; m_classToIndexToProperty[metaObject][idx] = subProperty; } } else { updateClassProperties(metaObject, false); } m_topLevelProperties.append(classProperty); m_browser->addProperty(classProperty); }
void ObjectControllerPrivate::addClassProperties(const QMetaObject *inmetaObject, bool subGroup) { if (!inmetaObject) return; // Collect a list of all sub classes in the object QList< const QMetaObject *> metaObjectsList; metaObjectsList.clear(); metaObjectsList << inmetaObject; const QMetaObject *tmpObj = inmetaObject->superClass(); metaObjectsList << tmpObj; while (tmpObj) { tmpObj = tmpObj->superClass(); if (tmpObj) metaObjectsList << tmpObj; } const QMetaObject *metaObject; for (int i = 0; i < metaObjectsList.count(); i++) { metaObject = metaObjectsList[i]; QtProperty *classProperty = m_classToProperty.value(metaObject); if (!classProperty) { QString className = QLatin1String(metaObject->className()); // Note: Skip class QObject from the property views if (className == QLatin1String("QObject")) return; // Process Class name into a user friendly view // Strip prefix C_ and process all _ to spaces QString prefix("C_"); // String to replace. QString replaceprefix(""); // Replacement string. className.replace(className.indexOf(prefix), prefix.size(), replaceprefix); className.replace(QString("_"), QString(" ")); classProperty = m_manager->addProperty(QtVariantPropertyManager::groupTypeId(), className); m_classToProperty[metaObject] = classProperty; m_propertyToClass[classProperty] = metaObject; for (int idx = metaObject->propertyOffset(); idx < metaObject->propertyCount(); idx++) { QMetaProperty metaProperty = metaObject->property(idx); int type = metaProperty.userType(); QtVariantProperty *subProperty = 0; // Note: Get the var member name and check if we want it to be writable (Enabled) QString memberVarName = QLatin1String(metaProperty.name()); bool b_SetEnabled = true; // Special case for enabling or disabling editing QString ememberVarName = "e" + QLatin1String(metaProperty.name()); QByteArray array = ememberVarName.toLocal8Bit(); char* buffer = array.data(); QVariant set = m_object->property(buffer); if (set.type() == QVariant::Bool) { b_SetEnabled = (bool &)set; } // qDebug() << "Member Name :" << memberVarName; // Note: process the first char if it contains _ then the var is read only and remove the _ char if (memberVarName.at(0) == "_") { b_SetEnabled = false; memberVarName.remove(0, 1); } // after that replace all occurance of _ with space char for display memberVarName.replace(QString("_"), QString(" ")); if (!metaProperty.isReadable()) { subProperty = m_readOnlyManager->addProperty(QVariant::String, memberVarName); subProperty->setValue(QLatin1String("< Non Readable >")); } else if (metaProperty.isEnumType()) { if (metaProperty.isFlagType()) { subProperty = m_manager->addProperty(QtVariantPropertyManager::flagTypeId(), memberVarName); QMetaEnum metaEnum = metaProperty.enumerator(); QMap<int, bool> valueMap; QStringList flagNames; for (int i = 0; i < metaEnum.keyCount(); i++) { int value = metaEnum.value(i); if (!valueMap.contains(value) && isPowerOf2(value)) { valueMap[value] = true; flagNames.append(QLatin1String(metaEnum.key(i))); } subProperty->setAttribute(QLatin1String("flagNames"), flagNames); subProperty->setValue(flagToInt(metaEnum, metaProperty.read(m_object).toInt())); } } else { subProperty = m_manager->addProperty(QtVariantPropertyManager::enumTypeId(), memberVarName); QMetaEnum metaEnum = metaProperty.enumerator(); QMap<int, bool> valueMap; // dont show multiple enum values which have the same values QStringList enumNames; for (int i = 0; i < metaEnum.keyCount(); i++) { int value = metaEnum.value(i); if (!valueMap.contains(value)) { valueMap[value] = true; enumNames.append(QLatin1String(metaEnum.key(i))); } } subProperty->setAttribute(QLatin1String("enumNames"), enumNames); subProperty->setValue(enumToInt(metaEnum, metaProperty.read(m_object).toInt())); } } else if (m_manager->isPropertyTypeSupported(type)) { if (!metaProperty.isWritable()) subProperty = m_readOnlyManager->addProperty(type, memberVarName + QLatin1String(" (Non Writable)")); if (!metaProperty.isDesignable()) subProperty = m_readOnlyManager->addProperty(type, memberVarName + QLatin1String(" (Non Designable)")); else subProperty = m_manager->addProperty(type, memberVarName); subProperty->setValue(metaProperty.read(m_object)); } else { subProperty = m_readOnlyManager->addProperty(QVariant::String, memberVarName); subProperty->setValue(QLatin1String("< Unknown Type >")); b_SetEnabled = false; } // Notes: QtVariantProperty *priority = variantManager->addProperty(QVariant::Int, "Priority"); if (subProperty) subProperty->setEnabled(b_SetEnabled); m_propertyToIndex[subProperty] = idx; m_classToIndexToProperty[metaObject][idx] = subProperty; if (subGroup) classProperty->addSubProperty(subProperty); else m_browser->addProperty(subProperty); } } else { updateClassProperties(metaObject, false); } m_topLevelProperties.append(classProperty); if (subGroup) m_browser->addProperty(classProperty); } // Loop i }
void QJnextMainLoop::introspect(QObject *object, QVariantList& args, QByteArray* retval) { const QMetaObject * meta = object->metaObject(); QVariantMap data; QVariantList properties; for (int i = 0; i < meta->propertyCount(); ++i) { QVariantMap propData; QMetaProperty prop = meta->property(i); propData["name"] = prop.name(); propData["type"] = prop.typeName(); if (!prop.isReadable()) { if (!prop.isWritable()) continue; propData["writeOnly"] = true; } if (!prop.isWritable()) propData["readOnly"] = true; if (prop.hasNotifySignal()) propData["notifySignal"] = getMethodName(prop.notifySignal()); if (prop.isEnumType()) propData["enumeration"] = true; properties.append(QVariant::fromValue(propData)); } data["properties"] = properties; QVariantList methods; QVariantList sigs; for (int i = 0; i < meta->methodCount(); ++i) { QVariantMap methodData; QMetaMethod method = meta->method(i); QByteArray name = getMethodName(method); if (method.access() == QMetaMethod::Private || name.startsWith("_") || name == "deleteLater" || name == "destroyed" || name == "creationCompleted") continue; else if (method.access() == QMetaMethod::Protected && method.methodType() != QMetaMethod::Signal) continue; methodData["name"] = name; QByteArray rType(method.typeName()); if (!rType.isEmpty()) methodData["type"] = rType; QList<QByteArray> pTypes = method.parameterTypes(); QList<QByteArray> pNames = method.parameterNames(); QVariantList params; for (int i = 0; i < pTypes.count(); ++i) { QVariantMap tp; tp["type"] = pTypes.at(i); tp["name"] = pNames.value(i); params.append(tp); } if (params.size() > 0) methodData["parameters"] = params; switch (method.methodType()) { case QMetaMethod::Method: //qDebug() << "=== METHOD ===" << methodData << method.signature(); methods.append(QVariant::fromValue(methodData)); break; case QMetaMethod::Signal: sigs.append(QVariant::fromValue(methodData)); break; case QMetaMethod::Constructor: methodData["constructor"] = true; methods.append(QVariant::fromValue(methodData)); break; case QMetaMethod::Slot: methods.append(QVariant::fromValue(methodData)); break; } } if (methods.size() > 0) data["methods"] = methods; if (sigs.size() > 0) data["signals"] = sigs; data["id"] = args.takeFirst(); bridge->json()->saveToBuffer(QVariant::fromValue(data), retval); #ifdef DEBUG_QJnextMainLoop qDebug() << "[QJnextMainLoop]\t[INTROSPECT]" << retval; #endif }
void QQmlValueTypeWrapper::put(Managed *m, String *name, const Value &value) { Q_ASSERT(m->as<QQmlValueTypeWrapper>()); ExecutionEngine *v4 = static_cast<QQmlValueTypeWrapper *>(m)->engine(); Scope scope(v4); if (scope.hasException()) return; Scoped<QQmlValueTypeWrapper> r(scope, static_cast<QQmlValueTypeWrapper *>(m)); Scoped<QQmlValueTypeReference> reference(scope, m->d()); int writeBackPropertyType = -1; if (reference) { QMetaProperty writebackProperty = reference->d()->object->metaObject()->property(reference->d()->property); if (!writebackProperty.isWritable() || !reference->readReferenceValue()) return; writeBackPropertyType = writebackProperty.userType(); } const QMetaObject *metaObject = r->d()->propertyCache->metaObject(); const QQmlPropertyData *pd = r->d()->propertyCache->property(name, 0, 0); if (!pd) return; QMetaProperty property = metaObject->property(pd->coreIndex); Q_ASSERT(property.isValid()); QQmlBinding *newBinding = 0; QV4::ScopedFunctionObject f(scope, value); if (reference && f) { if (!f->isBinding()) { // assigning a JS function to a non-var-property is not allowed. QString error = QStringLiteral("Cannot assign JavaScript function to value-type property"); ScopedString e(scope, v4->newString(error)); v4->throwError(e); return; } QQmlContextData *context = QmlContextWrapper::callingContext(v4); QQmlPropertyData cacheData; cacheData.setFlags(QQmlPropertyData::IsWritable | QQmlPropertyData::IsValueTypeVirtual); cacheData.propType = writeBackPropertyType; cacheData.coreIndex = reference->d()->property; cacheData.valueTypeFlags = 0; cacheData.valueTypeCoreIndex = pd->coreIndex; cacheData.valueTypePropType = property.userType(); QV4::Scoped<QQmlBindingFunction> bindingFunction(scope, (const Value &)f); bindingFunction->initBindingLocation(); newBinding = new QQmlBinding(value, reference->d()->object, context); newBinding->setTarget(reference->d()->object, cacheData, context); } if (reference) { QQmlAbstractBinding *oldBinding = QQmlPropertyPrivate::setBinding(reference->d()->object, reference->d()->property, pd->coreIndex, newBinding); if (oldBinding) oldBinding->destroy(); } if (newBinding) return; QVariant v = v4->toVariant(value, property.userType()); if (property.isEnumType() && (QMetaType::Type)v.type() == QMetaType::Double) v = v.toInt(); void *gadget = r->d()->gadgetPtr; property.writeOnGadget(gadget, v); if (reference) { if (writeBackPropertyType == QMetaType::QVariant) { QVariant variantReferenceValue = r->d()->toVariant(); int flags = 0; int status = -1; void *a[] = { &variantReferenceValue, 0, &status, &flags }; QMetaObject::metacall(reference->d()->object, QMetaObject::WriteProperty, reference->d()->property, a); } else { int flags = 0; int status = -1; void *a[] = { r->d()->gadgetPtr, 0, &status, &flags }; QMetaObject::metacall(reference->d()->object, QMetaObject::WriteProperty, reference->d()->property, a); } } }
bool Xsd::RenderXSD( HTTPRequest *pRequest, QObject *pClass ) { const QMetaObject *pMetaObject = pClass->metaObject(); QString sClassName = ConvertTypeToXSD( pMetaObject->className(), true); QDomElement oRoot = CreateSchemaRoot(); QMap<QString, TypeInfo> typesToInclude; // ------------------------------------------------------------------ // Create xs:complexType structure // ------------------------------------------------------------------ QDomElement oTypeNode = createElement( "xs:complexType" ); QDomElement oSeqNode = createElement( "xs:sequence" ); oTypeNode.setAttribute( "name", sClassName ); oTypeNode.appendChild( oSeqNode ); // -=>TODO: Add an xs:annotation node with class descriptions // ------------------------------------------------------------------ // Add all properties for this type // // <xs:element minOccurs="0" name="<propName>" type="<propType>"/> // <xs:element minOccurs="0" name="<childName>" nillable="true" // type="tns:<ChildType>"/> // ------------------------------------------------------------------ int nCount = pMetaObject->propertyCount(); for (int nIdx=0; nIdx < nCount; ++nIdx ) { QMetaProperty metaProperty = pMetaObject->property( nIdx ); if (metaProperty.isDesignable( pClass )) { const char *pszPropName = metaProperty.name(); QString sPropName( pszPropName ); if ( sPropName.compare( "objectName" ) == 0) continue; // ---------------------------------------------------------- // Create xs:element for this property // ---------------------------------------------------------- QDomElement oNode = createElement( "xs:element" ); QString sType = metaProperty.typeName(); bool bCustomType = false; QString sCustomAttr = "type"; QString sContentName = QString(); QString sContentType = QString(); // if this is a child object, sType will be QObject* // which we can't use, so we need to read the // properties value, and read it's metaObject data if (sType == "QObject*") { QVariant val = metaProperty.read( pClass ); const QObject *pObject = val.value< QObject* >(); sType = pObject->metaObject()->className(); bCustomType = true; } else if ((sType == "QVariantList" ) || (sType == "QVariantMap")) { sContentType = ReadPropertyMetadata( pClass, sPropName, "type" ); if (sContentType.at(0) == 'Q') sContentType = sContentType.mid( 1 ); sContentType.remove( "DTC::" ); sContentType.remove( QChar('*') ); if (sType == "QVariantMap") { sContentName = ReadPropertyMetadata( pClass, sPropName, "name" ); if (sContentName.isEmpty()) sContentName = sContentType; sType = "MapOfString" + sContentName; } else sType = "ArrayOf" + sContentType; bCustomType = true; } else if (sType == "QStringList") { sType = "ArrayOfString"; bCustomType = true; } else if (metaProperty.isEnumType() || metaProperty.isFlagType() ) { sCustomAttr = "enum"; sType = sClassName + "." + sType; bCustomType = true; } QString sNewPropName( metaProperty.name() ); if (IsNillable( sType )) oNode.setAttribute( "nillable" , true ); if (bCustomType) { TypeInfo info = { sCustomAttr, sContentType }; typesToInclude.insert( sType, info ); } oNode.setAttribute( "type" , (bCustomType ? "tns:" : "xs:") + ConvertTypeToXSD( sType, bCustomType )); oNode.setAttribute( "name" , sNewPropName ); oNode.setAttribute( "minOccurs", 0 ); oSeqNode.appendChild( oNode ); } } // ------------------------------------------------------------------ // Create element for class // // <xs:element name="<className>" nillable="true" type="tns:<className>"/> // ------------------------------------------------------------------ QDomElement oElementNode = createElement( "xs:element" ); oElementNode.setAttribute( "type" , "tns:" + sClassName ); oElementNode.setAttribute( "nillable", "true" ); oElementNode.setAttribute( "name" , sClassName ); // ---------------------------------------------------------------------- // Build xml tree... // ---------------------------------------------------------------------- appendChild( oRoot ); if (typesToInclude.count() > 0) { // ------------------------------------------------------------------ // Create all needed includes // // <xs:include schemaLocation="<path to dependant schema"/> // ------------------------------------------------------------------ QString sBaseUri = "http://" + pRequest->m_mapHeaders[ "host" ] + pRequest->m_sResourceUrl; QMap<QString, TypeInfo >::const_iterator it = typesToInclude.constBegin(); while( it != typesToInclude.constEnd()) { QDomElement oIncNode = createElement( "xs:include" ); QString sType = it.key(); sType.remove( "DTC::" ); TypeInfo info = it.value(); QString sValue = QString( "%1?%2=%3" ).arg( sBaseUri ) .arg( info.sAttrName ) .arg( sType ); if (!info.sContentType.isEmpty()) sValue += "&name=" + info.sContentType; oIncNode.setAttribute( "schemaLocation", sValue ); oRoot.appendChild( oIncNode ); ++it; } } oRoot.appendChild( oTypeNode ); oRoot.appendChild( oElementNode ); // ---------------------------------------------------------------------- // Return xsd doc to caller // ---------------------------------------------------------------------- QTextStream os( &(pRequest->m_response) ); pRequest->m_eResponseType = ResponseTypeXML; save( os, 0 ); return true; }
bool Component::deserialize(const QDomElement &componentElement) { m_ID = componentElement.attribute("id", "-1").toInt(); if (m_ID == -1 && m_parentObject) { m_ID = m_parentObject->getAvailableComponentID(); } else if (!m_parentObject) { m_ID = 0; } for (int i = 0; i<this->metaObject()->propertyCount(); i++) { QMetaProperty property = this->metaObject()->property(i); QString name = property.name(); QDomElement prop = componentElement.firstChildElement(name); if (prop.hasAttribute("type") && prop.hasAttribute("value")) { QVariant value; value.setValue(prop.attribute("value")); if (property.isEnumType()) { value.convert(QVariant::Int); property.write(this, value); } else if (value.convert((QVariant::Type)prop.attribute("type").toInt())) { property.write(this, value); } } else if (prop.hasAttribute("x") && prop.hasAttribute("y")) { QVariant value; QPointF point; point.setX(prop.attribute("x", "0").toDouble()); point.setY(prop.attribute("y", "0").toDouble()); value.setValue(point); property.write(this, value); } else if (prop.hasAttribute("type") && prop.hasAttribute("count")) { QVariant value; QStringList stringList; QDomElement child = prop.firstChildElement("listitem"); while (!child.isNull()) { stringList << child.attribute("value"); child = child.nextSiblingElement("listitem"); } value.setValue(stringList); property.write(this, value); } } // foreach (Property* prop, m_properties) // { // QDomElement propElem = componentElement.firstChildElement(prop->getName()); // if (!propElem.isNull()) // { // prop->deserialize(propElem); // } // } privateDeserialize(componentElement); return true; }