Add support to moc for registering non-local enums via Q_ENUMS.
When using the Q_ENUMS macro to register an enumeration in a class with moc, it's now possible to provide a scoped enumeration that exists in another class. This adds the enum class scope to a metaobject's list of related classes stored in the extradata field. This allows the declarative code to handle non-local enums in signal and slot functions that are exposed to QML. Task-number: QTBUG-20639 Change-Id: I94f5292818095fda75762bd1508ba5c69de19503 Reviewed-by: Martin Jones <martin.jones@nokia.com> Reviewed-by: Bradley T. Hughes <bradley.hughes@nokia.com>
This commit is contained in:
parent
ff049be072
commit
de9d845441
@ -313,6 +313,21 @@ void Generator::generateCode()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// QTBUG-20639 - Accept non-local enums for QML signal/slot parameters.
|
||||
// Look for any scoped enum declarations, and add those to the list
|
||||
// of extra/related metaobjects for this object.
|
||||
QList<QByteArray> enumKeys = cdef->enumDeclarations.keys();
|
||||
for (int i = 0; i < enumKeys.count(); ++i) {
|
||||
const QByteArray &enumKey = enumKeys[i];
|
||||
int s = enumKey.lastIndexOf("::");
|
||||
if (s > 0) {
|
||||
QByteArray scope = enumKey.left(s);
|
||||
if (scope != "Qt" && scope != cdef->classname && !extraList.contains(scope))
|
||||
extraList += scope;
|
||||
}
|
||||
}
|
||||
|
||||
if (!extraList.isEmpty()) {
|
||||
fprintf(out, "#ifdef Q_NO_DATA_RELOCATION\n");
|
||||
fprintf(out, "static const QMetaObjectAccessor qt_meta_extradata_%s[] = {\n ", qualifiedClassNameIdentifier.constData());
|
||||
|
@ -410,6 +410,24 @@ public:
|
||||
inline PropertyTestClass::TestEnum foo() const { return PropertyTestClass::One; }
|
||||
};
|
||||
|
||||
class EnumSourceClass : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum TestEnum { Value = 37 };
|
||||
|
||||
Q_ENUMS(TestEnum)
|
||||
};
|
||||
|
||||
class EnumUserClass : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
Q_ENUMS(EnumSourceClass::TestEnum)
|
||||
};
|
||||
|
||||
#if defined(Q_MOC_RUN)
|
||||
// Task #119503
|
||||
#define _TASK_119503
|
||||
@ -483,6 +501,7 @@ private slots:
|
||||
void blackslashNewlines();
|
||||
void slotWithSillyConst();
|
||||
void testExtraData();
|
||||
void testExtraDataForEnum();
|
||||
void namespaceTypeProperty();
|
||||
void slotsWithVoidTemplate();
|
||||
void structQObject();
|
||||
@ -810,6 +829,25 @@ void tst_Moc::testExtraData()
|
||||
QCOMPARE(QByteArray(en.name()), QByteArray("TestEnum"));
|
||||
}
|
||||
|
||||
// QTBUG-20639 - Accept non-local enums for QML signal/slot parameters.
|
||||
void tst_Moc::testExtraDataForEnum()
|
||||
{
|
||||
const QMetaObject *mobjSource = &EnumSourceClass::staticMetaObject;
|
||||
QCOMPARE(mobjSource->enumeratorCount(), 1);
|
||||
QCOMPARE(QByteArray(mobjSource->enumerator(0).name()), QByteArray("TestEnum"));
|
||||
|
||||
const QMetaObject *mobjUser = &EnumUserClass::staticMetaObject;
|
||||
QCOMPARE(mobjUser->enumeratorCount(), 0);
|
||||
|
||||
const QMetaObjectExtraData *extra = reinterpret_cast<const QMetaObjectExtraData *>(mobjUser->d.extradata);
|
||||
QVERIFY(extra);
|
||||
|
||||
const QMetaObject **objects = extra->objects;
|
||||
QVERIFY(objects);
|
||||
QVERIFY(objects[0] == mobjSource);
|
||||
QVERIFY(objects[1] == 0);
|
||||
}
|
||||
|
||||
void tst_Moc::namespaceTypeProperty()
|
||||
{
|
||||
qRegisterMetaType<myNS::Points>("myNS::Points");
|
||||
|
Loading…
Reference in New Issue
Block a user