4708 lines
152 KiB
Diff
4708 lines
152 KiB
Diff
Fix metaobjectbuilder build errors against Qt 4.8 and 4.7
|
|
|
|
Error message:
|
|
ipc/qmetaobjectbuilder.cpp:803:65: error: invalid conversion from \
|
|
'QMetaObjectExtraData::StaticMetacallFunction {aka void (*)(QObject*, \
|
|
QMetaObject::Call, int, void**)}' to 'QtMobility::QMetaObjectBuilder:: \
|
|
StaticMetacallFunction {aka int (*)(QMetaObject::Call, int, void**)}
|
|
|
|
Upstream-commit:
|
|
http://qt.gitorious.org/qt-mobility/qt-mobility/commit/f102053b28009b3094b0e5777177208afa6097c5
|
|
|
|
Task-number: QTMOBILITY-1990
|
|
|
|
Upstream-Status: Backport
|
|
|
|
Signed-off-by: Wenzong Fan <wenzong.fan@windriver.com>
|
|
------------------------------------------------------
|
|
diff --git a/plugins/declarative/common/dynamicproperties.pri b/plugins/declarative/common/dynamicproperties.pri
|
|
index 52737a3..4bd06de 100644
|
|
--- a/plugins/declarative/common/dynamicproperties.pri
|
|
+++ b/plugins/declarative/common/dynamicproperties.pri
|
|
@@ -1,6 +1,8 @@
|
|
INCLUDEPATH += ../../../plugins/declarative/common/dynamicproperties/
|
|
-HEADERS += ../../../plugins/declarative/common/dynamicproperties/qdeclarativeopenmetaobject_p.h \
|
|
- ../../../plugins/declarative/common/dynamicproperties/qmetaobjectbuilder_p.h
|
|
-SOURCES += ../../../plugins/declarative/common/dynamicproperties/qdeclarativeopenmetaobject.cpp \
|
|
- ../../../src/serviceframework/ipc/qmetaobjectbuilder.cpp
|
|
-
|
|
+HEADERS += ../../../plugins/declarative/common/dynamicproperties/qdeclarativeopenmetaobject_p.h
|
|
+SOURCES += ../../../plugins/declarative/common/dynamicproperties/qdeclarativeopenmetaobject.cpp
|
|
+include(../../../src/serviceframework/ipc/metaobjectbuilder.pri)
|
|
+INCLUDEPATH += ../../../src/serviceframework/$$OBJECTBUILDER_INCLUDEPATH
|
|
+DEPENDPATH += ../../../src/serviceframework/$$OBJECTBUILDER_DEPENDPATH
|
|
+HEADERS += ../../../src/serviceframework/$$OBJECTBUILDER_HEADERS
|
|
+SOURCES += ../../../src/serviceframework/$$OBJECTBUILDER_SOURCES
|
|
diff --git a/plugins/declarative/common/dynamicproperties/qdeclarativeopenmetaobject.cpp b/plugins/declarative/common/dynamicproperties/qdeclarativeopenmetaobject.cpp
|
|
index 79a2064..9eb6810 100644
|
|
--- a/plugins/declarative/common/dynamicproperties/qdeclarativeopenmetaobject.cpp
|
|
+++ b/plugins/declarative/common/dynamicproperties/qdeclarativeopenmetaobject.cpp
|
|
@@ -65,8 +65,7 @@ public:
|
|
{
|
|
int id = mob.propertyCount();
|
|
mob.addSignal("__" + QByteArray::number(id) + "()");
|
|
- QMetaPropertyBuilder build = mob.addProperty(name, type, id);
|
|
- build.setDynamic(true);
|
|
+ mob.addProperty(name, type, id);
|
|
qFree(mem);
|
|
mem = mob.toMetaObject();
|
|
|
|
diff --git a/plugins/declarative/common/dynamicproperties/qmetaobjectbuilder_p.h b/plugins/declarative/common/dynamicproperties/qmetaobjectbuilder_p.h
|
|
deleted file mode 100644
|
|
index bd937e4..0000000
|
|
--- a/plugins/declarative/common/dynamicproperties/qmetaobjectbuilder_p.h
|
|
+++ /dev/null
|
|
@@ -1,48 +0,0 @@
|
|
-/****************************************************************************
|
|
-**
|
|
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
|
|
-** All rights reserved.
|
|
-** Contact: Nokia Corporation (qt-info@nokia.com)
|
|
-**
|
|
-** This file is part of the Qt Mobility Components.
|
|
-**
|
|
-** $QT_BEGIN_LICENSE:LGPL$
|
|
-** No Commercial Usage
|
|
-** This file contains pre-release code and may not be distributed.
|
|
-** You may use this file in accordance with the terms and conditions
|
|
-** contained in the Technology Preview License Agreement accompanying
|
|
-** this package.
|
|
-**
|
|
-** GNU Lesser General Public License Usage
|
|
-** Alternatively, this file may be used under the terms of the GNU Lesser
|
|
-** General Public License version 2.1 as published by the Free Software
|
|
-** Foundation and appearing in the file LICENSE.LGPL included in the
|
|
-** packaging of this file. Please review the following information to
|
|
-** ensure the GNU Lesser General Public License version 2.1 requirements
|
|
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
|
-**
|
|
-** In addition, as a special exception, Nokia gives you certain additional
|
|
-** rights. These rights are described in the Nokia Qt LGPL Exception
|
|
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
|
-**
|
|
-** If you have questions regarding the use of this file, please contact
|
|
-** Nokia at qt-info@nokia.com.
|
|
-**
|
|
-**
|
|
-**
|
|
-**
|
|
-**
|
|
-**
|
|
-**
|
|
-**
|
|
-** $QT_END_LICENSE$
|
|
-**
|
|
-****************************************************************************/
|
|
-
|
|
-/*
|
|
-This header gets used in a number of different QML plugins
|
|
-and also in the source tree of Mobility itself.
|
|
-
|
|
-So this header is just a wrapper to grab it from there.
|
|
-*/
|
|
-#include "../../../../src/serviceframework/ipc/qmetaobjectbuilder_p.h"
|
|
diff --git a/src/serviceframework/ipc/ipc.pri b/src/serviceframework/ipc/ipc.pri
|
|
index 28b910f..d809f59 100644
|
|
--- a/src/serviceframework/ipc/ipc.pri
|
|
+++ b/src/serviceframework/ipc/ipc.pri
|
|
@@ -25,9 +25,14 @@ else {
|
|
}
|
|
}
|
|
|
|
+include(metaobjectbuilder.pri)
|
|
+INCLUDEPATH += $$OBJECTBUILDER_INCLUDEPATH
|
|
+DEPENDPATH += $$OBJECTBUILDER_DEPENDPATH
|
|
+PRIVATE_HEADERS += $$OBJECTBUILDER_HEADERS
|
|
+SOURCES += $$OBJECTBUILDER_SOURCES
|
|
+
|
|
PRIVATE_HEADERS += ipc/qslotinvoker_p.h \
|
|
ipc/qsignalintercepter_p.h \
|
|
- ipc/qmetaobjectbuilder_p.h \
|
|
ipc/instancemanager_p.h \
|
|
ipc/qservicepackage_p.h \
|
|
ipc/proxyobject_p.h \
|
|
@@ -37,7 +42,6 @@ PRIVATE_HEADERS += ipc/qslotinvoker_p.h \
|
|
|
|
SOURCES += ipc/qslotinvoker.cpp \
|
|
ipc/qsignalintercepter.cpp \
|
|
- ipc/qmetaobjectbuilder.cpp \
|
|
ipc/instancemanager.cpp \
|
|
ipc/qservicepackage.cpp \
|
|
ipc/proxyobject.cpp \
|
|
diff --git a/src/serviceframework/ipc/metaobjectbuilder.pri b/src/serviceframework/ipc/metaobjectbuilder.pri
|
|
new file mode 100644
|
|
index 0000000..cc905f9
|
|
--- /dev/null
|
|
+++ b/src/serviceframework/ipc/metaobjectbuilder.pri
|
|
@@ -0,0 +1,12 @@
|
|
+#check version for 4.7 ...
|
|
+contains(QT_MAJOR_VERSION, 4):lessThan(QT_MINOR_VERSION, 8) {
|
|
+ OBJECTBUILDER_INCLUDEPATH += ipc
|
|
+ OBJECTBUILDER_DEPENDPATH += ipc
|
|
+ OBJECTBUILDER_HEADERS += ipc/qmetaobjectbuilder_47_p.h
|
|
+ OBJECTBUILDER_SOURCES += ipc/qmetaobjectbuilder_47.cpp
|
|
+} else {
|
|
+ OBJECTBUILDER_INCLUDEPATH += ipc
|
|
+ OBJECTBUILDER_DEPENDPATH += ipc
|
|
+ OBJECTBUILDER_HEADERS += ipc/qmetaobjectbuilder_p.h
|
|
+ OBJECTBUILDER_SOURCES += ipc/qmetaobjectbuilder.cpp
|
|
+}
|
|
diff --git a/src/serviceframework/ipc/qmetaobjectbuilder.cpp b/src/serviceframework/ipc/qmetaobjectbuilder.cpp
|
|
index b19eb1a..6ffaa20 100644
|
|
--- a/src/serviceframework/ipc/qmetaobjectbuilder.cpp
|
|
+++ b/src/serviceframework/ipc/qmetaobjectbuilder.cpp
|
|
@@ -117,6 +117,8 @@ enum PropertyFlags {
|
|
EnumOrFlag = 0x00000008,
|
|
StdCppSet = 0x00000100,
|
|
// Override = 0x00000200,
|
|
+ Constant = 0x00000400,
|
|
+ Final = 0x00000800,
|
|
Designable = 0x00001000,
|
|
ResolveDesignable = 0x00002000,
|
|
Scriptable = 0x00004000,
|
|
@@ -128,7 +130,7 @@ enum PropertyFlags {
|
|
User = 0x00100000,
|
|
ResolveUser = 0x00200000,
|
|
Notify = 0x00400000,
|
|
- Dynamic = 0x00800000
|
|
+ Revisioned = 0x00800000
|
|
};
|
|
|
|
enum MethodFlags {
|
|
@@ -145,7 +147,8 @@ enum MethodFlags {
|
|
|
|
MethodCompatibility = 0x10,
|
|
MethodCloned = 0x20,
|
|
- MethodScriptable = 0x40
|
|
+ MethodScriptable = 0x40,
|
|
+ MethodRevisioned = 0x80
|
|
};
|
|
|
|
struct QMetaObjectPrivate
|
|
@@ -623,6 +626,8 @@ QMetaPropertyBuilder QMetaObjectBuilder::addProperty(const QMetaProperty& protot
|
|
property.setUser(prototype.isUser());
|
|
property.setStdCppSet(prototype.hasStdCppSet());
|
|
property.setEnumOrFlag(prototype.isEnumType());
|
|
+ property.setConstant(prototype.isConstant());
|
|
+ property.setFinal(prototype.isFinal());
|
|
if (prototype.hasNotifySignal()) {
|
|
// Find an existing method for the notify signal, or add a new one.
|
|
QMetaMethod method = prototype.notifySignal();
|
|
@@ -796,7 +801,7 @@ void QMetaObjectBuilder::addMetaObject
|
|
}
|
|
|
|
if ((members & StaticMetacall) != 0) {
|
|
- if (priv(prototype->d.data)->revision >= 2) {
|
|
+ if (priv(prototype->d.data)->revision >= 6) {
|
|
const QMetaObjectExtraData *extra =
|
|
(const QMetaObjectExtraData *)(prototype->d.extradata);
|
|
if (extra && extra->static_metacall)
|
|
@@ -1266,8 +1271,8 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf,
|
|
char *str = reinterpret_cast<char *>(buf + size);
|
|
if (buf) {
|
|
if (relocatable) {
|
|
- meta->d.stringdata = reinterpret_cast<const char *>((intptr_t)size);
|
|
- meta->d.data = reinterpret_cast<uint *>((intptr_t)pmetaSize);
|
|
+ meta->d.stringdata = reinterpret_cast<const char *>((quintptr)size);
|
|
+ meta->d.data = reinterpret_cast<uint *>((quintptr)pmetaSize);
|
|
} else {
|
|
meta->d.stringdata = str;
|
|
meta->d.data = reinterpret_cast<uint *>(data);
|
|
@@ -1504,8 +1509,8 @@ void QMetaObjectBuilder::fromRelocatableData(QMetaObject *output,
|
|
const char *buf = data.constData();
|
|
const QMetaObject *dataMo = reinterpret_cast<const QMetaObject *>(buf);
|
|
|
|
- intptr_t stringdataOffset = (intptr_t)dataMo->d.stringdata;
|
|
- intptr_t dataOffset = (intptr_t)dataMo->d.data;
|
|
+ quintptr stringdataOffset = (quintptr)dataMo->d.stringdata;
|
|
+ quintptr dataOffset = (quintptr)dataMo->d.data;
|
|
|
|
output->d.superdata = superclass;
|
|
output->d.stringdata = buf + stringdataOffset;
|
|
@@ -2289,16 +2294,27 @@ bool QMetaPropertyBuilder::isEnumOrFlag() const
|
|
}
|
|
|
|
/*!
|
|
- Returns true if the property has the dynamic flag set;
|
|
- otherwise returns false. The default value is false.
|
|
+ Returns true if the property is constant; otherwise returns false.
|
|
+ The default value is false.
|
|
+*/
|
|
+bool QMetaPropertyBuilder::isConstant() const
|
|
+{
|
|
+ QMetaPropertyBuilderPrivate *d = d_func();
|
|
+ if (d)
|
|
+ return d->flag(Constant);
|
|
+ else
|
|
+ return false;
|
|
+}
|
|
|
|
- \sa setDynamic()
|
|
+/*!
|
|
+ Returns true if the property is final; otherwise returns false.
|
|
+ The default value is false.
|
|
*/
|
|
-bool QMetaPropertyBuilder::isDynamic() const
|
|
+bool QMetaPropertyBuilder::isFinal() const
|
|
{
|
|
QMetaPropertyBuilderPrivate *d = d_func();
|
|
if (d)
|
|
- return d->flag(Dynamic);
|
|
+ return d->flag(Final);
|
|
else
|
|
return false;
|
|
}
|
|
@@ -2427,16 +2443,27 @@ void QMetaPropertyBuilder::setEnumOrFlag(bool value)
|
|
}
|
|
|
|
/*!
|
|
- Sets this property to have the dynamic flag if \a value is
|
|
- true.
|
|
+ Sets the \c CONSTANT flag on this property to \a value.
|
|
+
|
|
+ \sa isConstant()
|
|
+*/
|
|
+void QMetaPropertyBuilder::setConstant(bool value)
|
|
+{
|
|
+ QMetaPropertyBuilderPrivate *d = d_func();
|
|
+ if (d)
|
|
+ d->setFlag(Constant, value);
|
|
+}
|
|
+
|
|
+/*!
|
|
+ Sets the \c FINAL flag on this property to \a value.
|
|
|
|
- \sa isDynamic()
|
|
+ \sa isFinal()
|
|
*/
|
|
-void QMetaPropertyBuilder::setDynamic(bool value)
|
|
+void QMetaPropertyBuilder::setFinal(bool value)
|
|
{
|
|
QMetaPropertyBuilderPrivate *d = d_func();
|
|
if (d)
|
|
- d->setFlag(Dynamic, value);
|
|
+ d->setFlag(Final, value);
|
|
}
|
|
|
|
/*!
|
|
diff --git a/src/serviceframework/ipc/qmetaobjectbuilder_47.cpp b/src/serviceframework/ipc/qmetaobjectbuilder_47.cpp
|
|
new file mode 100644
|
|
index 0000000..509d6c6
|
|
--- /dev/null
|
|
+++ b/src/serviceframework/ipc/qmetaobjectbuilder_47.cpp
|
|
@@ -0,0 +1,2583 @@
|
|
+/****************************************************************************
|
|
+**
|
|
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
|
|
+** All rights reserved.
|
|
+** Contact: Nokia Corporation (qt-info@nokia.com)
|
|
+**
|
|
+** This file is part of the QtDeclarative module of the Qt Toolkit.
|
|
+**
|
|
+** $QT_BEGIN_LICENSE:LGPL$
|
|
+** No Commercial Usage
|
|
+** This file contains pre-release code and may not be distributed.
|
|
+** You may use this file in accordance with the terms and conditions
|
|
+** contained in the Technology Preview License Agreement accompanying
|
|
+** this package.
|
|
+**
|
|
+** GNU Lesser General Public License Usage
|
|
+** Alternatively, this file may be used under the terms of the GNU Lesser
|
|
+** General Public License version 2.1 as published by the Free Software
|
|
+** Foundation and appearing in the file LICENSE.LGPL included in the
|
|
+** packaging of this file. Please review the following information to
|
|
+** ensure the GNU Lesser General Public License version 2.1 requirements
|
|
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
|
+**
|
|
+** In addition, as a special exception, Nokia gives you certain additional
|
|
+** rights. These rights are described in the Nokia Qt LGPL Exception
|
|
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
|
+**
|
|
+** If you have questions regarding the use of this file, please contact
|
|
+** Nokia at qt-info@nokia.com.
|
|
+**
|
|
+**
|
|
+**
|
|
+**
|
|
+**
|
|
+**
|
|
+**
|
|
+**
|
|
+** $QT_END_LICENSE$
|
|
+**
|
|
+****************************************************************************/
|
|
+
|
|
+#include "qmetaobjectbuilder_47_p.h"
|
|
+#include <QDebug>
|
|
+
|
|
+#ifndef Q_OS_WIN
|
|
+#include <stdint.h>
|
|
+#endif
|
|
+
|
|
+QTM_BEGIN_NAMESPACE
|
|
+
|
|
+/*!
|
|
+ \class QMetaObjectBuilder
|
|
+ \internal
|
|
+ \brief The QMetaObjectBuilder class supports building QMetaObject objects at runtime.
|
|
+ \since 1.1
|
|
+
|
|
+*/
|
|
+
|
|
+/*!
|
|
+ \enum QMetaObjectBuilder::AddMember
|
|
+ This enum defines which members of QMetaObject should be copied by QMetaObjectBuilder::addMetaObject()
|
|
+
|
|
+ \value ClassName Add the class name.
|
|
+ \value SuperClass Add the super class.
|
|
+ \value Methods Add methods that aren't signals or slots.
|
|
+ \value Signals Add signals.
|
|
+ \value Slots Add slots.
|
|
+ \value Constructors Add constructors.
|
|
+ \value Properties Add properties.
|
|
+ \value Enumerators Add enumerators.
|
|
+ \value ClassInfos Add items of class information.
|
|
+ \value RelatedMetaObjects Add related meta objects.
|
|
+ \value StaticMetacall Add the static metacall function.
|
|
+ \value PublicMethods Add public methods (ignored for signals).
|
|
+ \value ProtectedMethods Add protected methods (ignored for signals).
|
|
+ \value PrivateMethods All private methods (ignored for signals).
|
|
+ \value AllMembers Add all members.
|
|
+ \value AllPrimaryMembers Add everything except the class name, super class, and static metacall function.
|
|
+*/
|
|
+
|
|
+// copied from moc's generator.cpp
|
|
+uint qvariant_nameToType(const char* name)
|
|
+{
|
|
+ if (!name)
|
|
+ return 0;
|
|
+
|
|
+ if (strcmp(name, "QVariant") == 0)
|
|
+ return 0xffffffff;
|
|
+ if (strcmp(name, "QCString") == 0)
|
|
+ return QMetaType::QByteArray;
|
|
+ if (strcmp(name, "Q_LLONG") == 0)
|
|
+ return QMetaType::LongLong;
|
|
+ if (strcmp(name, "Q_ULLONG") == 0)
|
|
+ return QMetaType::ULongLong;
|
|
+ if (strcmp(name, "QIconSet") == 0)
|
|
+ return QMetaType::QIcon;
|
|
+
|
|
+ uint tp = QMetaType::type(name);
|
|
+ return tp < QMetaType::User ? tp : 0;
|
|
+}
|
|
+
|
|
+/*
|
|
+ Returns true if the type is a QVariant types.
|
|
+*/
|
|
+bool isVariantType(const char* type)
|
|
+{
|
|
+ return qvariant_nameToType(type) != 0;
|
|
+}
|
|
+
|
|
+// copied from qmetaobject.cpp
|
|
+// do not touch without touching the moc as well
|
|
+enum PropertyFlags {
|
|
+ Invalid = 0x00000000,
|
|
+ Readable = 0x00000001,
|
|
+ Writable = 0x00000002,
|
|
+ Resettable = 0x00000004,
|
|
+ EnumOrFlag = 0x00000008,
|
|
+ StdCppSet = 0x00000100,
|
|
+// Override = 0x00000200,
|
|
+ Designable = 0x00001000,
|
|
+ ResolveDesignable = 0x00002000,
|
|
+ Scriptable = 0x00004000,
|
|
+ ResolveScriptable = 0x00008000,
|
|
+ Stored = 0x00010000,
|
|
+ ResolveStored = 0x00020000,
|
|
+ Editable = 0x00040000,
|
|
+ ResolveEditable = 0x00080000,
|
|
+ User = 0x00100000,
|
|
+ ResolveUser = 0x00200000,
|
|
+ Notify = 0x00400000,
|
|
+ Dynamic = 0x00800000
|
|
+};
|
|
+
|
|
+enum MethodFlags {
|
|
+ AccessPrivate = 0x00,
|
|
+ AccessProtected = 0x01,
|
|
+ AccessPublic = 0x02,
|
|
+ AccessMask = 0x03, //mask
|
|
+
|
|
+ MethodMethod = 0x00,
|
|
+ MethodSignal = 0x04,
|
|
+ MethodSlot = 0x08,
|
|
+ MethodConstructor = 0x0c,
|
|
+ MethodTypeMask = 0x0c,
|
|
+
|
|
+ MethodCompatibility = 0x10,
|
|
+ MethodCloned = 0x20,
|
|
+ MethodScriptable = 0x40
|
|
+};
|
|
+
|
|
+struct QMetaObjectPrivate
|
|
+{
|
|
+ int revision;
|
|
+ int className;
|
|
+ int classInfoCount, classInfoData;
|
|
+ int methodCount, methodData;
|
|
+ int propertyCount, propertyData;
|
|
+ int enumeratorCount, enumeratorData;
|
|
+ int constructorCount, constructorData;
|
|
+ int flags;
|
|
+};
|
|
+
|
|
+static inline const QMetaObjectPrivate *priv(const uint* data)
|
|
+{ return reinterpret_cast<const QMetaObjectPrivate*>(data); }
|
|
+// end of copied lines from qmetaobject.cpp
|
|
+
|
|
+class QMetaMethodBuilderPrivate
|
|
+{
|
|
+public:
|
|
+ QMetaMethodBuilderPrivate
|
|
+ (QMetaMethod::MethodType _methodType,
|
|
+ const QByteArray& _signature,
|
|
+ const QByteArray& _returnType = QByteArray(),
|
|
+ QMetaMethod::Access _access = QMetaMethod::Public)
|
|
+ : signature(QMetaObject::normalizedSignature(_signature.constData())),
|
|
+ returnType(QMetaObject::normalizedType(_returnType)),
|
|
+ attributes(((int)_access) | (((int)_methodType) << 2))
|
|
+ {
|
|
+ }
|
|
+
|
|
+ QByteArray signature;
|
|
+ QByteArray returnType;
|
|
+ QList<QByteArray> parameterNames;
|
|
+ QByteArray tag;
|
|
+ int attributes;
|
|
+
|
|
+ QMetaMethod::MethodType methodType() const
|
|
+ {
|
|
+ return (QMetaMethod::MethodType)((attributes & MethodTypeMask) >> 2);
|
|
+ }
|
|
+
|
|
+ QMetaMethod::Access access() const
|
|
+ {
|
|
+ return (QMetaMethod::Access)(attributes & AccessMask);
|
|
+ }
|
|
+
|
|
+ void setAccess(QMetaMethod::Access value)
|
|
+ {
|
|
+ attributes = ((attributes & ~AccessMask) | (int)value);
|
|
+ }
|
|
+};
|
|
+
|
|
+class QMetaPropertyBuilderPrivate
|
|
+{
|
|
+public:
|
|
+ QMetaPropertyBuilderPrivate
|
|
+ (const QByteArray& _name, const QByteArray& _type, int notifierIdx=-1)
|
|
+ : name(_name),
|
|
+ type(QMetaObject::normalizedType(_type.constData())),
|
|
+ flags(Readable | Writable | Scriptable), notifySignal(-1)
|
|
+ {
|
|
+ if (notifierIdx >= 0) {
|
|
+ flags |= Notify;
|
|
+ notifySignal = notifierIdx;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ QByteArray name;
|
|
+ QByteArray type;
|
|
+ int flags;
|
|
+ int notifySignal;
|
|
+
|
|
+ bool flag(int f) const
|
|
+ {
|
|
+ return ((flags & f) != 0);
|
|
+ }
|
|
+
|
|
+ void setFlag(int f, bool value)
|
|
+ {
|
|
+ if (value)
|
|
+ flags |= f;
|
|
+ else
|
|
+ flags &= ~f;
|
|
+ }
|
|
+};
|
|
+
|
|
+class QMetaEnumBuilderPrivate
|
|
+{
|
|
+public:
|
|
+ QMetaEnumBuilderPrivate(const QByteArray& _name)
|
|
+ : name(_name), isFlag(false)
|
|
+ {
|
|
+ }
|
|
+
|
|
+ QByteArray name;
|
|
+ bool isFlag;
|
|
+ QList<QByteArray> keys;
|
|
+ QList<int> values;
|
|
+};
|
|
+
|
|
+class QMetaObjectBuilderPrivate
|
|
+{
|
|
+public:
|
|
+ QMetaObjectBuilderPrivate()
|
|
+ : flags(0)
|
|
+ {
|
|
+ superClass = &QObject::staticMetaObject;
|
|
+ staticMetacallFunction = 0;
|
|
+ }
|
|
+
|
|
+ QByteArray className;
|
|
+ const QMetaObject *superClass;
|
|
+ QMetaObjectBuilder::StaticMetacallFunction staticMetacallFunction;
|
|
+ QList<QMetaMethodBuilderPrivate> methods;
|
|
+ QList<QMetaMethodBuilderPrivate> constructors;
|
|
+ QList<QMetaPropertyBuilderPrivate> properties;
|
|
+ QList<QByteArray> classInfoNames;
|
|
+ QList<QByteArray> classInfoValues;
|
|
+ QList<QMetaEnumBuilderPrivate> enumerators;
|
|
+#ifdef Q_NO_DATA_RELOCATION
|
|
+ QList<QMetaObjectAccessor> relatedMetaObjects;
|
|
+#else
|
|
+ QList<const QMetaObject *> relatedMetaObjects;
|
|
+#endif
|
|
+ int flags;
|
|
+};
|
|
+
|
|
+/*!
|
|
+ Constructs a new QMetaObjectBuilder.
|
|
+*/
|
|
+QMetaObjectBuilder::QMetaObjectBuilder()
|
|
+{
|
|
+ d = new QMetaObjectBuilderPrivate();
|
|
+}
|
|
+
|
|
+/*!
|
|
+ Constructs a new QMetaObjectBuilder which is a copy of the
|
|
+ meta object information in \a prototype. Note: the super class
|
|
+ contents for \a prototype are not copied, only the immediate
|
|
+ class that is defined by \a prototype.
|
|
+
|
|
+ The \a members parameter indicates which members of \a prototype
|
|
+ should be added. The default is AllMembers.
|
|
+
|
|
+ \sa addMetaObject()
|
|
+*/
|
|
+QMetaObjectBuilder::QMetaObjectBuilder
|
|
+ (const QMetaObject *prototype, QMetaObjectBuilder::AddMembers members)
|
|
+{
|
|
+ d = new QMetaObjectBuilderPrivate();
|
|
+ addMetaObject(prototype, members);
|
|
+}
|
|
+
|
|
+/*!
|
|
+ Destroys this meta object builder.
|
|
+*/
|
|
+QMetaObjectBuilder::~QMetaObjectBuilder()
|
|
+{
|
|
+ delete d;
|
|
+}
|
|
+
|
|
+/*!
|
|
+ Returns the name of the class being constructed by this
|
|
+ meta object builder. The default value is an empty QByteArray.
|
|
+
|
|
+ \sa setClassName(), superClass()
|
|
+*/
|
|
+QByteArray QMetaObjectBuilder::className() const
|
|
+{
|
|
+ return d->className;
|
|
+}
|
|
+
|
|
+/*!
|
|
+ Sets the \a name of the class being constructed by this
|
|
+ meta object builder.
|
|
+
|
|
+ \sa className(), setSuperClass()
|
|
+*/
|
|
+void QMetaObjectBuilder::setClassName(const QByteArray& name)
|
|
+{
|
|
+ d->className = name;
|
|
+}
|
|
+
|
|
+/*!
|
|
+ Returns the superclass meta object of the class being constructed
|
|
+ by this meta object builder. The default value is the meta object
|
|
+ for QObject.
|
|
+
|
|
+ \sa setSuperClass(), className()
|
|
+*/
|
|
+const QMetaObject *QMetaObjectBuilder::superClass() const
|
|
+{
|
|
+ return d->superClass;
|
|
+}
|
|
+
|
|
+/*!
|
|
+ Sets the superclass meta object of the class being constructed
|
|
+ by this meta object builder to \a meta. The \a meta parameter
|
|
+ must not be null.
|
|
+
|
|
+ \sa superClass(), setClassName()
|
|
+*/
|
|
+void QMetaObjectBuilder::setSuperClass(const QMetaObject *meta)
|
|
+{
|
|
+ Q_ASSERT(meta);
|
|
+ d->superClass = meta;
|
|
+}
|
|
+
|
|
+/*!
|
|
+ Returns the flags of the class being constructed by this meta object
|
|
+ builder.
|
|
+
|
|
+ \sa setFlags()
|
|
+*/
|
|
+QMetaObjectBuilder::MetaObjectFlags QMetaObjectBuilder::flags() const
|
|
+{
|
|
+ return (QMetaObjectBuilder::MetaObjectFlags)d->flags;
|
|
+}
|
|
+
|
|
+/*!
|
|
+ Sets the \a flags of the class being constructed by this meta object
|
|
+ builder.
|
|
+
|
|
+ \sa flags()
|
|
+*/
|
|
+void QMetaObjectBuilder::setFlags(MetaObjectFlags flags)
|
|
+{
|
|
+ d->flags = flags;
|
|
+}
|
|
+
|
|
+/*!
|
|
+ Returns the number of methods in this class, excluding the number
|
|
+ of methods in the base class. These include signals and slots
|
|
+ as well as normal member functions.
|
|
+
|
|
+ \sa addMethod(), method(), removeMethod(), indexOfMethod()
|
|
+*/
|
|
+int QMetaObjectBuilder::methodCount() const
|
|
+{
|
|
+ return d->methods.size();
|
|
+}
|
|
+
|
|
+/*!
|
|
+ Returns the number of constructors in this class.
|
|
+
|
|
+ \sa addConstructor(), constructor(), removeConstructor(), indexOfConstructor()
|
|
+*/
|
|
+int QMetaObjectBuilder::constructorCount() const
|
|
+{
|
|
+ return d->constructors.size();
|
|
+}
|
|
+
|
|
+/*!
|
|
+ Returns the number of properties in this class, excluding the number
|
|
+ of properties in the base class.
|
|
+
|
|
+ \sa addProperty(), property(), removeProperty(), indexOfProperty()
|
|
+*/
|
|
+int QMetaObjectBuilder::propertyCount() const
|
|
+{
|
|
+ return d->properties.size();
|
|
+}
|
|
+
|
|
+/*!
|
|
+ Returns the number of enumerators in this class, excluding the
|
|
+ number of enumerators in the base class.
|
|
+
|
|
+ \sa addEnumerator(), enumerator(), removeEnumerator()
|
|
+ \sa indexOfEnumerator()
|
|
+*/
|
|
+int QMetaObjectBuilder::enumeratorCount() const
|
|
+{
|
|
+ return d->enumerators.size();
|
|
+}
|
|
+
|
|
+/*!
|
|
+ Returns the number of items of class information in this class,
|
|
+ exclusing the number of items of class information in the base class.
|
|
+
|
|
+ \sa addClassInfo(), classInfoName(), classInfoValue(), removeClassInfo()
|
|
+ \sa indexOfClassInfo()
|
|
+*/
|
|
+int QMetaObjectBuilder::classInfoCount() const
|
|
+{
|
|
+ return d->classInfoNames.size();
|
|
+}
|
|
+
|
|
+/*!
|
|
+ Returns the number of related meta objects that are associated
|
|
+ with this class.
|
|
+
|
|
+ Related meta objects are used when resolving the enumerated type
|
|
+ associated with a property, where the enumerated type is in a
|
|
+ different class from the property.
|
|
+
|
|
+ \sa addRelatedMetaObject(), relatedMetaObject()
|
|
+ \sa removeRelatedMetaObject()
|
|
+*/
|
|
+int QMetaObjectBuilder::relatedMetaObjectCount() const
|
|
+{
|
|
+ return d->relatedMetaObjects.size();
|
|
+}
|
|
+
|
|
+/*!
|
|
+ Adds a new public method to this class with the specified \a signature.
|
|
+ Returns an object that can be used to adjust the other attributes
|
|
+ of the method. The \a signature will be normalized before it is
|
|
+ added to the class.
|
|
+
|
|
+ \sa method(), methodCount(), removeMethod(), indexOfMethod()
|
|
+*/
|
|
+QMetaMethodBuilder QMetaObjectBuilder::addMethod(const QByteArray& signature)
|
|
+{
|
|
+ int index = d->methods.size();
|
|
+ d->methods.append(QMetaMethodBuilderPrivate(QMetaMethod::Method, signature));
|
|
+ return QMetaMethodBuilder(this, index);
|
|
+}
|
|
+
|
|
+/*!
|
|
+ Adds a new public method to this class with the specified
|
|
+ \a signature and \a returnType. Returns an object that can be
|
|
+ used to adjust the other attributes of the method. The \a signature
|
|
+ and \a returnType will be normalized before they are added to
|
|
+ the class. If \a returnType is empty, then it indicates that
|
|
+ the method has \c{void} as its return type.
|
|
+
|
|
+ \sa method(), methodCount(), removeMethod(), indexOfMethod()
|
|
+*/
|
|
+QMetaMethodBuilder QMetaObjectBuilder::addMethod
|
|
+ (const QByteArray& signature, const QByteArray& returnType)
|
|
+{
|
|
+ int index = d->methods.size();
|
|
+ d->methods.append(QMetaMethodBuilderPrivate
|
|
+ (QMetaMethod::Method, signature, returnType));
|
|
+ return QMetaMethodBuilder(this, index);
|
|
+}
|
|
+
|
|
+/*!
|
|
+ Adds a new public method to this class that has the same information as
|
|
+ \a prototype. This is used to clone the methods of an existing
|
|
+ QMetaObject. Returns an object that can be used to adjust the
|
|
+ attributes of the method.
|
|
+
|
|
+ This function will detect if \a prototype is an ordinary method,
|
|
+ signal, slot, or constructor and act accordingly.
|
|
+
|
|
+ \sa method(), methodCount(), removeMethod(), indexOfMethod()
|
|
+*/
|
|
+QMetaMethodBuilder QMetaObjectBuilder::addMethod(const QMetaMethod& prototype)
|
|
+{
|
|
+ QMetaMethodBuilder method;
|
|
+ if (prototype.methodType() == QMetaMethod::Method)
|
|
+ method = addMethod(prototype.signature());
|
|
+ else if (prototype.methodType() == QMetaMethod::Signal)
|
|
+ method = addSignal(prototype.signature());
|
|
+ else if (prototype.methodType() == QMetaMethod::Slot)
|
|
+ method = addSlot(prototype.signature());
|
|
+ else if (prototype.methodType() == QMetaMethod::Constructor)
|
|
+ method = addConstructor(prototype.signature());
|
|
+ method.setReturnType(prototype.typeName());
|
|
+ method.setParameterNames(prototype.parameterNames());
|
|
+ method.setTag(prototype.tag());
|
|
+ method.setAccess(prototype.access());
|
|
+ method.setAttributes(prototype.attributes());
|
|
+ return method;
|
|
+}
|
|
+
|
|
+/*!
|
|
+ Adds a new public slot to this class with the specified \a signature.
|
|
+ Returns an object that can be used to adjust the other attributes
|
|
+ of the slot. The \a signature will be normalized before it is
|
|
+ added to the class.
|
|
+
|
|
+ \sa addMethod(), addSignal(), indexOfSlot()
|
|
+*/
|
|
+QMetaMethodBuilder QMetaObjectBuilder::addSlot(const QByteArray& signature)
|
|
+{
|
|
+ int index = d->methods.size();
|
|
+ d->methods.append(QMetaMethodBuilderPrivate(QMetaMethod::Slot, signature));
|
|
+ return QMetaMethodBuilder(this, index);
|
|
+}
|
|
+
|
|
+/*!
|
|
+ Adds a new signal to this class with the specified \a signature.
|
|
+ Returns an object that can be used to adjust the other attributes
|
|
+ of the signal. The \a signature will be normalized before it is
|
|
+ added to the class.
|
|
+
|
|
+ \sa addMethod(), addSlot(), indexOfSignal()
|
|
+*/
|
|
+QMetaMethodBuilder QMetaObjectBuilder::addSignal(const QByteArray& signature)
|
|
+{
|
|
+ int index = d->methods.size();
|
|
+ d->methods.append(QMetaMethodBuilderPrivate
|
|
+ (QMetaMethod::Signal, signature, QByteArray(), QMetaMethod::Protected));
|
|
+ return QMetaMethodBuilder(this, index);
|
|
+}
|
|
+
|
|
+/*!
|
|
+ Adds a new constructor to this class with the specified \a signature.
|
|
+ Returns an object that can be used to adjust the other attributes
|
|
+ of the constructor. The \a signature will be normalized before it is
|
|
+ added to the class.
|
|
+
|
|
+ \sa constructor(), constructorCount(), removeConstructor()
|
|
+ \sa indexOfConstructor()
|
|
+*/
|
|
+QMetaMethodBuilder QMetaObjectBuilder::addConstructor(const QByteArray& signature)
|
|
+{
|
|
+ int index = d->constructors.size();
|
|
+ d->constructors.append(QMetaMethodBuilderPrivate(QMetaMethod::Constructor, signature));
|
|
+ return QMetaMethodBuilder(this, -(index + 1));
|
|
+}
|
|
+
|
|
+/*!
|
|
+ Adds a new constructor to this class that has the same information as
|
|
+ \a prototype. This is used to clone the constructors of an existing
|
|
+ QMetaObject. Returns an object that can be used to adjust the
|
|
+ attributes of the constructor.
|
|
+
|
|
+ This function requires that \a prototype be a constructor.
|
|
+
|
|
+ \sa constructor(), constructorCount(), removeConstructor()
|
|
+ \sa indexOfConstructor()
|
|
+*/
|
|
+QMetaMethodBuilder QMetaObjectBuilder::addConstructor(const QMetaMethod& prototype)
|
|
+{
|
|
+ Q_ASSERT(prototype.methodType() == QMetaMethod::Constructor);
|
|
+ QMetaMethodBuilder ctor = addConstructor(prototype.signature());
|
|
+ ctor.setReturnType(prototype.typeName());
|
|
+ ctor.setParameterNames(prototype.parameterNames());
|
|
+ ctor.setTag(prototype.tag());
|
|
+ ctor.setAccess(prototype.access());
|
|
+ ctor.setAttributes(prototype.attributes());
|
|
+ return ctor;
|
|
+}
|
|
+
|
|
+/*!
|
|
+ Adds a new readable/writable property to this class with the
|
|
+ specified \a name and \a type. Returns an object that can be used
|
|
+ to adjust the other attributes of the property. The \a type will
|
|
+ be normalized before it is added to the class. \a notifierId will
|
|
+ be registered as the property's \e notify signal.
|
|
+
|
|
+ \sa property(), propertyCount(), removeProperty(), indexOfProperty()
|
|
+*/
|
|
+QMetaPropertyBuilder QMetaObjectBuilder::addProperty
|
|
+ (const QByteArray& name, const QByteArray& type, int notifierId)
|
|
+{
|
|
+ int index = d->properties.size();
|
|
+ d->properties.append(QMetaPropertyBuilderPrivate(name, type, notifierId));
|
|
+ return QMetaPropertyBuilder(this, index);
|
|
+}
|
|
+
|
|
+/*!
|
|
+ Adds a new property to this class that has the same information as
|
|
+ \a prototype. This is used to clone the properties of an existing
|
|
+ QMetaObject. Returns an object that can be used to adjust the
|
|
+ attributes of the property.
|
|
+
|
|
+ \sa property(), propertyCount(), removeProperty(), indexOfProperty()
|
|
+*/
|
|
+QMetaPropertyBuilder QMetaObjectBuilder::addProperty(const QMetaProperty& prototype)
|
|
+{
|
|
+ QMetaPropertyBuilder property = addProperty(prototype.name(), prototype.typeName());
|
|
+ property.setReadable(prototype.isReadable());
|
|
+ property.setWritable(prototype.isWritable());
|
|
+ property.setResettable(prototype.isResettable());
|
|
+ property.setDesignable(prototype.isDesignable());
|
|
+ property.setScriptable(prototype.isScriptable());
|
|
+ property.setStored(prototype.isStored());
|
|
+ property.setEditable(prototype.isEditable());
|
|
+ property.setUser(prototype.isUser());
|
|
+ property.setStdCppSet(prototype.hasStdCppSet());
|
|
+ property.setEnumOrFlag(prototype.isEnumType());
|
|
+ if (prototype.hasNotifySignal()) {
|
|
+ // Find an existing method for the notify signal, or add a new one.
|
|
+ QMetaMethod method = prototype.notifySignal();
|
|
+ int index = indexOfMethod(method.signature());
|
|
+ if (index == -1)
|
|
+ index = addMethod(method).index();
|
|
+ d->properties[property._index].notifySignal = index;
|
|
+ d->properties[property._index].setFlag(Notify, true);
|
|
+ }
|
|
+ return property;
|
|
+}
|
|
+
|
|
+/*!
|
|
+ Adds a new enumerator to this class with the specified
|
|
+ \a name. Returns an object that can be used to adjust
|
|
+ the other attributes of the enumerator.
|
|
+
|
|
+ \sa enumerator(), enumeratorCount(), removeEnumerator(),
|
|
+ \sa indexOfEnumerator()
|
|
+*/
|
|
+QMetaEnumBuilder QMetaObjectBuilder::addEnumerator(const QByteArray& name)
|
|
+{
|
|
+ int index = d->enumerators.size();
|
|
+ d->enumerators.append(QMetaEnumBuilderPrivate(name));
|
|
+ return QMetaEnumBuilder(this, index);
|
|
+}
|
|
+
|
|
+/*!
|
|
+ Adds a new enumerator to this class that has the same information as
|
|
+ \a prototype. This is used to clone the enumerators of an existing
|
|
+ QMetaObject. Returns an object that can be used to adjust the
|
|
+ attributes of the enumerator.
|
|
+
|
|
+ \sa enumerator(), enumeratorCount(), removeEnumerator(),
|
|
+ \sa indexOfEnumerator()
|
|
+*/
|
|
+QMetaEnumBuilder QMetaObjectBuilder::addEnumerator(const QMetaEnum& prototype)
|
|
+{
|
|
+ QMetaEnumBuilder en = addEnumerator(prototype.name());
|
|
+ en.setIsFlag(prototype.isFlag());
|
|
+ int count = prototype.keyCount();
|
|
+ for (int index = 0; index < count; ++index)
|
|
+ en.addKey(prototype.key(index), prototype.value(index));
|
|
+ return en;
|
|
+}
|
|
+
|
|
+/*!
|
|
+ Adds \a name and \a value as an item of class information to this class.
|
|
+ Returns the index of the new item of class information.
|
|
+
|
|
+ \sa classInfoCount(), classInfoName(), classInfoValue(), removeClassInfo()
|
|
+ \sa indexOfClassInfo()
|
|
+*/
|
|
+int QMetaObjectBuilder::addClassInfo(const QByteArray& name, const QByteArray& value)
|
|
+{
|
|
+ int index = d->classInfoNames.size();
|
|
+ d->classInfoNames += name;
|
|
+ d->classInfoValues += value;
|
|
+ return index;
|
|
+}
|
|
+
|
|
+/*!
|
|
+ Adds \a meta to this class as a related meta object. Returns
|
|
+ the index of the new related meta object entry.
|
|
+
|
|
+ Related meta objects are used when resolving the enumerated type
|
|
+ associated with a property, where the enumerated type is in a
|
|
+ different class from the property.
|
|
+
|
|
+ \sa relatedMetaObjectCount(), relatedMetaObject()
|
|
+ \sa removeRelatedMetaObject()
|
|
+*/
|
|
+#ifdef Q_NO_DATA_RELOCATION
|
|
+int QMetaObjectBuilder::addRelatedMetaObject(const QMetaObjectAccessor &meta)
|
|
+#else
|
|
+int QMetaObjectBuilder::addRelatedMetaObject(const QMetaObject *meta)
|
|
+#endif
|
|
+{
|
|
+ Q_ASSERT(meta);
|
|
+ int index = d->relatedMetaObjects.size();
|
|
+ d->relatedMetaObjects.append(meta);
|
|
+ return index;
|
|
+}
|
|
+
|
|
+/*!
|
|
+ Adds the contents of \a prototype to this meta object builder.
|
|
+ This function is useful for cloning the contents of an existing QMetaObject.
|
|
+
|
|
+ The \a members parameter indicates which members of \a prototype
|
|
+ should be added. The default is AllMembers.
|
|
+*/
|
|
+void QMetaObjectBuilder::addMetaObject
|
|
+ (const QMetaObject *prototype, QMetaObjectBuilder::AddMembers members)
|
|
+{
|
|
+ Q_ASSERT(prototype);
|
|
+ int index;
|
|
+
|
|
+ if ((members & ClassName) != 0)
|
|
+ d->className = prototype->className();
|
|
+
|
|
+ if ((members & SuperClass) != 0)
|
|
+ d->superClass = prototype->superClass();
|
|
+
|
|
+ if ((members & (Methods | Signals | Slots)) != 0) {
|
|
+ for (index = prototype->methodOffset(); index < prototype->methodCount(); ++index) {
|
|
+ QMetaMethod method = prototype->method(index);
|
|
+ if (method.methodType() != QMetaMethod::Signal) {
|
|
+ if (method.access() == QMetaMethod::Public && (members & PublicMethods) == 0)
|
|
+ continue;
|
|
+ if (method.access() == QMetaMethod::Private && (members & PrivateMethods) == 0)
|
|
+ continue;
|
|
+ if (method.access() == QMetaMethod::Protected && (members & ProtectedMethods) == 0)
|
|
+ continue;
|
|
+ }
|
|
+ if (method.methodType() == QMetaMethod::Method && (members & Methods) != 0) {
|
|
+ addMethod(method);
|
|
+ } else if (method.methodType() == QMetaMethod::Signal &&
|
|
+ (members & Signals) != 0) {
|
|
+ addMethod(method);
|
|
+ } else if (method.methodType() == QMetaMethod::Slot &&
|
|
+ (members & Slots) != 0) {
|
|
+ addMethod(method);
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if ((members & Constructors) != 0) {
|
|
+ for (index = 0; index < prototype->constructorCount(); ++index)
|
|
+ addConstructor(prototype->constructor(index));
|
|
+ }
|
|
+
|
|
+ if ((members & Properties) != 0) {
|
|
+ for (index = prototype->propertyOffset(); index < prototype->propertyCount(); ++index)
|
|
+ addProperty(prototype->property(index));
|
|
+ }
|
|
+
|
|
+ if ((members & Enumerators) != 0) {
|
|
+ for (index = prototype->enumeratorOffset(); index < prototype->enumeratorCount(); ++index)
|
|
+ addEnumerator(prototype->enumerator(index));
|
|
+ }
|
|
+
|
|
+ if ((members & ClassInfos) != 0) {
|
|
+ for (index = prototype->classInfoOffset(); index < prototype->classInfoCount(); ++index) {
|
|
+ QMetaClassInfo ci = prototype->classInfo(index);
|
|
+ addClassInfo(ci.name(), ci.value());
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if ((members & RelatedMetaObjects) != 0) {
|
|
+#ifdef Q_NO_DATA_RELOCATION
|
|
+ const QMetaObjectAccessor *objects = 0;
|
|
+#else
|
|
+ const QMetaObject **objects;
|
|
+ if (priv(prototype->d.data)->revision < 2) {
|
|
+ objects = (const QMetaObject **)(prototype->d.extradata);
|
|
+ } else
|
|
+#endif
|
|
+ {
|
|
+ const QMetaObjectExtraData *extra = (const QMetaObjectExtraData *)(prototype->d.extradata);
|
|
+ if (extra)
|
|
+ objects = extra->objects;
|
|
+ else
|
|
+ objects = 0;
|
|
+ }
|
|
+ if (objects) {
|
|
+ while (*objects != 0) {
|
|
+ addRelatedMetaObject(*objects);
|
|
+ ++objects;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if ((members & StaticMetacall) != 0) {
|
|
+ if (priv(prototype->d.data)->revision >= 2) {
|
|
+ const QMetaObjectExtraData *extra =
|
|
+ (const QMetaObjectExtraData *)(prototype->d.extradata);
|
|
+ if (extra && extra->static_metacall)
|
|
+ setStaticMetacallFunction(extra->static_metacall);
|
|
+ }
|
|
+ }
|
|
+}
|
|
+
|
|
+/*!
|
|
+ Returns the method at \a index in this class.
|
|
+
|
|
+ \sa methodCount(), addMethod(), removeMethod(), indexOfMethod()
|
|
+*/
|
|
+QMetaMethodBuilder QMetaObjectBuilder::method(int index) const
|
|
+{
|
|
+ if (index >= 0 && index < d->methods.size())
|
|
+ return QMetaMethodBuilder(this, index);
|
|
+ else
|
|
+ return QMetaMethodBuilder();
|
|
+}
|
|
+
|
|
+/*!
|
|
+ Returns the constructor at \a index in this class.
|
|
+
|
|
+ \sa methodCount(), addMethod(), removeMethod(), indexOfConstructor()
|
|
+*/
|
|
+QMetaMethodBuilder QMetaObjectBuilder::constructor(int index) const
|
|
+{
|
|
+ if (index >= 0 && index < d->constructors.size())
|
|
+ return QMetaMethodBuilder(this, -(index + 1));
|
|
+ else
|
|
+ return QMetaMethodBuilder();
|
|
+}
|
|
+
|
|
+/*!
|
|
+ Returns the property at \a index in this class.
|
|
+
|
|
+ \sa methodCount(), addMethod(), removeMethod(), indexOfProperty()
|
|
+*/
|
|
+QMetaPropertyBuilder QMetaObjectBuilder::property(int index) const
|
|
+{
|
|
+ if (index >= 0 && index < d->properties.size())
|
|
+ return QMetaPropertyBuilder(this, index);
|
|
+ else
|
|
+ return QMetaPropertyBuilder();
|
|
+}
|
|
+
|
|
+/*!
|
|
+ Returns the enumerator at \a index in this class.
|
|
+
|
|
+ \sa enumeratorCount(), addEnumerator(), removeEnumerator()
|
|
+ \sa indexOfEnumerator()
|
|
+*/
|
|
+QMetaEnumBuilder QMetaObjectBuilder::enumerator(int index) const
|
|
+{
|
|
+ if (index >= 0 && index < d->enumerators.size())
|
|
+ return QMetaEnumBuilder(this, index);
|
|
+ else
|
|
+ return QMetaEnumBuilder();
|
|
+}
|
|
+
|
|
+/*!
|
|
+ Returns the related meta object at \a index in this class.
|
|
+
|
|
+ Related meta objects are used when resolving the enumerated type
|
|
+ associated with a property, where the enumerated type is in a
|
|
+ different class from the property.
|
|
+
|
|
+ \sa relatedMetaObjectCount(), addRelatedMetaObject()
|
|
+ \sa removeRelatedMetaObject()
|
|
+*/
|
|
+const QMetaObject *QMetaObjectBuilder::relatedMetaObject(int index) const
|
|
+{
|
|
+ if (index >= 0 && index < d->relatedMetaObjects.size())
|
|
+#ifdef Q_NO_DATA_RELOCATION
|
|
+ return &((*(d->relatedMetaObjects[index]))());
|
|
+#else
|
|
+ return d->relatedMetaObjects[index];
|
|
+#endif
|
|
+ else
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+/*!
|
|
+ Returns the name of the item of class information at \a index
|
|
+ in this class.
|
|
+
|
|
+ \sa classInfoCount(), addClassInfo(), classInfoValue(), removeClassInfo()
|
|
+ \sa indexOfClassInfo()
|
|
+*/
|
|
+QByteArray QMetaObjectBuilder::classInfoName(int index) const
|
|
+{
|
|
+ if (index >= 0 && index < d->classInfoNames.size())
|
|
+ return d->classInfoNames[index];
|
|
+ else
|
|
+ return QByteArray();
|
|
+}
|
|
+
|
|
+/*!
|
|
+ Returns the value of the item of class information at \a index
|
|
+ in this class.
|
|
+
|
|
+ \sa classInfoCount(), addClassInfo(), classInfoName(), removeClassInfo()
|
|
+ \sa indexOfClassInfo()
|
|
+*/
|
|
+QByteArray QMetaObjectBuilder::classInfoValue(int index) const
|
|
+{
|
|
+ if (index >= 0 && index < d->classInfoValues.size())
|
|
+ return d->classInfoValues[index];
|
|
+ else
|
|
+ return QByteArray();
|
|
+}
|
|
+
|
|
+/*!
|
|
+ Removes the method at \a index from this class. The indices of
|
|
+ all following methods will be adjusted downwards by 1. If the
|
|
+ method is registered as a notify signal on a property, then the
|
|
+ notify signal will be removed from the property.
|
|
+
|
|
+ \sa methodCount(), addMethod(), method(), indexOfMethod()
|
|
+*/
|
|
+void QMetaObjectBuilder::removeMethod(int index)
|
|
+{
|
|
+ if (index >= 0 && index < d->methods.size()) {
|
|
+ d->methods.removeAt(index);
|
|
+ for (int prop = 0; prop < d->properties.size(); ++prop) {
|
|
+ // Adjust the indices of property notify signal references.
|
|
+ if (d->properties[prop].notifySignal == index) {
|
|
+ d->properties[prop].notifySignal = -1;
|
|
+ d->properties[prop].setFlag(Notify, false);
|
|
+ } else if (d->properties[prop].notifySignal > index)
|
|
+ (d->properties[prop].notifySignal)--;
|
|
+ }
|
|
+ }
|
|
+}
|
|
+
|
|
+/*!
|
|
+ Removes the constructor at \a index from this class. The indices of
|
|
+ all following constructors will be adjusted downwards by 1.
|
|
+
|
|
+ \sa constructorCount(), addConstructor(), constructor()
|
|
+ \sa indexOfConstructor()
|
|
+*/
|
|
+void QMetaObjectBuilder::removeConstructor(int index)
|
|
+{
|
|
+ if (index >= 0 && index < d->constructors.size())
|
|
+ d->constructors.removeAt(index);
|
|
+}
|
|
+
|
|
+/*!
|
|
+ Removes the property at \a index from this class. The indices of
|
|
+ all following properties will be adjusted downwards by 1.
|
|
+
|
|
+ \sa propertyCount(), addProperty(), property(), indexOfProperty()
|
|
+*/
|
|
+void QMetaObjectBuilder::removeProperty(int index)
|
|
+{
|
|
+ if (index >= 0 && index < d->properties.size())
|
|
+ d->properties.removeAt(index);
|
|
+}
|
|
+
|
|
+/*!
|
|
+ Removes the enumerator at \a index from this class. The indices of
|
|
+ all following enumerators will be adjusted downwards by 1.
|
|
+
|
|
+ \sa enumertorCount(), addEnumerator(), enumerator()
|
|
+ \sa indexOfEnumerator()
|
|
+*/
|
|
+void QMetaObjectBuilder::removeEnumerator(int index)
|
|
+{
|
|
+ if (index >= 0 && index < d->enumerators.size())
|
|
+ d->enumerators.removeAt(index);
|
|
+}
|
|
+
|
|
+/*!
|
|
+ Removes the item of class information at \a index from this class.
|
|
+ The indices of all following items will be adjusted downwards by 1.
|
|
+
|
|
+ \sa classInfoCount(), addClassInfo(), classInfoName(), classInfoValue()
|
|
+ \sa indexOfClassInfo()
|
|
+*/
|
|
+void QMetaObjectBuilder::removeClassInfo(int index)
|
|
+{
|
|
+ if (index >= 0 && index < d->classInfoNames.size()) {
|
|
+ d->classInfoNames.removeAt(index);
|
|
+ d->classInfoValues.removeAt(index);
|
|
+ }
|
|
+}
|
|
+
|
|
+/*!
|
|
+ Removes the related meta object at \a index from this class.
|
|
+ The indices of all following related meta objects will be adjusted
|
|
+ downwards by 1.
|
|
+
|
|
+ Related meta objects are used when resolving the enumerated type
|
|
+ associated with a property, where the enumerated type is in a
|
|
+ different class from the property.
|
|
+
|
|
+ \sa relatedMetaObjectCount(), addRelatedMetaObject()
|
|
+ \sa relatedMetaObject()
|
|
+*/
|
|
+void QMetaObjectBuilder::removeRelatedMetaObject(int index)
|
|
+{
|
|
+ if (index >= 0 && index < d->relatedMetaObjects.size())
|
|
+ d->relatedMetaObjects.removeAt(index);
|
|
+}
|
|
+
|
|
+/*!
|
|
+ Finds a method with the specified \a signature and returns its index;
|
|
+ otherwise returns -1. The \a signature will be normalized by this method.
|
|
+
|
|
+ \sa method(), methodCount(), addMethod(), removeMethod()
|
|
+*/
|
|
+int QMetaObjectBuilder::indexOfMethod(const QByteArray& signature)
|
|
+{
|
|
+ QByteArray sig = QMetaObject::normalizedSignature(signature);
|
|
+ for (int index = 0; index < d->methods.size(); ++index) {
|
|
+ if (sig == d->methods[index].signature)
|
|
+ return index;
|
|
+ }
|
|
+ return -1;
|
|
+}
|
|
+
|
|
+/*!
|
|
+ Finds a signal with the specified \a signature and returns its index;
|
|
+ otherwise returns -1. The \a signature will be normalized by this method.
|
|
+
|
|
+ \sa indexOfMethod(), indexOfSlot()
|
|
+*/
|
|
+int QMetaObjectBuilder::indexOfSignal(const QByteArray& signature)
|
|
+{
|
|
+ QByteArray sig = QMetaObject::normalizedSignature(signature);
|
|
+ for (int index = 0; index < d->methods.size(); ++index) {
|
|
+ if (sig == d->methods[index].signature &&
|
|
+ d->methods[index].methodType() == QMetaMethod::Signal)
|
|
+ return index;
|
|
+ }
|
|
+ return -1;
|
|
+}
|
|
+
|
|
+/*!
|
|
+ Finds a slot with the specified \a signature and returns its index;
|
|
+ otherwise returns -1. The \a signature will be normalized by this method.
|
|
+
|
|
+ \sa indexOfMethod(), indexOfSignal()
|
|
+*/
|
|
+int QMetaObjectBuilder::indexOfSlot(const QByteArray& signature)
|
|
+{
|
|
+ QByteArray sig = QMetaObject::normalizedSignature(signature);
|
|
+ for (int index = 0; index < d->methods.size(); ++index) {
|
|
+ if (sig == d->methods[index].signature &&
|
|
+ d->methods[index].methodType() == QMetaMethod::Slot)
|
|
+ return index;
|
|
+ }
|
|
+ return -1;
|
|
+}
|
|
+
|
|
+/*!
|
|
+ Finds a constructor with the specified \a signature and returns its index;
|
|
+ otherwise returns -1. The \a signature will be normalized by this method.
|
|
+
|
|
+ \sa constructor(), constructorCount(), addConstructor(), removeConstructor()
|
|
+*/
|
|
+int QMetaObjectBuilder::indexOfConstructor(const QByteArray& signature)
|
|
+{
|
|
+ QByteArray sig = QMetaObject::normalizedSignature(signature);
|
|
+ for (int index = 0; index < d->constructors.size(); ++index) {
|
|
+ if (sig == d->constructors[index].signature)
|
|
+ return index;
|
|
+ }
|
|
+ return -1;
|
|
+}
|
|
+
|
|
+/*!
|
|
+ Finds a property with the specified \a name and returns its index;
|
|
+ otherwise returns -1.
|
|
+
|
|
+ \sa property(), propertyCount(), addProperty(), removeProperty()
|
|
+*/
|
|
+int QMetaObjectBuilder::indexOfProperty(const QByteArray& name)
|
|
+{
|
|
+ for (int index = 0; index < d->properties.size(); ++index) {
|
|
+ if (name == d->properties[index].name)
|
|
+ return index;
|
|
+ }
|
|
+ return -1;
|
|
+}
|
|
+
|
|
+/*!
|
|
+ Finds an enumerator with the specified \a name and returns its index;
|
|
+ otherwise returns -1.
|
|
+
|
|
+ \sa enumertor(), enumeratorCount(), addEnumerator(), removeEnumerator()
|
|
+*/
|
|
+int QMetaObjectBuilder::indexOfEnumerator(const QByteArray& name)
|
|
+{
|
|
+ for (int index = 0; index < d->enumerators.size(); ++index) {
|
|
+ if (name == d->enumerators[index].name)
|
|
+ return index;
|
|
+ }
|
|
+ return -1;
|
|
+}
|
|
+
|
|
+/*!
|
|
+ Finds an item of class information with the specified \a name and
|
|
+ returns its index; otherwise returns -1.
|
|
+
|
|
+ \sa classInfoName(), classInfoValue(), classInfoCount(), addClassInfo()
|
|
+ \sa removeClassInfo()
|
|
+*/
|
|
+int QMetaObjectBuilder::indexOfClassInfo(const QByteArray& name)
|
|
+{
|
|
+ for (int index = 0; index < d->classInfoNames.size(); ++index) {
|
|
+ if (name == d->classInfoNames[index])
|
|
+ return index;
|
|
+ }
|
|
+ return -1;
|
|
+}
|
|
+
|
|
+// Align on a specific type boundary.
|
|
+#define ALIGN(size,type) \
|
|
+ (size) = ((size) + sizeof(type) - 1) & ~(sizeof(type) - 1)
|
|
+
|
|
+// Build a string into a QMetaObject representation. Returns the
|
|
+// position in the string table where the string was placed.
|
|
+static int buildString
|
|
+ (char *buf, char *str, int *offset, const QByteArray& value, int empty)
|
|
+{
|
|
+ if (value.size() == 0 && empty >= 0)
|
|
+ return empty;
|
|
+ if (buf) {
|
|
+ memcpy(str + *offset, value.constData(), value.size());
|
|
+ str[*offset + value.size()] = '\0';
|
|
+ }
|
|
+ int posn = *offset;
|
|
+ *offset += value.size() + 1;
|
|
+ return posn;
|
|
+}
|
|
+
|
|
+// Build the parameter array string for a method.
|
|
+static QByteArray buildParameterNames
|
|
+ (const QByteArray& signature, const QList<QByteArray>& parameterNames)
|
|
+{
|
|
+ // If the parameter name list is specified, then concatenate them.
|
|
+ if (!parameterNames.isEmpty()) {
|
|
+ QByteArray names;
|
|
+ bool first = true;
|
|
+ foreach (const QByteArray &name, parameterNames) {
|
|
+ if (first)
|
|
+ first = false;
|
|
+ else
|
|
+ names += (char)',';
|
|
+ names += name;
|
|
+ }
|
|
+ return names;
|
|
+ }
|
|
+
|
|
+ // Count commas in the signature, excluding those inside template arguments.
|
|
+ int index = signature.indexOf('(');
|
|
+ if (index < 0)
|
|
+ return QByteArray();
|
|
+ ++index;
|
|
+ if (index >= signature.size())
|
|
+ return QByteArray();
|
|
+ if (signature[index] == ')')
|
|
+ return QByteArray();
|
|
+ int count = 1;
|
|
+ int brackets = 0;
|
|
+ while (index < signature.size() && signature[index] != ',') {
|
|
+ char ch = signature[index++];
|
|
+ if (ch == '<')
|
|
+ ++brackets;
|
|
+ else if (ch == '>')
|
|
+ --brackets;
|
|
+ else if (ch == ',' && brackets <= 0)
|
|
+ ++count;
|
|
+ }
|
|
+ return QByteArray(count - 1, ',');
|
|
+}
|
|
+
|
|
+// Build a QMetaObject in "buf" based on the information in "d".
|
|
+// If "buf" is null, then return the number of bytes needed to
|
|
+// build the QMetaObject. Returns -1 if the metaobject if
|
|
+// relocatable is set, but the metaobject contains extradata.
|
|
+static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf,
|
|
+ bool relocatable)
|
|
+{
|
|
+ int size = 0;
|
|
+ int dataIndex;
|
|
+ int enumIndex;
|
|
+ int index;
|
|
+ bool hasNotifySignals = false;
|
|
+
|
|
+ if (relocatable &&
|
|
+ (d->relatedMetaObjects.size() > 0 || d->staticMetacallFunction))
|
|
+ return -1;
|
|
+
|
|
+ // Create the main QMetaObject structure at the start of the buffer.
|
|
+ QMetaObject *meta = reinterpret_cast<QMetaObject *>(buf);
|
|
+ size += sizeof(QMetaObject);
|
|
+ ALIGN(size, int);
|
|
+ if (buf) {
|
|
+ if (!relocatable) meta->d.superdata = d->superClass;
|
|
+ meta->d.extradata = 0;
|
|
+ }
|
|
+
|
|
+ // Populate the QMetaObjectPrivate structure.
|
|
+ QMetaObjectPrivate *pmeta
|
|
+ = reinterpret_cast<QMetaObjectPrivate *>(buf + size);
|
|
+ int pmetaSize = size;
|
|
+ dataIndex = 13; // Number of fields in the QMetaObjectPrivate.
|
|
+ for (index = 0; index < d->properties.size(); ++index) {
|
|
+ if (d->properties[index].notifySignal != -1) {
|
|
+ hasNotifySignals = true;
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+ if (buf) {
|
|
+ pmeta->revision = 3;
|
|
+ pmeta->flags = d->flags;
|
|
+ pmeta->className = 0; // Class name is always the first string.
|
|
+
|
|
+ pmeta->classInfoCount = d->classInfoNames.size();
|
|
+ pmeta->classInfoData = dataIndex;
|
|
+ dataIndex += 2 * d->classInfoNames.size();
|
|
+
|
|
+ pmeta->methodCount = d->methods.size();
|
|
+ pmeta->methodData = dataIndex;
|
|
+ dataIndex += 5 * d->methods.size();
|
|
+
|
|
+ pmeta->propertyCount = d->properties.size();
|
|
+ pmeta->propertyData = dataIndex;
|
|
+ dataIndex += 3 * d->properties.size();
|
|
+ if (hasNotifySignals)
|
|
+ dataIndex += d->properties.size();
|
|
+
|
|
+ pmeta->enumeratorCount = d->enumerators.size();
|
|
+ pmeta->enumeratorData = dataIndex;
|
|
+ dataIndex += 4 * d->enumerators.size();
|
|
+
|
|
+ pmeta->constructorCount = d->constructors.size();
|
|
+ pmeta->constructorData = dataIndex;
|
|
+ dataIndex += 5 * d->constructors.size();
|
|
+ } else {
|
|
+ dataIndex += 2 * d->classInfoNames.size();
|
|
+ dataIndex += 5 * d->methods.size();
|
|
+ dataIndex += 3 * d->properties.size();
|
|
+ if (hasNotifySignals)
|
|
+ dataIndex += d->properties.size();
|
|
+ dataIndex += 4 * d->enumerators.size();
|
|
+ dataIndex += 5 * d->constructors.size();
|
|
+ }
|
|
+
|
|
+ // Allocate space for the enumerator key names and values.
|
|
+ enumIndex = dataIndex;
|
|
+ for (index = 0; index < d->enumerators.size(); ++index) {
|
|
+ QMetaEnumBuilderPrivate *enumerator = &(d->enumerators[index]);
|
|
+ dataIndex += 2 * enumerator->keys.size();
|
|
+ }
|
|
+
|
|
+ // Zero terminator at the end of the data offset table.
|
|
+ ++dataIndex;
|
|
+
|
|
+ // Find the start of the data and string tables.
|
|
+ int *data = reinterpret_cast<int *>(pmeta);
|
|
+ size += dataIndex * sizeof(int);
|
|
+ char *str = reinterpret_cast<char *>(buf + size);
|
|
+ if (buf) {
|
|
+ if (relocatable) {
|
|
+ meta->d.stringdata = reinterpret_cast<const char *>((intptr_t)size);
|
|
+ meta->d.data = reinterpret_cast<uint *>((intptr_t)pmetaSize);
|
|
+ } else {
|
|
+ meta->d.stringdata = str;
|
|
+ meta->d.data = reinterpret_cast<uint *>(data);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ // Reset the current data position to just past the QMetaObjectPrivate.
|
|
+ dataIndex = 13;
|
|
+
|
|
+ // Add the class name to the string table.
|
|
+ int offset = 0;
|
|
+ buildString(buf, str, &offset, d->className, -1);
|
|
+
|
|
+ // Add a common empty string, which is used to indicate "void"
|
|
+ // method returns, empty tag strings, etc.
|
|
+ int empty = buildString(buf, str, &offset, QByteArray(), -1);
|
|
+
|
|
+ // Output the class infos,
|
|
+ for (index = 0; index < d->classInfoNames.size(); ++index) {
|
|
+ int name = buildString(buf, str, &offset, d->classInfoNames[index], empty);
|
|
+ int value = buildString(buf, str, &offset, d->classInfoValues[index], empty);
|
|
+ if (buf) {
|
|
+ data[dataIndex] = name;
|
|
+ data[dataIndex + 1] = value;
|
|
+ }
|
|
+ dataIndex += 2;
|
|
+ }
|
|
+
|
|
+ // Output the methods in the class.
|
|
+ for (index = 0; index < d->methods.size(); ++index) {
|
|
+ QMetaMethodBuilderPrivate *method = &(d->methods[index]);
|
|
+ int sig = buildString(buf, str, &offset, method->signature, empty);
|
|
+ int params;
|
|
+ QByteArray names = buildParameterNames
|
|
+ (method->signature, method->parameterNames);
|
|
+ params = buildString(buf, str, &offset, names, empty);
|
|
+ int ret = buildString(buf, str, &offset, method->returnType, empty);
|
|
+ int tag = buildString(buf, str, &offset, method->tag, empty);
|
|
+ int attrs = method->attributes;
|
|
+ if (buf) {
|
|
+ data[dataIndex] = sig;
|
|
+ data[dataIndex + 1] = params;
|
|
+ data[dataIndex + 2] = ret;
|
|
+ data[dataIndex + 3] = tag;
|
|
+ data[dataIndex + 4] = attrs;
|
|
+ }
|
|
+ dataIndex += 5;
|
|
+ }
|
|
+
|
|
+ // Output the properties in the class.
|
|
+ for (index = 0; index < d->properties.size(); ++index) {
|
|
+ QMetaPropertyBuilderPrivate *prop = &(d->properties[index]);
|
|
+ int name = buildString(buf, str, &offset, prop->name, empty);
|
|
+ int type = buildString(buf, str, &offset, prop->type, empty);
|
|
+ int flags = prop->flags;
|
|
+
|
|
+ if (!isVariantType(prop->type)) {
|
|
+ flags |= EnumOrFlag;
|
|
+ } else {
|
|
+ flags |= qvariant_nameToType(prop->type) << 24;
|
|
+ }
|
|
+
|
|
+ if (buf) {
|
|
+ data[dataIndex] = name;
|
|
+ data[dataIndex + 1] = type;
|
|
+ data[dataIndex + 2] = flags;
|
|
+ }
|
|
+ dataIndex += 3;
|
|
+ }
|
|
+ if (hasNotifySignals) {
|
|
+ for (index = 0; index < d->properties.size(); ++index) {
|
|
+ QMetaPropertyBuilderPrivate *prop = &(d->properties[index]);
|
|
+ if (buf) {
|
|
+ if (prop->notifySignal != -1)
|
|
+ data[dataIndex] = prop->notifySignal;
|
|
+ else
|
|
+ data[dataIndex] = 0;
|
|
+ }
|
|
+ ++dataIndex;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ // Output the enumerators in the class.
|
|
+ for (index = 0; index < d->enumerators.size(); ++index) {
|
|
+ QMetaEnumBuilderPrivate *enumerator = &(d->enumerators[index]);
|
|
+ int name = buildString(buf, str, &offset, enumerator->name, empty);
|
|
+ int isFlag = (int)(enumerator->isFlag);
|
|
+ int count = enumerator->keys.size();
|
|
+ int enumOffset = enumIndex;
|
|
+ if (buf) {
|
|
+ data[dataIndex] = name;
|
|
+ data[dataIndex + 1] = isFlag;
|
|
+ data[dataIndex + 2] = count;
|
|
+ data[dataIndex + 3] = enumOffset;
|
|
+ }
|
|
+ for (int key = 0; key < count; ++key) {
|
|
+ int keyIndex = buildString(buf, str, &offset, enumerator->keys[key], empty);
|
|
+ if (buf) {
|
|
+ data[enumOffset++] = keyIndex;
|
|
+ data[enumOffset++] = enumerator->values[key];
|
|
+ }
|
|
+ }
|
|
+ dataIndex += 4;
|
|
+ enumIndex += 2 * count;
|
|
+ }
|
|
+
|
|
+ // Output the constructors in the class.
|
|
+ for (index = 0; index < d->constructors.size(); ++index) {
|
|
+ QMetaMethodBuilderPrivate *method = &(d->constructors[index]);
|
|
+ int sig = buildString(buf, str, &offset, method->signature, empty);
|
|
+ int params;
|
|
+ QByteArray names = buildParameterNames
|
|
+ (method->signature, method->parameterNames);
|
|
+ params = buildString(buf, str, &offset, names, empty);
|
|
+ int ret = buildString(buf, str, &offset, method->returnType, empty);
|
|
+ int tag = buildString(buf, str, &offset, method->tag, empty);
|
|
+ int attrs = method->attributes;
|
|
+ if (buf) {
|
|
+ data[dataIndex] = sig;
|
|
+ data[dataIndex + 1] = params;
|
|
+ data[dataIndex + 2] = ret;
|
|
+ data[dataIndex + 3] = tag;
|
|
+ data[dataIndex + 4] = attrs;
|
|
+ }
|
|
+ dataIndex += 5;
|
|
+ }
|
|
+
|
|
+ // One more empty string to act as a terminator.
|
|
+ buildString(buf, str, &offset, QByteArray(), -1);
|
|
+ size += offset;
|
|
+
|
|
+ // Output the zero terminator in the data array.
|
|
+ if (buf)
|
|
+ data[enumIndex] = 0;
|
|
+
|
|
+ // Create the extradata block if we need one.
|
|
+ if (d->relatedMetaObjects.size() > 0 || d->staticMetacallFunction) {
|
|
+ ALIGN(size, QMetaObject **);
|
|
+ ALIGN(size, QMetaObjectBuilder::StaticMetacallFunction);
|
|
+ QMetaObjectExtraData *extra =
|
|
+ reinterpret_cast<QMetaObjectExtraData *>(buf + size);
|
|
+ size += sizeof(QMetaObjectExtraData);
|
|
+ ALIGN(size, QMetaObject *);
|
|
+#ifdef Q_NO_DATA_RELOCATION
|
|
+ QMetaObjectAccessor *objects =
|
|
+ reinterpret_cast<QMetaObjectAccessor *>(buf + size);
|
|
+#else
|
|
+ const QMetaObject **objects =
|
|
+ reinterpret_cast<const QMetaObject **>(buf + size);
|
|
+#endif
|
|
+ if (buf) {
|
|
+ if (d->relatedMetaObjects.size() > 0) {
|
|
+ extra->objects = objects;
|
|
+ for (index = 0; index < d->relatedMetaObjects.size(); ++index)
|
|
+ objects[index] = d->relatedMetaObjects[index];
|
|
+ objects[index] = 0;
|
|
+ } else {
|
|
+ extra->objects = 0;
|
|
+ }
|
|
+ extra->static_metacall = d->staticMetacallFunction;
|
|
+ meta->d.extradata = reinterpret_cast<void *>(extra);
|
|
+ }
|
|
+ if (d->relatedMetaObjects.size() > 0)
|
|
+ size += sizeof(QMetaObject *) * (d->relatedMetaObjects.size() + 1);
|
|
+ }
|
|
+
|
|
+ // Align the final size and return it.
|
|
+ ALIGN(size, void *);
|
|
+ return size;
|
|
+}
|
|
+
|
|
+/*!
|
|
+ Converts this meta object builder into a concrete QMetaObject.
|
|
+ The return value should be deallocated using qFree() once it
|
|
+ is no longer needed.
|
|
+
|
|
+ The returned meta object is a snapshot of the state of the
|
|
+ QMetaObjectBuilder. Any further modifications to the QMetaObjectBuilder
|
|
+ will not be reflected in previous meta objects returned by
|
|
+ this method.
|
|
+*/
|
|
+QMetaObject *QMetaObjectBuilder::toMetaObject() const
|
|
+{
|
|
+ int size = buildMetaObject(d, 0, false);
|
|
+ char *buf = reinterpret_cast<char *>(qMalloc(size));
|
|
+ buildMetaObject(d, buf, false);
|
|
+ return reinterpret_cast<QMetaObject *>(buf);
|
|
+}
|
|
+
|
|
+/*
|
|
+ \internal
|
|
+
|
|
+ Converts this meta object builder into relocatable data. This data can
|
|
+ be stored, copied and later passed to fromRelocatableData() to create a
|
|
+ concrete QMetaObject.
|
|
+
|
|
+ The data is specific to the architecture on which it was created, but is not
|
|
+ specific to the process that created it. Not all meta object builder's can
|
|
+ be converted to data in this way. If \a ok is provided, it will be set to
|
|
+ true if the conversion succeeds, and false otherwise. If a
|
|
+ staticMetacallFunction() or any relatedMetaObject()'s are specified the
|
|
+ conversion to relocatable data will fail.
|
|
+*/
|
|
+QByteArray QMetaObjectBuilder::toRelocatableData(bool *ok) const
|
|
+{
|
|
+ int size = buildMetaObject(d, 0, true);
|
|
+ if (size == -1) {
|
|
+ if (ok) *ok = false;
|
|
+ return QByteArray();
|
|
+ }
|
|
+
|
|
+ QByteArray data;
|
|
+ data.resize(size);
|
|
+ char *buf = data.data();
|
|
+ buildMetaObject(d, buf, true);
|
|
+ if (ok) *ok = true;
|
|
+ return data;
|
|
+}
|
|
+
|
|
+/*
|
|
+ \internal
|
|
+
|
|
+ Sets the \a data returned from toRelocatableData() onto a concrete
|
|
+ QMetaObject instance, \a output. As the meta object's super class is not
|
|
+ saved in the relocatable data, it must be passed as \a superClass.
|
|
+*/
|
|
+void QMetaObjectBuilder::fromRelocatableData(QMetaObject *output,
|
|
+ const QMetaObject *superclass,
|
|
+ const QByteArray &data)
|
|
+{
|
|
+ if (!output)
|
|
+ return;
|
|
+
|
|
+ const char *buf = data.constData();
|
|
+ const QMetaObject *dataMo = reinterpret_cast<const QMetaObject *>(buf);
|
|
+
|
|
+ intptr_t stringdataOffset = (intptr_t)dataMo->d.stringdata;
|
|
+ intptr_t dataOffset = (intptr_t)dataMo->d.data;
|
|
+
|
|
+ output->d.superdata = superclass;
|
|
+ output->d.stringdata = buf + stringdataOffset;
|
|
+ output->d.data = reinterpret_cast<const uint *>(buf + dataOffset);
|
|
+}
|
|
+
|
|
+/*!
|
|
+ \typedef QMetaObjectBuilder::StaticMetacallFunction
|
|
+
|
|
+ Typedef for static metacall functions. The three parameters are
|
|
+ the call type value, the constructor index, and the
|
|
+ array of parameters.
|
|
+*/
|
|
+
|
|
+/*!
|
|
+ Returns the static metacall function to use to construct objects
|
|
+ of this class. The default value is null.
|
|
+
|
|
+ \sa setStaticMetacallFunction()
|
|
+*/
|
|
+QMetaObjectBuilder::StaticMetacallFunction QMetaObjectBuilder::staticMetacallFunction() const
|
|
+{
|
|
+ return d->staticMetacallFunction;
|
|
+}
|
|
+
|
|
+/*!
|
|
+ Sets the static metacall function to use to construct objects
|
|
+ of this class to \a value. The default value is null.
|
|
+
|
|
+ \sa staticMetacallFunction()
|
|
+*/
|
|
+void QMetaObjectBuilder::setStaticMetacallFunction
|
|
+ (QMetaObjectBuilder::StaticMetacallFunction value)
|
|
+{
|
|
+ d->staticMetacallFunction = value;
|
|
+}
|
|
+
|
|
+#ifndef QT_NO_DATASTREAM
|
|
+
|
|
+/*!
|
|
+ Serializes the contents of the meta object builder onto \a stream.
|
|
+
|
|
+ \sa deserialize()
|
|
+*/
|
|
+void QMetaObjectBuilder::serialize(QDataStream& stream) const
|
|
+{
|
|
+ int index;
|
|
+
|
|
+ // Write the class and super class names.
|
|
+ stream << d->className;
|
|
+ if (d->superClass)
|
|
+ stream << QByteArray(d->superClass->className());
|
|
+ else
|
|
+ stream << QByteArray();
|
|
+
|
|
+ // Write the counts for each type of class member.
|
|
+ stream << d->classInfoNames.size();
|
|
+ stream << d->methods.size();
|
|
+ stream << d->properties.size();
|
|
+ stream << d->enumerators.size();
|
|
+ stream << d->constructors.size();
|
|
+ stream << d->relatedMetaObjects.size();
|
|
+
|
|
+ // Write the items of class information.
|
|
+ for (index = 0; index < d->classInfoNames.size(); ++index) {
|
|
+ stream << d->classInfoNames[index];
|
|
+ stream << d->classInfoValues[index];
|
|
+ }
|
|
+
|
|
+ // Write the methods.
|
|
+ for (index = 0; index < d->methods.size(); ++index) {
|
|
+ const QMetaMethodBuilderPrivate *method = &(d->methods[index]);
|
|
+ stream << method->signature;
|
|
+ stream << method->returnType;
|
|
+ stream << method->parameterNames;
|
|
+ stream << method->tag;
|
|
+ stream << method->attributes;
|
|
+ }
|
|
+
|
|
+ // Write the properties.
|
|
+ for (index = 0; index < d->properties.size(); ++index) {
|
|
+ const QMetaPropertyBuilderPrivate *property = &(d->properties[index]);
|
|
+ stream << property->name;
|
|
+ stream << property->type;
|
|
+ stream << property->flags;
|
|
+ stream << property->notifySignal;
|
|
+ }
|
|
+
|
|
+ // Write the enumerators.
|
|
+ for (index = 0; index < d->enumerators.size(); ++index) {
|
|
+ const QMetaEnumBuilderPrivate *enumerator = &(d->enumerators[index]);
|
|
+ stream << enumerator->name;
|
|
+ stream << enumerator->isFlag;
|
|
+ stream << enumerator->keys;
|
|
+ stream << enumerator->values;
|
|
+ }
|
|
+
|
|
+ // Write the constructors.
|
|
+ for (index = 0; index < d->constructors.size(); ++index) {
|
|
+ const QMetaMethodBuilderPrivate *method = &(d->constructors[index]);
|
|
+ stream << method->signature;
|
|
+ stream << method->returnType;
|
|
+ stream << method->parameterNames;
|
|
+ stream << method->tag;
|
|
+ stream << method->attributes;
|
|
+ }
|
|
+
|
|
+ // Write the related meta objects.
|
|
+#ifdef Q_NO_DATA_RELOCATION
|
|
+ //the related meta objects will be function pointers
|
|
+ //which you have to add to the builder manually.
|
|
+ //e.g.
|
|
+ //builder2.addRelatedMetaObject(QLocale::getStaticMetaObject);
|
|
+#else
|
|
+ for (index = 0; index < d->relatedMetaObjects.size(); ++index) {
|
|
+ const QMetaObject *meta = d->relatedMetaObjects[index];
|
|
+ stream << QByteArray(meta->className());
|
|
+ }
|
|
+#endif
|
|
+
|
|
+ // Add an extra empty QByteArray for additional data in future versions.
|
|
+ // This should help maintain backwards compatibility, allowing older
|
|
+ // versions to read newer data.
|
|
+ stream << QByteArray();
|
|
+}
|
|
+
|
|
+// Resolve a class name using the name reference map.
|
|
+static const QMetaObject *resolveClassName
|
|
+ (const QMap<QByteArray, const QMetaObject *>& references,
|
|
+ const QByteArray& name)
|
|
+{
|
|
+ if (name == QByteArray("QObject"))
|
|
+ return &QObject::staticMetaObject;
|
|
+ else
|
|
+ return references.value(name, 0);
|
|
+}
|
|
+
|
|
+/*!
|
|
+ Deserializes a meta object builder from \a stream into
|
|
+ this meta object builder.
|
|
+
|
|
+ The \a references parameter specifies a mapping from class names
|
|
+ to QMetaObject instances for resolving the super class name and
|
|
+ related meta objects in the object that is deserialized.
|
|
+ The meta object for QObject is implicitly added to \a references
|
|
+ and does not need to be supplied.
|
|
+
|
|
+ The QDataStream::status() value on \a stream will be set to
|
|
+ QDataStream::ReadCorruptData if the input data is corrupt.
|
|
+ The status will be set to QDataStream::ReadPastEnd if the
|
|
+ input was exhausted before the full meta object was read.
|
|
+
|
|
+ \sa serialize()
|
|
+*/
|
|
+void QMetaObjectBuilder::deserialize
|
|
+ (QDataStream& stream,
|
|
+ const QMap<QByteArray, const QMetaObject *>& references)
|
|
+{
|
|
+ QByteArray name;
|
|
+ const QMetaObject *cl;
|
|
+ int index;
|
|
+
|
|
+ // Clear all members in the builder to their default states.
|
|
+ d->className.clear();
|
|
+ d->superClass = &QObject::staticMetaObject;
|
|
+ d->classInfoNames.clear();
|
|
+ d->classInfoValues.clear();
|
|
+ d->methods.clear();
|
|
+ d->properties.clear();
|
|
+ d->enumerators.clear();
|
|
+ d->constructors.clear();
|
|
+ d->relatedMetaObjects.clear();
|
|
+ d->staticMetacallFunction = 0;
|
|
+
|
|
+ // Read the class and super class names.
|
|
+ stream >> d->className;
|
|
+ stream >> name;
|
|
+ if (name.isEmpty()) {
|
|
+ d->superClass = 0;
|
|
+ } else if ((cl = resolveClassName(references, name)) != 0) {
|
|
+ d->superClass = cl;
|
|
+ } else {
|
|
+ stream.setStatus(QDataStream::ReadCorruptData);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ // Read the counts for each type of class member.
|
|
+ int classInfoCount, methodCount, propertyCount;
|
|
+ int enumeratorCount, constructorCount, relatedMetaObjectCount;
|
|
+ stream >> classInfoCount;
|
|
+ stream >> methodCount;
|
|
+ stream >> propertyCount;
|
|
+ stream >> enumeratorCount;
|
|
+ stream >> constructorCount;
|
|
+ stream >> relatedMetaObjectCount;
|
|
+ if (classInfoCount < 0 || methodCount < 0 ||
|
|
+ propertyCount < 0 || enumeratorCount < 0 ||
|
|
+ constructorCount < 0 || relatedMetaObjectCount < 0) {
|
|
+ stream.setStatus(QDataStream::ReadCorruptData);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ // Read the items of class information.
|
|
+ for (index = 0; index < classInfoCount; ++index) {
|
|
+ if (stream.status() != QDataStream::Ok)
|
|
+ return;
|
|
+ QByteArray value;
|
|
+ stream >> name;
|
|
+ stream >> value;
|
|
+ addClassInfo(name, value);
|
|
+ }
|
|
+
|
|
+ // Read the member methods.
|
|
+ for (index = 0; index < methodCount; ++index) {
|
|
+ if (stream.status() != QDataStream::Ok)
|
|
+ return;
|
|
+ stream >> name;
|
|
+ addMethod(name);
|
|
+ QMetaMethodBuilderPrivate *method = &(d->methods[index]);
|
|
+ stream >> method->returnType;
|
|
+ stream >> method->parameterNames;
|
|
+ stream >> method->tag;
|
|
+ stream >> method->attributes;
|
|
+ if (method->methodType() == QMetaMethod::Constructor) {
|
|
+ // Cannot add a constructor in this set of methods.
|
|
+ stream.setStatus(QDataStream::ReadCorruptData);
|
|
+ return;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ // Read the properties.
|
|
+ for (index = 0; index < propertyCount; ++index) {
|
|
+ if (stream.status() != QDataStream::Ok)
|
|
+ return;
|
|
+ QByteArray type;
|
|
+ stream >> name;
|
|
+ stream >> type;
|
|
+ addProperty(name, type);
|
|
+ QMetaPropertyBuilderPrivate *property = &(d->properties[index]);
|
|
+ stream >> property->flags;
|
|
+ stream >> property->notifySignal;
|
|
+ if (property->notifySignal < -1 ||
|
|
+ property->notifySignal >= d->methods.size()) {
|
|
+ // Notify signal method index is out of range.
|
|
+ stream.setStatus(QDataStream::ReadCorruptData);
|
|
+ return;
|
|
+ }
|
|
+ if (property->notifySignal >= 0 &&
|
|
+ d->methods[property->notifySignal].methodType() != QMetaMethod::Signal) {
|
|
+ // Notify signal method index does not refer to a signal.
|
|
+ stream.setStatus(QDataStream::ReadCorruptData);
|
|
+ return;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ // Read the enumerators.
|
|
+ for (index = 0; index < enumeratorCount; ++index) {
|
|
+ if (stream.status() != QDataStream::Ok)
|
|
+ return;
|
|
+ stream >> name;
|
|
+ addEnumerator(name);
|
|
+ QMetaEnumBuilderPrivate *enumerator = &(d->enumerators[index]);
|
|
+ stream >> enumerator->isFlag;
|
|
+ stream >> enumerator->keys;
|
|
+ stream >> enumerator->values;
|
|
+ if (enumerator->keys.size() != enumerator->values.size()) {
|
|
+ // Mismatch between number of keys and number of values.
|
|
+ stream.setStatus(QDataStream::ReadCorruptData);
|
|
+ return;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ // Read the constructor methods.
|
|
+ for (index = 0; index < constructorCount; ++index) {
|
|
+ if (stream.status() != QDataStream::Ok)
|
|
+ return;
|
|
+ stream >> name;
|
|
+ addConstructor(name);
|
|
+ QMetaMethodBuilderPrivate *method = &(d->constructors[index]);
|
|
+ stream >> method->returnType;
|
|
+ stream >> method->parameterNames;
|
|
+ stream >> method->tag;
|
|
+ stream >> method->attributes;
|
|
+ if (method->methodType() != QMetaMethod::Constructor) {
|
|
+ // The type must be Constructor.
|
|
+ stream.setStatus(QDataStream::ReadCorruptData);
|
|
+ return;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ // Read the related meta objects.
|
|
+#ifdef Q_NO_DATA_RELOCATION
|
|
+ //the related meta objects will be function pointers
|
|
+ //which you have to add to the builder manually.
|
|
+ //e.g.
|
|
+ //builder2.addRelatedMetaObject(QLocale::getStaticMetaObject);
|
|
+#else
|
|
+ for (index = 0; index < relatedMetaObjectCount; ++index) {
|
|
+ if (stream.status() != QDataStream::Ok)
|
|
+ return;
|
|
+ stream >> name;
|
|
+ cl = resolveClassName(references, name);
|
|
+ if (!cl) {
|
|
+ stream.setStatus(QDataStream::ReadCorruptData);
|
|
+ return;
|
|
+ }
|
|
+ addRelatedMetaObject(cl);
|
|
+ }
|
|
+#endif
|
|
+
|
|
+ // Read the extra data block, which is reserved for future use.
|
|
+ stream >> name;
|
|
+}
|
|
+
|
|
+#endif // !QT_NO_DATASTREAM
|
|
+
|
|
+/*!
|
|
+ \class QMetaMethodBuilder
|
|
+ \internal
|
|
+ \brief The QMetaMethodBuilder class enables modifications to a method definition on a meta object builder.
|
|
+*/
|
|
+
|
|
+QMetaMethodBuilderPrivate *QMetaMethodBuilder::d_func() const
|
|
+{
|
|
+ // Positive indices indicate methods, negative indices indicate constructors.
|
|
+ if (_mobj && _index >= 0 && _index < _mobj->d->methods.size())
|
|
+ return &(_mobj->d->methods[_index]);
|
|
+ else if (_mobj && -_index >= 1 && -_index <= _mobj->d->constructors.size())
|
|
+ return &(_mobj->d->constructors[(-_index) - 1]);
|
|
+ else
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+/*!
|
|
+ \fn QMetaMethodBuilder::QMetaMethodBuilder()
|
|
+ \internal
|
|
+*/
|
|
+
|
|
+/*!
|
|
+ Returns the index of this method within its QMetaObjectBuilder.
|
|
+*/
|
|
+int QMetaMethodBuilder::index() const
|
|
+{
|
|
+ if (_index >= 0)
|
|
+ return _index; // Method, signal, or slot
|
|
+ else
|
|
+ return (-_index) - 1; // Constructor
|
|
+}
|
|
+
|
|
+/*!
|
|
+ Returns the type of this method (signal, slot, method, or constructor).
|
|
+*/
|
|
+QMetaMethod::MethodType QMetaMethodBuilder::methodType() const
|
|
+{
|
|
+ QMetaMethodBuilderPrivate *d = d_func();
|
|
+ if (d)
|
|
+ return d->methodType();
|
|
+ else
|
|
+ return QMetaMethod::Method;
|
|
+}
|
|
+
|
|
+/*!
|
|
+ Returns the signature of this method.
|
|
+
|
|
+ \sa parameterNames(), returnType()
|
|
+*/
|
|
+QByteArray QMetaMethodBuilder::signature() const
|
|
+{
|
|
+ QMetaMethodBuilderPrivate *d = d_func();
|
|
+ if (d)
|
|
+ return d->signature;
|
|
+ else
|
|
+ return QByteArray();
|
|
+}
|
|
+
|
|
+/*!
|
|
+ Returns the return type for this method; empty if the method's
|
|
+ return type is \c{void}.
|
|
+
|
|
+ \sa setReturnType(), signature()
|
|
+*/
|
|
+QByteArray QMetaMethodBuilder::returnType() const
|
|
+{
|
|
+ QMetaMethodBuilderPrivate *d = d_func();
|
|
+ if (d)
|
|
+ return d->returnType;
|
|
+ else
|
|
+ return QByteArray();
|
|
+}
|
|
+
|
|
+/*!
|
|
+ Sets the return type for this method to \a value. If \a value
|
|
+ is empty, then the method's return type is \c{void}. The \a value
|
|
+ will be normalized before it is added to the method.
|
|
+
|
|
+ \sa returnType(), signature()
|
|
+*/
|
|
+void QMetaMethodBuilder::setReturnType(const QByteArray& value)
|
|
+{
|
|
+ QMetaMethodBuilderPrivate *d = d_func();
|
|
+ if (d)
|
|
+ d->returnType = QMetaObject::normalizedType(value);
|
|
+}
|
|
+
|
|
+/*!
|
|
+ Returns the list of parameter names for this method.
|
|
+
|
|
+ \sa setParameterNames()
|
|
+*/
|
|
+QList<QByteArray> QMetaMethodBuilder::parameterNames() const
|
|
+{
|
|
+ QMetaMethodBuilderPrivate *d = d_func();
|
|
+ if (d)
|
|
+ return d->parameterNames;
|
|
+ else
|
|
+ return QList<QByteArray>();
|
|
+}
|
|
+
|
|
+/*!
|
|
+ Sets the list of parameter names for this method to \a value.
|
|
+
|
|
+ \sa parameterNames()
|
|
+*/
|
|
+void QMetaMethodBuilder::setParameterNames(const QList<QByteArray>& value)
|
|
+{
|
|
+ QMetaMethodBuilderPrivate *d = d_func();
|
|
+ if (d)
|
|
+ d->parameterNames = value;
|
|
+}
|
|
+
|
|
+/*!
|
|
+ Returns the tag associated with this method.
|
|
+
|
|
+ \sa setTag()
|
|
+*/
|
|
+QByteArray QMetaMethodBuilder::tag() const
|
|
+{
|
|
+ QMetaMethodBuilderPrivate *d = d_func();
|
|
+ if (d)
|
|
+ return d->tag;
|
|
+ else
|
|
+ return QByteArray();
|
|
+}
|
|
+
|
|
+/*!
|
|
+ Sets the tag associated with this method to \a value.
|
|
+
|
|
+ \sa setTag()
|
|
+*/
|
|
+void QMetaMethodBuilder::setTag(const QByteArray& value)
|
|
+{
|
|
+ QMetaMethodBuilderPrivate *d = d_func();
|
|
+ if (d)
|
|
+ d->tag = value;
|
|
+}
|
|
+
|
|
+/*!
|
|
+ Returns the access specification of this method (private, protected,
|
|
+ or public). The default value is QMetaMethod::Public for methods,
|
|
+ slots, and constructors. The default value is QMetaMethod::Protected
|
|
+ for signals.
|
|
+
|
|
+ \sa setAccess()
|
|
+*/
|
|
+QMetaMethod::Access QMetaMethodBuilder::access() const
|
|
+{
|
|
+ QMetaMethodBuilderPrivate *d = d_func();
|
|
+ if (d)
|
|
+ return d->access();
|
|
+ else
|
|
+ return QMetaMethod::Public;
|
|
+}
|
|
+
|
|
+/*!
|
|
+ Sets the access specification of this method (private, protected,
|
|
+ or public) to \a value. If the method is a signal, this function
|
|
+ will be ignored.
|
|
+
|
|
+ \sa access()
|
|
+*/
|
|
+void QMetaMethodBuilder::setAccess(QMetaMethod::Access value)
|
|
+{
|
|
+ QMetaMethodBuilderPrivate *d = d_func();
|
|
+ if (d && d->methodType() != QMetaMethod::Signal)
|
|
+ d->setAccess(value);
|
|
+}
|
|
+
|
|
+/*!
|
|
+ Returns the additional attributes for this method.
|
|
+
|
|
+ \sa setAttributes()
|
|
+*/
|
|
+int QMetaMethodBuilder::attributes() const
|
|
+{
|
|
+ QMetaMethodBuilderPrivate *d = d_func();
|
|
+ if (d)
|
|
+ return (d->attributes >> 4);
|
|
+ else
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+/*!
|
|
+ Sets the additional attributes for this method to \a value.
|
|
+
|
|
+ \sa attributes()
|
|
+*/
|
|
+void QMetaMethodBuilder::setAttributes(int value)
|
|
+{
|
|
+ QMetaMethodBuilderPrivate *d = d_func();
|
|
+ if (d)
|
|
+ d->attributes = ((d->attributes & 0x0f) | (value << 4));
|
|
+}
|
|
+
|
|
+/*!
|
|
+ \class QMetaPropertyBuilder
|
|
+ \internal
|
|
+ \brief The QMetaPropertyBuilder class enables modifications to a property definition on a meta object builder.
|
|
+*/
|
|
+
|
|
+QMetaPropertyBuilderPrivate *QMetaPropertyBuilder::d_func() const
|
|
+{
|
|
+ if (_mobj && _index >= 0 && _index < _mobj->d->properties.size())
|
|
+ return &(_mobj->d->properties[_index]);
|
|
+ else
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+/*!
|
|
+ \fn QMetaPropertyBuilder::QMetaPropertyBuilder()
|
|
+ \internal
|
|
+*/
|
|
+
|
|
+/*!
|
|
+ \fn int QMetaPropertyBuilder::index() const
|
|
+
|
|
+ Returns the index of this property within its QMetaObjectBuilder.
|
|
+*/
|
|
+
|
|
+/*!
|
|
+ Returns the name associated with this property.
|
|
+
|
|
+ \sa type()
|
|
+*/
|
|
+QByteArray QMetaPropertyBuilder::name() const
|
|
+{
|
|
+ QMetaPropertyBuilderPrivate *d = d_func();
|
|
+ if (d)
|
|
+ return d->name;
|
|
+ else
|
|
+ return QByteArray();
|
|
+}
|
|
+
|
|
+/*!
|
|
+ Returns the type associated with this property.
|
|
+
|
|
+ \sa name()
|
|
+*/
|
|
+QByteArray QMetaPropertyBuilder::type() const
|
|
+{
|
|
+ QMetaPropertyBuilderPrivate *d = d_func();
|
|
+ if (d)
|
|
+ return d->type;
|
|
+ else
|
|
+ return QByteArray();
|
|
+}
|
|
+
|
|
+/*!
|
|
+ Returns true if this property has a notify signal; false otherwise.
|
|
+
|
|
+ \sa notifySignal(), setNotifySignal(), removeNotifySignal()
|
|
+*/
|
|
+bool QMetaPropertyBuilder::hasNotifySignal() const
|
|
+{
|
|
+ QMetaPropertyBuilderPrivate *d = d_func();
|
|
+ if (d)
|
|
+ return d->flag(Notify);
|
|
+ else
|
|
+ return false;
|
|
+}
|
|
+
|
|
+/*!
|
|
+ Returns the notify signal associated with this property.
|
|
+
|
|
+ \sa hasNotifySignal(), setNotifySignal(), removeNotifySignal()
|
|
+*/
|
|
+QMetaMethodBuilder QMetaPropertyBuilder::notifySignal() const
|
|
+{
|
|
+ QMetaPropertyBuilderPrivate *d = d_func();
|
|
+ if (d && d->notifySignal >= 0)
|
|
+ return QMetaMethodBuilder(_mobj, d->notifySignal);
|
|
+ else
|
|
+ return QMetaMethodBuilder();
|
|
+}
|
|
+
|
|
+/*!
|
|
+ Sets the notify signal associated with this property to \a value.
|
|
+
|
|
+ \sa hasNotifySignal(), notifySignal(), removeNotifySignal()
|
|
+*/
|
|
+void QMetaPropertyBuilder::setNotifySignal(const QMetaMethodBuilder& value)
|
|
+{
|
|
+ QMetaPropertyBuilderPrivate *d = d_func();
|
|
+ if (d) {
|
|
+ if (value._mobj) {
|
|
+ d->notifySignal = value._index;
|
|
+ d->setFlag(Notify, true);
|
|
+ } else {
|
|
+ d->notifySignal = -1;
|
|
+ d->setFlag(Notify, false);
|
|
+ }
|
|
+ }
|
|
+}
|
|
+
|
|
+/*!
|
|
+ Removes the notify signal from this property.
|
|
+
|
|
+ \sa hasNotifySignal(), notifySignal(), setNotifySignal()
|
|
+*/
|
|
+void QMetaPropertyBuilder::removeNotifySignal()
|
|
+{
|
|
+ QMetaPropertyBuilderPrivate *d = d_func();
|
|
+ if (d) {
|
|
+ d->notifySignal = -1;
|
|
+ d->setFlag(Notify, false);
|
|
+ }
|
|
+}
|
|
+
|
|
+/*!
|
|
+ Returns true if this property is readable; otherwise returns false.
|
|
+ The default value is true.
|
|
+
|
|
+ \sa setReadable(), isWritable()
|
|
+*/
|
|
+bool QMetaPropertyBuilder::isReadable() const
|
|
+{
|
|
+ QMetaPropertyBuilderPrivate *d = d_func();
|
|
+ if (d)
|
|
+ return d->flag(Readable);
|
|
+ else
|
|
+ return false;
|
|
+}
|
|
+
|
|
+/*!
|
|
+ Returns true if this property is writable; otherwise returns false.
|
|
+ The default value is true.
|
|
+
|
|
+ \sa setWritable(), isReadable()
|
|
+*/
|
|
+bool QMetaPropertyBuilder::isWritable() const
|
|
+{
|
|
+ QMetaPropertyBuilderPrivate *d = d_func();
|
|
+ if (d)
|
|
+ return d->flag(Writable);
|
|
+ else
|
|
+ return false;
|
|
+}
|
|
+
|
|
+/*!
|
|
+ Returns true if this property can be reset to a default value; otherwise
|
|
+ returns false. The default value is false.
|
|
+
|
|
+ \sa setResettable()
|
|
+*/
|
|
+bool QMetaPropertyBuilder::isResettable() const
|
|
+{
|
|
+ QMetaPropertyBuilderPrivate *d = d_func();
|
|
+ if (d)
|
|
+ return d->flag(Resettable);
|
|
+ else
|
|
+ return false;
|
|
+}
|
|
+
|
|
+/*!
|
|
+ Returns true if this property is designable; otherwise returns false.
|
|
+ This default value is false.
|
|
+
|
|
+ \sa setDesignable(), isScriptable(), isStored()
|
|
+*/
|
|
+bool QMetaPropertyBuilder::isDesignable() const
|
|
+{
|
|
+ QMetaPropertyBuilderPrivate *d = d_func();
|
|
+ if (d)
|
|
+ return d->flag(Designable);
|
|
+ else
|
|
+ return false;
|
|
+}
|
|
+
|
|
+/*!
|
|
+ Returns true if the property is scriptable; otherwise returns false.
|
|
+ This default value is true.
|
|
+
|
|
+ \sa setScriptable(), isDesignable(), isStored()
|
|
+*/
|
|
+bool QMetaPropertyBuilder::isScriptable() const
|
|
+{
|
|
+ QMetaPropertyBuilderPrivate *d = d_func();
|
|
+ if (d)
|
|
+ return d->flag(Scriptable);
|
|
+ else
|
|
+ return false;
|
|
+}
|
|
+
|
|
+/*!
|
|
+ Returns true if the property is stored; otherwise returns false.
|
|
+ This default value is false.
|
|
+
|
|
+ \sa setStored(), isDesignable(), isScriptable()
|
|
+*/
|
|
+bool QMetaPropertyBuilder::isStored() const
|
|
+{
|
|
+ QMetaPropertyBuilderPrivate *d = d_func();
|
|
+ if (d)
|
|
+ return d->flag(Stored);
|
|
+ else
|
|
+ return false;
|
|
+}
|
|
+
|
|
+/*!
|
|
+ Returns true if the property is editable; otherwise returns false.
|
|
+ This default value is false.
|
|
+
|
|
+ \sa setEditable(), isDesignable(), isScriptable(), isStored()
|
|
+*/
|
|
+bool QMetaPropertyBuilder::isEditable() const
|
|
+{
|
|
+ QMetaPropertyBuilderPrivate *d = d_func();
|
|
+ if (d)
|
|
+ return d->flag(Editable);
|
|
+ else
|
|
+ return false;
|
|
+}
|
|
+
|
|
+/*!
|
|
+ Returns true if this property is designated as the \c USER
|
|
+ property, i.e., the one that the user can edit or that is
|
|
+ significant in some other way. Otherwise it returns
|
|
+ false. This default value is false.
|
|
+
|
|
+ \sa setUser(), isDesignable(), isScriptable()
|
|
+*/
|
|
+bool QMetaPropertyBuilder::isUser() const
|
|
+{
|
|
+ QMetaPropertyBuilderPrivate *d = d_func();
|
|
+ if (d)
|
|
+ return d->flag(User);
|
|
+ else
|
|
+ return false;
|
|
+}
|
|
+
|
|
+/*!
|
|
+ Returns true if the property has a C++ setter function that
|
|
+ follows Qt's standard "name" / "setName" pattern. Designer and uic
|
|
+ query hasStdCppSet() in order to avoid expensive
|
|
+ QObject::setProperty() calls. All properties in Qt [should] follow
|
|
+ this pattern. The default value is false.
|
|
+
|
|
+ \sa setStdCppSet()
|
|
+*/
|
|
+bool QMetaPropertyBuilder::hasStdCppSet() const
|
|
+{
|
|
+ QMetaPropertyBuilderPrivate *d = d_func();
|
|
+ if (d)
|
|
+ return d->flag(StdCppSet);
|
|
+ else
|
|
+ return false;
|
|
+}
|
|
+
|
|
+/*!
|
|
+ Returns true if the property is an enumerator or flag type;
|
|
+ otherwise returns false. This default value is false.
|
|
+
|
|
+ \sa setEnumOrFlag()
|
|
+*/
|
|
+bool QMetaPropertyBuilder::isEnumOrFlag() const
|
|
+{
|
|
+ QMetaPropertyBuilderPrivate *d = d_func();
|
|
+ if (d)
|
|
+ return d->flag(EnumOrFlag);
|
|
+ else
|
|
+ return false;
|
|
+}
|
|
+
|
|
+/*!
|
|
+ Returns true if the property has the dynamic flag set;
|
|
+ otherwise returns false. The default value is false.
|
|
+
|
|
+ \sa setDynamic()
|
|
+*/
|
|
+bool QMetaPropertyBuilder::isDynamic() const
|
|
+{
|
|
+ QMetaPropertyBuilderPrivate *d = d_func();
|
|
+ if (d)
|
|
+ return d->flag(Dynamic);
|
|
+ else
|
|
+ return false;
|
|
+}
|
|
+
|
|
+/*!
|
|
+ Sets this property to readable if \a value is true.
|
|
+
|
|
+ \sa isReadable(), setWritable()
|
|
+*/
|
|
+void QMetaPropertyBuilder::setReadable(bool value)
|
|
+{
|
|
+ QMetaPropertyBuilderPrivate *d = d_func();
|
|
+ if (d)
|
|
+ d->setFlag(Readable, value);
|
|
+}
|
|
+
|
|
+/*!
|
|
+ Sets this property to writable if \a value is true.
|
|
+
|
|
+ \sa isWritable(), setReadable()
|
|
+*/
|
|
+void QMetaPropertyBuilder::setWritable(bool value)
|
|
+{
|
|
+ QMetaPropertyBuilderPrivate *d = d_func();
|
|
+ if (d)
|
|
+ d->setFlag(Writable, value);
|
|
+}
|
|
+
|
|
+/*!
|
|
+ Sets this property to resettable if \a value is true.
|
|
+
|
|
+ \sa isResettable()
|
|
+*/
|
|
+void QMetaPropertyBuilder::setResettable(bool value)
|
|
+{
|
|
+ QMetaPropertyBuilderPrivate *d = d_func();
|
|
+ if (d)
|
|
+ d->setFlag(Resettable, value);
|
|
+}
|
|
+
|
|
+/*!
|
|
+ Sets this property to designable if \a value is true.
|
|
+
|
|
+ \sa isDesignable(), setScriptable(), setStored()
|
|
+*/
|
|
+void QMetaPropertyBuilder::setDesignable(bool value)
|
|
+{
|
|
+ QMetaPropertyBuilderPrivate *d = d_func();
|
|
+ if (d)
|
|
+ d->setFlag(Designable, value);
|
|
+}
|
|
+
|
|
+/*!
|
|
+ Sets this property to scriptable if \a value is true.
|
|
+
|
|
+ \sa isScriptable(), setDesignable(), setStored()
|
|
+*/
|
|
+void QMetaPropertyBuilder::setScriptable(bool value)
|
|
+{
|
|
+ QMetaPropertyBuilderPrivate *d = d_func();
|
|
+ if (d)
|
|
+ d->setFlag(Scriptable, value);
|
|
+}
|
|
+
|
|
+/*!
|
|
+ Sets this property to storable if \a value is true.
|
|
+
|
|
+ \sa isStored(), setDesignable(), setScriptable()
|
|
+*/
|
|
+void QMetaPropertyBuilder::setStored(bool value)
|
|
+{
|
|
+ QMetaPropertyBuilderPrivate *d = d_func();
|
|
+ if (d)
|
|
+ d->setFlag(Stored, value);
|
|
+}
|
|
+
|
|
+/*!
|
|
+ Sets this property to editable if \a value is true.
|
|
+
|
|
+ \sa isEditable(), setDesignable(), setScriptable(), setStored()
|
|
+*/
|
|
+void QMetaPropertyBuilder::setEditable(bool value)
|
|
+{
|
|
+ QMetaPropertyBuilderPrivate *d = d_func();
|
|
+ if (d)
|
|
+ d->setFlag(Editable, value);
|
|
+}
|
|
+
|
|
+/*!
|
|
+ Sets the \c USER flag on this property to \a value.
|
|
+
|
|
+ \sa isUser(), setDesignable(), setScriptable()
|
|
+*/
|
|
+void QMetaPropertyBuilder::setUser(bool value)
|
|
+{
|
|
+ QMetaPropertyBuilderPrivate *d = d_func();
|
|
+ if (d)
|
|
+ d->setFlag(User, value);
|
|
+}
|
|
+
|
|
+/*!
|
|
+ Sets the C++ setter flag on this property to \a value, which is
|
|
+ true if the property has a C++ setter function that follows Qt's
|
|
+ standard "name" / "setName" pattern.
|
|
+
|
|
+ \sa hasStdCppSet()
|
|
+*/
|
|
+void QMetaPropertyBuilder::setStdCppSet(bool value)
|
|
+{
|
|
+ QMetaPropertyBuilderPrivate *d = d_func();
|
|
+ if (d)
|
|
+ d->setFlag(StdCppSet, value);
|
|
+}
|
|
+
|
|
+/*!
|
|
+ Sets this property to be of an enumerator or flag type if
|
|
+ \a value is true.
|
|
+
|
|
+ \sa isEnumOrFlag()
|
|
+*/
|
|
+void QMetaPropertyBuilder::setEnumOrFlag(bool value)
|
|
+{
|
|
+ QMetaPropertyBuilderPrivate *d = d_func();
|
|
+ if (d)
|
|
+ d->setFlag(EnumOrFlag, value);
|
|
+}
|
|
+
|
|
+/*!
|
|
+ Sets this property to have the dynamic flag if \a value is
|
|
+ true.
|
|
+
|
|
+ \sa isDynamic()
|
|
+*/
|
|
+void QMetaPropertyBuilder::setDynamic(bool value)
|
|
+{
|
|
+ QMetaPropertyBuilderPrivate *d = d_func();
|
|
+ if (d)
|
|
+ d->setFlag(Dynamic, value);
|
|
+}
|
|
+
|
|
+/*!
|
|
+ \class QMetaEnumBuilder
|
|
+ \internal
|
|
+ \brief The QMetaEnumBuilder class enables modifications to an enumerator definition on a meta object builder.
|
|
+*/
|
|
+
|
|
+QMetaEnumBuilderPrivate *QMetaEnumBuilder::d_func() const
|
|
+{
|
|
+ if (_mobj && _index >= 0 && _index < _mobj->d->enumerators.size())
|
|
+ return &(_mobj->d->enumerators[_index]);
|
|
+ else
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+/*!
|
|
+ \fn QMetaEnumBuilder::QMetaEnumBuilder()
|
|
+ \internal
|
|
+*/
|
|
+
|
|
+/*!
|
|
+ \fn int QMetaEnumBuilder::index() const
|
|
+
|
|
+ Returns the index of this enumerator within its QMetaObjectBuilder.
|
|
+*/
|
|
+
|
|
+/*!
|
|
+ Returns the name of the enumerator (without the scope).
|
|
+*/
|
|
+QByteArray QMetaEnumBuilder::name() const
|
|
+{
|
|
+ QMetaEnumBuilderPrivate *d = d_func();
|
|
+ if (d)
|
|
+ return d->name;
|
|
+ else
|
|
+ return QByteArray();
|
|
+}
|
|
+
|
|
+/*!
|
|
+ Returns true if this enumerator is used as a flag; otherwise returns
|
|
+ false.
|
|
+
|
|
+ \sa setIsFlag()
|
|
+*/
|
|
+bool QMetaEnumBuilder::isFlag() const
|
|
+{
|
|
+ QMetaEnumBuilderPrivate *d = d_func();
|
|
+ if (d)
|
|
+ return d->isFlag;
|
|
+ else
|
|
+ return false;
|
|
+}
|
|
+
|
|
+/*!
|
|
+ Sets this enumerator to be used as a flag if \a value is true.
|
|
+
|
|
+ \sa isFlag()
|
|
+*/
|
|
+void QMetaEnumBuilder::setIsFlag(bool value)
|
|
+{
|
|
+ QMetaEnumBuilderPrivate *d = d_func();
|
|
+ if (d)
|
|
+ d->isFlag = value;
|
|
+}
|
|
+
|
|
+/*!
|
|
+ Returns the number of keys.
|
|
+
|
|
+ \sa key(), addKey()
|
|
+*/
|
|
+int QMetaEnumBuilder::keyCount() const
|
|
+{
|
|
+ QMetaEnumBuilderPrivate *d = d_func();
|
|
+ if (d)
|
|
+ return d->keys.size();
|
|
+ else
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+/*!
|
|
+ Returns the key with the given \a index, or an empty QByteArray
|
|
+ if no such key exists.
|
|
+
|
|
+ \sa keyCount(), addKey(), value()
|
|
+*/
|
|
+QByteArray QMetaEnumBuilder::key(int index) const
|
|
+{
|
|
+ QMetaEnumBuilderPrivate *d = d_func();
|
|
+ if (d && index >= 0 && index < d->keys.size())
|
|
+ return d->keys[index];
|
|
+ else
|
|
+ return QByteArray();
|
|
+}
|
|
+
|
|
+/*!
|
|
+ Returns the value with the given \a index; or returns -1 if there
|
|
+ is no such value.
|
|
+
|
|
+ \sa keyCount(), addKey(), key()
|
|
+*/
|
|
+int QMetaEnumBuilder::value(int index) const
|
|
+{
|
|
+ QMetaEnumBuilderPrivate *d = d_func();
|
|
+ if (d && index >= 0 && index < d->keys.size())
|
|
+ return d->values[index];
|
|
+ else
|
|
+ return -1;
|
|
+}
|
|
+
|
|
+/*!
|
|
+ Adds a new key called \a name to this enumerator, associated
|
|
+ with \a value. Returns the index of the new key.
|
|
+
|
|
+ \sa keyCount(), key(), value(), removeKey()
|
|
+*/
|
|
+int QMetaEnumBuilder::addKey(const QByteArray& name, int value)
|
|
+{
|
|
+ QMetaEnumBuilderPrivate *d = d_func();
|
|
+ if (d) {
|
|
+ int index = d->keys.size();
|
|
+ d->keys += name;
|
|
+ d->values += value;
|
|
+ return index;
|
|
+ } else {
|
|
+ return -1;
|
|
+ }
|
|
+}
|
|
+
|
|
+/*!
|
|
+ Removes the key at \a index from this enumerator.
|
|
+
|
|
+ \sa addKey()
|
|
+*/
|
|
+void QMetaEnumBuilder::removeKey(int index)
|
|
+{
|
|
+ QMetaEnumBuilderPrivate *d = d_func();
|
|
+ if (d && index >= 0 && index < d->keys.size()) {
|
|
+ d->keys.removeAt(index);
|
|
+ d->values.removeAt(index);
|
|
+ }
|
|
+}
|
|
+
|
|
+QTM_END_NAMESPACE
|
|
diff --git a/src/serviceframework/ipc/qmetaobjectbuilder_47_p.h b/src/serviceframework/ipc/qmetaobjectbuilder_47_p.h
|
|
new file mode 100644
|
|
index 0000000..5f25e0f
|
|
--- /dev/null
|
|
+++ b/src/serviceframework/ipc/qmetaobjectbuilder_47_p.h
|
|
@@ -0,0 +1,338 @@
|
|
+/****************************************************************************
|
|
+**
|
|
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
|
|
+** All rights reserved.
|
|
+** Contact: Nokia Corporation (qt-info@nokia.com)
|
|
+**
|
|
+** This file is part of the Qt Mobility Components.
|
|
+**
|
|
+** $QT_BEGIN_LICENSE:LGPL$
|
|
+** No Commercial Usage
|
|
+** This file contains pre-release code and may not be distributed.
|
|
+** You may use this file in accordance with the terms and conditions
|
|
+** contained in the Technology Preview License Agreement accompanying
|
|
+** this package.
|
|
+**
|
|
+** GNU Lesser General Public License Usage
|
|
+** Alternatively, this file may be used under the terms of the GNU Lesser
|
|
+** General Public License version 2.1 as published by the Free Software
|
|
+** Foundation and appearing in the file LICENSE.LGPL included in the
|
|
+** packaging of this file. Please review the following information to
|
|
+** ensure the GNU Lesser General Public License version 2.1 requirements
|
|
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
|
+**
|
|
+** In addition, as a special exception, Nokia gives you certain additional
|
|
+** rights. These rights are described in the Nokia Qt LGPL Exception
|
|
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
|
+**
|
|
+** If you have questions regarding the use of this file, please contact
|
|
+** Nokia at qt-info@nokia.com.
|
|
+**
|
|
+**
|
|
+**
|
|
+**
|
|
+**
|
|
+**
|
|
+**
|
|
+**
|
|
+** $QT_END_LICENSE$
|
|
+**
|
|
+****************************************************************************/
|
|
+
|
|
+#ifndef QMETAOBJECTBUILDER_H
|
|
+#define QMETAOBJECTBUILDER_H
|
|
+
|
|
+//
|
|
+// W A R N I N G
|
|
+// -------------
|
|
+//
|
|
+// This file is not part of the Qt API. It exists for the convenience
|
|
+// of moc. This header file may change from version to version without notice,
|
|
+// or even be removed.
|
|
+//
|
|
+// We mean it.
|
|
+//
|
|
+
|
|
+#include <qmobilityglobal.h>
|
|
+#include <QtCore/qobject.h>
|
|
+#include <QtCore/qmetaobject.h>
|
|
+#include <QtCore/qdatastream.h>
|
|
+#include <QtCore/qmap.h>
|
|
+
|
|
+QTM_BEGIN_NAMESPACE
|
|
+
|
|
+class QMetaObjectBuilderPrivate;
|
|
+class QMetaMethodBuilder;
|
|
+class QMetaMethodBuilderPrivate;
|
|
+class QMetaPropertyBuilder;
|
|
+class QMetaPropertyBuilderPrivate;
|
|
+class QMetaEnumBuilder;
|
|
+class QMetaEnumBuilderPrivate;
|
|
+
|
|
+#ifdef IGNORE_METAOBJECTBUILDER_EXPORT
|
|
+ class QMetaObjectBuilder
|
|
+#else
|
|
+ class QM_AUTOTEST_EXPORT QMetaObjectBuilder
|
|
+#endif
|
|
+{
|
|
+public:
|
|
+ enum AddMember
|
|
+ {
|
|
+ ClassName = 0x00000001,
|
|
+ SuperClass = 0x00000002,
|
|
+ Methods = 0x00000004,
|
|
+ Signals = 0x00000008,
|
|
+ Slots = 0x00000010,
|
|
+ Constructors = 0x00000020,
|
|
+ Properties = 0x00000040,
|
|
+ Enumerators = 0x00000080,
|
|
+ ClassInfos = 0x00000100,
|
|
+ RelatedMetaObjects = 0x00000200,
|
|
+ StaticMetacall = 0x00000400,
|
|
+ PublicMethods = 0x00000800,
|
|
+ ProtectedMethods = 0x00001000,
|
|
+ PrivateMethods = 0x00002000,
|
|
+ AllMembers = 0x7FFFFFFF,
|
|
+ AllPrimaryMembers = 0x7FFFFBFC
|
|
+ };
|
|
+ Q_DECLARE_FLAGS(AddMembers, AddMember)
|
|
+
|
|
+ enum MetaObjectFlag {
|
|
+ DynamicMetaObject = 0x01
|
|
+ };
|
|
+ Q_DECLARE_FLAGS(MetaObjectFlags, MetaObjectFlag)
|
|
+
|
|
+ QMetaObjectBuilder();
|
|
+ explicit QMetaObjectBuilder(const QMetaObject *prototype, QMetaObjectBuilder::AddMembers members = AllMembers);
|
|
+ virtual ~QMetaObjectBuilder();
|
|
+
|
|
+ QByteArray className() const;
|
|
+ void setClassName(const QByteArray& name);
|
|
+
|
|
+ const QMetaObject *superClass() const;
|
|
+ void setSuperClass(const QMetaObject *meta);
|
|
+
|
|
+ MetaObjectFlags flags() const;
|
|
+ void setFlags(MetaObjectFlags);
|
|
+
|
|
+ int methodCount() const;
|
|
+ int constructorCount() const;
|
|
+ int propertyCount() const;
|
|
+ int enumeratorCount() const;
|
|
+ int classInfoCount() const;
|
|
+ int relatedMetaObjectCount() const;
|
|
+
|
|
+ QMetaMethodBuilder addMethod(const QByteArray& signature);
|
|
+ QMetaMethodBuilder addMethod(const QByteArray& signature, const QByteArray& returnType);
|
|
+ QMetaMethodBuilder addMethod(const QMetaMethod& prototype);
|
|
+
|
|
+ QMetaMethodBuilder addSlot(const QByteArray& signature);
|
|
+ QMetaMethodBuilder addSignal(const QByteArray& signature);
|
|
+
|
|
+ QMetaMethodBuilder addConstructor(const QByteArray& signature);
|
|
+ QMetaMethodBuilder addConstructor(const QMetaMethod& prototype);
|
|
+
|
|
+ QMetaPropertyBuilder addProperty(const QByteArray& name, const QByteArray& type, int notifierId=-1);
|
|
+ QMetaPropertyBuilder addProperty(const QMetaProperty& prototype);
|
|
+
|
|
+ QMetaEnumBuilder addEnumerator(const QByteArray& name);
|
|
+ QMetaEnumBuilder addEnumerator(const QMetaEnum& prototype);
|
|
+
|
|
+ int addClassInfo(const QByteArray& name, const QByteArray& value);
|
|
+
|
|
+#ifdef Q_NO_DATA_RELOCATION
|
|
+ int addRelatedMetaObject(const QMetaObjectAccessor &meta);
|
|
+#else
|
|
+ int addRelatedMetaObject(const QMetaObject *meta);
|
|
+#endif
|
|
+
|
|
+ void addMetaObject(const QMetaObject *prototype, QMetaObjectBuilder::AddMembers members = AllMembers);
|
|
+
|
|
+ QMetaMethodBuilder method(int index) const;
|
|
+ QMetaMethodBuilder constructor(int index) const;
|
|
+ QMetaPropertyBuilder property(int index) const;
|
|
+ QMetaEnumBuilder enumerator(int index) const;
|
|
+ const QMetaObject *relatedMetaObject(int index) const;
|
|
+
|
|
+ QByteArray classInfoName(int index) const;
|
|
+ QByteArray classInfoValue(int index) const;
|
|
+
|
|
+ void removeMethod(int index);
|
|
+ void removeConstructor(int index);
|
|
+ void removeProperty(int index);
|
|
+ void removeEnumerator(int index);
|
|
+ void removeClassInfo(int index);
|
|
+ void removeRelatedMetaObject(int index);
|
|
+
|
|
+ int indexOfMethod(const QByteArray& signature);
|
|
+ int indexOfSignal(const QByteArray& signature);
|
|
+ int indexOfSlot(const QByteArray& signature);
|
|
+ int indexOfConstructor(const QByteArray& signature);
|
|
+ int indexOfProperty(const QByteArray& name);
|
|
+ int indexOfEnumerator(const QByteArray& name);
|
|
+ int indexOfClassInfo(const QByteArray& name);
|
|
+
|
|
+ typedef int (*StaticMetacallFunction)(QMetaObject::Call, int, void **);
|
|
+
|
|
+ QMetaObjectBuilder::StaticMetacallFunction staticMetacallFunction() const;
|
|
+ void setStaticMetacallFunction(QMetaObjectBuilder::StaticMetacallFunction value);
|
|
+
|
|
+ QMetaObject *toMetaObject() const;
|
|
+ QByteArray toRelocatableData(bool * = 0) const;
|
|
+ static void fromRelocatableData(QMetaObject *, const QMetaObject *, const QByteArray &);
|
|
+
|
|
+#ifndef QT_NO_DATASTREAM
|
|
+ void serialize(QDataStream& stream) const;
|
|
+ void deserialize
|
|
+ (QDataStream& stream,
|
|
+ const QMap<QByteArray, const QMetaObject *>& references);
|
|
+#endif
|
|
+
|
|
+private:
|
|
+ Q_DISABLE_COPY(QMetaObjectBuilder)
|
|
+
|
|
+ QMetaObjectBuilderPrivate *d;
|
|
+
|
|
+ friend class QMetaMethodBuilder;
|
|
+ friend class QMetaPropertyBuilder;
|
|
+ friend class QMetaEnumBuilder;
|
|
+};
|
|
+
|
|
+#ifdef IGNORE_METAOBJECTBUILDER_EXPORT
|
|
+ class QMetaMethodBuilder
|
|
+#else
|
|
+ class QM_AUTOTEST_EXPORT QMetaMethodBuilder
|
|
+#endif
|
|
+{
|
|
+public:
|
|
+ QMetaMethodBuilder() : _mobj(0), _index(0) {}
|
|
+
|
|
+ int index() const;
|
|
+
|
|
+ QMetaMethod::MethodType methodType() const;
|
|
+ QByteArray signature() const;
|
|
+
|
|
+ QByteArray returnType() const;
|
|
+ void setReturnType(const QByteArray& value);
|
|
+
|
|
+ QList<QByteArray> parameterNames() const;
|
|
+ void setParameterNames(const QList<QByteArray>& value);
|
|
+
|
|
+ QByteArray tag() const;
|
|
+ void setTag(const QByteArray& value);
|
|
+
|
|
+ QMetaMethod::Access access() const;
|
|
+ void setAccess(QMetaMethod::Access value);
|
|
+
|
|
+ int attributes() const;
|
|
+ void setAttributes(int value);
|
|
+
|
|
+private:
|
|
+ const QMetaObjectBuilder *_mobj;
|
|
+ int _index;
|
|
+
|
|
+ friend class QMetaObjectBuilder;
|
|
+ friend class QMetaPropertyBuilder;
|
|
+
|
|
+ QMetaMethodBuilder(const QMetaObjectBuilder *mobj, int index)
|
|
+ : _mobj(mobj), _index(index) {}
|
|
+
|
|
+ QMetaMethodBuilderPrivate *d_func() const;
|
|
+};
|
|
+
|
|
+#ifdef IGNORE_METAOBJECTBUILDER_EXPORT
|
|
+ class QMetaPropertyBuilder
|
|
+#else
|
|
+ class QM_AUTOTEST_EXPORT QMetaPropertyBuilder
|
|
+#endif
|
|
+{
|
|
+public:
|
|
+ QMetaPropertyBuilder() : _mobj(0), _index(0) {}
|
|
+
|
|
+ int index() const { return _index; }
|
|
+
|
|
+ QByteArray name() const;
|
|
+ QByteArray type() const;
|
|
+
|
|
+ bool hasNotifySignal() const;
|
|
+ QMetaMethodBuilder notifySignal() const;
|
|
+ void setNotifySignal(const QMetaMethodBuilder& value);
|
|
+ void removeNotifySignal();
|
|
+
|
|
+ bool isReadable() const;
|
|
+ bool isWritable() const;
|
|
+ bool isResettable() const;
|
|
+ bool isDesignable() const;
|
|
+ bool isScriptable() const;
|
|
+ bool isStored() const;
|
|
+ bool isEditable() const;
|
|
+ bool isUser() const;
|
|
+ bool hasStdCppSet() const;
|
|
+ bool isEnumOrFlag() const;
|
|
+ bool isDynamic() const;
|
|
+
|
|
+ void setReadable(bool value);
|
|
+ void setWritable(bool value);
|
|
+ void setResettable(bool value);
|
|
+ void setDesignable(bool value);
|
|
+ void setScriptable(bool value);
|
|
+ void setStored(bool value);
|
|
+ void setEditable(bool value);
|
|
+ void setUser(bool value);
|
|
+ void setStdCppSet(bool value);
|
|
+ void setEnumOrFlag(bool value);
|
|
+ void setDynamic(bool value);
|
|
+
|
|
+private:
|
|
+ const QMetaObjectBuilder *_mobj;
|
|
+ int _index;
|
|
+
|
|
+ friend class QMetaObjectBuilder;
|
|
+
|
|
+ QMetaPropertyBuilder(const QMetaObjectBuilder *mobj, int index)
|
|
+ : _mobj(mobj), _index(index) {}
|
|
+
|
|
+ QMetaPropertyBuilderPrivate *d_func() const;
|
|
+};
|
|
+
|
|
+#ifdef IGNORE_METAOBJECTBUILDER_EXPORT
|
|
+ class QMetaEnumBuilder
|
|
+#else
|
|
+ class QM_AUTOTEST_EXPORT QMetaEnumBuilder
|
|
+#endif
|
|
+{
|
|
+public:
|
|
+ QMetaEnumBuilder() : _mobj(0), _index(0) {}
|
|
+
|
|
+ int index() const { return _index; }
|
|
+
|
|
+ QByteArray name() const;
|
|
+
|
|
+ bool isFlag() const;
|
|
+ void setIsFlag(bool value);
|
|
+
|
|
+ int keyCount() const;
|
|
+ QByteArray key(int index) const;
|
|
+ int value(int index) const;
|
|
+
|
|
+ int addKey(const QByteArray& name, int value);
|
|
+ void removeKey(int index);
|
|
+
|
|
+private:
|
|
+ const QMetaObjectBuilder *_mobj;
|
|
+ int _index;
|
|
+
|
|
+ friend class QMetaObjectBuilder;
|
|
+
|
|
+ QMetaEnumBuilder(const QMetaObjectBuilder *mobj, int index)
|
|
+ : _mobj(mobj), _index(index) {}
|
|
+
|
|
+ QMetaEnumBuilderPrivate *d_func() const;
|
|
+};
|
|
+
|
|
+Q_DECLARE_OPERATORS_FOR_FLAGS(QMetaObjectBuilder::AddMembers)
|
|
+Q_DECLARE_OPERATORS_FOR_FLAGS(QMetaObjectBuilder::MetaObjectFlags)
|
|
+
|
|
+QTM_END_NAMESPACE
|
|
+
|
|
+#endif
|
|
diff --git a/src/serviceframework/ipc/qmetaobjectbuilder_p.h b/src/serviceframework/ipc/qmetaobjectbuilder_p.h
|
|
index 5f25e0f..7f29ddc 100644
|
|
--- a/src/serviceframework/ipc/qmetaobjectbuilder_p.h
|
|
+++ b/src/serviceframework/ipc/qmetaobjectbuilder_p.h
|
|
@@ -69,6 +69,8 @@ class QMetaPropertyBuilderPrivate;
|
|
class QMetaEnumBuilder;
|
|
class QMetaEnumBuilderPrivate;
|
|
|
|
+typedef const QMetaObject& (*QMetaObjectAccessor)();
|
|
+
|
|
#ifdef IGNORE_METAOBJECTBUILDER_EXPORT
|
|
class QMetaObjectBuilder
|
|
#else
|
|
@@ -172,7 +174,7 @@ public:
|
|
int indexOfEnumerator(const QByteArray& name);
|
|
int indexOfClassInfo(const QByteArray& name);
|
|
|
|
- typedef int (*StaticMetacallFunction)(QMetaObject::Call, int, void **);
|
|
+ typedef QMetaObjectExtraData::StaticMetacallFunction StaticMetacallFunction;
|
|
|
|
QMetaObjectBuilder::StaticMetacallFunction staticMetacallFunction() const;
|
|
void setStaticMetacallFunction(QMetaObjectBuilder::StaticMetacallFunction value);
|
|
@@ -269,7 +271,8 @@ public:
|
|
bool isUser() const;
|
|
bool hasStdCppSet() const;
|
|
bool isEnumOrFlag() const;
|
|
- bool isDynamic() const;
|
|
+ bool isConstant() const;
|
|
+ bool isFinal() const;
|
|
|
|
void setReadable(bool value);
|
|
void setWritable(bool value);
|
|
@@ -281,7 +284,8 @@ public:
|
|
void setUser(bool value);
|
|
void setStdCppSet(bool value);
|
|
void setEnumOrFlag(bool value);
|
|
- void setDynamic(bool value);
|
|
+ void setConstant(bool value);
|
|
+ void setFinal(bool value);
|
|
|
|
private:
|
|
const QMetaObjectBuilder *_mobj;
|
|
diff --git a/tests/auto/qmetaobjectbuilder/qmetaobjectbuilder.pro b/tests/auto/qmetaobjectbuilder/qmetaobjectbuilder.pro
|
|
index 4cbc03a..fa6123b 100644
|
|
--- a/tests/auto/qmetaobjectbuilder/qmetaobjectbuilder.pro
|
|
+++ b/tests/auto/qmetaobjectbuilder/qmetaobjectbuilder.pro
|
|
@@ -9,7 +9,11 @@ QT = core
|
|
include(../../../common.pri)
|
|
|
|
# Input
|
|
-SOURCES += tst_qmetaobjectbuilder.cpp
|
|
+contains(QT_MAJOR_VERSION, 4):lessThan(QT_MINOR_VERSION, 8) {
|
|
+ SOURCES += tst_qmetaobjectbuilder_47.cpp
|
|
+} else {
|
|
+ SOURCES += tst_qmetaobjectbuilder.cpp
|
|
+}
|
|
|
|
CONFIG += mobility
|
|
MOBILITY = serviceframework
|
|
diff --git a/tests/auto/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp b/tests/auto/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp
|
|
index 48ba43c..470d9e5 100644
|
|
--- a/tests/auto/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp
|
|
+++ b/tests/auto/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp
|
|
@@ -149,9 +149,9 @@ void tst_QMetaObjectBuilder::mocVersionCheck()
|
|
// whenenver moc changes. Once QMetaObjectBuilder has been
|
|
// updated, this test can be changed to check for the next version.
|
|
int version = int(QObject::staticMetaObject.d.data[0]);
|
|
- QVERIFY(version == 4 || version == 5);
|
|
+ QVERIFY(version == 4 || version == 5 || version == 6);
|
|
version = int(staticMetaObject.d.data[0]);
|
|
- QVERIFY(version == 4 || version == 5);
|
|
+ QVERIFY(version == 4 || version == 5 || version == 6);
|
|
}
|
|
|
|
void tst_QMetaObjectBuilder::create()
|
|
@@ -555,7 +555,8 @@ void tst_QMetaObjectBuilder::property()
|
|
QVERIFY(!nullProp.isUser());
|
|
QVERIFY(!nullProp.hasStdCppSet());
|
|
QVERIFY(!nullProp.isEnumOrFlag());
|
|
- QVERIFY(!nullProp.isDynamic());
|
|
+ QVERIFY(!nullProp.isConstant());
|
|
+ QVERIFY(!nullProp.isFinal());
|
|
QCOMPARE(nullProp.index(), 0);
|
|
|
|
// Add a property and check its attributes.
|
|
@@ -573,7 +574,8 @@ void tst_QMetaObjectBuilder::property()
|
|
QVERIFY(!prop1.isUser());
|
|
QVERIFY(!prop1.hasStdCppSet());
|
|
QVERIFY(!prop1.isEnumOrFlag());
|
|
- QVERIFY(!prop1.isDynamic());
|
|
+ QVERIFY(!prop1.isConstant());
|
|
+ QVERIFY(!prop1.isFinal());
|
|
QCOMPARE(prop1.index(), 0);
|
|
QCOMPARE(builder.propertyCount(), 1);
|
|
|
|
@@ -592,7 +594,8 @@ void tst_QMetaObjectBuilder::property()
|
|
QVERIFY(!prop2.isUser());
|
|
QVERIFY(!prop2.hasStdCppSet());
|
|
QVERIFY(!prop2.isEnumOrFlag());
|
|
- QVERIFY(!prop2.isDynamic());
|
|
+ QVERIFY(!prop2.isConstant());
|
|
+ QVERIFY(!prop2.isFinal());
|
|
QCOMPARE(prop2.index(), 1);
|
|
QCOMPARE(builder.propertyCount(), 2);
|
|
|
|
@@ -614,7 +617,8 @@ void tst_QMetaObjectBuilder::property()
|
|
prop1.setUser(true);
|
|
prop1.setStdCppSet(true);
|
|
prop1.setEnumOrFlag(true);
|
|
- prop1.setDynamic(true);
|
|
+ prop1.setConstant(true);
|
|
+ prop1.setFinal(true);
|
|
|
|
// Check that prop1 is changed, but prop2 is not.
|
|
QCOMPARE(prop1.name(), QByteArray("foo"));
|
|
@@ -629,7 +633,8 @@ void tst_QMetaObjectBuilder::property()
|
|
QVERIFY(prop1.isUser());
|
|
QVERIFY(prop1.hasStdCppSet());
|
|
QVERIFY(prop1.isEnumOrFlag());
|
|
- QVERIFY(prop1.isDynamic());
|
|
+ QVERIFY(prop1.isConstant());
|
|
+ QVERIFY(prop1.isFinal());
|
|
QVERIFY(prop2.isReadable());
|
|
QVERIFY(prop2.isWritable());
|
|
QCOMPARE(prop2.name(), QByteArray("bar"));
|
|
@@ -642,7 +647,8 @@ void tst_QMetaObjectBuilder::property()
|
|
QVERIFY(!prop2.isUser());
|
|
QVERIFY(!prop2.hasStdCppSet());
|
|
QVERIFY(!prop2.isEnumOrFlag());
|
|
- QVERIFY(!prop2.isDynamic());
|
|
+ QVERIFY(!prop2.isConstant());
|
|
+ QVERIFY(!prop2.isFinal());
|
|
|
|
// Remove prop1 and check that prop2 becomes index 0.
|
|
builder.removeProperty(0);
|
|
@@ -658,7 +664,8 @@ void tst_QMetaObjectBuilder::property()
|
|
QVERIFY(!prop2.isUser());
|
|
QVERIFY(!prop2.hasStdCppSet());
|
|
QVERIFY(!prop2.isEnumOrFlag());
|
|
- QVERIFY(!prop2.isDynamic());
|
|
+ QVERIFY(!prop2.isConstant());
|
|
+ QVERIFY(!prop2.isFinal());
|
|
QCOMPARE(prop2.index(), 0);
|
|
|
|
// Perform index-based lookup again.
|
|
@@ -682,7 +689,8 @@ void tst_QMetaObjectBuilder::property()
|
|
prop2.setUser(false); \
|
|
prop2.setStdCppSet(false); \
|
|
prop2.setEnumOrFlag(false); \
|
|
- prop2.setDynamic(false); \
|
|
+ prop2.setConstant(false); \
|
|
+ prop2.setFinal(false); \
|
|
} while (0)
|
|
#define COUNT_FLAGS() \
|
|
((prop2.isReadable() ? 1 : 0) + \
|
|
@@ -695,7 +703,8 @@ void tst_QMetaObjectBuilder::property()
|
|
(prop2.isUser() ? 1 : 0) + \
|
|
(prop2.hasStdCppSet() ? 1 : 0) + \
|
|
(prop2.isEnumOrFlag() ? 1 : 0) + \
|
|
- (prop2.isDynamic() ? 1 : 0))
|
|
+ (prop2.isConstant() ? 1 : 0) + \
|
|
+ (prop2.isFinal() ? 1 : 0))
|
|
#define CHECK_FLAG(setFunc,isFunc) \
|
|
do { \
|
|
CLEAR_FLAGS(); \
|
|
@@ -714,7 +723,8 @@ void tst_QMetaObjectBuilder::property()
|
|
CHECK_FLAG(setUser, isUser);
|
|
CHECK_FLAG(setStdCppSet, hasStdCppSet);
|
|
CHECK_FLAG(setEnumOrFlag, isEnumOrFlag);
|
|
- CHECK_FLAG(setDynamic, isDynamic);
|
|
+ CHECK_FLAG(setConstant, isConstant);
|
|
+ CHECK_FLAG(setFinal, isFinal);
|
|
|
|
// Check that nothing else changed.
|
|
QVERIFY(checkForSideEffects(builder, QMetaObjectBuilder::Properties));
|
|
@@ -958,9 +968,9 @@ void tst_QMetaObjectBuilder::relatedMetaObject()
|
|
QVERIFY(checkForSideEffects(builder, QMetaObjectBuilder::RelatedMetaObjects));
|
|
}
|
|
|
|
-static int smetacall(QMetaObject::Call, int, void **)
|
|
+static void smetacall(QObject *, QMetaObject::Call, int, void **)
|
|
{
|
|
- return 0;
|
|
+ return;
|
|
}
|
|
|
|
void tst_QMetaObjectBuilder::staticMetacall()
|
|
@@ -1263,8 +1273,8 @@ bool tst_QMetaObjectBuilder::sameMetaObject
|
|
if (extra1 && extra2) {
|
|
if (extra1->static_metacall != extra2->static_metacall)
|
|
return false;
|
|
- //objects1 = extra1->objects;
|
|
- //objects2 = extra1->objects;
|
|
+ objects1 = extra1->objects;
|
|
+ objects2 = extra1->objects;
|
|
}
|
|
} else if (meta1->d.data[0] == meta2->d.data[0] && meta1->d.data[0] == 1) {
|
|
objects1 = (const QMetaObject **)(meta1->d.extradata);
|
|
diff --git a/tests/auto/qmetaobjectbuilder/tst_qmetaobjectbuilder_47.cpp b/tests/auto/qmetaobjectbuilder/tst_qmetaobjectbuilder_47.cpp
|
|
new file mode 100644
|
|
index 0000000..96a7eca
|
|
--- /dev/null
|
|
+++ b/tests/auto/qmetaobjectbuilder/tst_qmetaobjectbuilder_47.cpp
|
|
@@ -0,0 +1,1283 @@
|
|
+/****************************************************************************
|
|
+**
|
|
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
|
|
+** All rights reserved.
|
|
+** Contact: Nokia Corporation (qt-info@nokia.com)
|
|
+**
|
|
+** This file is part of the test suite of the Qt Toolkit.
|
|
+**
|
|
+** $QT_BEGIN_LICENSE:LGPL$
|
|
+** No Commercial Usage
|
|
+** This file contains pre-release code and may not be distributed.
|
|
+** You may use this file in accordance with the terms and conditions
|
|
+** contained in the Technology Preview License Agreement accompanying
|
|
+** this package.
|
|
+**
|
|
+** GNU Lesser General Public License Usage
|
|
+** Alternatively, this file may be used under the terms of the GNU Lesser
|
|
+** General Public License version 2.1 as published by the Free Software
|
|
+** Foundation and appearing in the file LICENSE.LGPL included in the
|
|
+** packaging of this file. Please review the following information to
|
|
+** ensure the GNU Lesser General Public License version 2.1 requirements
|
|
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
|
+**
|
|
+** In addition, as a special exception, Nokia gives you certain additional
|
|
+** rights. These rights are described in the Nokia Qt LGPL Exception
|
|
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
|
+**
|
|
+** If you have questions regarding the use of this file, please contact
|
|
+** Nokia at qt-info@nokia.com.
|
|
+**
|
|
+**
|
|
+**
|
|
+**
|
|
+**
|
|
+**
|
|
+**
|
|
+**
|
|
+** $QT_END_LICENSE$
|
|
+**
|
|
+****************************************************************************/
|
|
+
|
|
+//TESTED_COMPONENT=src/serviceframework
|
|
+
|
|
+#include <qmobilityglobal.h>
|
|
+#include <QtTest/QtTest>
|
|
+#include <QtCore/qlocale.h>
|
|
+#include <qmetaobjectbuilder_47_p.h>
|
|
+
|
|
+QTM_USE_NAMESPACE
|
|
+
|
|
+class tst_QMetaObjectBuilder : public QObject
|
|
+{
|
|
+ Q_OBJECT
|
|
+public:
|
|
+ tst_QMetaObjectBuilder() {}
|
|
+ ~tst_QMetaObjectBuilder() {}
|
|
+
|
|
+private slots:
|
|
+ void mocVersionCheck();
|
|
+ void create();
|
|
+ void className();
|
|
+ void superClass();
|
|
+ void flags();
|
|
+ void method();
|
|
+ void slot();
|
|
+ void signal();
|
|
+ void constructor();
|
|
+ void property();
|
|
+ void notifySignal();
|
|
+ void enumerator();
|
|
+ void classInfo();
|
|
+ void relatedMetaObject();
|
|
+ void staticMetacall();
|
|
+ void copyMetaObject();
|
|
+ void serialize();
|
|
+ void removeNotifySignal();
|
|
+
|
|
+private:
|
|
+ static bool checkForSideEffects
|
|
+ (const QMetaObjectBuilder& builder,
|
|
+ QMetaObjectBuilder::AddMembers members);
|
|
+ static bool sameMetaObject
|
|
+ (const QMetaObject *meta1, const QMetaObject *meta2);
|
|
+};
|
|
+
|
|
+#ifdef Q_NO_DATA_RELOCATION
|
|
+const QMetaObject *meta;
|
|
+#endif
|
|
+
|
|
+// Dummy class that has something of every type of thing moc can generate.
|
|
+class SomethingOfEverything : public QObject
|
|
+{
|
|
+ Q_OBJECT
|
|
+ Q_CLASSINFO("ci_foo", "ABC")
|
|
+ Q_CLASSINFO("ci_bar", "DEF")
|
|
+ Q_PROPERTY(QString prop READ prop WRITE setProp NOTIFY propChanged)
|
|
+ Q_PROPERTY(QString prop2 READ prop WRITE setProp)
|
|
+ Q_PROPERTY(SomethingEnum eprop READ eprop)
|
|
+ Q_PROPERTY(SomethingFlagEnum fprop READ fprop)
|
|
+ Q_PROPERTY(QLocale::Language language READ language)
|
|
+ Q_ENUMS(SomethingEnum)
|
|
+ Q_FLAGS(SomethingFlagEnum)
|
|
+public:
|
|
+ Q_INVOKABLE SomethingOfEverything() {}
|
|
+ ~SomethingOfEverything() {}
|
|
+
|
|
+ enum SomethingEnum
|
|
+ {
|
|
+ GHI,
|
|
+ JKL = 10
|
|
+ };
|
|
+
|
|
+ enum SomethingFlagEnum
|
|
+ {
|
|
+ XYZ = 1,
|
|
+ UVW = 8
|
|
+ };
|
|
+
|
|
+ Q_INVOKABLE Q_SCRIPTABLE void method1() {}
|
|
+
|
|
+ QString prop() const { return QString(); }
|
|
+ void setProp(const QString& v) { Q_UNUSED(v); }
|
|
+
|
|
+ SomethingOfEverything::SomethingEnum eprop() const { return GHI; }
|
|
+ SomethingOfEverything::SomethingFlagEnum fprop() const { return XYZ; }
|
|
+ QLocale::Language language() const { return QLocale::English; }
|
|
+
|
|
+public slots:
|
|
+ void slot1(const QString&) {}
|
|
+ void slot2(int, const QString&) {}
|
|
+
|
|
+private slots:
|
|
+ void slot3() {}
|
|
+
|
|
+protected slots:
|
|
+ Q_SCRIPTABLE void slot4(int) {}
|
|
+ void slot5(int a, const QString& b) { Q_UNUSED(a); Q_UNUSED(b); }
|
|
+
|
|
+signals:
|
|
+ void sig1();
|
|
+ void sig2(int x, const QString& y);
|
|
+ void propChanged(const QString&);
|
|
+};
|
|
+
|
|
+void tst_QMetaObjectBuilder::mocVersionCheck()
|
|
+{
|
|
+ // This test will fail when the moc version number is changed.
|
|
+ // It is intended as a reminder to also update QMetaObjectBuilder
|
|
+ // whenenver moc changes. Once QMetaObjectBuilder has been
|
|
+ // updated, this test can be changed to check for the next version.
|
|
+ int version = int(QObject::staticMetaObject.d.data[0]);
|
|
+ QVERIFY(version == 4 || version == 5 || version == 6);
|
|
+ version = int(staticMetaObject.d.data[0]);
|
|
+ QVERIFY(version == 4 || version == 5 || version == 6);
|
|
+}
|
|
+
|
|
+void tst_QMetaObjectBuilder::create()
|
|
+{
|
|
+ QMetaObjectBuilder builder;
|
|
+ QVERIFY(builder.className().isEmpty());
|
|
+ QVERIFY(builder.superClass() == &QObject::staticMetaObject);
|
|
+ QCOMPARE(builder.methodCount(), 0);
|
|
+ QCOMPARE(builder.constructorCount(), 0);
|
|
+ QCOMPARE(builder.propertyCount(), 0);
|
|
+ QCOMPARE(builder.enumeratorCount(), 0);
|
|
+ QCOMPARE(builder.classInfoCount(), 0);
|
|
+ QCOMPARE(builder.relatedMetaObjectCount(), 0);
|
|
+ QVERIFY(builder.staticMetacallFunction() == 0);
|
|
+}
|
|
+
|
|
+void tst_QMetaObjectBuilder::className()
|
|
+{
|
|
+ QMetaObjectBuilder builder;
|
|
+
|
|
+ // Change the class name.
|
|
+ builder.setClassName("Foo");
|
|
+ QCOMPARE(builder.className(), QByteArray("Foo"));
|
|
+
|
|
+ // Change it again.
|
|
+ builder.setClassName("Bar");
|
|
+ QCOMPARE(builder.className(), QByteArray("Bar"));
|
|
+
|
|
+ // Clone the class name off a static QMetaObject.
|
|
+ builder.addMetaObject(&QObject::staticMetaObject, QMetaObjectBuilder::ClassName);
|
|
+ QCOMPARE(builder.className(), QByteArray("QObject"));
|
|
+
|
|
+ // Check that nothing else changed.
|
|
+ QVERIFY(checkForSideEffects(builder, QMetaObjectBuilder::ClassName));
|
|
+}
|
|
+
|
|
+void tst_QMetaObjectBuilder::superClass()
|
|
+{
|
|
+ QMetaObjectBuilder builder;
|
|
+
|
|
+ // Change the super class.
|
|
+ builder.setSuperClass(&QObject::staticMetaObject);
|
|
+ QVERIFY(builder.superClass() == &QObject::staticMetaObject);
|
|
+
|
|
+ // Change it again.
|
|
+ builder.setSuperClass(&staticMetaObject);
|
|
+ QVERIFY(builder.superClass() == &staticMetaObject);
|
|
+
|
|
+ // Clone the super class off a static QMetaObject.
|
|
+ builder.addMetaObject(&QObject::staticMetaObject, QMetaObjectBuilder::SuperClass);
|
|
+ QVERIFY(builder.superClass() == 0);
|
|
+ builder.addMetaObject(&staticMetaObject, QMetaObjectBuilder::SuperClass);
|
|
+ QVERIFY(builder.superClass() == staticMetaObject.superClass());
|
|
+
|
|
+ // Check that nothing else changed.
|
|
+ QVERIFY(checkForSideEffects(builder, QMetaObjectBuilder::SuperClass));
|
|
+}
|
|
+
|
|
+void tst_QMetaObjectBuilder::flags()
|
|
+{
|
|
+ QMetaObjectBuilder builder;
|
|
+
|
|
+ // Check default
|
|
+ QVERIFY(builder.flags() == 0);
|
|
+
|
|
+ // Set flags
|
|
+ builder.setFlags(QMetaObjectBuilder::DynamicMetaObject);
|
|
+ QVERIFY(builder.flags() == QMetaObjectBuilder::DynamicMetaObject);
|
|
+}
|
|
+
|
|
+void tst_QMetaObjectBuilder::method()
|
|
+{
|
|
+ QMetaObjectBuilder builder;
|
|
+
|
|
+ // Check null method
|
|
+ QMetaMethodBuilder nullMethod;
|
|
+ QCOMPARE(nullMethod.signature(), QByteArray());
|
|
+ QVERIFY(nullMethod.methodType() == QMetaMethod::Method);
|
|
+ QVERIFY(nullMethod.returnType().isEmpty());
|
|
+ QVERIFY(nullMethod.parameterNames().isEmpty());
|
|
+ QVERIFY(nullMethod.tag().isEmpty());
|
|
+ QVERIFY(nullMethod.access() == QMetaMethod::Public);
|
|
+ QCOMPARE(nullMethod.attributes(), 0);
|
|
+ QCOMPARE(nullMethod.index(), 0);
|
|
+
|
|
+ // Add a method and check its attributes.
|
|
+ QMetaMethodBuilder method1 = builder.addMethod("foo(const QString&, int)");
|
|
+ QCOMPARE(method1.signature(), QByteArray("foo(QString,int)"));
|
|
+ QVERIFY(method1.methodType() == QMetaMethod::Method);
|
|
+ QVERIFY(method1.returnType().isEmpty());
|
|
+ QVERIFY(method1.parameterNames().isEmpty());
|
|
+ QVERIFY(method1.tag().isEmpty());
|
|
+ QVERIFY(method1.access() == QMetaMethod::Public);
|
|
+ QCOMPARE(method1.attributes(), 0);
|
|
+ QCOMPARE(method1.index(), 0);
|
|
+ QCOMPARE(builder.methodCount(), 1);
|
|
+
|
|
+ // Add another method and check again.
|
|
+ QMetaMethodBuilder method2 = builder.addMethod("bar(QString)", "int");
|
|
+ QCOMPARE(method2.signature(), QByteArray("bar(QString)"));
|
|
+ QVERIFY(method2.methodType() == QMetaMethod::Method);
|
|
+ QCOMPARE(method2.returnType(), QByteArray("int"));
|
|
+ QVERIFY(method2.parameterNames().isEmpty());
|
|
+ QVERIFY(method2.tag().isEmpty());
|
|
+ QVERIFY(method2.access() == QMetaMethod::Public);
|
|
+ QCOMPARE(method2.attributes(), 0);
|
|
+ QCOMPARE(method2.index(), 1);
|
|
+ QCOMPARE(builder.methodCount(), 2);
|
|
+
|
|
+ // Perform index-based lookup.
|
|
+ QCOMPARE(builder.indexOfMethod("foo(const QString&, int)"), 0);
|
|
+ QCOMPARE(builder.indexOfMethod("bar(QString)"), 1);
|
|
+ QCOMPARE(builder.indexOfMethod("baz()"), -1);
|
|
+
|
|
+ // Modify the attributes on method1.
|
|
+ method1.setReturnType("int");
|
|
+ method1.setParameterNames(QList<QByteArray>() << "a" << "b");
|
|
+ method1.setTag("tag");
|
|
+ method1.setAccess(QMetaMethod::Private);
|
|
+ method1.setAttributes(42);
|
|
+
|
|
+ // Check that method1 is changed, but method2 is not.
|
|
+ QCOMPARE(method1.signature(), QByteArray("foo(QString,int)"));
|
|
+ QVERIFY(method1.methodType() == QMetaMethod::Method);
|
|
+ QCOMPARE(method1.returnType(), QByteArray("int"));
|
|
+ QCOMPARE(method1.parameterNames(), QList<QByteArray>() << "a" << "b");
|
|
+ QCOMPARE(method1.tag(), QByteArray("tag"));
|
|
+ QVERIFY(method1.access() == QMetaMethod::Private);
|
|
+ QCOMPARE(method1.attributes(), 42);
|
|
+ QCOMPARE(method1.index(), 0);
|
|
+ QCOMPARE(method2.signature(), QByteArray("bar(QString)"));
|
|
+ QVERIFY(method2.methodType() == QMetaMethod::Method);
|
|
+ QCOMPARE(method2.returnType(), QByteArray("int"));
|
|
+ QVERIFY(method2.parameterNames().isEmpty());
|
|
+ QVERIFY(method2.tag().isEmpty());
|
|
+ QVERIFY(method2.access() == QMetaMethod::Public);
|
|
+ QCOMPARE(method2.attributes(), 0);
|
|
+ QCOMPARE(method2.index(), 1);
|
|
+ QCOMPARE(builder.methodCount(), 2);
|
|
+
|
|
+ // Modify the attributes on method2.
|
|
+ method2.setReturnType("QString");
|
|
+ method2.setParameterNames(QList<QByteArray>() << "c");
|
|
+ method2.setTag("Q_FOO");
|
|
+ method2.setAccess(QMetaMethod::Protected);
|
|
+ method2.setAttributes(24);
|
|
+
|
|
+ // This time check that only method2 changed.
|
|
+ QCOMPARE(method1.signature(), QByteArray("foo(QString,int)"));
|
|
+ QVERIFY(method1.methodType() == QMetaMethod::Method);
|
|
+ QCOMPARE(method1.returnType(), QByteArray("int"));
|
|
+ QCOMPARE(method1.parameterNames(), QList<QByteArray>() << "a" << "b");
|
|
+ QCOMPARE(method1.tag(), QByteArray("tag"));
|
|
+ QVERIFY(method1.access() == QMetaMethod::Private);
|
|
+ QCOMPARE(method1.attributes(), 42);
|
|
+ QCOMPARE(method1.index(), 0);
|
|
+ QCOMPARE(method2.signature(), QByteArray("bar(QString)"));
|
|
+ QVERIFY(method2.methodType() == QMetaMethod::Method);
|
|
+ QCOMPARE(method2.returnType(), QByteArray("QString"));
|
|
+ QCOMPARE(method2.parameterNames(), QList<QByteArray>() << "c");
|
|
+ QCOMPARE(method2.tag(), QByteArray("Q_FOO"));
|
|
+ QVERIFY(method2.access() == QMetaMethod::Protected);
|
|
+ QCOMPARE(method2.attributes(), 24);
|
|
+ QCOMPARE(method2.index(), 1);
|
|
+ QCOMPARE(builder.methodCount(), 2);
|
|
+
|
|
+ // Remove method1 and check that method2 becomes index 0.
|
|
+ builder.removeMethod(0);
|
|
+ QCOMPARE(builder.methodCount(), 1);
|
|
+ method2 = builder.method(0);
|
|
+ QCOMPARE(method2.signature(), QByteArray("bar(QString)"));
|
|
+ QVERIFY(method2.methodType() == QMetaMethod::Method);
|
|
+ QCOMPARE(method2.returnType(), QByteArray("QString"));
|
|
+ QCOMPARE(method2.parameterNames(), QList<QByteArray>() << "c");
|
|
+ QCOMPARE(method2.tag(), QByteArray("Q_FOO"));
|
|
+ QVERIFY(method2.access() == QMetaMethod::Protected);
|
|
+ QCOMPARE(method2.attributes(), 24);
|
|
+ QCOMPARE(method2.index(), 0);
|
|
+
|
|
+ // Perform index-based lookup again.
|
|
+ QCOMPARE(builder.indexOfMethod("foo(const QString&, int)"), -1);
|
|
+ QCOMPARE(builder.indexOfMethod("bar(QString)"), 0);
|
|
+ QCOMPARE(builder.indexOfMethod("baz()"), -1);
|
|
+ QCOMPARE(builder.method(0).signature(), QByteArray("bar(QString)"));
|
|
+ QCOMPARE(builder.method(9).signature(), QByteArray());
|
|
+
|
|
+ // Check that nothing else changed.
|
|
+ QVERIFY(checkForSideEffects(builder, QMetaObjectBuilder::Methods));
|
|
+}
|
|
+
|
|
+void tst_QMetaObjectBuilder::slot()
|
|
+{
|
|
+ QMetaObjectBuilder builder;
|
|
+
|
|
+ // Add a slot and check its attributes.
|
|
+ QMetaMethodBuilder method1 = builder.addSlot("foo(const QString&, int)");
|
|
+ QCOMPARE(method1.signature(), QByteArray("foo(QString,int)"));
|
|
+ QVERIFY(method1.methodType() == QMetaMethod::Slot);
|
|
+ QVERIFY(method1.returnType().isEmpty());
|
|
+ QVERIFY(method1.parameterNames().isEmpty());
|
|
+ QVERIFY(method1.tag().isEmpty());
|
|
+ QVERIFY(method1.access() == QMetaMethod::Public);
|
|
+ QCOMPARE(method1.attributes(), 0);
|
|
+ QCOMPARE(method1.index(), 0);
|
|
+ QCOMPARE(builder.methodCount(), 1);
|
|
+
|
|
+ // Add another slot and check again.
|
|
+ QMetaMethodBuilder method2 = builder.addSlot("bar(QString)");
|
|
+ QCOMPARE(method2.signature(), QByteArray("bar(QString)"));
|
|
+ QVERIFY(method2.methodType() == QMetaMethod::Slot);
|
|
+ QVERIFY(method2.returnType().isEmpty());
|
|
+ QVERIFY(method2.parameterNames().isEmpty());
|
|
+ QVERIFY(method2.tag().isEmpty());
|
|
+ QVERIFY(method2.access() == QMetaMethod::Public);
|
|
+ QCOMPARE(method2.attributes(), 0);
|
|
+ QCOMPARE(method2.index(), 1);
|
|
+ QCOMPARE(builder.methodCount(), 2);
|
|
+
|
|
+ // Perform index-based lookup
|
|
+ QCOMPARE(builder.indexOfSlot("foo(const QString &, int)"), 0);
|
|
+ QCOMPARE(builder.indexOfSlot("bar(QString)"), 1);
|
|
+ QCOMPARE(builder.indexOfSlot("baz()"), -1);
|
|
+
|
|
+ // Check that nothing else changed.
|
|
+ QVERIFY(checkForSideEffects(builder, QMetaObjectBuilder::Methods));
|
|
+}
|
|
+
|
|
+void tst_QMetaObjectBuilder::signal()
|
|
+{
|
|
+ QMetaObjectBuilder builder;
|
|
+
|
|
+ // Add a signal and check its attributes.
|
|
+ QMetaMethodBuilder method1 = builder.addSignal("foo(const QString&, int)");
|
|
+ QCOMPARE(method1.signature(), QByteArray("foo(QString,int)"));
|
|
+ QVERIFY(method1.methodType() == QMetaMethod::Signal);
|
|
+ QVERIFY(method1.returnType().isEmpty());
|
|
+ QVERIFY(method1.parameterNames().isEmpty());
|
|
+ QVERIFY(method1.tag().isEmpty());
|
|
+ QVERIFY(method1.access() == QMetaMethod::Protected);
|
|
+ QCOMPARE(method1.attributes(), 0);
|
|
+ QCOMPARE(method1.index(), 0);
|
|
+ QCOMPARE(builder.methodCount(), 1);
|
|
+
|
|
+ // Add another signal and check again.
|
|
+ QMetaMethodBuilder method2 = builder.addSignal("bar(QString)");
|
|
+ QCOMPARE(method2.signature(), QByteArray("bar(QString)"));
|
|
+ QVERIFY(method2.methodType() == QMetaMethod::Signal);
|
|
+ QVERIFY(method2.returnType().isEmpty());
|
|
+ QVERIFY(method2.parameterNames().isEmpty());
|
|
+ QVERIFY(method2.tag().isEmpty());
|
|
+ QVERIFY(method2.access() == QMetaMethod::Protected);
|
|
+ QCOMPARE(method2.attributes(), 0);
|
|
+ QCOMPARE(method2.index(), 1);
|
|
+ QCOMPARE(builder.methodCount(), 2);
|
|
+
|
|
+ // Perform index-based lookup
|
|
+ QCOMPARE(builder.indexOfSignal("foo(const QString &, int)"), 0);
|
|
+ QCOMPARE(builder.indexOfSignal("bar(QString)"), 1);
|
|
+ QCOMPARE(builder.indexOfSignal("baz()"), -1);
|
|
+
|
|
+ // Check that nothing else changed.
|
|
+ QVERIFY(checkForSideEffects(builder, QMetaObjectBuilder::Methods));
|
|
+}
|
|
+
|
|
+void tst_QMetaObjectBuilder::constructor()
|
|
+{
|
|
+ QMetaObjectBuilder builder;
|
|
+
|
|
+ // Add a constructor and check its attributes.
|
|
+ QMetaMethodBuilder ctor1 = builder.addConstructor("foo(const QString&, int)");
|
|
+ QCOMPARE(ctor1.signature(), QByteArray("foo(QString,int)"));
|
|
+ QVERIFY(ctor1.methodType() == QMetaMethod::Constructor);
|
|
+ QVERIFY(ctor1.returnType().isEmpty());
|
|
+ QVERIFY(ctor1.parameterNames().isEmpty());
|
|
+ QVERIFY(ctor1.tag().isEmpty());
|
|
+ QVERIFY(ctor1.access() == QMetaMethod::Public);
|
|
+ QCOMPARE(ctor1.attributes(), 0);
|
|
+ QCOMPARE(ctor1.index(), 0);
|
|
+ QCOMPARE(builder.constructorCount(), 1);
|
|
+
|
|
+ // Add another constructor and check again.
|
|
+ QMetaMethodBuilder ctor2 = builder.addConstructor("bar(QString)");
|
|
+ QCOMPARE(ctor2.signature(), QByteArray("bar(QString)"));
|
|
+ QVERIFY(ctor2.methodType() == QMetaMethod::Constructor);
|
|
+ QVERIFY(ctor2.returnType().isEmpty());
|
|
+ QVERIFY(ctor2.parameterNames().isEmpty());
|
|
+ QVERIFY(ctor2.tag().isEmpty());
|
|
+ QVERIFY(ctor2.access() == QMetaMethod::Public);
|
|
+ QCOMPARE(ctor2.attributes(), 0);
|
|
+ QCOMPARE(ctor2.index(), 1);
|
|
+ QCOMPARE(builder.constructorCount(), 2);
|
|
+
|
|
+ // Perform index-based lookup.
|
|
+ QCOMPARE(builder.indexOfConstructor("foo(const QString&, int)"), 0);
|
|
+ QCOMPARE(builder.indexOfConstructor("bar(QString)"), 1);
|
|
+ QCOMPARE(builder.indexOfConstructor("baz()"), -1);
|
|
+ QCOMPARE(builder.constructor(1).signature(), QByteArray("bar(QString)"));
|
|
+ QCOMPARE(builder.constructor(9).signature(), QByteArray());
|
|
+
|
|
+ // Modify the attributes on ctor1.
|
|
+ ctor1.setReturnType("int");
|
|
+ ctor1.setParameterNames(QList<QByteArray>() << "a" << "b");
|
|
+ ctor1.setTag("tag");
|
|
+ ctor1.setAccess(QMetaMethod::Private);
|
|
+ ctor1.setAttributes(42);
|
|
+
|
|
+ // Check that ctor1 is changed, but ctor2 is not.
|
|
+ QCOMPARE(ctor1.signature(), QByteArray("foo(QString,int)"));
|
|
+ QVERIFY(ctor1.methodType() == QMetaMethod::Constructor);
|
|
+ QCOMPARE(ctor1.returnType(), QByteArray("int"));
|
|
+ QCOMPARE(ctor1.parameterNames(), QList<QByteArray>() << "a" << "b");
|
|
+ QCOMPARE(ctor1.tag(), QByteArray("tag"));
|
|
+ QVERIFY(ctor1.access() == QMetaMethod::Private);
|
|
+ QCOMPARE(ctor1.attributes(), 42);
|
|
+ QCOMPARE(ctor1.index(), 0);
|
|
+ QCOMPARE(ctor2.signature(), QByteArray("bar(QString)"));
|
|
+ QVERIFY(ctor2.methodType() == QMetaMethod::Constructor);
|
|
+ QVERIFY(ctor2.returnType().isEmpty());
|
|
+ QVERIFY(ctor2.parameterNames().isEmpty());
|
|
+ QVERIFY(ctor2.tag().isEmpty());
|
|
+ QVERIFY(ctor2.access() == QMetaMethod::Public);
|
|
+ QCOMPARE(ctor2.attributes(), 0);
|
|
+ QCOMPARE(ctor2.index(), 1);
|
|
+ QCOMPARE(builder.constructorCount(), 2);
|
|
+
|
|
+ // Modify the attributes on ctor2.
|
|
+ ctor2.setReturnType("QString");
|
|
+ ctor2.setParameterNames(QList<QByteArray>() << "c");
|
|
+ ctor2.setTag("Q_FOO");
|
|
+ ctor2.setAccess(QMetaMethod::Protected);
|
|
+ ctor2.setAttributes(24);
|
|
+
|
|
+ // This time check that only ctor2 changed.
|
|
+ QCOMPARE(ctor1.signature(), QByteArray("foo(QString,int)"));
|
|
+ QVERIFY(ctor1.methodType() == QMetaMethod::Constructor);
|
|
+ QCOMPARE(ctor1.returnType(), QByteArray("int"));
|
|
+ QCOMPARE(ctor1.parameterNames(), QList<QByteArray>() << "a" << "b");
|
|
+ QCOMPARE(ctor1.tag(), QByteArray("tag"));
|
|
+ QVERIFY(ctor1.access() == QMetaMethod::Private);
|
|
+ QCOMPARE(ctor1.attributes(), 42);
|
|
+ QCOMPARE(ctor1.index(), 0);
|
|
+ QCOMPARE(ctor2.signature(), QByteArray("bar(QString)"));
|
|
+ QVERIFY(ctor2.methodType() == QMetaMethod::Constructor);
|
|
+ QCOMPARE(ctor2.returnType(), QByteArray("QString"));
|
|
+ QCOMPARE(ctor2.parameterNames(), QList<QByteArray>() << "c");
|
|
+ QCOMPARE(ctor2.tag(), QByteArray("Q_FOO"));
|
|
+ QVERIFY(ctor2.access() == QMetaMethod::Protected);
|
|
+ QCOMPARE(ctor2.attributes(), 24);
|
|
+ QCOMPARE(ctor2.index(), 1);
|
|
+ QCOMPARE(builder.constructorCount(), 2);
|
|
+
|
|
+ // Remove ctor1 and check that ctor2 becomes index 0.
|
|
+ builder.removeConstructor(0);
|
|
+ QCOMPARE(builder.constructorCount(), 1);
|
|
+ ctor2 = builder.constructor(0);
|
|
+ QCOMPARE(ctor2.signature(), QByteArray("bar(QString)"));
|
|
+ QVERIFY(ctor2.methodType() == QMetaMethod::Constructor);
|
|
+ QCOMPARE(ctor2.returnType(), QByteArray("QString"));
|
|
+ QCOMPARE(ctor2.parameterNames(), QList<QByteArray>() << "c");
|
|
+ QCOMPARE(ctor2.tag(), QByteArray("Q_FOO"));
|
|
+ QVERIFY(ctor2.access() == QMetaMethod::Protected);
|
|
+ QCOMPARE(ctor2.attributes(), 24);
|
|
+ QCOMPARE(ctor2.index(), 0);
|
|
+
|
|
+ // Perform index-based lookup again.
|
|
+ QCOMPARE(builder.indexOfConstructor("foo(const QString&, int)"), -1);
|
|
+ QCOMPARE(builder.indexOfConstructor("bar(QString)"), 0);
|
|
+ QCOMPARE(builder.indexOfConstructor("baz()"), -1);
|
|
+
|
|
+ // Add constructor from prototype
|
|
+ QMetaMethod prototype = SomethingOfEverything::staticMetaObject.constructor(0);
|
|
+ QMetaMethodBuilder prototypeConstructor = builder.addMethod(prototype);
|
|
+ QCOMPARE(builder.constructorCount(), 2);
|
|
+
|
|
+ QCOMPARE(prototypeConstructor.signature(), QByteArray("SomethingOfEverything()"));
|
|
+ QVERIFY(prototypeConstructor.methodType() == QMetaMethod::Constructor);
|
|
+ QCOMPARE(prototypeConstructor.returnType(), QByteArray());
|
|
+ QVERIFY(prototypeConstructor.access() == QMetaMethod::Public);
|
|
+ QCOMPARE(prototypeConstructor.index(), 1);
|
|
+
|
|
+ // Check that nothing else changed.
|
|
+ QVERIFY(checkForSideEffects(builder, QMetaObjectBuilder::Constructors));
|
|
+}
|
|
+
|
|
+void tst_QMetaObjectBuilder::property()
|
|
+{
|
|
+ QMetaObjectBuilder builder;
|
|
+
|
|
+ // Null property builder
|
|
+ QMetaPropertyBuilder nullProp;
|
|
+ QCOMPARE(nullProp.name(), QByteArray());
|
|
+ QCOMPARE(nullProp.type(), QByteArray());
|
|
+ QVERIFY(!nullProp.hasNotifySignal());
|
|
+ QVERIFY(!nullProp.isReadable());
|
|
+ QVERIFY(!nullProp.isWritable());
|
|
+ QVERIFY(!nullProp.isResettable());
|
|
+ QVERIFY(!nullProp.isDesignable());
|
|
+ QVERIFY(!nullProp.isScriptable());
|
|
+ QVERIFY(!nullProp.isStored());
|
|
+ QVERIFY(!nullProp.isEditable());
|
|
+ QVERIFY(!nullProp.isUser());
|
|
+ QVERIFY(!nullProp.hasStdCppSet());
|
|
+ QVERIFY(!nullProp.isEnumOrFlag());
|
|
+ QCOMPARE(nullProp.index(), 0);
|
|
+
|
|
+ // Add a property and check its attributes.
|
|
+ QMetaPropertyBuilder prop1 = builder.addProperty("foo", "const QString &");
|
|
+ QCOMPARE(prop1.name(), QByteArray("foo"));
|
|
+ QCOMPARE(prop1.type(), QByteArray("QString"));
|
|
+ QVERIFY(!prop1.hasNotifySignal());
|
|
+ QVERIFY(prop1.isReadable());
|
|
+ QVERIFY(prop1.isWritable());
|
|
+ QVERIFY(!prop1.isResettable());
|
|
+ QVERIFY(!prop1.isDesignable());
|
|
+ QVERIFY(prop1.isScriptable());
|
|
+ QVERIFY(!prop1.isStored());
|
|
+ QVERIFY(!prop1.isEditable());
|
|
+ QVERIFY(!prop1.isUser());
|
|
+ QVERIFY(!prop1.hasStdCppSet());
|
|
+ QVERIFY(!prop1.isEnumOrFlag());
|
|
+
|
|
+ QCOMPARE(prop1.index(), 0);
|
|
+ QCOMPARE(builder.propertyCount(), 1);
|
|
+
|
|
+ // Add another property and check again.
|
|
+ QMetaPropertyBuilder prop2 = builder.addProperty("bar", "int");
|
|
+ QCOMPARE(prop2.name(), QByteArray("bar"));
|
|
+ QCOMPARE(prop2.type(), QByteArray("int"));
|
|
+ QVERIFY(!prop2.hasNotifySignal());
|
|
+ QVERIFY(prop2.isReadable());
|
|
+ QVERIFY(prop2.isWritable());
|
|
+ QVERIFY(!prop2.isResettable());
|
|
+ QVERIFY(!prop2.isDesignable());
|
|
+ QVERIFY(prop2.isScriptable());
|
|
+ QVERIFY(!prop2.isStored());
|
|
+ QVERIFY(!prop2.isEditable());
|
|
+ QVERIFY(!prop2.isUser());
|
|
+ QVERIFY(!prop2.hasStdCppSet());
|
|
+ QVERIFY(!prop2.isEnumOrFlag());
|
|
+
|
|
+ QCOMPARE(prop2.index(), 1);
|
|
+ QCOMPARE(builder.propertyCount(), 2);
|
|
+
|
|
+ // Perform index-based lookup.
|
|
+ QCOMPARE(builder.indexOfProperty("foo"), 0);
|
|
+ QCOMPARE(builder.indexOfProperty("bar"), 1);
|
|
+ QCOMPARE(builder.indexOfProperty("baz"), -1);
|
|
+ QCOMPARE(builder.property(1).name(), QByteArray("bar"));
|
|
+ QCOMPARE(builder.property(9).name(), QByteArray());
|
|
+
|
|
+ // Modify the attributes on prop1.
|
|
+ prop1.setReadable(false);
|
|
+ prop1.setWritable(false);
|
|
+ prop1.setResettable(true);
|
|
+ prop1.setDesignable(true);
|
|
+ prop1.setScriptable(false);
|
|
+ prop1.setStored(true);
|
|
+ prop1.setEditable(true);
|
|
+ prop1.setUser(true);
|
|
+ prop1.setStdCppSet(true);
|
|
+ prop1.setEnumOrFlag(true);
|
|
+
|
|
+ // Check that prop1 is changed, but prop2 is not.
|
|
+ QCOMPARE(prop1.name(), QByteArray("foo"));
|
|
+ QCOMPARE(prop1.type(), QByteArray("QString"));
|
|
+ QVERIFY(!prop1.isReadable());
|
|
+ QVERIFY(!prop1.isWritable());
|
|
+ QVERIFY(prop1.isResettable());
|
|
+ QVERIFY(prop1.isDesignable());
|
|
+ QVERIFY(!prop1.isScriptable());
|
|
+ QVERIFY(prop1.isStored());
|
|
+ QVERIFY(prop1.isEditable());
|
|
+ QVERIFY(prop1.isUser());
|
|
+ QVERIFY(prop1.hasStdCppSet());
|
|
+ QVERIFY(prop1.isEnumOrFlag());
|
|
+ QVERIFY(prop2.isReadable());
|
|
+ QVERIFY(prop2.isWritable());
|
|
+ QCOMPARE(prop2.name(), QByteArray("bar"));
|
|
+ QCOMPARE(prop2.type(), QByteArray("int"));
|
|
+ QVERIFY(!prop2.isResettable());
|
|
+ QVERIFY(!prop2.isDesignable());
|
|
+ QVERIFY(prop2.isScriptable());
|
|
+ QVERIFY(!prop2.isStored());
|
|
+ QVERIFY(!prop2.isEditable());
|
|
+ QVERIFY(!prop2.isUser());
|
|
+ QVERIFY(!prop2.hasStdCppSet());
|
|
+ QVERIFY(!prop2.isEnumOrFlag());
|
|
+
|
|
+ // Remove prop1 and check that prop2 becomes index 0.
|
|
+ builder.removeProperty(0);
|
|
+ QCOMPARE(builder.propertyCount(), 1);
|
|
+ prop2 = builder.property(0);
|
|
+ QCOMPARE(prop2.name(), QByteArray("bar"));
|
|
+ QCOMPARE(prop2.type(), QByteArray("int"));
|
|
+ QVERIFY(!prop2.isResettable());
|
|
+ QVERIFY(!prop2.isDesignable());
|
|
+ QVERIFY(prop2.isScriptable());
|
|
+ QVERIFY(!prop2.isStored());
|
|
+ QVERIFY(!prop2.isEditable());
|
|
+ QVERIFY(!prop2.isUser());
|
|
+ QVERIFY(!prop2.hasStdCppSet());
|
|
+ QVERIFY(!prop2.isEnumOrFlag());
|
|
+ QCOMPARE(prop2.index(), 0);
|
|
+
|
|
+ // Perform index-based lookup again.
|
|
+ QCOMPARE(builder.indexOfProperty("foo"), -1);
|
|
+ QCOMPARE(builder.indexOfProperty("bar"), 0);
|
|
+ QCOMPARE(builder.indexOfProperty("baz"), -1);
|
|
+
|
|
+ // Check for side-effects between the flags on prop2.
|
|
+ // Setting a flag to true shouldn't set any of the others to true.
|
|
+ // This checks for cut-and-paste bugs in the implementation where
|
|
+ // the flag code was pasted but the flag name was not changed.
|
|
+#define CLEAR_FLAGS() \
|
|
+ do { \
|
|
+ prop2.setReadable(false); \
|
|
+ prop2.setWritable(false); \
|
|
+ prop2.setResettable(false); \
|
|
+ prop2.setDesignable(false); \
|
|
+ prop2.setScriptable(false); \
|
|
+ prop2.setStored(false); \
|
|
+ prop2.setEditable(false); \
|
|
+ prop2.setUser(false); \
|
|
+ prop2.setStdCppSet(false); \
|
|
+ prop2.setEnumOrFlag(false); \
|
|
+ } while (0)
|
|
+#define COUNT_FLAGS() \
|
|
+ ((prop2.isReadable() ? 1 : 0) + \
|
|
+ (prop2.isWritable() ? 1 : 0) + \
|
|
+ (prop2.isResettable() ? 1 : 0) + \
|
|
+ (prop2.isDesignable() ? 1 : 0) + \
|
|
+ (prop2.isScriptable() ? 1 : 0) + \
|
|
+ (prop2.isStored() ? 1 : 0) + \
|
|
+ (prop2.isEditable() ? 1 : 0) + \
|
|
+ (prop2.isUser() ? 1 : 0) + \
|
|
+ (prop2.hasStdCppSet() ? 1 : 0) + \
|
|
+ (prop2.isEnumOrFlag() ? 1 : 0))
|
|
+#define CHECK_FLAG(setFunc,isFunc) \
|
|
+ do { \
|
|
+ CLEAR_FLAGS(); \
|
|
+ QCOMPARE(COUNT_FLAGS(), 0); \
|
|
+ prop2.setFunc(true); \
|
|
+ QVERIFY(prop2.isFunc()); \
|
|
+ QCOMPARE(COUNT_FLAGS(), 1); \
|
|
+ } while (0)
|
|
+ CHECK_FLAG(setReadable, isReadable);
|
|
+ CHECK_FLAG(setWritable, isWritable);
|
|
+ CHECK_FLAG(setResettable, isResettable);
|
|
+ CHECK_FLAG(setDesignable, isDesignable);
|
|
+ CHECK_FLAG(setScriptable, isScriptable);
|
|
+ CHECK_FLAG(setStored, isStored);
|
|
+ CHECK_FLAG(setEditable, isEditable);
|
|
+ CHECK_FLAG(setUser, isUser);
|
|
+ CHECK_FLAG(setStdCppSet, hasStdCppSet);
|
|
+ CHECK_FLAG(setEnumOrFlag, isEnumOrFlag);
|
|
+
|
|
+ // Check that nothing else changed.
|
|
+ QVERIFY(checkForSideEffects(builder, QMetaObjectBuilder::Properties));
|
|
+
|
|
+ // Add property from prototype
|
|
+ QMetaProperty prototype = SomethingOfEverything::staticMetaObject.property(1);
|
|
+ QVERIFY(prototype.name() == QByteArray("prop"));
|
|
+ QMetaPropertyBuilder prototypeProp = builder.addProperty(prototype);
|
|
+ QCOMPARE(prototypeProp.name(), QByteArray("prop"));
|
|
+ QVERIFY(prototypeProp.hasNotifySignal());
|
|
+ QCOMPARE(prototypeProp.notifySignal().signature(), QByteArray("propChanged(QString)"));
|
|
+ QCOMPARE(builder.methodCount(), 1);
|
|
+ QCOMPARE(builder.method(0).signature(), QByteArray("propChanged(QString)"));
|
|
+}
|
|
+
|
|
+void tst_QMetaObjectBuilder::notifySignal()
|
|
+{
|
|
+ QMetaObjectBuilder builder;
|
|
+
|
|
+ QMetaPropertyBuilder prop = builder.addProperty("foo", "const QString &");
|
|
+ builder.addSlot("setFoo(QString)");
|
|
+ QMetaMethodBuilder notify = builder.addSignal("fooChanged(QString)");
|
|
+
|
|
+ QVERIFY(!prop.hasNotifySignal());
|
|
+ QCOMPARE(prop.notifySignal().index(), 0);
|
|
+
|
|
+ prop.setNotifySignal(notify);
|
|
+ QVERIFY(prop.hasNotifySignal());
|
|
+ QCOMPARE(prop.notifySignal().index(), 1);
|
|
+
|
|
+ prop.setNotifySignal(QMetaMethodBuilder());
|
|
+ QVERIFY(!prop.hasNotifySignal());
|
|
+ QCOMPARE(prop.notifySignal().index(), 0);
|
|
+
|
|
+ prop.setNotifySignal(notify);
|
|
+ prop.removeNotifySignal();
|
|
+ QVERIFY(!prop.hasNotifySignal());
|
|
+ QCOMPARE(prop.notifySignal().index(), 0);
|
|
+
|
|
+ QCOMPARE(builder.methodCount(), 2);
|
|
+ QCOMPARE(builder.propertyCount(), 1);
|
|
+
|
|
+ // Check that nothing else changed except methods and properties.
|
|
+ QVERIFY(checkForSideEffects
|
|
+ (builder, QMetaObjectBuilder::Methods | QMetaObjectBuilder::Properties));
|
|
+}
|
|
+
|
|
+void tst_QMetaObjectBuilder::enumerator()
|
|
+{
|
|
+ QMetaObjectBuilder builder;
|
|
+
|
|
+ // Add an enumerator and check its attributes.
|
|
+ QMetaEnumBuilder enum1 = builder.addEnumerator("foo");
|
|
+ QCOMPARE(enum1.name(), QByteArray("foo"));
|
|
+ QVERIFY(!enum1.isFlag());
|
|
+ QCOMPARE(enum1.keyCount(), 0);
|
|
+ QCOMPARE(enum1.index(), 0);
|
|
+ QCOMPARE(builder.enumeratorCount(), 1);
|
|
+
|
|
+ // Add another enumerator and check again.
|
|
+ QMetaEnumBuilder enum2 = builder.addEnumerator("bar");
|
|
+ QCOMPARE(enum2.name(), QByteArray("bar"));
|
|
+ QVERIFY(!enum2.isFlag());
|
|
+ QCOMPARE(enum2.keyCount(), 0);
|
|
+ QCOMPARE(enum2.index(), 1);
|
|
+ QCOMPARE(builder.enumeratorCount(), 2);
|
|
+
|
|
+ // Perform index-based lookup.
|
|
+ QCOMPARE(builder.indexOfEnumerator("foo"), 0);
|
|
+ QCOMPARE(builder.indexOfEnumerator("bar"), 1);
|
|
+ QCOMPARE(builder.indexOfEnumerator("baz"), -1);
|
|
+ QCOMPARE(builder.enumerator(1).name(), QByteArray("bar"));
|
|
+ QCOMPARE(builder.enumerator(9).name(), QByteArray());
|
|
+
|
|
+ // Modify the attributes on enum1.
|
|
+ enum1.setIsFlag(true);
|
|
+ QCOMPARE(enum1.addKey("ABC", 0), 0);
|
|
+ QCOMPARE(enum1.addKey("DEF", 1), 1);
|
|
+ QCOMPARE(enum1.addKey("GHI", -1), 2);
|
|
+
|
|
+ // Check that enum1 is changed, but enum2 is not.
|
|
+ QCOMPARE(enum1.name(), QByteArray("foo"));
|
|
+ QVERIFY(enum1.isFlag());
|
|
+ QCOMPARE(enum1.keyCount(), 3);
|
|
+ QCOMPARE(enum1.index(), 0);
|
|
+ QCOMPARE(enum1.key(0), QByteArray("ABC"));
|
|
+ QCOMPARE(enum1.key(1), QByteArray("DEF"));
|
|
+ QCOMPARE(enum1.key(2), QByteArray("GHI"));
|
|
+ QCOMPARE(enum1.key(3), QByteArray());
|
|
+ QCOMPARE(enum1.value(0), 0);
|
|
+ QCOMPARE(enum1.value(1), 1);
|
|
+ QCOMPARE(enum1.value(2), -1);
|
|
+ QCOMPARE(enum2.name(), QByteArray("bar"));
|
|
+ QVERIFY(!enum2.isFlag());
|
|
+ QCOMPARE(enum2.keyCount(), 0);
|
|
+ QCOMPARE(enum2.index(), 1);
|
|
+
|
|
+ // Modify the attributes on enum2.
|
|
+ enum2.setIsFlag(true);
|
|
+ QCOMPARE(enum2.addKey("XYZ", 10), 0);
|
|
+ QCOMPARE(enum2.addKey("UVW", 19), 1);
|
|
+
|
|
+ // This time check that only method2 changed.
|
|
+ QCOMPARE(enum1.name(), QByteArray("foo"));
|
|
+ QVERIFY(enum1.isFlag());
|
|
+ QCOMPARE(enum1.keyCount(), 3);
|
|
+ QCOMPARE(enum1.index(), 0);
|
|
+ QCOMPARE(enum1.key(0), QByteArray("ABC"));
|
|
+ QCOMPARE(enum1.key(1), QByteArray("DEF"));
|
|
+ QCOMPARE(enum1.key(2), QByteArray("GHI"));
|
|
+ QCOMPARE(enum1.key(3), QByteArray());
|
|
+ QCOMPARE(enum1.value(0), 0);
|
|
+ QCOMPARE(enum1.value(1), 1);
|
|
+ QCOMPARE(enum1.value(2), -1);
|
|
+ QCOMPARE(enum2.name(), QByteArray("bar"));
|
|
+ QVERIFY(enum2.isFlag());
|
|
+ QCOMPARE(enum2.keyCount(), 2);
|
|
+ QCOMPARE(enum2.index(), 1);
|
|
+ QCOMPARE(enum2.key(0), QByteArray("XYZ"));
|
|
+ QCOMPARE(enum2.key(1), QByteArray("UVW"));
|
|
+ QCOMPARE(enum2.key(2), QByteArray());
|
|
+ QCOMPARE(enum2.value(0), 10);
|
|
+ QCOMPARE(enum2.value(1), 19);
|
|
+
|
|
+ // Remove enum1 key
|
|
+ enum1.removeKey(2);
|
|
+ QCOMPARE(enum1.name(), QByteArray("foo"));
|
|
+ QVERIFY(enum1.isFlag());
|
|
+ QCOMPARE(enum1.keyCount(), 2);
|
|
+ QCOMPARE(enum1.index(), 0);
|
|
+ QCOMPARE(enum1.key(0), QByteArray("ABC"));
|
|
+ QCOMPARE(enum1.key(1), QByteArray("DEF"));
|
|
+ QCOMPARE(enum1.key(2), QByteArray());
|
|
+ QCOMPARE(enum1.value(0), 0);
|
|
+ QCOMPARE(enum1.value(1), 1);
|
|
+ QCOMPARE(enum1.value(2), -1);
|
|
+ QCOMPARE(enum2.name(), QByteArray("bar"));
|
|
+ QVERIFY(enum2.isFlag());
|
|
+ QCOMPARE(enum2.keyCount(), 2);
|
|
+ QCOMPARE(enum2.index(), 1);
|
|
+ QCOMPARE(enum2.key(0), QByteArray("XYZ"));
|
|
+ QCOMPARE(enum2.key(1), QByteArray("UVW"));
|
|
+ QCOMPARE(enum2.key(2), QByteArray());
|
|
+ QCOMPARE(enum2.value(0), 10);
|
|
+ QCOMPARE(enum2.value(1), 19);
|
|
+
|
|
+ // Remove enum1 and check that enum2 becomes index 0.
|
|
+ builder.removeEnumerator(0);
|
|
+ QCOMPARE(builder.enumeratorCount(), 1);
|
|
+ enum2 = builder.enumerator(0);
|
|
+ QCOMPARE(enum2.name(), QByteArray("bar"));
|
|
+ QVERIFY(enum2.isFlag());
|
|
+ QCOMPARE(enum2.keyCount(), 2);
|
|
+ QCOMPARE(enum2.index(), 0);
|
|
+ QCOMPARE(enum2.key(0), QByteArray("XYZ"));
|
|
+ QCOMPARE(enum2.key(1), QByteArray("UVW"));
|
|
+ QCOMPARE(enum2.key(2), QByteArray());
|
|
+ QCOMPARE(enum2.value(0), 10);
|
|
+ QCOMPARE(enum2.value(1), 19);
|
|
+
|
|
+ // Perform index-based lookup again.
|
|
+ QCOMPARE(builder.indexOfEnumerator("foo"), -1);
|
|
+ QCOMPARE(builder.indexOfEnumerator("bar"), 0);
|
|
+ QCOMPARE(builder.indexOfEnumerator("baz"), -1);
|
|
+
|
|
+ // Check that nothing else changed.
|
|
+ QVERIFY(checkForSideEffects(builder, QMetaObjectBuilder::Enumerators));
|
|
+}
|
|
+
|
|
+void tst_QMetaObjectBuilder::classInfo()
|
|
+{
|
|
+ QMetaObjectBuilder builder;
|
|
+
|
|
+ // Add two items of class information and check their attributes.
|
|
+ QCOMPARE(builder.addClassInfo("foo", "value1"), 0);
|
|
+ QCOMPARE(builder.addClassInfo("bar", "value2"), 1);
|
|
+ QCOMPARE(builder.classInfoName(0), QByteArray("foo"));
|
|
+ QCOMPARE(builder.classInfoValue(0), QByteArray("value1"));
|
|
+ QCOMPARE(builder.classInfoName(1), QByteArray("bar"));
|
|
+ QCOMPARE(builder.classInfoValue(1), QByteArray("value2"));
|
|
+ QCOMPARE(builder.classInfoName(9), QByteArray());
|
|
+ QCOMPARE(builder.classInfoValue(9), QByteArray());
|
|
+ QCOMPARE(builder.classInfoCount(), 2);
|
|
+
|
|
+ // Perform index-based lookup.
|
|
+ QCOMPARE(builder.indexOfClassInfo("foo"), 0);
|
|
+ QCOMPARE(builder.indexOfClassInfo("bar"), 1);
|
|
+ QCOMPARE(builder.indexOfClassInfo("baz"), -1);
|
|
+
|
|
+ // Remove the first one and check again.
|
|
+ builder.removeClassInfo(0);
|
|
+ QCOMPARE(builder.classInfoName(0), QByteArray("bar"));
|
|
+ QCOMPARE(builder.classInfoValue(0), QByteArray("value2"));
|
|
+ QCOMPARE(builder.classInfoCount(), 1);
|
|
+
|
|
+ // Perform index-based lookup again.
|
|
+ QCOMPARE(builder.indexOfClassInfo("foo"), -1);
|
|
+ QCOMPARE(builder.indexOfClassInfo("bar"), 0);
|
|
+ QCOMPARE(builder.indexOfClassInfo("baz"), -1);
|
|
+
|
|
+ // Check that nothing else changed.
|
|
+ QVERIFY(checkForSideEffects(builder, QMetaObjectBuilder::ClassInfos));
|
|
+}
|
|
+
|
|
+#ifdef Q_NO_DATA_RELOCATION
|
|
+const QMetaObject& staticMetaObjectGlobal()
|
|
+{
|
|
+ return QObject::staticMetaObject;
|
|
+}
|
|
+
|
|
+const QMetaObject& staticMetaObjectLocal()
|
|
+{
|
|
+ return *meta;
|
|
+}
|
|
+#endif
|
|
+
|
|
+
|
|
+void tst_QMetaObjectBuilder::relatedMetaObject()
|
|
+{
|
|
+ QMetaObjectBuilder builder;
|
|
+
|
|
+ // Add two related meta objects and check their attributes.
|
|
+#ifdef Q_NO_DATA_RELOCATION
|
|
+ meta = &staticMetaObject;
|
|
+ QCOMPARE(builder.addRelatedMetaObject(&staticMetaObjectGlobal), 0);
|
|
+ QCOMPARE(builder.addRelatedMetaObject(&staticMetaObjectLocal), 1);
|
|
+#else
|
|
+ QCOMPARE(builder.addRelatedMetaObject(&QObject::staticMetaObject), 0);
|
|
+ QCOMPARE(builder.addRelatedMetaObject(&staticMetaObject), 1);
|
|
+#endif
|
|
+ QVERIFY(builder.relatedMetaObject(0) == &QObject::staticMetaObject);
|
|
+ QVERIFY(builder.relatedMetaObject(1) == &staticMetaObject);
|
|
+ QCOMPARE(builder.relatedMetaObjectCount(), 2);
|
|
+
|
|
+ // Remove the first one and check again.
|
|
+ builder.removeRelatedMetaObject(0);
|
|
+ QVERIFY(builder.relatedMetaObject(0) == &staticMetaObject);
|
|
+ QCOMPARE(builder.relatedMetaObjectCount(), 1);
|
|
+
|
|
+ // Check that nothing else changed.
|
|
+ QVERIFY(checkForSideEffects(builder, QMetaObjectBuilder::RelatedMetaObjects));
|
|
+}
|
|
+
|
|
+static int smetacall(QMetaObject::Call, int, void **)
|
|
+{
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+void tst_QMetaObjectBuilder::staticMetacall()
|
|
+{
|
|
+ QMetaObjectBuilder builder;
|
|
+ QVERIFY(!builder.staticMetacallFunction());
|
|
+ builder.setStaticMetacallFunction(smetacall);
|
|
+ QVERIFY(builder.staticMetacallFunction() == smetacall);
|
|
+ QVERIFY(checkForSideEffects(builder, QMetaObjectBuilder::StaticMetacall));
|
|
+}
|
|
+
|
|
+// Copy the entire contents of a static QMetaObject and then check
|
|
+// that QMetaObjectBuilder will produce an exact copy as output.
|
|
+void tst_QMetaObjectBuilder::copyMetaObject()
|
|
+{
|
|
+ QMetaObjectBuilder builder(&QObject::staticMetaObject);
|
|
+ QMetaObject *meta = builder.toMetaObject();
|
|
+ QVERIFY(sameMetaObject(meta, &QObject::staticMetaObject));
|
|
+ qFree(meta);
|
|
+
|
|
+ QMetaObjectBuilder builder2(&staticMetaObject);
|
|
+ meta = builder2.toMetaObject();
|
|
+ QVERIFY(sameMetaObject(meta, &staticMetaObject));
|
|
+ qFree(meta);
|
|
+
|
|
+ QMetaObjectBuilder builder3(&SomethingOfEverything::staticMetaObject);
|
|
+ meta = builder3.toMetaObject();
|
|
+ QVERIFY(sameMetaObject(meta, &SomethingOfEverything::staticMetaObject));
|
|
+ qFree(meta);
|
|
+}
|
|
+
|
|
+// Serialize and deserialize a meta object and check that
|
|
+// it round-trips to the exact same value.
|
|
+void tst_QMetaObjectBuilder::serialize()
|
|
+{
|
|
+ // Full QMetaObjectBuilder
|
|
+ {
|
|
+ QMetaObjectBuilder builder(&SomethingOfEverything::staticMetaObject);
|
|
+ QMetaObject *meta = builder.toMetaObject();
|
|
+
|
|
+ QByteArray data;
|
|
+ QDataStream stream(&data, QIODevice::WriteOnly | QIODevice::Append);
|
|
+ builder.serialize(stream);
|
|
+
|
|
+ QMetaObjectBuilder builder2;
|
|
+ QDataStream stream2(data);
|
|
+ QMap<QByteArray, const QMetaObject *> references;
|
|
+ references.insert(QByteArray("QLocale"), &QLocale::staticMetaObject);
|
|
+ builder2.deserialize(stream2, references);
|
|
+#ifdef Q_NO_DATA_RELOCATION
|
|
+ //the related meta objects will be function pointers
|
|
+ //which you have to add to the builder manually.
|
|
+ builder2.addRelatedMetaObject(QLocale::getStaticMetaObject);
|
|
+#endif
|
|
+ builder2.setStaticMetacallFunction(builder.staticMetacallFunction());
|
|
+ QMetaObject *meta2 = builder2.toMetaObject();
|
|
+
|
|
+ QVERIFY(sameMetaObject(meta, meta2));
|
|
+ qFree(meta);
|
|
+ qFree(meta2);
|
|
+ }
|
|
+
|
|
+ // Partial QMetaObjectBuilder
|
|
+ {
|
|
+ QMetaObjectBuilder builder;
|
|
+ builder.setClassName("Test");
|
|
+ builder.addProperty("foo", "int");
|
|
+
|
|
+ QByteArray data;
|
|
+ QDataStream stream(&data, QIODevice::WriteOnly | QIODevice::Append);
|
|
+ builder.serialize(stream);
|
|
+
|
|
+ QMetaObjectBuilder builder2;
|
|
+ QDataStream stream2(data);
|
|
+ builder2.deserialize(stream2, QMap<QByteArray, const QMetaObject *>());
|
|
+
|
|
+ QCOMPARE(builder.superClass(), builder2.superClass());
|
|
+ QCOMPARE(builder.className(), builder2.className());
|
|
+ QCOMPARE(builder.propertyCount(), builder2.propertyCount());
|
|
+ QCOMPARE(builder.property(0).name(), builder2.property(0).name());
|
|
+ QCOMPARE(builder.property(0).type(), builder2.property(0).type());
|
|
+ }
|
|
+}
|
|
+
|
|
+// Check that removing a method updates notify signals appropriately
|
|
+void tst_QMetaObjectBuilder::removeNotifySignal()
|
|
+{
|
|
+ QMetaObjectBuilder builder;
|
|
+
|
|
+ QMetaMethodBuilder method1 = builder.addSignal("foo(const QString&, int)");
|
|
+ QMetaMethodBuilder method2 = builder.addSignal("bar(QString)");
|
|
+
|
|
+ // Setup property
|
|
+ QMetaPropertyBuilder prop = builder.addProperty("prop", "const QString &");
|
|
+ prop.setNotifySignal(method2);
|
|
+ QVERIFY(prop.hasNotifySignal());
|
|
+ QCOMPARE(prop.notifySignal().index(), 1);
|
|
+
|
|
+ // Remove non-notify signal
|
|
+ builder.removeMethod(0);
|
|
+ QVERIFY(prop.hasNotifySignal());
|
|
+ QCOMPARE(prop.notifySignal().index(), 0);
|
|
+
|
|
+ // Remove notify signal
|
|
+ builder.removeMethod(0);
|
|
+ QVERIFY(!prop.hasNotifySignal());
|
|
+}
|
|
+
|
|
+// Check that the only changes to a "builder" relative to the default
|
|
+// state is specified by "members".
|
|
+bool tst_QMetaObjectBuilder::checkForSideEffects
|
|
+ (const QMetaObjectBuilder& builder,
|
|
+ QMetaObjectBuilder::AddMembers members)
|
|
+{
|
|
+ if ((members & QMetaObjectBuilder::ClassName) == 0) {
|
|
+ if (!builder.className().isEmpty())
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ if ((members & QMetaObjectBuilder::SuperClass) == 0) {
|
|
+ if (builder.superClass() != &QObject::staticMetaObject)
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ if ((members & QMetaObjectBuilder::Methods) == 0) {
|
|
+ if (builder.methodCount() != 0)
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ if ((members & QMetaObjectBuilder::Constructors) == 0) {
|
|
+ if (builder.constructorCount() != 0)
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ if ((members & QMetaObjectBuilder::Properties) == 0) {
|
|
+ if (builder.propertyCount() != 0)
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ if ((members & QMetaObjectBuilder::Enumerators) == 0) {
|
|
+ if (builder.enumeratorCount() != 0)
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ if ((members & QMetaObjectBuilder::ClassInfos) == 0) {
|
|
+ if (builder.classInfoCount() != 0)
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ if ((members & QMetaObjectBuilder::RelatedMetaObjects) == 0) {
|
|
+ if (builder.relatedMetaObjectCount() != 0)
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ if ((members & QMetaObjectBuilder::StaticMetacall) == 0) {
|
|
+ if (builder.staticMetacallFunction() != 0)
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ return true;
|
|
+}
|
|
+
|
|
+static bool sameMethod(const QMetaMethod& method1, const QMetaMethod& method2)
|
|
+{
|
|
+ if (QByteArray(method1.signature()) != QByteArray(method2.signature()))
|
|
+ return false;
|
|
+
|
|
+ if (QByteArray(method1.typeName()) != QByteArray(method2.typeName()))
|
|
+ return false;
|
|
+
|
|
+ if (method1.parameterNames() != method2.parameterNames())
|
|
+ return false;
|
|
+
|
|
+ if (QByteArray(method1.tag()) != QByteArray(method2.tag()))
|
|
+ return false;
|
|
+
|
|
+ if (method1.access() != method2.access())
|
|
+ return false;
|
|
+
|
|
+ if (method1.methodType() != method2.methodType())
|
|
+ return false;
|
|
+
|
|
+ if (method1.attributes() != method2.attributes())
|
|
+ return false;
|
|
+
|
|
+ return true;
|
|
+}
|
|
+
|
|
+static bool sameProperty(const QMetaProperty& prop1, const QMetaProperty& prop2)
|
|
+{
|
|
+ if (QByteArray(prop1.name()) != QByteArray(prop2.name()))
|
|
+ return false;
|
|
+
|
|
+ if (QByteArray(prop1.typeName()) != QByteArray(prop2.typeName()))
|
|
+ return false;
|
|
+
|
|
+ if (prop1.isReadable() != prop2.isReadable() ||
|
|
+ prop1.isWritable() != prop2.isWritable() ||
|
|
+ prop1.isResettable() != prop2.isResettable() ||
|
|
+ prop1.isDesignable() != prop2.isDesignable() ||
|
|
+ prop1.isScriptable() != prop2.isScriptable() ||
|
|
+ prop1.isStored() != prop2.isStored() ||
|
|
+ prop1.isEditable() != prop2.isEditable() ||
|
|
+ prop1.isUser() != prop2.isUser() ||
|
|
+ prop1.isFlagType() != prop2.isFlagType() ||
|
|
+ prop1.isEnumType() != prop2.isEnumType() ||
|
|
+ prop1.hasNotifySignal() != prop2.hasNotifySignal() ||
|
|
+ prop1.hasStdCppSet() != prop2.hasStdCppSet())
|
|
+ return false;
|
|
+
|
|
+ if (prop1.hasNotifySignal()) {
|
|
+ if (prop1.notifySignalIndex() != prop2.notifySignalIndex())
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ return true;
|
|
+}
|
|
+
|
|
+static bool sameEnumerator(const QMetaEnum& enum1, const QMetaEnum& enum2)
|
|
+{
|
|
+ if (QByteArray(enum1.name()) != QByteArray(enum2.name()))
|
|
+ return false;
|
|
+
|
|
+ if (enum1.isFlag() != enum2.isFlag())
|
|
+ return false;
|
|
+
|
|
+ if (enum1.keyCount() != enum2.keyCount())
|
|
+ return false;
|
|
+
|
|
+ for (int index = 0; index < enum1.keyCount(); ++index) {
|
|
+ if (QByteArray(enum1.key(index)) != QByteArray(enum2.key(index)))
|
|
+ return false;
|
|
+ if (enum1.value(index) != enum2.value(index))
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ if (QByteArray(enum1.scope()) != QByteArray(enum2.scope()))
|
|
+ return false;
|
|
+
|
|
+ return true;
|
|
+}
|
|
+
|
|
+// Determine if two meta objects are identical.
|
|
+bool tst_QMetaObjectBuilder::sameMetaObject
|
|
+ (const QMetaObject *meta1, const QMetaObject *meta2)
|
|
+{
|
|
+ int index;
|
|
+
|
|
+ if (strcmp(meta1->className(), meta2->className()) != 0)
|
|
+ return false;
|
|
+
|
|
+ if (meta1->superClass() != meta2->superClass())
|
|
+ return false;
|
|
+
|
|
+ if (meta1->constructorCount() != meta2->constructorCount() ||
|
|
+ meta1->methodCount() != meta2->methodCount() ||
|
|
+ meta1->enumeratorCount() != meta2->enumeratorCount() ||
|
|
+ meta1->propertyCount() != meta2->propertyCount() ||
|
|
+ meta1->classInfoCount() != meta2->classInfoCount())
|
|
+ return false;
|
|
+
|
|
+ for (index = 0; index < meta1->constructorCount(); ++index) {
|
|
+ if (!sameMethod(meta1->constructor(index), meta2->constructor(index)))
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ for (index = 0; index < meta1->methodCount(); ++index) {
|
|
+ if (!sameMethod(meta1->method(index), meta2->method(index)))
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ for (index = 0; index < meta1->propertyCount(); ++index) {
|
|
+ if (!sameProperty(meta1->property(index), meta2->property(index)))
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ for (index = 0; index < meta1->enumeratorCount(); ++index) {
|
|
+ if (!sameEnumerator(meta1->enumerator(index), meta2->enumerator(index)))
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ for (index = 0; index < meta1->classInfoCount(); ++index) {
|
|
+ if (QByteArray(meta1->classInfo(index).name()) !=
|
|
+ QByteArray(meta2->classInfo(index).name()))
|
|
+ return false;
|
|
+ if (QByteArray(meta1->classInfo(index).value()) !=
|
|
+ QByteArray(meta2->classInfo(index).value()))
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ const QMetaObject **objects1 = 0;
|
|
+ const QMetaObject **objects2 = 0;
|
|
+ if (meta1->d.data[0] == meta2->d.data[0] && meta1->d.data[0] >= 2) {
|
|
+ QMetaObjectExtraData *extra1 = (QMetaObjectExtraData *)(meta1->d.extradata);
|
|
+ QMetaObjectExtraData *extra2 = (QMetaObjectExtraData *)(meta2->d.extradata);
|
|
+ if (extra1 && !extra2)
|
|
+ return false;
|
|
+ if (extra2 && !extra1)
|
|
+ return false;
|
|
+ if (extra1 && extra2) {
|
|
+ if (extra1->static_metacall != extra2->static_metacall)
|
|
+ return false;
|
|
+ //objects1 = extra1->objects;
|
|
+ //objects2 = extra1->objects;
|
|
+ }
|
|
+ } else if (meta1->d.data[0] == meta2->d.data[0] && meta1->d.data[0] == 1) {
|
|
+ objects1 = (const QMetaObject **)(meta1->d.extradata);
|
|
+ objects2 = (const QMetaObject **)(meta2->d.extradata);
|
|
+ }
|
|
+ if (objects1 && !objects2)
|
|
+ return false;
|
|
+ if (objects2 && !objects1)
|
|
+ return false;
|
|
+ if (objects1 && objects2) {
|
|
+ while (*objects1 != 0 && *objects2 != 0) {
|
|
+ if (*objects1 != *objects2)
|
|
+ return false;
|
|
+ ++objects1;
|
|
+ ++objects2;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return true;
|
|
+}
|
|
+
|
|
+QTEST_MAIN(tst_QMetaObjectBuilder)
|
|
+
|
|
+#include "tst_qmetaobjectbuilder_47.moc"
|