Qt6: remove support for property flags being functions

Property flags should be compile time booleans, not something to
be determined at runtime.

We've been using this to dynamically disable some properties in QWidget
based classes dependent on the state of a different property, but this
should better get implemented on top of our widgets.

Change-Id: I6296e8761303ecdf24d9e842142e8596304c015d
Reviewed-by: Simon Hausmann <hausmann@gmail.com>
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io>
This commit is contained in:
Lars Knoll 2019-05-02 14:50:31 +02:00 committed by Fabian Kosmale
parent 679492ecc6
commit 5603be705e
9 changed files with 30 additions and 212 deletions

View File

@ -110,13 +110,11 @@
\li The \c DESIGNABLE attribute indicates whether the property
should be visible in the property editor of GUI design tool (e.g.,
\l {Qt Designer Manual}{Qt Designer}). Most properties are \c DESIGNABLE
(default true). Instead of true or false, you can specify a boolean
member function.
(default true). Valid values are true and false.
\li The \c SCRIPTABLE attribute indicates whether this property
should be accessible by a scripting engine (default true).
Instead of true or false, you can specify a boolean member
function.
Valid values are true and false.
\li The \c STORED attribute indicates whether the property should
be thought of as existing on its own or as depending on other

View File

@ -133,11 +133,6 @@ QT_BEGIN_NAMESPACE
\value ReadProperty
\value WriteProperty
\value ResetProperty
\value QueryPropertyDesignable
\value QueryPropertyScriptable
\value QueryPropertyStored
\value QueryPropertyEditable
\value QueryPropertyUser
\value CreateInstance
*/
@ -3401,82 +3396,67 @@ bool QMetaProperty::isWritable() const
/*!
Returns \c true if this property is designable for the given \a object;
Returns \c true if this property is designable;
otherwise returns \c false.
If no \a object is given, the function returns \c false if the
\c{Q_PROPERTY()}'s \c DESIGNABLE attribute is false; otherwise
returns \c true (if the attribute is true or is a function or expression).
returns \c true.
\sa isScriptable(), isStored()
*/
bool QMetaProperty::isDesignable(const QObject *object) const
bool QMetaProperty::isDesignable() const
{
if (!mobj)
return false;
int flags = mobj->d.data[handle + 2];
bool b = flags & Designable;
if (object) {
void *argv[] = { &b };
QMetaObject::metacall(const_cast<QObject*>(object), QMetaObject::QueryPropertyDesignable,
idx + mobj->propertyOffset(), argv);
}
return b;
}
/*!
Returns \c true if the property is scriptable for the given \a object;
Returns \c true if the property is scriptable;
otherwise returns \c false.
If no \a object is given, the function returns \c false if the
\c{Q_PROPERTY()}'s \c SCRIPTABLE attribute is false; otherwise returns
true (if the attribute is true or is a function or expression).
true.
\sa isDesignable(), isStored()
*/
bool QMetaProperty::isScriptable(const QObject *object) const
bool QMetaProperty::isScriptable() const
{
if (!mobj)
return false;
int flags = mobj->d.data[handle + 2];
bool b = flags & Scriptable;
if (object) {
void *argv[] = { &b };
QMetaObject::metacall(const_cast<QObject*>(object), QMetaObject::QueryPropertyScriptable,
idx + mobj->propertyOffset(), argv);
}
return b;
}
/*!
Returns \c true if the property is stored for \a object; otherwise returns
Returns \c true if the property is stored; otherwise returns
false.
If no \a object is given, the function returns \c false if the
The function returns \c false if the
\c{Q_PROPERTY()}'s \c STORED attribute is false; otherwise returns
true (if the attribute is true or is a function or expression).
true.
\sa isDesignable(), isScriptable()
*/
bool QMetaProperty::isStored(const QObject *object) const
bool QMetaProperty::isStored() const
{
if (!mobj)
return false;
int flags = mobj->d.data[handle + 2];
bool b = flags & Stored;
if (object) {
void *argv[] = { &b };
QMetaObject::metacall(const_cast<QObject*>(object), QMetaObject::QueryPropertyStored,
idx + mobj->propertyOffset(), argv);
}
return b;
}
/*!
Returns \c true if this property is designated as the \c USER
property, i.e., the one that the user can edit for \a object or
property, i.e., the one that the user can edit or
that is significant in some other way. Otherwise it returns
false. e.g., the \c text property is the \c USER editable property
of a QLineEdit.
@ -3487,17 +3467,12 @@ bool QMetaProperty::isStored(const QObject *object) const
\sa QMetaObject::userProperty(), isDesignable(), isScriptable()
*/
bool QMetaProperty::isUser(const QObject *object) const
bool QMetaProperty::isUser() const
{
if (!mobj)
return false;
int flags = mobj->d.data[handle + 2];
bool b = flags & User;
if (object) {
void *argv[] = { &b };
QMetaObject::metacall(const_cast<QObject*>(object), QMetaObject::QueryPropertyUser,
idx + mobj->propertyOffset(), argv);
}
return b;
}
@ -3564,7 +3539,7 @@ bool QMetaProperty::isQProperty() const
/*!
\obsolete
Returns \c true if the property is editable for the given \a object;
Returns \c true if the property is editable;
otherwise returns \c false.
If no \a object is given, the function returns \c false if the
@ -3574,17 +3549,12 @@ bool QMetaProperty::isQProperty() const
\sa isDesignable(), isScriptable(), isStored()
*/
#if QT_DEPRECATED_SINCE(5, 15)
bool QMetaProperty::isEditable(const QObject *object) const
bool QMetaProperty::isEditable() const
{
if (!mobj)
return false;
int flags = mobj->d.data[handle + 2];
bool b = flags & Editable;
if (object) {
void *argv[] = { &b };
QMetaObject::metacall(const_cast<QObject*>(object), QMetaObject::QueryPropertyEditable,
idx + mobj->propertyOffset(), argv);
}
return b;
}
#endif

