void tst_QMetaProperty::isFinal() { const QMetaObject *mo = metaObject(); QMetaProperty prop = mo->property(mo->indexOfProperty("value10")); QVERIFY(prop.isValid()); QVERIFY(prop.isFinal()); prop = mo->property(mo->indexOfProperty("value9")); QVERIFY(prop.isValid()); QVERIFY(!prop.isFinal()); }
QVariant ObjectStaticPropertyModel::data(const QModelIndex &index, int role) const { if (!index.isValid() || !m_obj || index.row() < 0 || index.row() >= m_obj.data()->metaObject()->propertyCount()) { return QVariant(); } const QMetaProperty prop = m_obj.data()->metaObject()->property(index.row()); if (role == Qt::DisplayRole) { if (index.column() == 0) { return prop.name(); } else if (index.column() == 1) { // QMetaProperty::read sets QVariant::typeName to int for enums, // so we need to handle that separately here const QVariant value = prop.read(m_obj.data()); const QString enumStr = Util::enumToString(value, prop.typeName(), m_obj.data()); if (!enumStr.isEmpty()) { return enumStr; } return VariantHandler::displayString(value); } else if (index.column() == 2) { return prop.typeName(); } else if (index.column() == 3) { const QMetaObject *mo = m_obj.data()->metaObject(); while (mo->propertyOffset() > index.row()) { mo = mo->superClass(); } return mo->className(); } } else if (role == Qt::DecorationRole) { if (index.column() == 1) { return VariantHandler::decoration(prop.read(m_obj.data())); } } else if (role == Qt::EditRole) { if (index.column() == 1) { return prop.read(m_obj.data()); } } else if (role == Qt::ToolTipRole) { const QString toolTip = tr("Constant: %1\nDesignable: %2\nFinal: %3\nResetable: %4\n" "Has notification: %5\nScriptable: %6\nStored: %7\nUser: %8\nWritable: %9"). arg(translateBool(prop.isConstant())). arg(translateBool(prop.isDesignable(m_obj.data()))). arg(translateBool(prop.isFinal())). arg(translateBool(prop.isResettable())). arg(translateBool(prop.hasNotifySignal())). arg(translateBool(prop.isScriptable(m_obj.data()))). arg(translateBool(prop.isStored(m_obj.data()))). arg(translateBool(prop.isUser(m_obj.data()))). arg(translateBool(prop.isWritable())); return toolTip; } return QVariant(); }
QVariant ObjectStaticPropertyModel::data(const QModelIndex &index, int role) const { if (!index.isValid() || !m_obj || index.row() < 0 || index.row() >= m_obj.data()->metaObject()->propertyCount()) { return QVariant(); } const QMetaProperty prop = m_obj.data()->metaObject()->property(index.row()); if (role == Qt::DisplayRole) { if (index.column() == 0) { return prop.name(); } else if (index.column() == 1) { return Util::variantToString(prop.read(m_obj.data())); } else if (index.column() == 2) { return prop.typeName(); } else if (index.column() == 3) { const QMetaObject *mo = m_obj.data()->metaObject(); while (mo->propertyOffset() > index.row()) { mo = mo->superClass(); } return mo->className(); } } else if (role == Qt::EditRole) { if (index.column() == 1) { return prop.read(m_obj.data()); } } else if (role == Qt::ToolTipRole) { const QString toolTip = tr("Constant: %1\nDesignable: %2\nFinal: %3\nResetable: %4\n" "Has notification: %5\nScriptable: %6\nStored: %7\nUser: %8\nWritable: %9"). arg(translateBool(prop.isConstant())). arg(translateBool(prop.isDesignable(m_obj.data()))). arg(translateBool(prop.isFinal())). arg(translateBool(prop.isResettable())). arg(translateBool(prop.hasNotifySignal())). arg(translateBool(prop.isScriptable(m_obj.data()))). arg(translateBool(prop.isStored(m_obj.data()))). arg(translateBool(prop.isUser(m_obj.data()))). arg(translateBool(prop.isWritable())); return toolTip; } return QVariant(); }
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; }
QString ObjectStaticPropertyModel::detailString(const QMetaProperty& prop) const { QStringList s; s << tr("Constant: %1").arg(translateBool(prop.isConstant())); s << tr("Designable: %1").arg(translateBool(prop.isDesignable(m_obj.data()))); s << tr("Final: %1").arg(translateBool(prop.isFinal())); if (prop.hasNotifySignal()) { s << tr("Notification: %1").arg(Util::prettyMethodSignature(prop.notifySignal())); } else { s << tr("Notification: no"); } s << tr("Resetable: %1").arg(translateBool(prop.isResettable())); #if QT_VERSION >= QT_VERSION_CHECK(5, 1, 0) s << tr("Revision: %1").arg(prop.revision()); #endif s << tr("Scriptable: %1").arg(translateBool(prop.isScriptable(m_obj.data()))); s << tr("Stored: %1").arg(translateBool(prop.isStored(m_obj.data()))); s << tr("User: %1").arg(translateBool(prop.isUser(m_obj.data()))); s << tr("Writable: %1").arg(translateBool(prop.isWritable())); return s.join("\n"); }
QString QMetaPropertyAdaptor::detailString(const QMetaProperty &prop) const { QObject *obj = object().qtObject(); QStringList s; s << tr("Constant: %1").arg(translateBool(prop.isConstant())); s << tr("Designable: %1").arg(translateBool(prop.isDesignable(obj))); s << tr("Final: %1").arg(translateBool(prop.isFinal())); if (prop.hasNotifySignal()) s << tr("Notification: %1").arg(Util::prettyMethodSignature(prop.notifySignal())); else s << tr("Notification: no"); s << tr("Resetable: %1").arg(translateBool(prop.isResettable())); #if QT_VERSION >= QT_VERSION_CHECK(5, 1, 0) s << tr("Revision: %1").arg(prop.revision()); #endif s << tr("Scriptable: %1").arg(translateBool(prop.isScriptable(obj))); s << tr("Stored: %1").arg(translateBool(prop.isStored(obj))); s << tr("User: %1").arg(translateBool(prop.isUser(obj))); s << tr("Writable: %1").arg(translateBool(prop.isWritable())); return s.join(QStringLiteral("\n")); }
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; }