summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/src/properties.qdoc5
-rw-r--r--doc/src/snippets/code/doc_src_properties.qdoc3
-rw-r--r--src/corelib/kernel/qmetaobject.cpp17
-rw-r--r--src/corelib/kernel/qmetaobject.h1
-rw-r--r--src/tools/moc/generator.cpp5
-rw-r--r--src/tools/moc/moc.cpp3
-rw-r--r--src/tools/moc/moc.h3
-rw-r--r--tests/auto/qmetaobject/tst_qmetaobject.cpp17
8 files changed, 50 insertions, 4 deletions
diff --git a/doc/src/properties.qdoc b/doc/src/properties.qdoc
index cac5016..2d03e91 100644
--- a/doc/src/properties.qdoc
+++ b/doc/src/properties.qdoc
@@ -128,6 +128,11 @@
constant value may be different for different instances of the object. A
constant property cannot have a WRTE method or a NOTIFY signal.
+ \o The presence of the \c FINAL attribute indicates that the property
+ will not be overridden by a derived class. This can be used for performance
+ optimizations in some cases, but is not enforced by moc. Care must be taken
+ never to override a \c FINAL property.
+
\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 64e5377..3c9109f 100644
--- a/doc/src/snippets/code/doc_src_properties.qdoc
+++ b/doc/src/snippets/code/doc_src_properties.qdoc
@@ -8,7 +8,8 @@ Q_PROPERTY(type name
[SCRIPTABLE bool]
[STORED bool]
[USER bool]
- [CONSTANT])
+ [CONSTANT]
+ [FINAL])
//! [0]
diff --git a/src/corelib/kernel/qmetaobject.cpp b/src/corelib/kernel/qmetaobject.cpp
index fee2da9..3b09061 100644
--- a/src/corelib/kernel/qmetaobject.cpp
+++ b/src/corelib/kernel/qmetaobject.cpp
@@ -161,7 +161,8 @@ enum PropertyFlags {
ResolveUser = 0x00200000,
Notify = 0x00400000,
Dynamic = 0x00800000,
- Constant = 0x00000400
+ Constant = 0x00000400,
+ Final = 0x00000800
};
enum MethodFlags {
@@ -2466,6 +2467,20 @@ bool QMetaProperty::isConstant() const
}
/*!
+ Returns true if the property is final; otherwise returns false.
+
+ A property is final if the \c{Q_PROPERTY()}'s \c FINAL attribute
+ is set.
+*/
+bool QMetaProperty::isFinal() const
+{
+ if (!mobj)
+ return false;
+ int flags = mobj->d.data[handle + 2];
+ return flags & Final;
+}
+
+/*!
\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 73b52a9..bd47582 100644
--- a/src/corelib/kernel/qmetaobject.h
+++ b/src/corelib/kernel/qmetaobject.h
@@ -189,6 +189,7 @@ public:
bool isUser(const QObject *obj = 0) const;
bool isDynamic() const;
bool isConstant() const;
+ bool isFinal() const;
bool isFlagType() const;
bool isEnumType() const;
diff --git a/src/tools/moc/generator.cpp b/src/tools/moc/generator.cpp
index e4086e6..fbc434d 100644
--- a/src/tools/moc/generator.cpp
+++ b/src/tools/moc/generator.cpp
@@ -68,7 +68,8 @@ enum PropertyFlags {
ResolveUser = 0x00200000,
Notify = 0x00400000,
Dynamic = 0x00800000,
- Constant = 0x00000400
+ Constant = 0x00000400,
+ Final = 0x00000800
};
enum MethodFlags {
AccessPrivate = 0x00,
@@ -601,6 +602,8 @@ void Generator::generateProperties()
if (p.constant)
flags |= Constant;
+ if (p.final)
+ flags |= Final;
fprintf(out, " %4d, %4d, ",
strreg(p.name),
diff --git a/src/tools/moc/moc.cpp b/src/tools/moc/moc.cpp
index 66012ca..aa11d0e 100644
--- a/src/tools/moc/moc.cpp
+++ b/src/tools/moc/moc.cpp
@@ -912,6 +912,9 @@ void Moc::parseProperty(ClassDef *def)
if (l[0] == 'C' && l == "CONSTANT") {
propDef.constant = true;
continue;
+ } else if(l[0] == 'F' && l == "FINAL") {
+ propDef.final = true;
+ continue;
}
QByteArray v, v2;
diff --git a/src/tools/moc/moc.h b/src/tools/moc/moc.h
index 494d53e..767f84e 100644
--- a/src/tools/moc/moc.h
+++ b/src/tools/moc/moc.h
@@ -115,10 +115,11 @@ struct FunctionDef
struct PropertyDef
{
- PropertyDef():notifyId(-1), constant(false), gspec(ValueSpec){}
+ PropertyDef():notifyId(-1), constant(false), final(false), gspec(ValueSpec){}
QByteArray name, type, read, write, reset, designable, scriptable, editable, stored, user, notify;
int notifyId;
bool constant;
+ bool final;
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 f4cff2b..ac2858c 100644
--- a/tests/auto/qmetaobject/tst_qmetaobject.cpp
+++ b/tests/auto/qmetaobject/tst_qmetaobject.cpp
@@ -109,6 +109,7 @@ class tst_QMetaObject : public QObject
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)
+ Q_PROPERTY(int value10 READ value10 FINAL)
public:
enum EnumType { EnumType1 };
@@ -140,6 +141,8 @@ public:
int value9() const { return 1; }
+ int value10() const { return 1; }
+
QList<QVariant> value4;
QVariantList value5;
@@ -163,6 +166,7 @@ private slots:
void checkScope();
void propertyNotify();
void propertyConstant();
+ void propertyFinal();
void stdSet();
void classInfo();
@@ -802,6 +806,19 @@ void tst_QMetaObject::propertyConstant()
QVERIFY(prop.isConstant());
}
+void tst_QMetaObject::propertyFinal()
+{
+ 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());
+}
+
class ClassInfoTestObjectA : public QObject
{
Q_OBJECT