From 29202f033c87b5efe305e606805a26c59886875b Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Wed, 29 Jul 2009 18:13:24 +1000 Subject: Add CONSTANT attribute to Q_PROPERTY() This will be used by the declarative module to determine if a property lacking a NOTIFY signal is truly constant, or just missing a NOTIFY signal. Reviewed-by: Roberto Raggi --- doc/src/properties.qdoc | 6 ++++++ doc/src/snippets/code/doc_src_properties.qdoc | 3 ++- src/corelib/kernel/qmetaobject.cpp | 29 ++++++++++++++++++++++++++- src/corelib/kernel/qmetaobject.h | 2 ++ src/tools/moc/generator.cpp | 7 ++++++- src/tools/moc/moc.cpp | 23 +++++++++++++++++++++ src/tools/moc/moc.h | 3 ++- tests/auto/qmetaobject/tst_qmetaobject.cpp | 17 ++++++++++++++++ 8 files changed, 86 insertions(+), 4 deletions(-) diff --git a/doc/src/properties.qdoc b/doc/src/properties.qdoc index 5490dd0..cac5016 100644 --- a/doc/src/properties.qdoc +++ b/doc/src/properties.qdoc @@ -122,6 +122,12 @@ editable property for (checkable) buttons. Note that QItemDelegate gets and sets a widget's \c USER property. + \o The presence of the \c CONSTANT attibute indicates that the property + value is constant. For a given object instance, the READ method of a + constant property must return the same value every time it is called. This + constant value may be different for different instances of the object. A + constant property cannot have a WRTE method or a NOTIFY signal. + \endlist The \c READ, \c WRITE, and \c RESET functions can be inherited. diff --git a/doc/src/snippets/code/doc_src_properties.qdoc b/doc/src/snippets/code/doc_src_properties.qdoc index 377cc9c..64e5377 100644 --- a/doc/src/snippets/code/doc_src_properties.qdoc +++ b/doc/src/snippets/code/doc_src_properties.qdoc @@ -7,7 +7,8 @@ Q_PROPERTY(type name [DESIGNABLE bool] [SCRIPTABLE bool] [STORED bool] - [USER bool]) + [USER bool] + [CONSTANT]) //! [0] diff --git a/src/corelib/kernel/qmetaobject.cpp b/src/corelib/kernel/qmetaobject.cpp index 08cecaf..fee2da9 100644 --- a/src/corelib/kernel/qmetaobject.cpp +++ b/src/corelib/kernel/qmetaobject.cpp @@ -159,7 +159,9 @@ enum PropertyFlags { ResolveEditable = 0x00080000, User = 0x00100000, ResolveUser = 0x00200000, - Notify = 0x00400000 + Notify = 0x00400000, + Dynamic = 0x00800000, + Constant = 0x00000400 }; enum MethodFlags { @@ -2439,6 +2441,31 @@ bool QMetaProperty::isUser(const QObject *object) const } /*! + \internal +*/ +bool QMetaProperty::isDynamic() const +{ + if (!mobj) + return false; + int flags = mobj->d.data[handle + 2]; + return flags & Dynamic; +} + +/*! + Returns true if the property is constant; otherwise returns false. + + A property is constant if the \c{Q_PROPERTY()}'s \c CONSTANT attribute + is set. +*/ +bool QMetaProperty::isConstant() const +{ + if (!mobj) + return false; + int flags = mobj->d.data[handle + 2]; + return flags & Constant; +} + +/*! \obsolete Returns true if the property is editable for the given \a object; diff --git a/src/corelib/kernel/qmetaobject.h b/src/corelib/kernel/qmetaobject.h index 000ba6e..73b52a9 100644 --- a/src/corelib/kernel/qmetaobject.h +++ b/src/corelib/kernel/qmetaobject.h @@ -187,6 +187,8 @@ public: bool isStored(const QObject *obj = 0) const; bool isEditable(const QObject *obj = 0) const; bool isUser(const QObject *obj = 0) const; + bool isDynamic() const; + bool isConstant() const; bool isFlagType() const; bool isEnumType() const; diff --git a/src/tools/moc/generator.cpp b/src/tools/moc/generator.cpp index b872dfd..e4086e6 100644 --- a/src/tools/moc/generator.cpp +++ b/src/tools/moc/generator.cpp @@ -66,7 +66,9 @@ enum PropertyFlags { ResolveEditable = 0x00080000, User = 0x00100000, ResolveUser = 0x00200000, - Notify = 0x00400000 + Notify = 0x00400000, + Dynamic = 0x00800000, + Constant = 0x00000400 }; enum MethodFlags { AccessPrivate = 0x00, @@ -597,6 +599,9 @@ void Generator::generateProperties() if (p.notifyId != -1) flags |= Notify; + if (p.constant) + flags |= Constant; + fprintf(out, " %4d, %4d, ", strreg(p.name), strreg(p.type)); diff --git a/src/tools/moc/moc.cpp b/src/tools/moc/moc.cpp index 797595f..66012ca 100644 --- a/src/tools/moc/moc.cpp +++ b/src/tools/moc/moc.cpp @@ -908,6 +908,12 @@ void Moc::parseProperty(ClassDef *def) propDef.name = lexem(); while (test(IDENTIFIER)) { QByteArray l = lexem(); + + if (l[0] == 'C' && l == "CONSTANT") { + propDef.constant = true; + continue; + } + QByteArray v, v2; if (test(LPAREN)) { v = lexemUntil(RPAREN); @@ -963,6 +969,23 @@ void Moc::parseProperty(ClassDef *def) msg += " has no READ accessor function. The property will be invalid."; warning(msg.constData()); } + if (propDef.constant && !propDef.write.isNull()) { + QByteArray msg; + msg += "Property declaration "; + msg += propDef.name; + msg += " is both WRITEable and CONSTANT. CONSTANT will be ignored."; + propDef.constant = false; + warning(msg.constData()); + } + if (propDef.constant && !propDef.notify.isNull()) { + QByteArray msg; + msg += "Property declaration "; + msg += propDef.name; + msg += " is both NOTIFYable and CONSTANT. CONSTANT will be ignored."; + propDef.constant = false; + warning(msg.constData()); + } + if(!propDef.notify.isEmpty()) def->notifyableProperties++; diff --git a/src/tools/moc/moc.h b/src/tools/moc/moc.h index 9fa9ac2..494d53e 100644 --- a/src/tools/moc/moc.h +++ b/src/tools/moc/moc.h @@ -115,9 +115,10 @@ struct FunctionDef struct PropertyDef { - PropertyDef():notifyId(-1), gspec(ValueSpec){} + PropertyDef():notifyId(-1), constant(false), gspec(ValueSpec){} QByteArray name, type, read, write, reset, designable, scriptable, editable, stored, user, notify; int notifyId; + bool constant; enum Specification { ValueSpec, ReferenceSpec, PointerSpec }; Specification gspec; bool stdCppSet() const { diff --git a/tests/auto/qmetaobject/tst_qmetaobject.cpp b/tests/auto/qmetaobject/tst_qmetaobject.cpp index dea0ffb..f4cff2b 100644 --- a/tests/auto/qmetaobject/tst_qmetaobject.cpp +++ b/tests/auto/qmetaobject/tst_qmetaobject.cpp @@ -108,6 +108,7 @@ class tst_QMetaObject : public QObject Q_PROPERTY(int value6 READ value6 NOTIFY value6Changed) Q_PROPERTY(MyStruct value7 READ value7 WRITE setVal7 NOTIFY value7Changed) Q_PROPERTY(int value8 READ value8 NOTIFY value8Changed) + Q_PROPERTY(int value9 READ value9 CONSTANT) public: enum EnumType { EnumType1 }; @@ -137,6 +138,8 @@ public: int value8() const { return 1; } + int value9() const { return 1; } + QList value4; QVariantList value5; @@ -159,6 +162,7 @@ private slots: void customPropertyType(); void checkScope(); void propertyNotify(); + void propertyConstant(); void stdSet(); void classInfo(); @@ -785,6 +789,19 @@ void tst_QMetaObject::propertyNotify() QCOMPARE(signal.signature(), (const char *)0); } +void tst_QMetaObject::propertyConstant() +{ + const QMetaObject *mo = metaObject(); + + QMetaProperty prop = mo->property(mo->indexOfProperty("value8")); + QVERIFY(prop.isValid()); + QVERIFY(!prop.isConstant()); + + prop = mo->property(mo->indexOfProperty("value9")); + QVERIFY(prop.isValid()); + QVERIFY(prop.isConstant()); +} + class ClassInfoTestObjectA : public QObject { Q_OBJECT -- cgit v0.12