summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOlivier Goffart <ogoffart@trolltech.com>2010-03-02 10:03:12 (GMT)
committerOlivier Goffart <ogoffart@trolltech.com>2010-03-02 13:22:45 (GMT)
commit03daf059647c0a0222e8774b0a083f58c8e64934 (patch)
tree62f7bda5a497c508d98598a4ae4ef8d2fd0157c9
parenta140e37fab6a1d028fd1b751a98774dacb4f1a89 (diff)
downloadQt-03daf059647c0a0222e8774b0a083f58c8e64934.zip
Qt-03daf059647c0a0222e8774b0a083f58c8e64934.tar.gz
Qt-03daf059647c0a0222e8774b0a083f58c8e64934.tar.bz2
QMetaType: Now we can register typedefs.
Task-number: QTBUG-6833 Task-number: QTBUG-937 Reviewed-by: Brad Reviewed-by: Kent Hansen
-rw-r--r--doc/src/snippets/code/src_corelib_kernel_qmetatype.cpp5
-rw-r--r--src/corelib/kernel/qmetatype.cpp60
-rw-r--r--src/corelib/kernel/qmetatype.h37
-rw-r--r--tests/auto/qmetaobject/tst_qmetaobject.cpp20
-rw-r--r--tests/auto/qmetatype/tst_qmetatype.cpp14
-rw-r--r--tests/auto/qobject/tst_qobject.cpp16
6 files changed, 146 insertions, 6 deletions
diff --git a/doc/src/snippets/code/src_corelib_kernel_qmetatype.cpp b/doc/src/snippets/code/src_corelib_kernel_qmetatype.cpp
index bff72a0..19e37ba 100644
--- a/doc/src/snippets/code/src_corelib_kernel_qmetatype.cpp
+++ b/doc/src/snippets/code/src_corelib_kernel_qmetatype.cpp
@@ -108,3 +108,8 @@ int id = qRegisterMetaType<MyStruct>();
int id = qMetaTypeId<QString>(); // id is now QMetaType::QString
id = qMetaTypeId<MyStruct>(); // compile error if MyStruct not declared
//! [8]
+
+//! [9]
+typedef QString CustomString;
+qRegisterMetaType<CustomString>("CustomString");
+//! [9]
diff --git a/src/corelib/kernel/qmetatype.cpp b/src/corelib/kernel/qmetatype.cpp
index 779b69b..be506b4 100644
--- a/src/corelib/kernel/qmetatype.cpp
+++ b/src/corelib/kernel/qmetatype.cpp
@@ -352,6 +352,7 @@ public:
QMetaType::SaveOperator saveOp;
QMetaType::LoadOperator loadOp;
#endif
+ int alias;
};
Q_DECLARE_TYPEINFO(QCustomTypeInfo, Q_MOVABLE_TYPE);
@@ -436,8 +437,11 @@ static int qMetaTypeCustomType_unlocked(const char *typeName, int length)
return 0;
for (int v = 0; v < ct->count(); ++v) {
- if ((length == ct->at(v).typeName.size())
- && !strcmp(typeName, ct->at(v).typeName.constData())) {
+ const QCustomTypeInfo &customInfo = ct->at(v);
+ if ((length == customInfo.typeName.size())
+ && !strcmp(typeName, customInfo.typeName.constData())) {
+ if (customInfo.alias >= 0)
+ return customInfo.alias;
return v + QMetaType::User;
}
}
@@ -475,6 +479,7 @@ int QMetaType::registerType(const char *typeName, Destructor destructor,
inf.typeName = normalizedTypeName;
inf.constr = constructor;
inf.destr = destructor;
+ inf.alias = -1;
idx = ct->size() + User;
ct->append(inf);
}
@@ -482,6 +487,51 @@ int QMetaType::registerType(const char *typeName, Destructor destructor,
return idx;
}
+/*! \internal
+ \since 4.7
+
+ Registers a user type for marshalling, as an alias of another type (typedef)
+*/
+int QMetaType::registerTypedef(const char* typeName, int aliasId)
+{
+ QVector<QCustomTypeInfo> *ct = customTypes();
+ if (!ct || !typeName)
+ return -1;
+
+#ifdef QT_NO_QOBJECT
+ NS(QByteArray) normalizedTypeName = typeName;
+#else
+ NS(QByteArray) normalizedTypeName = QMetaObject::normalizedType(typeName);
+#endif
+
+ int idx = qMetaTypeStaticType(normalizedTypeName.constData(),
+ normalizedTypeName.size());
+
+ if (idx) {
+ Q_ASSERT(idx == aliasId);
+ return idx;
+ }
+
+ QWriteLocker locker(customTypesLock());
+ idx = qMetaTypeCustomType_unlocked(normalizedTypeName.constData(),
+ normalizedTypeName.size());
+
+ if (idx) {
+ Q_ASSERT(idx == aliasId);
+ return idx;
+ }
+
+ if (!idx) {
+ QCustomTypeInfo inf;
+ inf.typeName = normalizedTypeName;
+ inf.alias = aliasId;
+ inf.constr = 0;
+ inf.destr = 0;
+ ct->append(inf);
+ }
+ return aliasId;
+}
+
/*!
\since 4.4
@@ -507,6 +557,7 @@ void QMetaType::unregisterType(const char *typeName)
inf.typeName.clear();
inf.constr = 0;
inf.destr = 0;
+ inf.alias = -1;
}
}
}
@@ -1349,6 +1400,11 @@ void QMetaType::destroy(int type, void *data)
\snippet doc/src/snippets/code/src_corelib_kernel_qmetatype.cpp 4
+ This function is usefull to register typedefs so they can be used
+ by QMetaProperty, or in QueuedConnections
+
+ \snippet doc/src/snippets/code/src_corelib_kernel_qmetatype.cpp 9
+
\sa qRegisterMetaTypeStreamOperators(), QMetaType::isRegistered(),
Q_DECLARE_METATYPE()
*/
diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h
index 33126e8..2ed4a1f 100644
--- a/src/corelib/kernel/qmetatype.h
+++ b/src/corelib/kernel/qmetatype.h
@@ -113,6 +113,7 @@ public:
#endif
static int registerType(const char *typeName, Destructor destructor,
Constructor constructor);
+ static int registerTypedef(const char *typeName, int aliasId);
static int type(const char *typeName);
static const char *typeName(int type);
static bool isRegistered(int type);
@@ -154,13 +155,31 @@ void qMetaTypeLoadHelper(QDataStream &stream, T *t)
}
#endif // QT_NO_DATASTREAM
+template <typename T> struct QMetaTypeId2;
+
+namespace QtPrivate {
+ template <typename T, bool Defined = QMetaTypeId2<T>::Defined>
+ struct QMetaTypeIdHelper {
+ static inline int qt_metatype_id()
+ { return QMetaTypeId2<T>::qt_metatype_id(); }
+ };
+ template <typename T> struct QMetaTypeIdHelper<T, false> {
+ static inline int qt_metatype_id()
+ { return -1; }
+ };
+}
+
template <typename T>
int qRegisterMetaType(const char *typeName
#ifndef qdoc
- , T * /* dummy */ = 0
+ , typename QMetaTypeId2<T>::CustomType * dummy = 0
#endif
)
{
+ const int typedefOf = dummy ? -1 : QtPrivate::QMetaTypeIdHelper<T>::qt_metatype_id();
+ if (typedefOf != -1)
+ return QMetaType::registerTypedef(typeName, typedefOf);
+
typedef void*(*ConstructPtr)(const T*);
ConstructPtr cptr = qMetaTypeConstructHelper<T>;
typedef void(*DeletePtr)(T*);
@@ -170,6 +189,17 @@ int qRegisterMetaType(const char *typeName
reinterpret_cast<QMetaType::Constructor>(cptr));
}
+template <typename T>
+int qRegisterMetaType(const char *typeName
+#ifndef qdoc
+ , typename QMetaTypeId2<T>::BuiltinType * /* dummy */ = 0
+#endif
+)
+{
+ return QMetaType::registerTypedef(typeName, QMetaTypeId2<T>::MetaType);
+}
+
+
#ifndef QT_NO_DATASTREAM
template <typename T>
void qRegisterMetaTypeStreamOperators(const char *typeName
@@ -198,6 +228,7 @@ struct QMetaTypeId
template <typename T>
struct QMetaTypeId2
{
+ typedef T CustomType;
enum { Defined = QMetaTypeId<T>::Defined };
static inline int qt_metatype_id() { return QMetaTypeId<T>::qt_metatype_id(); }
};
@@ -254,7 +285,8 @@ inline int qRegisterMetaTypeStreamOperators()
{ \
static QBasicAtomicInt metatype_id = Q_BASIC_ATOMIC_INITIALIZER(0); \
if (!metatype_id) \
- metatype_id = qRegisterMetaType< TYPE >(#TYPE); \
+ metatype_id = qRegisterMetaType< TYPE >(#TYPE, \
+ reinterpret_cast< TYPE *>(quintptr(-1))); \
return metatype_id; \
} \
}; \
@@ -264,6 +296,7 @@ inline int qRegisterMetaTypeStreamOperators()
QT_BEGIN_NAMESPACE \
template<> struct QMetaTypeId2<TYPE> \
{ \
+ typedef TYPE BuiltinType; \
enum { Defined = 1, MetaType = QMetaType::NAME }; \
static inline int qt_metatype_id() { return QMetaType::NAME; } \
}; \
diff --git a/tests/auto/qmetaobject/tst_qmetaobject.cpp b/tests/auto/qmetaobject/tst_qmetaobject.cpp
index bd54975..bb4a0d2 100644
--- a/tests/auto/qmetaobject/tst_qmetaobject.cpp
+++ b/tests/auto/qmetaobject/tst_qmetaobject.cpp
@@ -157,6 +157,7 @@ private slots:
void invokeQueuedMetaMember();
void invokeCustomTypes();
void invokeMetaConstructor();
+ void invokeTypedefTypes();
void qtMetaObjectInheritance();
void normalizedSignature_data();
void normalizedSignature();
@@ -598,6 +599,8 @@ struct MyType
int i1, i2, i3;
};
+typedef QString CustomString;
+
class QtTestCustomObject: public QObject
{
Q_OBJECT
@@ -607,6 +610,9 @@ public:
public slots:
void sl1(MyType myType);
+signals:
+ void sig_custom(const CustomString &string);
+
public:
int sum;
};
@@ -664,6 +670,20 @@ void tst_QMetaObject::invokeMetaConstructor()
}
}
+void tst_QMetaObject::invokeTypedefTypes()
+{
+ qRegisterMetaType<CustomString>("CustomString");
+ QtTestCustomObject obj;
+ QSignalSpy spy(&obj, SIGNAL(sig_custom(CustomString)));
+
+ QCOMPARE(spy.count(), 0);
+ CustomString arg("hello");
+ QVERIFY(QMetaObject::invokeMethod(&obj, "sig_custom", Q_ARG(CustomString, arg)));
+ QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.at(0).count(), 1);
+ QCOMPARE(spy.at(0).at(0), QVariant(arg));
+}
+
void tst_QMetaObject::normalizedSignature_data()
{
QTest::addColumn<QString>("signature");
diff --git a/tests/auto/qmetatype/tst_qmetatype.cpp b/tests/auto/qmetatype/tst_qmetatype.cpp
index 943b05b..f4e122f 100644
--- a/tests/auto/qmetatype/tst_qmetatype.cpp
+++ b/tests/auto/qmetatype/tst_qmetatype.cpp
@@ -241,6 +241,9 @@ void tst_QMetaType::construct()
QMetaType::destroy(QMetaType::QSize, size);
}
+typedef QString CustomString;
+Q_DECLARE_METATYPE(CustomString) //this line is useless
+
void tst_QMetaType::typedefs()
{
QCOMPARE(QMetaType::type("long long"), int(QMetaType::LongLong));
@@ -256,6 +259,13 @@ void tst_QMetaType::typedefs()
// make sure the qreal typeId is the type id of the type it's defined to
QCOMPARE(QMetaType::type("qreal"), ::qMetaTypeId<qreal>());
+
+ qRegisterMetaType<CustomString>("CustomString");
+ QCOMPARE(QMetaType::type("CustomString"), ::qMetaTypeId<CustomString>());
+
+ typedef Whity<double> WhityDouble;
+ qRegisterMetaType<WhityDouble>("WhityDouble");
+ QCOMPARE(QMetaType::type("WhityDouble"), ::qMetaTypeId<WhityDouble>());
}
class IsRegisteredDummyType { };
@@ -286,9 +296,9 @@ void tst_QMetaType::isRegistered()
QCOMPARE(QMetaType::isRegistered(typeId), registered);
}
-class RegUnreg
+class RegUnreg
{
-public:
+public:
RegUnreg() {};
RegUnreg(const RegUnreg &) {};
~RegUnreg() {};
diff --git a/tests/auto/qobject/tst_qobject.cpp b/tests/auto/qobject/tst_qobject.cpp
index 3896d70..c8f846e 100644
--- a/tests/auto/qobject/tst_qobject.cpp
+++ b/tests/auto/qobject/tst_qobject.cpp
@@ -1112,6 +1112,8 @@ void tst_QObject::streamCustomTypes()
QCOMPARE(instanceCount, 0);
}
+typedef QString CustomString;
+
class PropertyObject : public QObject
{
Q_OBJECT
@@ -1125,6 +1127,7 @@ class PropertyObject : public QObject
Q_PROPERTY(CustomType* custom READ custom WRITE setCustom)
Q_PROPERTY(float myFloat READ myFloat WRITE setMyFloat)
Q_PROPERTY(qreal myQReal READ myQReal WRITE setMyQReal)
+ Q_PROPERTY(CustomString customString READ customString WRITE setCustomString )
public:
enum Alpha {
@@ -1163,6 +1166,9 @@ public:
void setMyQReal(qreal value) { m_qreal = value; }
qreal myQReal() const { return m_qreal; }
+ CustomString customString() const { return m_customString; }
+ void setCustomString(const QString &string) { m_customString = string; }
+
private:
Alpha m_alpha;
Priority m_priority;
@@ -1172,6 +1178,7 @@ private:
CustomType *m_custom;
float m_float;
qreal m_qreal;
+ CustomString m_customString;
};
Q_DECLARE_METATYPE(PropertyObject::Priority)
@@ -1626,6 +1633,15 @@ void tst_QObject::property()
QCOMPARE(qVariantValue<PropertyObject::Priority>(object.property("priority")), PropertyObject::Low);
object.setProperty("priority", var);
QCOMPARE(qVariantValue<PropertyObject::Priority>(object.property("priority")), PropertyObject::High);
+
+ qRegisterMetaType<CustomString>("CustomString");
+ QVERIFY(mo->indexOfProperty("customString") != -1);
+ QCOMPARE(object.property("customString").toString(), QString());
+ object.setCustomString("String1");
+ QCOMPARE(object.property("customString"), QVariant("String1"));
+ QVERIFY(object.setProperty("customString", "String2"));
+ QCOMPARE(object.property("customString"), QVariant("String2"));
+ QVERIFY(!object.setProperty("customString", QVariant()));
}
void tst_QObject::metamethod()