View File

@ -289,13 +289,13 @@ public:
bool isReadable() const;
bool isWritable() const;
bool isResettable() const;
bool isDesignable(const QObject *obj = nullptr) const;
bool isScriptable(const QObject *obj = nullptr) const;
bool isStored(const QObject *obj = nullptr) const;
bool isDesignable() const;
bool isScriptable() const;
bool isStored() const;
#if QT_DEPRECATED_SINCE(5, 15)
QT_DEPRECATED_VERSION_5_15 bool isEditable(const QObject *obj = nullptr) const;
QT_DEPRECATED_VERSION_5_15 bool isEditable() const;
#endif
bool isUser(const QObject *obj = nullptr) const;
bool isUser() const;
bool isConstant() const;
bool isFinal() const;
bool isRequired() const;

View File

@ -76,15 +76,10 @@ enum PropertyFlags {
Constant = 0x00000400,
Final = 0x00000800,
Designable = 0x00001000,
ResolveDesignable = 0x00002000,
Scriptable = 0x00004000,
ResolveScriptable = 0x00008000,
Stored = 0x00010000,
ResolveStored = 0x00020000,
Editable = 0x00040000,
ResolveEditable = 0x00080000,
User = 0x00100000,
ResolveUser = 0x00200000,
Notify = 0x00400000,
Revisioned = 0x00800000,
Required = 0x01000000,

View File

@ -382,11 +382,6 @@ struct Q_CORE_EXPORT QMetaObject
ReadProperty,
WriteProperty,
ResetProperty,
QueryPropertyDesignable,
QueryPropertyScriptable,
QueryPropertyStored,
QueryPropertyEditable,
QueryPropertyUser,
CreateInstance,
IndexOfMethod,
RegisterPropertyMetaType,

View File

@ -869,35 +869,23 @@ void Generator::generateProperties()
if (p.stdCppSet())
flags |= StdCppSet;
}
if (!p.reset.isEmpty())
flags |= Resettable;
// if (p.override)
// flags |= Override;
if (p.designable.isEmpty())
flags |= ResolveDesignable;
else if (p.designable != "false")
if (p.designable != "false")
flags |= Designable;
if (p.scriptable.isEmpty())
flags |= ResolveScriptable;
else if (p.scriptable != "false")
if (p.scriptable != "false")
flags |= Scriptable;
if (p.stored.isEmpty())
flags |= ResolveStored;
else if (p.stored != "false")
if (p.stored != "false")
flags |= Stored;
if (p.editable.isEmpty())
flags |= ResolveEditable;
else if (p.editable != "false")
if (p.editable != "false")
flags |= Editable;
if (p.user.isEmpty())
flags |= ResolveUser;
else if (p.user != "false")
if (p.user != "false")
flags |= User;
if (p.notifyId != -1)
@ -1045,19 +1033,6 @@ void Generator::generateMetacall()
}
if (cdef->propertyList.size()) {
bool needDesignable = false;
bool needScriptable = false;
bool needStored = false;
bool needEditable = false;
bool needUser = false;
for (int i = 0; i < cdef->propertyList.size(); ++i) {
const PropertyDef &p = cdef->propertyList.at(i);
needDesignable |= p.designable.endsWith(')');
needScriptable |= p.scriptable.endsWith(')');
needStored |= p.stored.endsWith(')');
needEditable |= p.editable.endsWith(')');
needUser |= p.user.endsWith(')');
}
fprintf(out, "\n#ifndef QT_NO_PROPERTIES\n ");
if (needElse)
@ -1069,103 +1044,6 @@ void Generator::generateMetacall()
" || _c == QMetaObject::SetQPropertyBinding) {\n"
" qt_static_metacall(this, _c, _id, _a);\n"
" _id -= %d;\n }", cdef->propertyList.count());
fprintf(out, " else ");
fprintf(out, "if (_c == QMetaObject::QueryPropertyDesignable) {\n");
if (needDesignable) {
fprintf(out, " bool *_b = reinterpret_cast<bool*>(_a[0]);\n");
fprintf(out, " switch (_id) {\n");
for (int propindex = 0; propindex < cdef->propertyList.size(); ++propindex) {
const PropertyDef &p = cdef->propertyList.at(propindex);
if (!p.designable.endsWith(')'))
continue;
fprintf(out, " case %d: *_b = %s; break;\n",
propindex, p.designable.constData());
}
fprintf(out, " default: break;\n");
fprintf(out, " }\n");
}
fprintf(out,
" _id -= %d;\n"
" }", cdef->propertyList.count());
fprintf(out, " else ");
fprintf(out, "if (_c == QMetaObject::QueryPropertyScriptable) {\n");
if (needScriptable) {
fprintf(out, " bool *_b = reinterpret_cast<bool*>(_a[0]);\n");
fprintf(out, " switch (_id) {\n");
for (int propindex = 0; propindex < cdef->propertyList.size(); ++propindex) {
const PropertyDef &p = cdef->propertyList.at(propindex);
if (!p.scriptable.endsWith(')'))
continue;
fprintf(out, " case %d: *_b = %s; break;\n",
propindex, p.scriptable.constData());
}
fprintf(out, " default: break;\n");
fprintf(out, " }\n");
}
fprintf(out,
" _id -= %d;\n"
" }", cdef->propertyList.count());
fprintf(out, " else ");
fprintf(out, "if (_c == QMetaObject::QueryPropertyStored) {\n");
if (needStored) {
fprintf(out, " bool *_b = reinterpret_cast<bool*>(_a[0]);\n");
fprintf(out, " switch (_id) {\n");
for (int propindex = 0; propindex < cdef->propertyList.size(); ++propindex) {
const PropertyDef &p = cdef->propertyList.at(propindex);
if (!p.stored.endsWith(')'))
continue;
fprintf(out, " case %d: *_b = %s; break;\n",
propindex, p.stored.constData());
}
fprintf(out, " default: break;\n");
fprintf(out, " }\n");
}
fprintf(out,
" _id -= %d;\n"
" }", cdef->propertyList.count());
fprintf(out, " else ");
fprintf(out, "if (_c == QMetaObject::QueryPropertyEditable) {\n");
if (needEditable) {
fprintf(out, " bool *_b = reinterpret_cast<bool*>(_a[0]);\n");
fprintf(out, " switch (_id) {\n");
for (int propindex = 0; propindex < cdef->propertyList.size(); ++propindex) {
const PropertyDef &p = cdef->propertyList.at(propindex);
if (!p.editable.endsWith(')'))
continue;
fprintf(out, " case %d: *_b = %s; break;\n",
propindex, p.editable.constData());
}
fprintf(out, " default: break;\n");
fprintf(out, " }\n");
}
fprintf(out,
" _id -= %d;\n"
" }", cdef->propertyList.count());
fprintf(out, " else ");
fprintf(out, "if (_c == QMetaObject::QueryPropertyUser) {\n");
if (needUser) {
fprintf(out, " bool *_b = reinterpret_cast<bool*>(_a[0]);\n");
fprintf(out, " switch (_id) {\n");
for (int propindex = 0; propindex < cdef->propertyList.size(); ++propindex) {
const PropertyDef &p = cdef->propertyList.at(propindex);
if (!p.user.endsWith(')'))
continue;
fprintf(out, " case %d: *_b = %s; break;\n",
propindex, p.user.constData());
}
fprintf(out, " default: break;\n");
fprintf(out, " }\n");
}
fprintf(out,
" _id -= %d;\n"
" }", cdef->propertyList.count());
fprintf(out, "\n#endif // QT_NO_PROPERTIES");
}
if (methodList.size() || cdef->propertyList.size())

