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:
Glenn Watson 2011-11-25 11:58:37 +10:00 committed by Qt by Nokia
parent ff049be072
commit de9d845441
2 changed files with 53 additions and 0 deletions

View File

@ -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()) { if (!extraList.isEmpty()) {
fprintf(out, "#ifdef Q_NO_DATA_RELOCATION\n"); fprintf(out, "#ifdef Q_NO_DATA_RELOCATION\n");
fprintf(out, "static const QMetaObjectAccessor qt_meta_extradata_%s[] = {\n ", qualifiedClassNameIdentifier.constData()); fprintf(out, "static const QMetaObjectAccessor qt_meta_extradata_%s[] = {\n ", qualifiedClassNameIdentifier.constData());

View File

@ -410,6 +410,24 @@ public:
inline PropertyTestClass::TestEnum foo() const { return PropertyTestClass::One; } 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) #if defined(Q_MOC_RUN)
// Task #119503 // Task #119503
#define _TASK_119503 #define _TASK_119503
@ -483,6 +501,7 @@ private slots:
void blackslashNewlines(); void blackslashNewlines();
void slotWithSillyConst(); void slotWithSillyConst();
void testExtraData(); void testExtraData();
void testExtraDataForEnum();
void namespaceTypeProperty(); void namespaceTypeProperty();
void slotsWithVoidTemplate(); void slotsWithVoidTemplate();
void structQObject(); void structQObject();
@ -810,6 +829,25 @@ void tst_Moc::testExtraData()
QCOMPARE(QByteArray(en.name()), QByteArray("TestEnum")); 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() void tst_Moc::namespaceTypeProperty()
{ {
qRegisterMetaType<myNS::Points>("myNS::Points"); qRegisterMetaType<myNS::Points>("myNS::Points");