diff options
author | Liang Qi <liang.qi@theqtcompany.com> | 2015-04-21 15:31:45 +0200 |
---|---|---|
committer | Liang Qi <liang.qi@theqtcompany.com> | 2015-04-21 15:31:45 +0200 |
commit | 2ca0f0b505fa4cebf9aa99c8cf2eb84b0818ff97 (patch) | |
tree | f8af76aa0e3a3ea852bdf73a2afe959a0cb30883 | |
parent | 5e7cc82c42078d7e88b08eeb283a31d1089c3b49 (diff) | |
parent | 65019ea1e1af0acc45517ef74f58bbd0efbba36e (diff) |
Merge remote-tracking branch 'origin/5.5' into dev
Change-Id: I24d14e84caa2e47ea39d477b07f711f6ac3ba2de
-rw-r--r-- | examples/activeqt/comapp/comapp.pro | 2 | ||||
-rw-r--r-- | examples/activeqt/comapp/doc/src/comapp.qdoc | 2 | ||||
-rw-r--r-- | examples/activeqt/hierarchy/hierarchy.pro | 2 | ||||
-rw-r--r-- | examples/activeqt/menus/menus.pro | 2 | ||||
-rw-r--r-- | examples/activeqt/multiple/multiple.pro | 2 | ||||
-rw-r--r-- | examples/activeqt/shared.pri | 7 | ||||
-rw-r--r-- | examples/activeqt/simple/simple.pro | 2 | ||||
-rw-r--r-- | examples/activeqt/wrapper/wrapper.pro | 2 | ||||
-rw-r--r-- | qtactiveqt.pro | 3 | ||||
-rw-r--r-- | src/activeqt/axshared.prx | 2 | ||||
-rw-r--r-- | src/activeqt/container/qaxbase.cpp | 27 | ||||
-rw-r--r-- | src/activeqt/control/qaxfactory.cpp | 4 | ||||
-rw-r--r-- | src/activeqt/control/qaxserver.cpp | 7 | ||||
-rw-r--r-- | src/activeqt/control/qaxserverbase.cpp | 8 | ||||
-rw-r--r-- | src/activeqt/shared/qaxtypefunctions.h | 4 | ||||
-rw-r--r-- | src/activeqt/shared/qaxtypes.cpp | 157 | ||||
-rw-r--r-- | src/activeqt/shared/qaxtypes.h | 4 | ||||
-rw-r--r-- | src/activeqt/shared/qaxutils_p.h | 4 | ||||
-rw-r--r-- | src/tools/idc/main.cpp | 2 | ||||
-rw-r--r-- | tests/auto/auto.pro | 1 | ||||
-rw-r--r-- | tests/auto/conversion/conversion.pro | 3 | ||||
-rw-r--r-- | tests/auto/conversion/tst_conversion.cpp | 204 |
22 files changed, 327 insertions, 124 deletions
diff --git a/examples/activeqt/comapp/comapp.pro b/examples/activeqt/comapp/comapp.pro index 271241b..c706759 100644 --- a/examples/activeqt/comapp/comapp.pro +++ b/examples/activeqt/comapp/comapp.pro @@ -1,3 +1,5 @@ +include(../shared.pri) + TEMPLATE = app QT += axserver diff --git a/examples/activeqt/comapp/doc/src/comapp.qdoc b/examples/activeqt/comapp/doc/src/comapp.qdoc index 59cd471..7e89731 100644 --- a/examples/activeqt/comapp/doc/src/comapp.qdoc +++ b/examples/activeqt/comapp/doc/src/comapp.qdoc @@ -73,7 +73,7 @@ name (accessible through the \c id property) is set to \c "From QAxFactory" to indicate that this COM object has been created by COM. Note that there is no destructor that would delete the QTabWidget - this is instead done in the - \c quit() slot, before calling \l {QApplication::}{quit()} through a single-shot-timer, + \c quit() slot, before calling \l {QCoreApplication::}{quit()} through a single-shot-timer, which is necessary to ensure that the COM call to the slot is complete. \snippet activeqt/comapp/main.cpp 6 diff --git a/examples/activeqt/hierarchy/hierarchy.pro b/examples/activeqt/hierarchy/hierarchy.pro index c0d534f..acc108a 100644 --- a/examples/activeqt/hierarchy/hierarchy.pro +++ b/examples/activeqt/hierarchy/hierarchy.pro @@ -1,3 +1,5 @@ +include(../shared.pri) + TEMPLATE = lib TARGET = hierarchyax diff --git a/examples/activeqt/menus/menus.pro b/examples/activeqt/menus/menus.pro index be5d75d..0aa677e 100644 --- a/examples/activeqt/menus/menus.pro +++ b/examples/activeqt/menus/menus.pro @@ -1,3 +1,5 @@ +include(../shared.pri) + TEMPLATE = app TARGET = menusax diff --git a/examples/activeqt/multiple/multiple.pro b/examples/activeqt/multiple/multiple.pro index 3254c0e..f08d3a2 100644 --- a/examples/activeqt/multiple/multiple.pro +++ b/examples/activeqt/multiple/multiple.pro @@ -1,3 +1,5 @@ +include(../shared.pri) + TEMPLATE = lib TARGET = multipleax diff --git a/examples/activeqt/shared.pri b/examples/activeqt/shared.pri new file mode 100644 index 0000000..d07afa9 --- /dev/null +++ b/examples/activeqt/shared.pri @@ -0,0 +1,7 @@ +# This .pri file suppresses the registration of the examples in the +# Qt Continuous Integration infrastructure. +QT_CI_JENKINS_HOME=$$(JENKINS_HOME) +!isEmpty(QT_CI_JENKINS_HOME) { + message("Qt CI environment detected, suppressing example registration") + CONFIG += qaxserver_no_postlink +} diff --git a/examples/activeqt/simple/simple.pro b/examples/activeqt/simple/simple.pro index a512c81..33d5410 100644 --- a/examples/activeqt/simple/simple.pro +++ b/examples/activeqt/simple/simple.pro @@ -1,3 +1,5 @@ +include(../shared.pri) + TEMPLATE = app TARGET = simpleax diff --git a/examples/activeqt/wrapper/wrapper.pro b/examples/activeqt/wrapper/wrapper.pro index 229f790..2efbea8 100644 --- a/examples/activeqt/wrapper/wrapper.pro +++ b/examples/activeqt/wrapper/wrapper.pro @@ -1,3 +1,5 @@ +include(../shared.pri) + TEMPLATE = lib TARGET = wrapperax diff --git a/qtactiveqt.pro b/qtactiveqt.pro index b993871..83d709a 100644 --- a/qtactiveqt.pro +++ b/qtactiveqt.pro @@ -1,4 +1,7 @@ CONFIG += tests_need_tools load(qt_parts) +!win32|winrt|wince { + message("ActiveQt is a Windows Desktop-only module. Will just generate a docs target.") +} SUBDIRS = src diff --git a/src/activeqt/axshared.prx b/src/activeqt/axshared.prx index 6d335e9..2964354 100644 --- a/src/activeqt/axshared.prx +++ b/src/activeqt/axshared.prx @@ -18,6 +18,8 @@ SOURCES = \ shared/qaxtypefunctions.cpp \ shared/qaxutils.cpp +mingw: HEADERSCLEAN_EXCLUDE += shared/qaxtypefunctions.h shared/qaxtypes.h control/qaxfactory.h + MODULE = axbase load(qt_module) QMAKE_DOCS_TARGETDIR = # Make qt_docs.prf default to activeqt instead of qtaxbase diff --git a/src/activeqt/container/qaxbase.cpp b/src/activeqt/container/qaxbase.cpp index 2c5865c..b3c2b90 100644 --- a/src/activeqt/container/qaxbase.cpp +++ b/src/activeqt/container/qaxbase.cpp @@ -69,6 +69,7 @@ #include <ctype.h> #include "../shared/qaxtypes.h" +#include "../shared/qaxutils_p.h" QT_BEGIN_NAMESPACE @@ -3676,16 +3677,20 @@ int QAxBase::internalInvoke(QMetaObject::Call call, int index, void **v) qvar = QVariant(vt, v[p + 1]); if (!qvar.isValid()) { - if (type == "IDispatch*") - qvar.setValue(*(IDispatch**)v[p+1]); - else if (type == "IUnknown*") - qvar.setValue(*(IUnknown**)v[p+1]); - else if (type == "QVariant") + if (type == "IDispatch*") { + if (out) + qvar.setValue(*(IDispatch***)v[p+1]); + else + qvar.setValue(*(IDispatch**)v[p+1]); + } else if (type == "IUnknown*") { + qvar.setValue(*(IUnknown**)v[p+1]); + } else if (type == "QVariant") { qvar = *(QVariant*)v[p + 1]; - else if (mo->indexOfEnumerator(type) != -1) + } else if (mo->indexOfEnumerator(type) != -1) { qvar = *(int*)v[p + 1]; - else + } else { qvar = QVariant(QMetaType::type(type), v[p + 1]); + } } QVariantToVARIANT(qvar, params.rgvarg[params.cArgs - p - 1], type, out); @@ -3710,8 +3715,12 @@ int QAxBase::internalInvoke(QMetaObject::Call call, int index, void **v) for (p = 0; p < (int)params.cArgs; ++p) { bool out; QByteArray ptype = d->metaobj->paramType(signature, p, &out); - if (out) - QVariantToVoidStar(VARIANTToQVariant(params.rgvarg[params.cArgs - p - 1], ptype), v[p+1], ptype); + if (out) { + VARIANTARG &var = params.rgvarg[params.cArgs - p - 1]; + QVariantToVoidStar(VARIANTToQVariant(var, ptype), v[p+1], ptype); + if (var.vt == (VT_DISPATCH | VT_BYREF)) + VariantInit(&var); // Prevent clearVARIANT() from releasing returned IDispatch* out parameters. + } } // clean up for (p = 0; p < (int)params.cArgs; ++p) diff --git a/src/activeqt/control/qaxfactory.cpp b/src/activeqt/control/qaxfactory.cpp index 3d6ff9f..5797bb7 100644 --- a/src/activeqt/control/qaxfactory.cpp +++ b/src/activeqt/control/qaxfactory.cpp @@ -548,8 +548,8 @@ bool QAxFactory::registerActiveObject(QObject *object) \a IDTypeLib, and if the server is an executable server then it will have the application id \a IDApp. - This macro needs to be used together with the \l {QAxFactory::}{QAXCLASS()}, \c {QAxFactory::}{QAXTYPE()} - and \c {QAxFactory::}{QAXFACTORY_END()} macros. + This macro needs to be used together with the QAXCLASS(), QAXTYPE() + and QAXFACTORY_END() macros. \snippet src_activeqt_control_qaxfactory.cpp 9 */ diff --git a/src/activeqt/control/qaxserver.cpp b/src/activeqt/control/qaxserver.cpp index 4326eb8..2de749f 100644 --- a/src/activeqt/control/qaxserver.cpp +++ b/src/activeqt/control/qaxserver.cpp @@ -467,9 +467,16 @@ static const char* const type_map[][2] = { "QString", "BSTR" }, { "QCString", "BSTR" }, { "bool", "VARIANT_BOOL" }, + { "char", "char" }, + { "unsigned char", "unsigned char" }, + { "uchar", "unsigned char" }, + { "short", "short" }, + { "unsigned short", "unsigned short" }, + { "ushort", "unsigned short" }, { "int", "int" }, { "void", "void" }, { "uint", "unsigned int" }, + { "float", "float" }, { "double", "double" }, { "QColor", "OLE_COLOR" }, { "QDate", "DATE" }, diff --git a/src/activeqt/control/qaxserverbase.cpp b/src/activeqt/control/qaxserverbase.cpp index 5929270..b788e07 100644 --- a/src/activeqt/control/qaxserverbase.cpp +++ b/src/activeqt/control/qaxserverbase.cpp @@ -423,7 +423,7 @@ public: InitializeCriticalSection(&refCountSection); InitializeCriticalSection(&createWindowSection); } - ~QAxServerAggregate() + virtual ~QAxServerAggregate() { DeleteCriticalSection(&refCountSection); DeleteCriticalSection(&createWindowSection); @@ -504,7 +504,7 @@ public: for (int i = 0; i < count; ++i) cpoints.at(i)->AddRef(); } - ~QAxSignalVec() + virtual ~QAxSignalVec() { const int count = cpoints.count(); for (int i = 0; i < count; ++i) @@ -623,7 +623,7 @@ public: foreach (const CONNECTDATA &connection, connections) connection.pUnk->AddRef(); } - ~QAxConnection() + virtual ~QAxConnection() { DeleteCriticalSection(&refCountSection); } @@ -843,7 +843,7 @@ public: } } - ~QClassFactory() + virtual ~QClassFactory() { DeleteCriticalSection(&refCountSection); } diff --git a/src/activeqt/shared/qaxtypefunctions.h b/src/activeqt/shared/qaxtypefunctions.h index 7dd200f..a3efa61 100644 --- a/src/activeqt/shared/qaxtypefunctions.h +++ b/src/activeqt/shared/qaxtypefunctions.h @@ -40,9 +40,7 @@ #ifndef QAXTYPEFUNCTIONS_P_H #define QAXTYPEFUNCTIONS_P_H -#if !defined(_WINDOWS_) && !defined(_WINDOWS_H) && !defined(__WINDOWS__) -#error Must include windows.h first! -#endif +#include <QtCore/qt_windows.h> #include <QtGui/qcolor.h> #include <QtGui/qfont.h> diff --git a/src/activeqt/shared/qaxtypes.cpp b/src/activeqt/shared/qaxtypes.cpp index 7d9d882..ba11ac2 100644 --- a/src/activeqt/shared/qaxtypes.cpp +++ b/src/activeqt/shared/qaxtypes.cpp @@ -233,17 +233,27 @@ static QByteArray msgOutParameterNotSupported(const QByteArray &type) Also called recoursively for lists. */ + +// Convenience macro for function QVariantToVARIANT() +// storing a POD QVariant value in the VARIANT arg. +#define QVARIANT_TO_VARIANT_POD(type, value, out, varType, varMember, varPointerMember) \ + if (out && arg.vt == ((varType) | VT_BYREF)) { \ + *arg.varPointerMember = value; /* pre-allocated out-parameter */ \ + } else { \ + if (out) { \ + arg.vt = (varType) | VT_BYREF; \ + arg.varPointerMember = new type(value); \ + } else { \ + arg.vt = (varType); \ + arg.varMember = value; \ + } \ + } + bool QVariantToVARIANT(const QVariant &var, VARIANT &arg, const QByteArray &typeName, bool out) { QVariant qvar = var; // "type" is the expected type, so coerce if necessary - QVariant::Type proptype = typeName.isEmpty() ? QVariant::Invalid : QVariant::nameToType(typeName); - if ((proptype == QVariant::UserType || proptype == int(QMetaType::QVariant)) && !typeName.isEmpty()) { - if (typeName == "short" || typeName == "char") - proptype = QVariant::Int; - else if (typeName == "float") - proptype = QVariant::Double; - } + const QVariant::Type proptype = typeName.isEmpty() ? QVariant::Invalid : QVariant::nameToType(typeName); if (proptype != QVariant::Invalid && proptype != QVariant::UserType && proptype != int(QMetaType::QVariant) @@ -283,128 +293,71 @@ bool QVariantToVARIANT(const QVariant &var, VARIANT &arg, const QByteArray &type } break; + case QMetaType::Char: + QVARIANT_TO_VARIANT_POD(char, char(qvar.toInt()), out, VT_I1, cVal, pcVal) + break; + + case QMetaType::UChar: + QVARIANT_TO_VARIANT_POD(BYTE, uchar(qvar.toUInt()), out, VT_UI1, bVal, pbVal) + break; + + case QMetaType::Short: + QVARIANT_TO_VARIANT_POD(short, qvariant_cast<short>(qvar), out, VT_I2, iVal, piVal) + break; + + case QMetaType::UShort: + QVARIANT_TO_VARIANT_POD(ushort, qvariant_cast<ushort>(qvar), out, VT_UI2, uiVal, puiVal) + break; + case QVariant::Int: - if (out && arg.vt == (VT_I4|VT_BYREF)) { - *arg.plVal = qvar.toInt(); - } else { - arg.vt = VT_I4; - arg.lVal = qvar.toInt(); - if (out) { - if (typeName == "short") { - arg.vt = VT_I2; - arg.piVal = new short(arg.lVal); - } else if (typeName == "char") { - arg.vt = VT_I1; - arg.pcVal= new char(arg.lVal); - } else { - arg.plVal = new long(arg.lVal); - } - arg.vt |= VT_BYREF; - } - } + QVARIANT_TO_VARIANT_POD(long, qvar.toInt(), out, VT_I4, lVal, plVal) break; case QVariant::UInt: - if (out && (arg.vt == (VT_UINT|VT_BYREF) || arg.vt == (VT_I4|VT_BYREF))) { - *arg.puintVal = qvar.toUInt(); - } else { - arg.vt = VT_UINT; - arg.uintVal = qvar.toUInt(); - if (out) { - arg.puintVal = new uint(arg.uintVal); - arg.vt |= VT_BYREF; - } - } + QVARIANT_TO_VARIANT_POD(uint, qvar.toUInt(), out, VT_UI4, uintVal, puintVal) break; case QVariant::LongLong: - if (out && arg.vt == (VT_CY|VT_BYREF)) { + if (out && arg.vt == (VT_CY|VT_BYREF)) { // VT_CY: Currency arg.pcyVal->int64 = qvar.toLongLong(); - } else if (out && arg.vt == (VT_I8|VT_BYREF)) { - *arg.pllVal = qvar.toLongLong(); } else { - arg.vt = VT_I8; - arg.llVal = qvar.toLongLong(); - if (out) { - arg.pllVal = new LONGLONG(arg.llVal); - arg.vt |= VT_BYREF; - } + QVARIANT_TO_VARIANT_POD(LONGLONG, qvar.toLongLong(), out, VT_I8, llVal, pllVal) } break; case QVariant::ULongLong: - if (out && arg.vt == (VT_CY|VT_BYREF)) { + if (out && arg.vt == (VT_CY|VT_BYREF)) { // VT_CY: Currency arg.pcyVal->int64 = qvar.toULongLong(); - } else if (out && arg.vt == (VT_UI8|VT_BYREF)) { - *arg.pullVal = qvar.toULongLong(); } else { - arg.vt = VT_UI8; - arg.ullVal = qvar.toULongLong(); - if (out) { - arg.pullVal = new ULONGLONG(arg.ullVal); - arg.vt |= VT_BYREF; - } + QVARIANT_TO_VARIANT_POD(ULONGLONG, qvar.toULongLong(), out, VT_UI8, ullVal, pullVal) } break; case QVariant::Bool: - if (out && arg.vt == (VT_BOOL|VT_BYREF)) { - *arg.pboolVal = qvar.toBool() ? VARIANT_TRUE : VARIANT_FALSE; - } else { - arg.vt = VT_BOOL; - arg.boolVal = qvar.toBool() ? VARIANT_TRUE : VARIANT_FALSE; - if (out) { - arg.pboolVal = new short(arg.boolVal); - arg.vt |= VT_BYREF; - } - } + QVARIANT_TO_VARIANT_POD(short, short(qvar.toBool() ? VARIANT_TRUE : VARIANT_FALSE), + out, VT_BOOL, boolVal, pboolVal) break; + case QMetaType::Float: - case QVariant::Double: - if (out && arg.vt == (VT_R8|VT_BYREF)) { - *arg.pdblVal = qvar.toDouble(); - } else { - arg.vt = VT_R8; - arg.dblVal = qvar.toDouble(); - if (out) { - if (typeName == "float") { - arg.vt = VT_R4; - arg.pfltVal = new float(arg.dblVal); - } else { - arg.pdblVal = new double(arg.dblVal); - } - arg.vt |= VT_BYREF; - } - } + QVARIANT_TO_VARIANT_POD(float, float(qvar.toDouble()), out, VT_R4, fltVal, pfltVal) break; - case QVariant::Color: - if (out && arg.vt == (VT_COLOR|VT_BYREF)) { - *arg.plVal = QColorToOLEColor(qvariant_cast<QColor>(qvar)); - } else { - arg.vt = VT_COLOR; - arg.lVal = QColorToOLEColor(qvariant_cast<QColor>(qvar)); - if (out) { - arg.plVal = new long(arg.lVal); - arg.vt |= VT_BYREF; - } - } + case QMetaType::Double: + QVARIANT_TO_VARIANT_POD(double, qvar.toDouble(), out, VT_R8, dblVal, pdblVal) + break; + + case QVariant::Color: + QVARIANT_TO_VARIANT_POD(long, QColorToOLEColor(qvariant_cast<QColor>(qvar)), + out, VT_COLOR, lVal, plVal) break; case QVariant::Date: case QVariant::Time: - case QVariant::DateTime: - if (out && arg.vt == (VT_DATE|VT_BYREF)) { - *arg.pdate = QDateTimeToDATE(qvar.toDateTime()); - } else { - arg.vt = VT_DATE; - arg.date = QDateTimeToDATE(qvar.toDateTime()); - if (out) { - arg.pdate = new DATE(arg.date); - arg.vt |= VT_BYREF; - } - } + case QVariant::DateTime: // DATE = double + QVARIANT_TO_VARIANT_POD(DATE, QDateTimeToDATE(qvar.toDateTime()), + out, VT_DATE, date, pdate) break; + case QVariant::Font: if (out && arg.vt == (VT_DISPATCH|VT_BYREF)) { if (*arg.ppdispVal) @@ -775,6 +728,8 @@ bool QVariantToVARIANT(const QVariant &var, VARIANT &arg, const QByteArray &type return true; } +#undef QVARIANT_TO_VARIANT_POD + /*! Returns \a arg as a QVariant of type \a type. diff --git a/src/activeqt/shared/qaxtypes.h b/src/activeqt/shared/qaxtypes.h index 3823f71..12ec397 100644 --- a/src/activeqt/shared/qaxtypes.h +++ b/src/activeqt/shared/qaxtypes.h @@ -53,10 +53,10 @@ QT_BEGIN_NAMESPACE # define VARIANTToQVariantFunc VARIANTToQVariant_container #endif -extern bool QVariantToVARIANTFunc(const QVariant &var, VARIANT &arg, const QByteArray &typeName = 0, bool out = false); +extern bool QVariantToVARIANTFunc(const QVariant &var, VARIANT &arg, const QByteArray &typeName = QByteArray(), bool out = false); extern QVariant VARIANTToQVariantFunc(const VARIANT &arg, const QByteArray &typeName, uint type = 0); -inline bool QVariantToVARIANT(const QVariant &var, VARIANT &arg, const QByteArray &typeName = 0, bool out = false) +inline bool QVariantToVARIANT(const QVariant &var, VARIANT &arg, const QByteArray &typeName = QByteArray(), bool out = false) { return QVariantToVARIANTFunc(var, arg, typeName, out); } diff --git a/src/activeqt/shared/qaxutils_p.h b/src/activeqt/shared/qaxutils_p.h index 7da5811..75a4c89 100644 --- a/src/activeqt/shared/qaxutils_p.h +++ b/src/activeqt/shared/qaxutils_p.h @@ -53,7 +53,7 @@ // #include <QtCore/qt_windows.h> -#include <QtCore/QtGlobal> +#include <QtCore/QMetaType> QT_BEGIN_NAMESPACE @@ -76,4 +76,6 @@ HRGN qaxHrgnFromQRegion(const QRegion ®ion); QT_END_NAMESPACE +Q_DECLARE_METATYPE(IDispatch**) + #endif diff --git a/src/tools/idc/main.cpp b/src/tools/idc/main.cpp index 1cd0ed0..6f00477 100644 --- a/src/tools/idc/main.cpp +++ b/src/tools/idc/main.cpp @@ -140,7 +140,7 @@ static bool runWithQtInEnvironment(const QString &cmd) CloseHandle(pi.hThread); CloseHandle(pi.hProcess); if (exitCode) - fprintf(stderr, "\"%s\" returned exit code: %ul\n", qPrintable(cmd), exitCode); + fprintf(stderr, "\"%s\" returned exit code: %lu (0x%lx)\n", qPrintable(cmd), exitCode, exitCode); return exitCode == 0; } diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro index 593ed3f..0b43b0d 100644 --- a/tests/auto/auto.pro +++ b/tests/auto/auto.pro @@ -1,5 +1,6 @@ TEMPLATE = subdirs SUBDIRS += \ + conversion \ qaxobject \ qaxscript \ dumpcpp \ diff --git a/tests/auto/conversion/conversion.pro b/tests/auto/conversion/conversion.pro new file mode 100644 index 0000000..47f0699 --- /dev/null +++ b/tests/auto/conversion/conversion.pro @@ -0,0 +1,3 @@ +CONFIG += testcase +QT += axcontainer testlib +SOURCES += tst_conversion.cpp diff --git a/tests/auto/conversion/tst_conversion.cpp b/tests/auto/conversion/tst_conversion.cpp new file mode 100644 index 0000000..8cf3c4d --- /dev/null +++ b/tests/auto/conversion/tst_conversion.cpp @@ -0,0 +1,204 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** 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 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtTest/QtTest> +#include <QtCore/QVariant> +#include <QtCore/QDateTime> +#include <QtCore/QMetaType> + +#include <qt_windows.h> + +QT_BEGIN_NAMESPACE + +// Conversion functions from statically linked library (axtypes.h) +bool QVariantToVARIANT_container(const QVariant &var, VARIANT &arg, + const QByteArray &typeName = QByteArray(), + bool out = false); + +QVariant VARIANTToQVariant_container(const VARIANT &arg, const QByteArray &typeName, + uint type = 0); + +QT_END_NAMESPACE + +class tst_Conversion : public QObject +{ + Q_OBJECT + +private slots: + void conversion_data(); + void conversion(); +}; + +enum Mode { + ByValue, + ByReference, // Allocate new value + OutParameter // Pre-allocated out-parameter by reference (test works only for types < qint64) +}; + +Q_DECLARE_METATYPE(Mode) + +void tst_Conversion::conversion_data() +{ + QTest::addColumn<QVariant>("value"); + QTest::addColumn<uint>("expectedType"); + QTest::addColumn<QByteArray>("typeName"); + QTest::addColumn<Mode>("mode"); + + QVariant qvar; + QByteArray typeName; + + qvar = QVariant('a'); + typeName = QByteArrayLiteral("char"); + QTest::newRow("char") + << qvar << uint(VT_I1) << typeName << ByValue; + QTest::newRow("char-ref") + << qvar << uint(VT_I1 | VT_BYREF) << typeName << ByReference; + QTest::newRow("char-out") + << qvar << uint(VT_I1 | VT_BYREF) << typeName << OutParameter; + + qvar = QVariant(uchar(197)); + typeName = QByteArrayLiteral("uchar"); + QTest::newRow("uchar") + << qvar << uint(VT_UI1) << typeName << ByValue; + QTest::newRow("uchar-ref") + << qvar << uint(VT_UI1 | VT_BYREF) << typeName << ByReference; + QTest::newRow("uchar-out") + << qvar << uint(VT_UI1 | VT_BYREF) << typeName << OutParameter; + + qvar = QVariant(ushort(42)); + typeName = QByteArrayLiteral("ushort"); + QTest::newRow("ushort") + << qvar << uint(VT_UI2) << typeName << ByValue; + QTest::newRow("ushort-ref") + << qvar << uint(VT_UI2 | VT_BYREF) << typeName << ByReference; + QTest::newRow("ushort-out") + << qvar << uint(VT_UI2 | VT_BYREF) << typeName << OutParameter; + + qvar = QVariant(short(42)); + typeName = QByteArrayLiteral("short"); + QTest::newRow("short") + << qvar << uint(VT_I2) << typeName << ByValue; + QTest::newRow("short-ref") + << qvar << uint(VT_I2 | VT_BYREF) << typeName << ByReference; + QTest::newRow("short-out") + << qvar << uint(VT_I2 | VT_BYREF) << typeName << OutParameter; + + qvar = QVariant(42); + typeName.clear(); + QTest::newRow("int") + << qvar << uint(VT_I4) << typeName << ByValue; + QTest::newRow("int-ref") + << qvar << uint(VT_I4 | VT_BYREF) << typeName << ByReference; + QTest::newRow("int-out") + << qvar << uint(VT_I4 | VT_BYREF) << typeName << OutParameter; + + qvar = QVariant(42u); + typeName.clear(); + QTest::newRow("uint") + << qvar << uint(VT_UI4) << typeName << ByValue; + QTest::newRow("uint-ref") + << qvar << uint(VT_UI4 | VT_BYREF) << typeName << ByReference; + QTest::newRow("uint-out") + << qvar << uint(VT_UI4 | VT_BYREF) << typeName << OutParameter; + + qvar = QVariant(qint64(42)); + typeName.clear(); + QTest::newRow("int64") + << qvar << uint(VT_I8) << typeName << ByValue; + QTest::newRow("int64-ref") + << qvar << uint(VT_I8 | VT_BYREF) << typeName << ByReference; + QTest::newRow("int64-out") + << qvar << uint(VT_I8 | VT_BYREF) << typeName << OutParameter; + + qvar = QVariant(quint64(42u)); + typeName.clear(); + QTest::newRow("uint64") + << qvar << uint(VT_UI8) << typeName << ByValue; + QTest::newRow("uint64-ref") + << qvar << uint(VT_UI8 | VT_BYREF) << typeName << ByReference; + QTest::newRow("uint64-out") + << qvar << uint(VT_UI8 | VT_BYREF) << typeName << OutParameter; + + qvar = QVariant(3.141f); + typeName = QByteArrayLiteral("float"); + QTest::newRow("float") + << qvar << uint(VT_R4) << typeName << ByValue; + QTest::newRow("float-ref") + << qvar << uint(VT_R4 | VT_BYREF) << typeName << ByReference; + QTest::newRow("float-out") + << qvar << uint(VT_R4 | VT_BYREF) << typeName << OutParameter; + + qvar = QVariant(3.141); + typeName.clear(); + QTest::newRow("double") + << qvar << uint(VT_R8) << typeName << ByValue; + QTest::newRow("double-ref") + << qvar << uint(VT_R8 | VT_BYREF) << typeName << ByReference; + QTest::newRow("double-out") + << qvar << uint(VT_R8 | VT_BYREF) << typeName << OutParameter; + + qvar = QDateTime(QDate(1968, 3, 9), QTime(10, 0)); + typeName.clear(); + QTest::newRow("datetime") + << qvar << uint(VT_DATE) << typeName << ByValue; + QTest::newRow("datetime-ref") + << qvar << uint(VT_DATE | VT_BYREF) << typeName << ByReference; + QTest::newRow("datetime-out") + << qvar << uint(VT_DATE | VT_BYREF) << typeName << OutParameter; +} + +void tst_Conversion::conversion() +{ + QFETCH(QVariant, value); + QFETCH(uint, expectedType); + QFETCH(QByteArray, typeName); + QFETCH(Mode, mode); + + VARIANT variant; + VariantInit(&variant); + if (mode == OutParameter) { + variant.vt = expectedType | VT_BYREF; + variant.pullVal = new ULONGLONG(0); + } + + QVERIFY(QVariantToVARIANT_container(value, variant, typeName, mode != ByValue)); + QCOMPARE(uint(variant.vt), expectedType); + const QVariant converted = VARIANTToQVariant_container(variant, QByteArray()); + QCOMPARE(converted, value); + + if (mode == OutParameter) + delete variant.pullVal; +} + +QTEST_MAIN(tst_Conversion) +#include "tst_conversion.moc" |