void QDBusAdaptorConnector::addAdaptor(QDBusAbstractAdaptor *adaptor) { // find the interface name const QMetaObject *mo = adaptor->metaObject(); int ciid = mo->indexOfClassInfo(QCLASSINFO_DBUS_INTERFACE); if (ciid != -1) { QMetaClassInfo mci = mo->classInfo(ciid); if (*mci.value()) { // find out if this interface exists first const char *interface = mci.value(); AdaptorMap::Iterator it = qLowerBound(adaptors.begin(), adaptors.end(), QByteArray(interface)); if (it != adaptors.end() && qstrcmp(interface, it->interface) == 0) { // exists. Replace it (though it's probably the same) if (it->adaptor != adaptor) { // reconnect the signals disconnectAllSignals(it->adaptor); connectAllSignals(adaptor); } it->adaptor = adaptor; } else { // create a new one AdaptorData entry; entry.interface = interface; entry.adaptor = adaptor; adaptors << entry; // connect the adaptor's signals to our relaySlot slot connectAllSignals(adaptor); } } } }
QMetaMethod QQmlMetaType::defaultMethod(const QMetaObject *metaObject) { int idx = metaObject->indexOfClassInfo("DefaultMethod"); if (-1 == idx) return QMetaMethod(); QMetaClassInfo info = metaObject->classInfo(idx); if (!info.value()) return QMetaMethod(); idx = metaObject->indexOfMethod(info.value()); if (-1 == idx) return QMetaMethod(); return metaObject->method(idx); }
QMetaProperty QQmlMetaType::defaultProperty(const QMetaObject *metaObject) { int idx = metaObject->indexOfClassInfo("DefaultProperty"); if (-1 == idx) return QMetaProperty(); QMetaClassInfo info = metaObject->classInfo(idx); if (!info.value()) return QMetaProperty(); idx = metaObject->indexOfProperty(info.value()); if (-1 == idx) return QMetaProperty(); return metaObject->property(idx); }
const char *defaultPropertyName(QObject *obj) { const QMetaObject *metaObject = obj->metaObject(); int idx = metaObject->indexOfClassInfo("DefaultProperty"); if (-1 == idx) return 0; QMetaClassInfo info = metaObject->classInfo(idx); return info.value(); }
void MetaInfoPrivate::parseClassInfo(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 index = qMetaObject->classInfoCount() - 1 ; index >= 0 ; --index) { QMetaClassInfo classInfo = qMetaObject->classInfo(index); if (QLatin1String(classInfo.name()) == QLatin1String("DefaultProperty")) { nodeMetaInfo.setDefaultProperty(classInfo.value()); return; } } }
QVariant ObjectClassInfoModel::metaData(const QModelIndex &index, const QMetaClassInfo &classInfo, int role) const { if (role == Qt::DisplayRole) { if (index.column() == 0) { return classInfo.name(); } if (index.column() == 1) { return classInfo.value(); } } return QVariant(); }
QString qax_clean_type(const QString &type, const QMetaObject *mo) { if (mo) { int classInfoIdx = mo->indexOfClassInfo("CoClassAlias"); if (classInfoIdx != -1) { const QMetaClassInfo classInfo = mo->classInfo(classInfoIdx); return QLatin1String(classInfo.value()); } } QString alias(type); alias.remove(QLatin1String("::")); return alias; }
void ControlInfo::setControl(QWidget *activex) { listInfo->clear(); const QMetaObject *mo = activex->metaObject(); QTreeWidgetItem *group = new QTreeWidgetItem(listInfo); group->setText(0, tr("Class Info")); group->setText(1, QString::number(mo->classInfoCount())); QTreeWidgetItem *item = 0; int i; int count; for (i = mo->classInfoOffset(); i < mo->classInfoCount(); ++i) { const QMetaClassInfo info = mo->classInfo(i); item = new QTreeWidgetItem(group); item->setText(0, QString::fromLatin1(info.name())); item->setText(1, QString::fromLatin1(info.value())); } group = new QTreeWidgetItem(listInfo); group->setText(0, tr("Signals")); count = 0; for (i = mo->methodOffset(); i < mo->methodCount(); ++i) { const QMetaMethod method = mo->method(i); if (method.methodType() == QMetaMethod::Signal) { ++count; item = new QTreeWidgetItem(group); item->setText(0, QString::fromLatin1(method.signature())); } } group->setText(1, QString::number(count)); group = new QTreeWidgetItem(listInfo); group->setText(0, tr("Slots")); count = 0; for (i = mo->methodOffset(); i < mo->methodCount(); ++i) { const QMetaMethod method = mo->method(i); if (method.methodType() == QMetaMethod::Slot) { ++count; item = new QTreeWidgetItem(group); item->setText(0, QString::fromLatin1(method.signature())); } } group->setText(1, QString::number(count)); group = new QTreeWidgetItem(listInfo); group->setText(0, tr("Properties")); count = 0; for (i = mo->propertyOffset(); i < mo->propertyCount(); ++i) { ++count; const QMetaProperty property = mo->property(i); item = new QTreeWidgetItem(group); 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); } } group->setText(1, QString::number(count)); }
// Component type is the one passed inside QML (registered name) MetaComponent * MetaComponent::create(const QString &componentType, QObject *parent) { // 1. Try to get the C++ metatype registered from the QML name // Right now, we run through all registered QML modules, and get the correct one. // If several are found, we break. Not the nicest, but we can do something better later. QList<QQmlType *> types = QQmlMetaType::qmlTypes(); QList<QByteArray> found; foreach (const QQmlType *type, types) { if (type->elementName() == componentType) { found.append(type->typeName()); } } if (found.isEmpty()) { qWarning() << "No QML component were registered with name" << componentType; return 0; } if (found.count() > 1) { qWarning() << "Several QML components were registered with name" << componentType; return 0; } QByteArray cppTypeByteArray = found.first(); cppTypeByteArray.append("*"); const char *cppType = QMetaObject::normalizedType(cppTypeByteArray).constData(); // 2. Try to get the Phonebot MetaData int componentTypeIndex = QMetaType::type(cppType); if (componentTypeIndex == QMetaType::UnknownType) { qWarning() << "Cannot get Phonebot metadata from" << componentType << ":" << "Cannot find Qt metatype for" << cppType << "It might not be registered via qmlRegisterType."; return 0; } const QMetaObject *componentMeta = QMetaType::metaObjectForType(componentTypeIndex); int metaClassInfoIndex = componentMeta->indexOfClassInfo("meta"); if (metaClassInfoIndex == -1) { qWarning() << "Cannot get Phonebot metadata from" << componentType << ":" << cppType << "don't have a Phonebot metatype." << "Did you forgot PHONEBOT_METADATA macro ?"; return 0; } QMetaClassInfo metaClassInfo = componentMeta->classInfo(metaClassInfoIndex); QByteArray metaNameByteArray (metaClassInfo.value()); metaNameByteArray.append("*"); const char *metaName = QMetaObject::normalizedType(metaNameByteArray).constData(); int metaTypeIndex = QMetaType::type(metaName); if (metaTypeIndex == QMetaType::UnknownType) { qWarning() << "Cannot get Phonebot metadata from" << componentType << ":" << "Cannot find Qt metatype for Phonebot metatype" << metaName << "It might not be registered via qDeclareMetaType."; return 0; } // Check if it inherits from AbstractMetaData bool ok = false; const QMetaObject *componentMetaMeta = QMetaType::metaObjectForType(metaTypeIndex); const QMetaObject *super = componentMetaMeta; while (super) { if (!ok) { ok = (super->className() == AbstractMetaData::staticMetaObject.className()); } super = super->superClass(); } if (!ok) { qWarning() << "Cannot get Phonebot metadata from" << componentType << ":" << "Phonebot metatype class" << metaName << "don't inherit from" << AbstractMetaData::staticMetaObject.className(); return 0; } // Construct QObject *meta = componentMetaMeta->newInstance(); if (!meta) { qWarning() << "Cannot get Phonebot metadata from" << componentType << ":" << "Phonebot metatype class " << metaName << "don't have an invokable constructor and cannot be created."; return 0; } AbstractMetaData *castedMeta = qobject_cast<AbstractMetaData *>(meta); Q_ASSERT(castedMeta); QSet<QString> properties; for (int i = componentMeta->propertyOffset(); i < componentMeta->propertyCount(); ++i) { properties.insert(componentMeta->property(i).name()); } QStringList removedProperties; foreach (const QString &property, properties) { if (!castedMeta->property(property)) { qWarning() << property << "do not have metadata registered"; } } foreach (const QString &property, removedProperties) { properties.remove(property); }
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; }
static void clone(QMetaObjectBuilder &builder, const QMetaObject *mo, const QMetaObject *ignoreStart, const QMetaObject *ignoreEnd) { // Set classname builder.setClassName(ignoreEnd->className()); // Clone Q_CLASSINFO for (int ii = mo->classInfoOffset(); ii < mo->classInfoCount(); ++ii) { QMetaClassInfo info = mo->classInfo(ii); int otherIndex = ignoreEnd->indexOfClassInfo(info.name()); if (otherIndex >= ignoreStart->classInfoOffset() + ignoreStart->classInfoCount()) { // Skip } else { builder.addClassInfo(info.name(), info.value()); } } // Clone Q_PROPERTY for (int ii = mo->propertyOffset(); ii < mo->propertyCount(); ++ii) { QMetaProperty property = mo->property(ii); int otherIndex = ignoreEnd->indexOfProperty(property.name()); if (otherIndex >= ignoreStart->propertyOffset() + ignoreStart->propertyCount()) { builder.addProperty(QByteArray("__qml_ignore__") + property.name(), QByteArray("void")); // Skip } else { builder.addProperty(property); } } // Clone Q_METHODS for (int ii = mo->methodOffset(); ii < mo->methodCount(); ++ii) { QMetaMethod method = mo->method(ii); // More complex - need to search name QByteArray name = method.name(); bool found = false; for (int ii = ignoreStart->methodOffset() + ignoreStart->methodCount(); !found && ii < ignoreEnd->methodOffset() + ignoreEnd->methodCount(); ++ii) { QMetaMethod other = ignoreEnd->method(ii); found = name == other.name(); } QMetaMethodBuilder m = builder.addMethod(method); if (found) // SKIP m.setAccess(QMetaMethod::Private); } // Clone Q_ENUMS for (int ii = mo->enumeratorOffset(); ii < mo->enumeratorCount(); ++ii) { QMetaEnum enumerator = mo->enumerator(ii); int otherIndex = ignoreEnd->indexOfEnumerator(enumerator.name()); if (otherIndex >= ignoreStart->enumeratorOffset() + ignoreStart->enumeratorCount()) { // Skip } else { builder.addEnumerator(enumerator); } } }