View File

@ -1267,8 +1267,7 @@ void Moc::createPropertyDef(PropertyDef &propDef)
if (typeWrappedInQProperty)
next(RANGLE);
propDef.designable = propDef.scriptable = propDef.stored = "true";
propDef.user = "false";
propDef.user = propDef.editable = "false";
/*
The Q_PROPERTY construct cannot contain any commas, since
commas separate macro arguments. We therefore expect users
@ -1301,8 +1300,8 @@ void Moc::parsePropertyAttributes(PropertyDef &propDef)
if (def.endsWith(')')) {
QByteArray msg = "Providing a function for ";
msg += name;
msg += " in a property declaration is deprecated and will not be supported in Qt 6 anymore.";
warning(msg.constData());
msg += " in a property declaration is not be supported in Qt 6.";
error(msg.constData());
}
};

View File

@ -1565,16 +1565,6 @@ int TestObject::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
_id -= ownPropertyCount;
} else if (_c == QMetaObject::ResetProperty) {
_id -= ownPropertyCount;
} else if (_c == QMetaObject::QueryPropertyDesignable) {
_id -= ownPropertyCount;
} else if (_c == QMetaObject::QueryPropertyScriptable) {
_id -= ownPropertyCount;
} else if (_c == QMetaObject::QueryPropertyStored) {
_id -= ownPropertyCount;
} else if (_c == QMetaObject::QueryPropertyEditable) {
_id -= ownPropertyCount;
} else if (_c == QMetaObject::QueryPropertyUser) {
_id -= ownPropertyCount;
}
#endif // QT_NO_PROPERTIES
return _id;

View File

@ -620,7 +620,6 @@ class tst_Moc : public QObject
Q_PROPERTY(bool user1 READ user1 USER true )
Q_PROPERTY(bool user2 READ user2 USER false)
Q_PROPERTY(bool user3 READ user3 USER userFunction())
Q_PROPERTY(QString member1 MEMBER sMember)
Q_PROPERTY(QString member2 MEMBER sMember READ member2)
Q_PROPERTY(QString member3 MEMBER sMember WRITE setMember3)
@ -744,8 +743,6 @@ signals:
private:
bool user1() { return true; };
bool user2() { return false; };
bool user3() { return false; };
bool userFunction(){ return false; };
template <class T> void revisions_T();
QString member2() const { return sMember; }
void setMember3( const QString &sVal ) { sMember = sVal; }
@ -919,10 +916,6 @@ void tst_Moc::userProperties()
property = mobj->property(mobj->indexOfProperty("user2"));
QVERIFY(property.isValid());
QVERIFY(!property.isUser());
property = mobj->property(mobj->indexOfProperty("user3"));
QVERIFY(property.isValid());
QVERIFY(!property.isUser(this));
}
void tst_Moc::supportConstSignals()