aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/webchannel/qmetaobjectpublisher.cpp34
-rw-r--r--tests/auto/webchannel/tst_webchannel.cpp43
-rw-r--r--tests/auto/webchannel/tst_webchannel.h14
3 files changed, 91 insertions, 0 deletions
diff --git a/src/webchannel/qmetaobjectpublisher.cpp b/src/webchannel/qmetaobjectpublisher.cpp
index 9e08453..6ea3480 100644
--- a/src/webchannel/qmetaobjectpublisher.cpp
+++ b/src/webchannel/qmetaobjectpublisher.cpp
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2016 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Milian Wolff <milian.wolff@kdab.com>
+** Copyright (C) 2019 Menlo Systems GmbH, author Arno Rehn <a.rehn@menlosystems.com>
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtWebChannel module of the Qt Toolkit.
@@ -56,6 +57,32 @@ QT_BEGIN_NAMESPACE
namespace {
+// FIXME: QFlags don't have the QMetaType::IsEnumeration flag set, although they have a QMetaEnum entry in the QMetaObject.
+// They only way to detect registered QFlags types is to find the named entry in the QMetaObject's enumerator list.
+// Ideally, this would be fixed in QMetaType.
+bool isQFlagsType(uint id)
+{
+ QMetaType type(id);
+
+ // Short-circuit to avoid more expensive operations
+ QMetaType::TypeFlags flags = type.flags();
+ if (flags.testFlag(QMetaType::PointerToQObject) || flags.testFlag(QMetaType::IsEnumeration)
+ || flags.testFlag(QMetaType::SharedPointerToQObject) || flags.testFlag(QMetaType::WeakPointerToQObject)
+ || flags.testFlag(QMetaType::TrackingPointerToQObject) || flags.testFlag(QMetaType::IsGadget))
+ {
+ return false;
+ }
+
+ const QMetaObject *mo = type.metaObject();
+ if (!mo) {
+ return false;
+ }
+
+ QByteArray name = QMetaType::typeName(id);
+ name = name.mid(name.lastIndexOf(":") + 1);
+ return mo->indexOfEnumerator(name.constData()) > -1;
+}
+
MessageType toType(const QJsonValue &value)
{
int i = value.toInt(-1);
@@ -487,6 +514,9 @@ QVariant QMetaObjectPublisher::toVariant(const QJsonValue &value, int targetType
if (unwrappedObject == Q_NULLPTR)
qWarning() << "Cannot not convert non-object argument" << value << "to QObject*.";
return QVariant::fromValue(unwrappedObject);
+ } else if (isQFlagsType(targetType)) {
+ int flagsValue = value.toInt();
+ return QVariant(targetType, reinterpret_cast<const void*>(&flagsValue));
}
// this converts QJsonObjects to QVariantMaps, which is not desired when
@@ -570,6 +600,10 @@ QJsonValue QMetaObjectPublisher::wrapResult(const QVariant &result, QWebChannelA
objectInfo[KEY_DATA] = classInfo;
return objectInfo;
+ } else if (QMetaType::typeFlags(result.userType()).testFlag(QMetaType::IsEnumeration)) {
+ return result.toInt();
+ } else if (isQFlagsType(result.userType())) {
+ return *reinterpret_cast<const int*>(result.constData());
#ifndef QT_NO_JSVALUE
} else if (result.canConvert<QJSValue>()) {
// Workaround for keeping QJSValues from QVariant.
diff --git a/tests/auto/webchannel/tst_webchannel.cpp b/tests/auto/webchannel/tst_webchannel.cpp
index b62a596..6764204 100644
--- a/tests/auto/webchannel/tst_webchannel.cpp
+++ b/tests/auto/webchannel/tst_webchannel.cpp
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2016 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Milian Wolff <milian.wolff@kdab.com>
+** Copyright (C) 2019 Menlo Systems GmbH, author Arno Rehn <a.rehn@menlosystems.com>
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtWebChannel module of the Qt Toolkit.
@@ -341,8 +342,12 @@ void TestWebChannel::testInfoForObject()
QJsonObject fooEnum;
fooEnum["Asdf"] = TestObject::Asdf;
fooEnum["Bar"] = TestObject::Bar;
+ QJsonObject testFlags;
+ testFlags["FirstFlag"] = static_cast<int>(TestObject::FirstFlag);
+ testFlags["SecondFlag"] = static_cast<int>(TestObject::SecondFlag);
QJsonObject expected;
expected["Foo"] = fooEnum;
+ expected["TestFlags"] = testFlags;
QCOMPARE(info["enums"].toObject(), expected);
}
@@ -755,6 +760,44 @@ void TestWebChannel::testPassWrappedObjectBack()
QCOMPARE(registeredObj.mReturnedObject, &returnedObjProperty);
}
+void TestWebChannel::testWrapValues()
+{
+ QWebChannel channel;
+ channel.connectTo(m_dummyTransport);
+
+ {
+ QVariant variant = QVariant::fromValue(TestObject::Asdf);
+ QJsonValue value = channel.d_func()->publisher->wrapResult(variant, m_dummyTransport);
+ QVERIFY(value.isDouble());
+ QCOMPARE(value.toInt(), (int) TestObject::Asdf);
+ }
+ {
+ TestObject::TestFlags flags = TestObject::FirstFlag | TestObject::SecondFlag;
+ QVariant variant = QVariant::fromValue(flags);
+ QJsonValue value = channel.d_func()->publisher->wrapResult(variant, m_dummyTransport);
+ QVERIFY(value.isDouble());
+ QCOMPARE(value.toInt(), (int) flags);
+ }
+}
+
+void TestWebChannel::testJsonToVariant()
+{
+ QWebChannel channel;
+ channel.connectTo(m_dummyTransport);
+
+ {
+ QVariant variant = QVariant::fromValue(TestObject::Asdf);
+ QVariant convertedValue = channel.d_func()->publisher->toVariant(static_cast<int>(TestObject::Asdf), variant.userType());
+ QCOMPARE(convertedValue, variant);
+ }
+ {
+ TestObject::TestFlags flags = TestObject::FirstFlag | TestObject::SecondFlag;
+ QVariant variant = QVariant::fromValue(flags);
+ QVariant convertedValue = channel.d_func()->publisher->toVariant(static_cast<int>(flags), variant.userType());
+ QCOMPARE(convertedValue, variant);
+ }
+}
+
void TestWebChannel::testInfiniteRecursion()
{
QWebChannel channel;
diff --git a/tests/auto/webchannel/tst_webchannel.h b/tests/auto/webchannel/tst_webchannel.h
index 85846e7..386f314 100644
--- a/tests/auto/webchannel/tst_webchannel.h
+++ b/tests/auto/webchannel/tst_webchannel.h
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2016 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Milian Wolff <milian.wolff@kdab.com>
+** Copyright (C) 2019 Menlo Systems GmbH, author Arno Rehn <a.rehn@menlosystems.com>
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtWebChannel module of the Qt Toolkit.
@@ -92,6 +93,13 @@ public:
Asdf
};
+ enum TestFlag : quint16 {
+ FirstFlag = 0x1,
+ SecondFlag = 0x2
+ };
+ Q_DECLARE_FLAGS(TestFlags, TestFlag)
+ Q_FLAG(TestFlags)
+
Foo foo() const {return Bar;}
int asdf() const {return 42;}
QString bar() const {return QString();}
@@ -160,6 +168,8 @@ public:
QString mProp;
};
+Q_DECLARE_OPERATORS_FOR_FLAGS(TestObject::TestFlags)
+
class BenchObject : public QObject
{
Q_OBJECT
@@ -303,6 +313,8 @@ private slots:
void testWrapRegisteredObject();
void testRemoveUnusedTransports();
void testPassWrappedObjectBack();
+ void testWrapValues();
+ void testJsonToVariant();
void testInfiniteRecursion();
void testAsyncObject();
void testDeletionDuringMethodInvocation_data();
@@ -330,4 +342,6 @@ private:
QT_END_NAMESPACE
+Q_DECLARE_METATYPE(TestObject::Foo)
+
#endif // TST_WEBCHANNEL_H