summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMilian Wolff <milian.wolff@kdab.com>2016-05-25 16:42:01 +0200
committerMilian Wolff <milian.wolff@kdab.com>2016-05-25 17:06:15 +0000
commit97c876a1353f29ed0129360f013f2529bed69d98 (patch)
treeaf2671db0f408bc88a4fe950a5bbfdcf8a6e3811
parentcc0ed84fa6eac8119313543d2dc33658a78e50c7 (diff)
downloadqtwebchannel-97c876a1353f29ed0129360f013f2529bed69d98.tar.gz
Enable calling C++ functions taking QJson arguments via webchannel.
We used to convert the QJsonValue arguments to QVariants, which then failed to call a C++ function which expected on of the three QJson data types, i.e. QJsonValue, QJsonObject or QJsonArray. Instead, we now detect these three cases and manually convert the QJsonValue as needed. [ChangeLog] C++ functions taking arguments of type QJsonValue, QJsonArray or QJsonObject can now be called via the Qt WebChannel. Change-Id: I94e0c8937ca35e2ecd3554f7ddf2d4e5a3328570 Task-number: QTBUG-48198 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
-rw-r--r--src/webchannel/qmetaobjectpublisher.cpp29
-rw-r--r--tests/auto/webchannel/tst_webchannel.cpp41
-rw-r--r--tests/auto/webchannel/tst_webchannel.h5
3 files changed, 70 insertions, 5 deletions
diff --git a/src/webchannel/qmetaobjectpublisher.cpp b/src/webchannel/qmetaobjectpublisher.cpp
index 324191e..e85bc76 100644
--- a/src/webchannel/qmetaobjectpublisher.cpp
+++ b/src/webchannel/qmetaobjectpublisher.cpp
@@ -87,6 +87,29 @@ QJsonObject createResponse(const QJsonValue &id, const QJsonValue &data)
/// TODO: what is the proper value here?
const int PROPERTY_UPDATE_INTERVAL = 50;
+
+QVariant toVariant(const QJsonValue &value, int targetType)
+{
+ if (targetType == QMetaType::QJsonValue) {
+ return QVariant::fromValue(value);
+ } else if (targetType == QMetaType::QJsonArray) {
+ if (!value.isArray())
+ qWarning() << "Cannot not convert non-array argument" << value << "to QJsonArray.";
+ return QVariant::fromValue(value.toArray());
+ } else if (targetType == QMetaType::QJsonObject) {
+ if (!value.isObject())
+ qWarning() << "Cannot not convert non-object argument" << value << "to QJsonObject.";
+ return QVariant::fromValue(value.toObject());
+ }
+
+ // this converts QJsonObjects to QVariantMaps, which is not desired when
+ // we want to get a QJsonObject or QJsonValue (see above)
+ QVariant variant = value.toVariant();
+ if (targetType != QMetaType::QVariant && !variant.convert(targetType)) {
+ qWarning() << "Could not convert argument" << value << "to target type" << QVariant::typeToName(targetType) << '.';
+ }
+ return variant;
+}
}
QMetaObjectPublisher::QMetaObjectPublisher(QWebChannel *webChannel)
@@ -366,11 +389,7 @@ QVariant QMetaObjectPublisher::invokeMethod(QObject *const object, const int met
// construct converter objects of QVariant to QGenericArgument
VariantArgument arguments[10];
for (int i = 0; i < qMin(args.size(), method.parameterCount()); ++i) {
- QVariant arg = args.at(i).toVariant();
- if (method.parameterType(i) != QMetaType::QVariant && !arg.convert(method.parameterType(i))) {
- qWarning() << "Could not convert argument" << args.at(i) << "to target type" << method.parameterTypes().at(i) << '.';
- }
- arguments[i].value = arg;
+ arguments[i].value = toVariant(args.at(i), method.parameterType(i));
}
// construct QGenericReturnArgument
diff --git a/tests/auto/webchannel/tst_webchannel.cpp b/tests/auto/webchannel/tst_webchannel.cpp
index f1911e5..4db8bae 100644
--- a/tests/auto/webchannel/tst_webchannel.cpp
+++ b/tests/auto/webchannel/tst_webchannel.cpp
@@ -216,6 +216,21 @@ void TestWebChannel::setVariant(const QVariant &v)
m_lastVariant = v;
}
+void TestWebChannel::setJsonValue(const QJsonValue& v)
+{
+ m_lastJsonValue = v;
+}
+
+void TestWebChannel::setJsonObject(const QJsonObject& v)
+{
+ m_lastJsonValue = v;
+}
+
+void TestWebChannel::setJsonArray(const QJsonArray& v)
+{
+ m_lastJsonValue = v;
+}
+
void TestWebChannel::testRegisterObjects()
{
QWebChannel channel;
@@ -426,6 +441,32 @@ void TestWebChannel::testInvokeMethodConversion()
channel.d_func()->publisher->invokeMethod(this, method, args);
QCOMPARE(m_lastVariant, args.at(0).toVariant());
}
+ {
+ int method = metaObject()->indexOfMethod("setJsonValue(QJsonValue)");
+ QVERIFY(method != -1);
+ channel.d_func()->publisher->invokeMethod(this, method, args);
+ QCOMPARE(m_lastJsonValue, args.at(0));
+ }
+ {
+ int method = metaObject()->indexOfMethod("setJsonObject(QJsonObject)");
+ QVERIFY(method != -1);
+ QJsonObject object;
+ object["foo"] = QJsonValue(123);
+ object["bar"] = QJsonValue(4.2);
+ args[0] = object;
+ channel.d_func()->publisher->invokeMethod(this, method, args);
+ QCOMPARE(m_lastJsonValue.toObject(), object);
+ }
+ {
+ int method = metaObject()->indexOfMethod("setJsonArray(QJsonArray)");
+ QVERIFY(method != -1);
+ QJsonArray array;
+ array << QJsonValue(123);
+ array << QJsonValue(4.2);
+ args[0] = array;
+ channel.d_func()->publisher->invokeMethod(this, method, args);
+ QCOMPARE(m_lastJsonValue.toArray(), array);
+ }
}
void TestWebChannel::testDisconnect()
diff --git a/tests/auto/webchannel/tst_webchannel.h b/tests/auto/webchannel/tst_webchannel.h
index b2a1040..e551458 100644
--- a/tests/auto/webchannel/tst_webchannel.h
+++ b/tests/auto/webchannel/tst_webchannel.h
@@ -36,6 +36,7 @@
#include <QObject>
#include <QVariant>
+#include <QJsonValue>
#include <QtWebChannel/QWebChannelAbstractTransport>
@@ -229,6 +230,9 @@ public:
Q_INVOKABLE void setInt(int i);
Q_INVOKABLE void setDouble(double d);
Q_INVOKABLE void setVariant(const QVariant &v);
+ Q_INVOKABLE void setJsonValue(const QJsonValue &v);
+ Q_INVOKABLE void setJsonObject(const QJsonObject &v);
+ Q_INVOKABLE void setJsonArray(const QJsonArray &v);
private slots:
void testRegisterObjects();
@@ -252,6 +256,7 @@ private:
int m_lastInt;
double m_lastDouble;
QVariant m_lastVariant;
+ QJsonValue m_lastJsonValue;
};
QT_END_NAMESPACE