diff options
Diffstat (limited to 'sources/pyside6/PySide6/glue/qtcore.cpp')
-rw-r--r-- | sources/pyside6/PySide6/glue/qtcore.cpp | 1879 |
1 files changed, 1879 insertions, 0 deletions
diff --git a/sources/pyside6/PySide6/glue/qtcore.cpp b/sources/pyside6/PySide6/glue/qtcore.cpp new file mode 100644 index 000000000..1ce41d003 --- /dev/null +++ b/sources/pyside6/PySide6/glue/qtcore.cpp @@ -0,0 +1,1879 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt for Python. +** +** $QT_BEGIN_LICENSE:LGPL$ +** 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 https://www.qt.io/terms-conditions. For further +** information use the contact form at https://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 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/********************************************************************* + * INJECT CODE + ********************************************************************/ + +// @snippet include-pyside +#include <pyside.h> +#include <limits> +// @snippet include-pyside + +// @snippet qsettings-value +// If we enter the kwds, means that we have a defaultValue or +// at least a type. +// This avoids that we are passing '0' as defaultValue. +// defaultValue can also be passed as positional argument, +// not only as keyword. +QVariant out; +if (kwds || numArgs > 1) { + Py_BEGIN_ALLOW_THREADS + out = %CPPSELF.value(%1, %2); + Py_END_ALLOW_THREADS +} else { + Py_BEGIN_ALLOW_THREADS + out = %CPPSELF.value(%1); + Py_END_ALLOW_THREADS +} + +PyTypeObject *typeObj = reinterpret_cast<PyTypeObject*>(%PYARG_3); + +if (typeObj) { + if (typeObj == &PyList_Type) { + QByteArray out_ba = out.toByteArray(); + if (!out_ba.isEmpty()) { + QByteArrayList valuesList = out_ba.split(','); + const int valuesSize = valuesList.size(); + if (valuesSize > 0) { + PyObject *list = PyList_New(valuesSize); + for (int i = 0; i < valuesSize; i++) { + PyObject *item = PyUnicode_FromString(valuesList[i].data()); + PyList_SET_ITEM(list, i, item); + } + %PYARG_0 = list; + + } else { + %PYARG_0 = %CONVERTTOPYTHON[QVariant](out); + } + } else { + %PYARG_0 = PyList_New(0); + } + } else if (typeObj == &PyBytes_Type) { + QByteArray asByteArray = out.toByteArray(); + %PYARG_0 = PyBytes_FromString(asByteArray.data()); + } else if (typeObj == &PyUnicode_Type) { + QByteArray asByteArray = out.toByteArray(); + %PYARG_0 = PyUnicode_FromString(asByteArray.data()); + } else if (typeObj == &PyLong_Type) { + float asFloat = out.toFloat(); + pyResult = PyLong_FromDouble(asFloat); + } else if (typeObj == &PyFloat_Type) { + float asFloat = out.toFloat(); + %PYARG_0 = PyFloat_FromDouble(asFloat); + } else if (typeObj == &PyBool_Type) { + if (out.toBool()) { + Py_INCREF(Py_True); + %PYARG_0 = Py_True; + } else { + Py_INCREF(Py_False); + %PYARG_0 = Py_False; + } + } + // TODO: PyDict_Type and PyTuple_Type +} +else { + if (!out.isValid()) { + Py_INCREF(Py_None); + %PYARG_0 = Py_None; + } else { + %PYARG_0 = %CONVERTTOPYTHON[QVariant](out); + } +} + +// @snippet qsettings-value + +// @snippet qvariant-conversion +static QMetaType QVariant_resolveMetaType(PyTypeObject *type) +{ + if (PyObject_TypeCheck(type, SbkObjectType_TypeF())) { + auto sbkType = reinterpret_cast<SbkObjectType *>(type); + const char *typeName = Shiboken::ObjectType::getOriginalName(sbkType); + if (!typeName) + return {}; + const bool valueType = '*' != typeName[qstrlen(typeName) - 1]; + // Do not convert user type of value + if (valueType && Shiboken::ObjectType::isUserType(type)) + return {}; + QMetaType metaType = QMetaType::fromName(typeName); + if (metaType.isValid()) + return metaType; + // Do not resolve types to value type + if (valueType) + return {}; + // Find in base types. First check tp_bases, and only after check tp_base, because + // tp_base does not always point to the first base class, but rather to the first + // that has added any python fields or slots to its object layout. + // See https://mail.python.org/pipermail/python-list/2009-January/520733.html + if (type->tp_bases) { + for (int i = 0, size = PyTuple_GET_SIZE(type->tp_bases); i < size; ++i) { + auto baseType = reinterpret_cast<PyTypeObject *>(PyTuple_GET_ITEM(type->tp_bases, i)); + const QMetaType derived = QVariant_resolveMetaType(baseType); + if (derived.isValid()) + return derived; + } + } else if (type->tp_base) { + return QVariant_resolveMetaType(type->tp_base); + } + } + return {}; +} +static QVariant QVariant_convertToValueList(PyObject *list) +{ + if (PySequence_Size(list) < 0) { + // clear the error if < 0 which means no length at all + PyErr_Clear(); + return QVariant(); + } + + Shiboken::AutoDecRef element(PySequence_GetItem(list, 0)); + + const QMetaType metaType = QVariant_resolveMetaType(element.cast<PyTypeObject *>()); + if (metaType.isValid()) { + QByteArray listTypeName("QList<"); + listTypeName += metaType.name(); + listTypeName += '>'; + QMetaType metaType = QMetaType::fromName(listTypeName); + if (metaType.isValid()) { + Shiboken::Conversions::SpecificConverter converter(listTypeName); + if (converter) { + QVariant var(metaType); + converter.toCpp(list, &var); + return var; + } + qWarning() << "Type converter for :" << listTypeName << "not registered."; + } + } + return QVariant(); +} +static bool QVariant_isStringList(PyObject *list) +{ + if (!PySequence_Check(list)) { + // If it is not a list or a derived list class + // we assume that will not be a String list neither. + return false; + } + + if (PySequence_Size(list) < 0) { + // clear the error if < 0 which means no length at all + PyErr_Clear(); + return false; + } + + Shiboken::AutoDecRef fast(PySequence_Fast(list, "Failed to convert QVariantList")); + const Py_ssize_t size = PySequence_Fast_GET_SIZE(fast.object()); + for (Py_ssize_t i = 0; i < size; ++i) { + PyObject *item = PySequence_Fast_GET_ITEM(fast.object(), i); + if (!%CHECKTYPE[QString](item)) + return false; + } + return true; +} +static QVariant QVariant_convertToVariantMap(PyObject *map) +{ + Py_ssize_t pos = 0; + Shiboken::AutoDecRef keys(PyDict_Keys(map)); + if (!QVariant_isStringList(keys)) + return QVariant(); + PyObject *key; + PyObject *value; + QMap<QString,QVariant> ret; + while (PyDict_Next(map, &pos, &key, &value)) { + QString cppKey = %CONVERTTOCPP[QString](key); + QVariant cppValue = %CONVERTTOCPP[QVariant](value); + ret.insert(cppKey, cppValue); + } + return QVariant(ret); +} +static QVariant QVariant_convertToVariantList(PyObject *list) +{ + if (QVariant_isStringList(list)) { + QList<QString > lst = %CONVERTTOCPP[QList<QString>](list); + return QVariant(QStringList(lst)); + } + QVariant valueList = QVariant_convertToValueList(list); + if (valueList.isValid()) + return valueList; + + if (PySequence_Size(list) < 0) { + // clear the error if < 0 which means no length at all + PyErr_Clear(); + return QVariant(); + } + + QList<QVariant> lst; + Shiboken::AutoDecRef fast(PySequence_Fast(list, "Failed to convert QVariantList")); + const Py_ssize_t size = PySequence_Fast_GET_SIZE(fast.object()); + for (Py_ssize_t i = 0; i < size; ++i) { + PyObject *pyItem = PySequence_Fast_GET_ITEM(fast.object(), i); + QVariant item = %CONVERTTOCPP[QVariant](pyItem); + lst.append(item); + } + return QVariant(lst); +} +// @snippet qvariant-conversion + +// @snippet qvariantmap-check +static bool QVariantType_isStringList(PyObject *list) +{ + Shiboken::AutoDecRef fast(PySequence_Fast(list, "Failed to convert QVariantList")); + const Py_ssize_t size = PySequence_Fast_GET_SIZE(fast.object()); + for (Py_ssize_t i=0; i < size; i++) { + PyObject *item = PySequence_Fast_GET_ITEM(fast.object(), i); + if (!%CHECKTYPE[QString](item)) + return false; + } + return true; +} +static bool QVariantType_checkAllStringKeys(PyObject *dict) +{ + Shiboken::AutoDecRef keys(PyDict_Keys(dict)); + return QVariantType_isStringList(keys); +} +// @snippet qvariantmap-check + +// @snippet qt-qabs +double _abs = qAbs(%1); +%PYARG_0 = %CONVERTTOPYTHON[double](_abs); +// @snippet qt-qabs + +// @snippet qt-postroutine +namespace PySide { +static QStack<PyObject *> globalPostRoutineFunctions; +void globalPostRoutineCallback() +{ + Shiboken::GilState state; + for (auto *callback : globalPostRoutineFunctions) { + Shiboken::AutoDecRef result(PyObject_CallObject(callback, nullptr)); + Py_DECREF(callback); + } + globalPostRoutineFunctions.clear(); +} +void addPostRoutine(PyObject *callback) +{ + if (PyCallable_Check(callback)) { + globalPostRoutineFunctions << callback; + Py_INCREF(callback); + } else { + PyErr_SetString(PyExc_TypeError, "qAddPostRoutine: The argument must be a callable object."); + } +} +} // namespace +// @snippet qt-postroutine + +// @snippet qt-addpostroutine +PySide::addPostRoutine(%1); +// @snippet qt-addpostroutine + +// @snippet qt-qaddpostroutine +qAddPostRoutine(PySide::globalPostRoutineCallback); +// @snippet qt-qaddpostroutine + +// @snippet qt-version +QList<QByteArray> version = QByteArray(qVersion()).split('.'); +PyObject *pyQtVersion = PyTuple_New(3); +for (int i = 0; i < 3; ++i) + PyTuple_SET_ITEM(pyQtVersion, i, PyInt_FromLong(version[i].toInt())); +PyModule_AddObject(module, "__version_info__", pyQtVersion); +PyModule_AddStringConstant(module, "__version__", qVersion()); +// @snippet qt-version + +// @snippet qobject-connect +static bool isDecorator(PyObject *method, PyObject *self) +{ + Shiboken::AutoDecRef methodName(PyObject_GetAttr(method, Shiboken::PyMagicName::name())); + if (!PyObject_HasAttr(self, methodName)) + return true; + Shiboken::AutoDecRef otherMethod(PyObject_GetAttr(self, methodName)); + return PyMethod_GET_FUNCTION(otherMethod.object()) != PyMethod_GET_FUNCTION(method); +} + +static bool getReceiver(QObject *source, const char *signal, PyObject *callback, QObject **receiver, PyObject **self, QByteArray *callbackSig) +{ + bool forceGlobalReceiver = false; + if (PyMethod_Check(callback)) { + *self = PyMethod_GET_SELF(callback); + if (%CHECKTYPE[QObject *](*self)) + *receiver = %CONVERTTOCPP[QObject *](*self); + forceGlobalReceiver = isDecorator(callback, *self); + } else if (PyCFunction_Check(callback)) { + *self = PyCFunction_GET_SELF(callback); + if (*self && %CHECKTYPE[QObject *](*self)) + *receiver = %CONVERTTOCPP[QObject *](*self); + } else if (PyCallable_Check(callback)) { + // Ok, just a callable object + *receiver = nullptr; + *self = nullptr; + } + + bool usingGlobalReceiver = !*receiver || forceGlobalReceiver; + + // Check if this callback is a overwrite of a non-virtual Qt slot. + if (!usingGlobalReceiver && receiver && self) { + *callbackSig = PySide::Signal::getCallbackSignature(signal, *receiver, callback, usingGlobalReceiver).toLatin1(); + const QMetaObject *metaObject = (*receiver)->metaObject(); + int slotIndex = metaObject->indexOfSlot(callbackSig->constData()); + if (slotIndex != -1 && slotIndex < metaObject->methodOffset() && PyMethod_Check(callback)) + usingGlobalReceiver = true; + } + + const auto receiverThread = *receiver ? (*receiver)->thread() : nullptr; + + if (usingGlobalReceiver) { + PySide::SignalManager &signalManager = PySide::SignalManager::instance(); + *receiver = signalManager.globalReceiver(source, callback); + // PYSIDE-1354: Move the global receiver to the original receivers's thread + // so that autoconnections work correctly. + if (receiverThread && receiverThread != (*receiver)->thread()) + (*receiver)->moveToThread(receiverThread); + *callbackSig = PySide::Signal::getCallbackSignature(signal, *receiver, callback, usingGlobalReceiver).toLatin1(); + } + + return usingGlobalReceiver; +} + +static bool qobjectConnect(QObject *source, const char *signal, QObject *receiver, const char *slot, Qt::ConnectionType type) +{ + if (!signal || !slot) + return false; + + if (!PySide::Signal::checkQtSignal(signal)) + return false; + signal++; + + if (!PySide::SignalManager::registerMetaMethod(source, signal, QMetaMethod::Signal)) + return false; + + bool isSignal = PySide::Signal::isQtSignal(slot); + slot++; + PySide::SignalManager::registerMetaMethod(receiver, slot, isSignal ? QMetaMethod::Signal : QMetaMethod::Slot); + bool connection; + connection = QObject::connect(source, signal - 1, receiver, slot - 1, type); + return connection; +} + +static bool qobjectConnect(QObject *source, QMetaMethod signal, QObject *receiver, QMetaMethod slot, Qt::ConnectionType type) +{ + return qobjectConnect(source, signal.methodSignature(), receiver, slot.methodSignature(), type); +} + +static bool qobjectConnectCallback(QObject *source, const char *signal, PyObject *callback, Qt::ConnectionType type) +{ + if (!signal || !PySide::Signal::checkQtSignal(signal)) + return false; + signal++; + + int signalIndex = PySide::SignalManager::registerMetaMethodGetIndex(source, signal, QMetaMethod::Signal); + if (signalIndex == -1) + return false; + + PySide::SignalManager &signalManager = PySide::SignalManager::instance(); + + // Extract receiver from callback + QObject *receiver = nullptr; + PyObject *self = nullptr; + QByteArray callbackSig; + bool usingGlobalReceiver = getReceiver(source, signal, callback, &receiver, &self, &callbackSig); + if (receiver == nullptr && self == nullptr) + return false; + + const QMetaObject *metaObject = receiver->metaObject(); + const char *slot = callbackSig.constData(); + int slotIndex = metaObject->indexOfSlot(slot); + QMetaMethod signalMethod = metaObject->method(signalIndex); + + if (slotIndex == -1) { + if (!usingGlobalReceiver && self && !Shiboken::Object::hasCppWrapper(reinterpret_cast<SbkObject *>(self))) { + qWarning("You can't add dynamic slots on an object originated from C++."); + if (usingGlobalReceiver) + signalManager.releaseGlobalReceiver(source, receiver); + + return false; + } + + if (usingGlobalReceiver) + slotIndex = signalManager.globalReceiverSlotIndex(receiver, slot); + else + slotIndex = PySide::SignalManager::registerMetaMethodGetIndex(receiver, slot, QMetaMethod::Slot); + + if (slotIndex == -1) { + if (usingGlobalReceiver) + signalManager.releaseGlobalReceiver(source, receiver); + + return false; + } + } + bool connection; + connection = QMetaObject::connect(source, signalIndex, receiver, slotIndex, type); + if (connection) { + if (usingGlobalReceiver) + signalManager.notifyGlobalReceiver(receiver); + #ifndef AVOID_PROTECTED_HACK + source->connectNotify(signalMethod); //Qt5: QMetaMethod instead of char * + #else + // Need to cast to QObjectWrapper * and call the public version of + // connectNotify when avoiding the protected hack. + reinterpret_cast<QObjectWrapper *>(source)->connectNotify(signalMethod); //Qt5: QMetaMethod instead of char * + #endif + + return connection; + } + + if (usingGlobalReceiver) + signalManager.releaseGlobalReceiver(source, receiver); + + return false; +} + + +static bool qobjectDisconnectCallback(QObject *source, const char *signal, PyObject *callback) +{ + if (!PySide::Signal::checkQtSignal(signal)) + return false; + + PySide::SignalManager &signalManager = PySide::SignalManager::instance(); + + // Extract receiver from callback + QObject *receiver = nullptr; + PyObject *self = nullptr; + QByteArray callbackSig; + QMetaMethod slotMethod; + bool usingGlobalReceiver = getReceiver(nullptr, signal, callback, &receiver, &self, &callbackSig); + if (receiver == nullptr && self == nullptr) + return false; + + const QMetaObject *metaObject = receiver->metaObject(); + int signalIndex = source->metaObject()->indexOfSignal(++signal); + int slotIndex = -1; + + slotIndex = metaObject->indexOfSlot(callbackSig); + slotMethod = metaObject->method(slotIndex); + + bool disconnected; + disconnected = QMetaObject::disconnectOne(source, signalIndex, receiver, slotIndex); + + if (disconnected) { + if (usingGlobalReceiver) + signalManager.releaseGlobalReceiver(source, receiver); + + #ifndef AVOID_PROTECTED_HACK + source->disconnectNotify(slotMethod); //Qt5: QMetaMethod instead of char * + #else + // Need to cast to QObjectWrapper * and call the public version of + // connectNotify when avoiding the protected hack. + reinterpret_cast<QObjectWrapper *>(source)->disconnectNotify(slotMethod); //Qt5: QMetaMethod instead of char * + #endif + return true; + } + return false; +} +// @snippet qobject-connect + +// @snippet qobject-connect-1 +// %FUNCTION_NAME() - disable generation of function call. +bool %0 = qobjectConnect(%1, %2, %CPPSELF, %3, %4); +%PYARG_0 = %CONVERTTOPYTHON[bool](%0); +// @snippet qobject-connect-1 + +// @snippet qobject-connect-2 +// %FUNCTION_NAME() - disable generation of function call. +bool %0 = qobjectConnect(%1, %2, %3, %4, %5); +%PYARG_0 = %CONVERTTOPYTHON[bool](%0); +// @snippet qobject-connect-2 + +// @snippet qobject-connect-3 +// %FUNCTION_NAME() - disable generation of function call. +bool %0 = qobjectConnect(%1, %2, %3, %4, %5); +%PYARG_0 = %CONVERTTOPYTHON[bool](%0); +// @snippet qobject-connect-3 + +// @snippet qobject-connect-4 +// %FUNCTION_NAME() - disable generation of function call. +%RETURN_TYPE %0 = qobjectConnectCallback(%1, %2, %PYARG_3, %4); +%PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0); +// @snippet qobject-connect-4 + +// @snippet qobject-connect-5 +// %FUNCTION_NAME() - disable generation of function call. +%RETURN_TYPE %0 = qobjectConnectCallback(%CPPSELF, %1, %PYARG_2, %3); +%PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0); +// @snippet qobject-connect-5 + +// @snippet qobject-connect-6 +// %FUNCTION_NAME() - disable generation of function call. +%RETURN_TYPE %0 = qobjectConnect(%CPPSELF, %1, %2, %3, %4); +%PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0); +// @snippet qobject-connect-6 + +// @snippet qobject-emit +%RETURN_TYPE %0 = PySide::SignalManager::instance().emitSignal(%CPPSELF, %1, %PYARG_2); +%PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0); +// @snippet qobject-emit + +// @snippet qobject-disconnect-1 +// %FUNCTION_NAME() - disable generation of function call. +%RETURN_TYPE %0 = qobjectDisconnectCallback(%CPPSELF, %1, %2); +%PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0); +// @snippet qobject-disconnect-1 + +// @snippet qobject-disconnect-2 +// %FUNCTION_NAME() - disable generation of function call. +%RETURN_TYPE %0 = qobjectDisconnectCallback(%1, %2, %3); +%PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0); +// @snippet qobject-disconnect-2 + +// @snippet qfatal +// qFatal doesn't have a stream version, so we do a +// qWarning call followed by a qFatal() call using a +// literal. +Py_BEGIN_ALLOW_THREADS +qWarning() << %1; +qFatal("[A qFatal() call was made from Python code]"); +Py_END_ALLOW_THREADS +// @snippet qfatal + +// @snippet moduleshutdown +PySide::runCleanupFunctions(); +// @snippet moduleshutdown + +// @snippet qt-qenum +%PYARG_0 = PySide::QEnum::QEnumMacro(%1, false); +// @snippet qt-qenum + +// @snippet qt-qflag +%PYARG_0 = PySide::QEnum::QEnumMacro(%1, true); +// @snippet qt-qflag + +// @snippet qt-init-feature +PySide::Feature::init(); +// @snippet qt-init-feature + +// @snippet qt-pysideinit +Shiboken::Conversions::registerConverterName(SbkPySide6_QtCoreTypeConverters[SBK_QSTRING_IDX], "unicode"); +Shiboken::Conversions::registerConverterName(SbkPySide6_QtCoreTypeConverters[SBK_QSTRING_IDX], "str"); +Shiboken::Conversions::registerConverterName(SbkPySide6_QtCoreTypeConverters[SBK_QTCORE_QLIST_QVARIANT_IDX], "QVariantList"); +Shiboken::Conversions::registerConverterName(SbkPySide6_QtCoreTypeConverters[SBK_QTCORE_QMAP_QSTRING_QVARIANT_IDX], "QVariantMap"); + +PySide::registerInternalQtConf(); +PySide::init(module); +Py_AtExit(QtCoreModuleExit); +// @snippet qt-pysideinit + +// @snippet qt-messagehandler +// Define a global variable to handle qInstallMessageHandler callback +static PyObject *qtmsghandler = nullptr; + +static void msgHandlerCallback(QtMsgType type, const QMessageLogContext &ctx, const QString &msg) +{ + Shiboken::GilState state; + Shiboken::AutoDecRef arglist(PyTuple_New(3)); + PyTuple_SET_ITEM(arglist, 0, %CONVERTTOPYTHON[QtMsgType](type)); + PyTuple_SET_ITEM(arglist, 1, %CONVERTTOPYTHON[QMessageLogContext &](ctx)); + QByteArray array = msg.toUtf8(); // Python handler requires UTF-8 + char *data = array.data(); + PyTuple_SET_ITEM(arglist, 2, %CONVERTTOPYTHON[char *](data)); + Shiboken::AutoDecRef ret(PyObject_CallObject(qtmsghandler, arglist)); +} +static void QtCoreModuleExit() +{ + PySide::SignalManager::instance().clear(); +} +// @snippet qt-messagehandler + +// @snippet qt-installmessagehandler +if (%PYARG_1 == Py_None) { + qInstallMessageHandler(0); + %PYARG_0 = qtmsghandler ? qtmsghandler : Py_None; + qtmsghandler = 0; +} else if (!PyCallable_Check(%PYARG_1)) { + PyErr_SetString(PyExc_TypeError, "parameter must be callable"); +} else { + %PYARG_0 = qtmsghandler ? qtmsghandler : Py_None; + Py_INCREF(%PYARG_1); + qtmsghandler = %PYARG_1; + qInstallMessageHandler(msgHandlerCallback); +} + +if (%PYARG_0 == Py_None) + Py_INCREF(%PYARG_0); +// @snippet qt-installmessagehandler + +// @snippet qline-hash +namespace PySide { + template<> inline Py_ssize_t hash(const QLine &l) + { + const int v[4] = {l.x1(), l.y1(), l.x2(), l.y2()}; + return qHashRange(v, v + 4); + } +}; +// @snippet qline-hash + +// @snippet qlinef-intersect +QPointF p; +%RETURN_TYPE retval = %CPPSELF.%FUNCTION_NAME(%ARGUMENT_NAMES, &p); +%PYARG_0 = PyTuple_New(2); +PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[%RETURN_TYPE](retval)); +PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[QPointF](p)); +// @snippet qlinef-intersect + +// @snippet qresource-data +const void *d = %CPPSELF.%FUNCTION_NAME(); +if (d) { + %PYARG_0 = Shiboken::Buffer::newObject(d, %CPPSELF.size()); +} else { + Py_INCREF(Py_None); + %PYARG_0 = Py_None; +} +// @snippet qresource-data + +// @snippet qdate-topython +if (!PyDateTimeAPI) + PyDateTime_IMPORT; +%PYARG_0 = PyDate_FromDate(%CPPSELF.year(), %CPPSELF.month(), %CPPSELF.day()); +// @snippet qdate-topython + +// @snippet qdate-getdate +int year, month, day; +%CPPSELF.%FUNCTION_NAME(&year, &month, &day); +%PYARG_0 = PyTuple_New(3); +PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[int](year)); +PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[int](month)); +PyTuple_SET_ITEM(%PYARG_0, 2, %CONVERTTOPYTHON[int](day)); +// @snippet qdate-getdate + +// @snippet qdate-weeknumber +int yearNumber; +int week = %CPPSELF.%FUNCTION_NAME(&yearNumber); +%PYARG_0 = PyTuple_New(2); +PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[int](week)); +PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[int](yearNumber)); +// @snippet qdate-weeknumber + +// @snippet qdatetime-1 +QDate date(%1, %2, %3); +QTime time(%4, %5, %6, %7); +%0 = new %TYPE(date, time, Qt::TimeSpec(%8)); +// @snippet qdatetime-1 + +// @snippet qdatetime-2 +QDate date(%1, %2, %3); +QTime time(%4, %5, %6); +%0 = new %TYPE(date, time); +// @snippet qdatetime-2 + +// @snippet qdatetime-topython +QDate date = %CPPSELF.date(); +QTime time = %CPPSELF.time(); +if (!PyDateTimeAPI) + PyDateTime_IMPORT; +%PYARG_0 = PyDateTime_FromDateAndTime(date.year(), date.month(), date.day(), time.hour(), time.minute(), time.second(), time.msec()*1000); +// @snippet qdatetime-topython + +// @snippet qpoint +namespace PySide { + template<> inline Py_ssize_t hash(const QPoint &v) { + return qHash(qMakePair(v.x(), v.y())); + } +}; +// @snippet qpoint + +// @snippet qrect +namespace PySide { + template<> inline Py_ssize_t hash(const QRect &r) { + const int v[4] = {r.x(), r.y(), r.width(), r.height()}; + return qHashRange(v, v + 4); + } +}; +// @snippet qrect + +// @snippet qsize +namespace PySide { + template<> inline Py_ssize_t hash(const QSize &v) { + return qHash(qMakePair(v.width(), v.height())); + } +}; +// @snippet qsize + +// @snippet qtime-topython +if (!PyDateTimeAPI) + PyDateTime_IMPORT; +%PYARG_0 = PyTime_FromTime(%CPPSELF.hour(), %CPPSELF.minute(), %CPPSELF.second(), %CPPSELF.msec()*1000); +// @snippet qtime-topython + +// @snippet qbitarray-len +return %CPPSELF.size(); +// @snippet qbitarray-len + +// @snippet qbitarray-getitem +if (_i < 0 || _i >= %CPPSELF.size()) { + PyErr_SetString(PyExc_IndexError, "index out of bounds"); + return 0; +} +bool ret = %CPPSELF.at(_i); +return %CONVERTTOPYTHON[bool](ret); +// @snippet qbitarray-getitem + +// @snippet qbitarray-setitem +PyObject *args = Py_BuildValue("(iiO)", _i, 1, _value); +PyObject *result = Sbk_QBitArrayFunc_setBit(self, args); +Py_DECREF(args); +Py_XDECREF(result); +return !result ? -1 : 0; +// @snippet qbitarray-setitem + +// @snippet unlock +%CPPSELF.unlock(); +// @snippet unlock + +// @snippet qabstractitemmodel-createindex +%RETURN_TYPE %0 = %CPPSELF.%FUNCTION_NAME(%1, %2, %PYARG_3); +%PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0); +// @snippet qabstractitemmodel-createindex + +// @snippet qabstractitemmodel +qRegisterMetaType<QVector<int> >("QVector<int>"); +// @snippet qabstractitemmodel + +// @snippet qobject-metaobject +%RETURN_TYPE %0 = %CPPSELF.%FUNCTION_NAME(); +%PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0); +// @snippet qobject-metaobject + +// @snippet qobject-findchild-1 +static QObject *_findChildHelper(const QObject *parent, const QString &name, PyTypeObject *desiredType) +{ + for (auto *child : parent->children()) { + Shiboken::AutoDecRef pyChild(%CONVERTTOPYTHON[QObject *](child)); + if (PyType_IsSubtype(Py_TYPE(pyChild), desiredType) + && (name.isNull() || name == child->objectName())) { + return child; + } + } + + for (auto *child : parent->children()) { + QObject *obj = _findChildHelper(child, name, desiredType); + if (obj) + return obj; + } + return nullptr; +} + +static inline bool _findChildrenComparator(const QObject *&child, const QRegularExpression &name) +{ + return name.match(child->objectName()).hasMatch(); +} + +static inline bool _findChildrenComparator(const QObject *&child, const QString &name) +{ + return name.isNull() || name == child->objectName(); +} + +template<typename T> +static void _findChildrenHelper(const QObject *parent, const T& name, PyTypeObject *desiredType, PyObject *result) +{ + for (const auto *child : parent->children()) { + Shiboken::AutoDecRef pyChild(%CONVERTTOPYTHON[QObject *](child)); + if (PyType_IsSubtype(Py_TYPE(pyChild), desiredType) && _findChildrenComparator(child, name)) + PyList_Append(result, pyChild); + _findChildrenHelper(child, name, desiredType, result); + } +} +// @snippet qobject-findchild-1 + +// @snippet qobject-findchild-2 +QObject *child = _findChildHelper(%CPPSELF, %2, reinterpret_cast<PyTypeObject *>(%PYARG_1)); +%PYARG_0 = %CONVERTTOPYTHON[QObject *](child); +// @snippet qobject-findchild-2 + +// @snippet qobject-findchildren +%PYARG_0 = PyList_New(0); +_findChildrenHelper(%CPPSELF, %2, reinterpret_cast<PyTypeObject *>(%PYARG_1), %PYARG_0); +// @snippet qobject-findchildren + +// @snippet qobject-tr +QString result; +if (QCoreApplication::instance()) { + PyObject *klass = PyObject_GetAttr(%PYSELF, Shiboken::PyMagicName::class_()); + PyObject *cname = PyObject_GetAttr(klass, Shiboken::PyMagicName::name()); + result = QString(QCoreApplication::instance()->translate(Shiboken::String::toCString(cname), + /* %1, %2, QCoreApplication::CodecForTr, %3)); */ + %1, %2, %3)); + + Py_DECREF(klass); + Py_DECREF(cname); +} else { + result = QString(QString::fromLatin1(%1)); +} +%PYARG_0 = %CONVERTTOPYTHON[QString](result); +// @snippet qobject-tr + +// @snippet qobject-receivers +// Avoid return +1 because SignalManager connect to "destroyed()" signal to control object timelife +int ret = %CPPSELF.%FUNCTION_NAME(%1); +if (ret > 0 && ((strcmp(%1, SIGNAL(destroyed())) == 0) || (strcmp(%1, SIGNAL(destroyed(QObject*))) == 0))) + ret -= PySide::SignalManager::instance().countConnectionsWith(%CPPSELF); + +%PYARG_0 = %CONVERTTOPYTHON[int](ret); +// @snippet qobject-receivers + +// @snippet qregexp-replace +%1.replace(*%CPPSELF, %2); +%PYARG_0 = %CONVERTTOPYTHON[QString](%1); +// @snippet qregexp-replace + +// @snippet qbytearray-mgetitem +if (PyIndex_Check(_key)) { + Py_ssize_t _i; + _i = PyNumber_AsSsize_t(_key, PyExc_IndexError); + if (_i < 0 || _i >= %CPPSELF.size()) { + PyErr_SetString(PyExc_IndexError, "index out of bounds"); + return 0; + } else { + char res[2]; + res[0] = %CPPSELF.at(_i); + res[1] = 0; + return PyBytes_FromStringAndSize(res, 1); + } +} else if (PySlice_Check(_key)) { + Py_ssize_t start, stop, step, slicelength, cur; + if (PySlice_GetIndicesEx(_key, %CPPSELF.count(), &start, &stop, &step, &slicelength) < 0) { + return nullptr; + } + + QByteArray ba; + if (slicelength <= 0) { + return %CONVERTTOPYTHON[QByteArray](ba); + } else if (step == 1) { + Py_ssize_t max = %CPPSELF.count(); + start = qBound(Py_ssize_t(0), start, max); + stop = qBound(Py_ssize_t(0), stop, max); + QByteArray ba; + if (start < stop) + ba = %CPPSELF.mid(start, stop - start); + return %CONVERTTOPYTHON[QByteArray](ba); + } else { + QByteArray ba; + for (cur = start; slicelength > 0; cur += static_cast<size_t>(step), slicelength--) { + ba.append(%CPPSELF.at(cur)); + } + return %CONVERTTOPYTHON[QByteArray](ba); + } +} else { + PyErr_Format(PyExc_TypeError, + "list indices must be integers or slices, not %.200s", + Py_TYPE(_key)->tp_name); + return nullptr; +} +// @snippet qbytearray-mgetitem + +// @snippet qbytearray-msetitem +if (PyIndex_Check(_key)) { + Py_ssize_t _i = PyNumber_AsSsize_t(_key, PyExc_IndexError); + if (_i == -1 && PyErr_Occurred()) + return -1; + + if (_i < 0) + _i += %CPPSELF.count(); + + if (_i < 0 || _i >= %CPPSELF.size()) { + PyErr_SetString(PyExc_IndexError, "QByteArray index out of range"); + return -1; + } + + // Provide more specific error message for bytes/str, bytearray, QByteArray respectively + if (PyBytes_Check(_value)) { + if (Py_SIZE(_value) != 1) { + PyErr_SetString(PyExc_ValueError, "bytes must be of size 1"); + return -1; + } + } else if (PyByteArray_Check(_value)) { + if (Py_SIZE(_value) != 1) { + PyErr_SetString(PyExc_ValueError, "bytearray must be of size 1"); + return -1; + } + } else if (reinterpret_cast<PyTypeObject *>(Py_TYPE(_value)) == reinterpret_cast<PyTypeObject *>(SbkPySide6_QtCoreTypes[SBK_QBYTEARRAY_IDX])) { + if (PyObject_Length(_value) != 1) { + PyErr_SetString(PyExc_ValueError, "QByteArray must be of size 1"); + return -1; + } + } else { + PyErr_SetString(PyExc_ValueError, "a bytes, bytearray, QByteArray of size 1 is required"); + return -1; + } + + // Not support int or long. + %CPPSELF.remove(_i, 1); + PyObject *args = Py_BuildValue("(nO)", _i, _value); + PyObject *result = Sbk_QByteArrayFunc_insert(self, args); + Py_DECREF(args); + Py_XDECREF(result); + return !result ? -1 : 0; +} else if (PySlice_Check(_key)) { + Py_ssize_t start, stop, step, slicelength, value_length; + if (PySlice_GetIndicesEx(_key, %CPPSELF.count(), &start, &stop, &step, &slicelength) < 0) { + return -1; + } + // The parameter candidates are: bytes/str, bytearray, QByteArray itself. + // Not support iterable which contains ints between 0~255 + + // case 1: value is nullpre, means delete the items within the range + // case 2: step is 1, means shrink or expanse + // case 3: step is not 1, then the number of slots have to equal the number of items in _value + QByteArray ba; + if (_value == nullptr || _value == Py_None) { + ba = QByteArray(); + value_length = 0; + } else if (!(PyBytes_Check(_value) || PyByteArray_Check(_value) || reinterpret_cast<PyTypeObject *>(Py_TYPE(_value)) == reinterpret_cast<PyTypeObject *>(SbkPySide6_QtCoreTypes[SBK_QBYTEARRAY_IDX]))) { + PyErr_Format(PyExc_TypeError, "bytes, bytearray or QByteArray is required, not %.200s", Py_TYPE(_value)->tp_name); + return -1; + } else { + value_length = PyObject_Length(_value); + } + + if (step != 1 && value_length != slicelength) { + PyErr_Format(PyExc_ValueError, "attempt to assign %s of size %d to extended slice of size %d", + Py_TYPE(_value)->tp_name, int(value_length), int(slicelength)); + return -1; + } + + if (step != 1) { + int i = start; + for (int j = 0; j < slicelength; j++) { + PyObject *item = PyObject_GetItem(_value, PyLong_FromLong(j)); + QByteArray temp; + if (PyLong_Check(item)) { + int overflow; + long ival = PyLong_AsLongAndOverflow(item, &overflow); + // Not suppose to bigger than 255 because only bytes, bytearray, QByteArray were accept + temp = QByteArray(reinterpret_cast<const char *>(&ival)); + } else { + temp = %CONVERTTOCPP[QByteArray](item); + } + + %CPPSELF.replace(i, 1, temp); + i += step; + } + return 0; + } else { + ba = %CONVERTTOCPP[QByteArray](_value); + %CPPSELF.replace(start, slicelength, ba); + return 0; + } +} else { + PyErr_Format(PyExc_TypeError, "QBytearray indices must be integers or slices, not %.200s", + Py_TYPE(_key)->tp_name); + return -1; +} +// @snippet qbytearray-msetitem + +// @snippet qbytearray-bufferprotocol +extern "C" { +// QByteArray buffer protocol functions +// see: http://www.python.org/dev/peps/pep-3118/ + +static int SbkQByteArray_getbufferproc(PyObject *obj, Py_buffer *view, int flags) +{ + if (!view || !Shiboken::Object::isValid(obj)) + return -1; + + QByteArray * cppSelf = %CONVERTTOCPP[QByteArray *](obj); + //XXX /|\ omitting this space crashes shiboken! + #ifdef Py_LIMITED_API + view->obj = obj; + view->buf = reinterpret_cast<void *>(cppSelf->data()); + view->len = cppSelf->size(); + view->readonly = 0; + view->itemsize = 1; + view->format = const_cast<char *>("c"); + view->ndim = 1; + view->shape = (flags & PyBUF_ND) == PyBUF_ND ? &(view->len) : nullptr; + view->strides = &view->itemsize; + view->suboffsets = NULL; + view->internal = NULL; + + Py_XINCREF(obj); + return 0; +#else // Py_LIMITED_API + const int result = PyBuffer_FillInfo(view, obj, reinterpret_cast<void *>(cppSelf->data()), + cppSelf->size(), 0, flags); + if (result == 0) + Py_XINCREF(obj); + return result; +#endif +} + +static PyBufferProcs SbkQByteArrayBufferProc = { + /*bf_getbuffer*/ (getbufferproc)SbkQByteArray_getbufferproc, + /*bf_releasebuffer*/ (releasebufferproc)0, +}; + +} +// @snippet qbytearray-bufferprotocol + +// @snippet qbytearray-operatorplus-1 +QByteArray ba = QByteArray(PyBytes_AS_STRING(%PYARG_1), PyBytes_GET_SIZE(%PYARG_1)) + *%CPPSELF; +%PYARG_0 = %CONVERTTOPYTHON[QByteArray](ba); +// @snippet qbytearray-operatorplus-1 + +// @snippet qbytearray-operatorplus-2 +QByteArray ba = QByteArray(PyByteArray_AsString(%PYARG_1), PyByteArray_Size(%PYARG_1)) + *%CPPSELF; +%PYARG_0 = %CONVERTTOPYTHON[QByteArray](ba); +// @snippet qbytearray-operatorplus-2 + +// @snippet qbytearray-operatorplus-3 +QByteArray ba = *%CPPSELF + QByteArray(PyByteArray_AsString(%PYARG_1), PyByteArray_Size(%PYARG_1)); +%PYARG_0 = %CONVERTTOPYTHON[QByteArray](ba); +// @snippet qbytearray-operatorplus-3 + +// @snippet qbytearray-operatorplusequal +*%CPPSELF += QByteArray(PyByteArray_AsString(%PYARG_1), PyByteArray_Size(%PYARG_1)); +// @snippet qbytearray-operatorplusequal + +// @snippet qbytearray-operatorequalequal +if (PyUnicode_CheckExact(%PYARG_1)) { + Shiboken::AutoDecRef data(PyUnicode_AsASCIIString(%PYARG_1)); + QByteArray ba = QByteArray(PyBytes_AsString(data.object()), PyBytes_GET_SIZE(data.object())); + bool cppResult = %CPPSELF == ba; + %PYARG_0 = %CONVERTTOPYTHON[bool](cppResult); +} +// @snippet qbytearray-operatorequalequal + +// @snippet qbytearray-operatornotequal +if (PyUnicode_CheckExact(%PYARG_1)) { + Shiboken::AutoDecRef data(PyUnicode_AsASCIIString(%PYARG_1)); + QByteArray ba = QByteArray(PyBytes_AsString(data.object()), PyBytes_GET_SIZE(data.object())); + bool cppResult = %CPPSELF != ba; + %PYARG_0 = %CONVERTTOPYTHON[bool](cppResult); +} +// @snippet qbytearray-operatornotequal + +// @snippet qbytearray-operatorgreater +if (PyUnicode_CheckExact(%PYARG_1)) { + Shiboken::AutoDecRef data(PyUnicode_AsASCIIString(%PYARG_1)); + QByteArray ba = QByteArray(PyBytes_AsString(data.object()), PyBytes_GET_SIZE(data.object())); + bool cppResult = %CPPSELF > ba; + %PYARG_0 = %CONVERTTOPYTHON[bool](cppResult); +} +// @snippet qbytearray-operatorgreater + +// @snippet qbytearray-operatorgreaterequal +if (PyUnicode_CheckExact(%PYARG_1)) { + Shiboken::AutoDecRef data(PyUnicode_AsASCIIString(%PYARG_1)); + QByteArray ba = QByteArray(PyBytes_AsString(data.object()), PyBytes_GET_SIZE(data.object())); + bool cppResult = %CPPSELF >= ba; + %PYARG_0 = %CONVERTTOPYTHON[bool](cppResult); +} +// @snippet qbytearray-operatorgreaterequal + +// @snippet qbytearray-operatorlower +if (PyUnicode_CheckExact(%PYARG_1)) { + Shiboken::AutoDecRef data(PyUnicode_AsASCIIString(%PYARG_1)); + QByteArray ba = QByteArray(PyBytes_AsString(data.object()), PyBytes_GET_SIZE(data.object())); + bool cppResult = %CPPSELF < ba; + %PYARG_0 = %CONVERTTOPYTHON[bool](cppResult); +} +// @snippet qbytearray-operatorlower + +// @snippet qbytearray-operatorlowerequal +if (PyUnicode_CheckExact(%PYARG_1)) { + Shiboken::AutoDecRef data(PyUnicode_AsASCIIString(%PYARG_1)); + QByteArray ba = QByteArray(PyBytes_AsString(data.object()), PyBytes_GET_SIZE(data.object())); + bool cppResult = %CPPSELF <= ba; + %PYARG_0 = %CONVERTTOPYTHON[bool](cppResult); +} +// @snippet qbytearray-operatorlowerequal + +// @snippet qbytearray-repr +PyObject *aux = PyBytes_FromStringAndSize(%CPPSELF.constData(), %CPPSELF.size()); +if (aux == nullptr) { + return nullptr; +} +QByteArray b(Py_TYPE(%PYSELF)->tp_name); +%PYARG_0 = PyUnicode_FromFormat("%s(%R)", b.constData(), aux); +Py_DECREF(aux); +// @snippet qbytearray-repr + +// @snippet qbytearray-1 +if (PyBytes_Check(%PYARG_1)) { + %0 = new QByteArray(PyBytes_AsString(%PYARG_1), PyBytes_GET_SIZE(%PYARG_1)); +} else if (Shiboken::String::check(%PYARG_1)) { + %0 = new QByteArray(Shiboken::String::toCString(%PYARG_1), Shiboken::String::len(%PYARG_1)); +} +// @snippet qbytearray-1 + +// @snippet qbytearray-2 +%0 = new QByteArray(PyByteArray_AsString(%PYARG_1), PyByteArray_Size(%PYARG_1)); +// @snippet qbytearray-2 + +// @snippet qbytearray-3 +%0 = new QByteArray(PyBytes_AS_STRING(%PYARG_1), PyBytes_GET_SIZE(%PYARG_1)); +// @snippet qbytearray-3 + +// @snippet qbytearray-py3 +PepType_AS_BUFFER(Shiboken::SbkType<QByteArray>()) = &SbkQByteArrayBufferProc; +// @snippet qbytearray-py3 + +// @snippet qbytearray-data +%PYARG_0 = PyBytes_FromStringAndSize(%CPPSELF.%FUNCTION_NAME(), %CPPSELF.size()); +// @snippet qbytearray-data + +// @snippet qbytearray-fromrawdata +%RETURN_TYPE %0 = %CPPSELF.%FUNCTION_NAME(PyBytes_AsString(%PYARG_1), PyBytes_GET_SIZE(%PYARG_1)); +%PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0); +// @snippet qbytearray-fromrawdata + +// @snippet qbytearray-str +PyObject *aux = PyBytes_FromStringAndSize(%CPPSELF.constData(), %CPPSELF.size()); +if (aux == nullptr) { + return nullptr; +} +%PYARG_0 = PyObject_Repr(aux); +Py_DECREF(aux); +// @snippet qbytearray-str + +// @snippet qbytearray-len +return %CPPSELF.count(); +// @snippet qbytearray-len + +// @snippet qbytearray-getitem +if (_i < 0 || _i >= %CPPSELF.size()) { + PyErr_SetString(PyExc_IndexError, "index out of bounds"); + return 0; +} else { + char res[2]; + res[0] = %CPPSELF.at(_i); + res[1] = 0; + return PyBytes_FromStringAndSize(res, 1); +} +// @snippet qbytearray-getitem + +// @snippet qbytearray-setitem +%CPPSELF.remove(_i, 1); +PyObject *args = Py_BuildValue("(nO)", _i, _value); +PyObject *result = Sbk_QByteArrayFunc_insert(self, args); +Py_DECREF(args); +Py_XDECREF(result); +return !result ? -1 : 0; +// @snippet qbytearray-setitem + +// @snippet qfiledevice-unmap +uchar *ptr = reinterpret_cast<uchar *>(Shiboken::Buffer::getPointer(%PYARG_1)); +%RETURN_TYPE %0 = %CPPSELF.%FUNCTION_NAME(ptr); +%PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0); +// @snippet qfiledevice-unmap + +// @snippet qfiledevice-map +%PYARG_0 = Shiboken::Buffer::newObject(%CPPSELF.%FUNCTION_NAME(%1, %2, %3), %2, Shiboken::Buffer::ReadWrite); +// @snippet qfiledevice-map + +// @snippet qiodevice-readdata +QByteArray ba(1 + int(%2), char(0)); +%CPPSELF.%FUNCTION_NAME(ba.data(), int(%2)); +%PYARG_0 = Shiboken::String::fromCString(ba.constData()); +// @snippet qiodevice-readdata + +// @snippet qcryptographichash-adddata +%CPPSELF.%FUNCTION_NAME(Shiboken::String::toCString(%PYARG_1), Shiboken::String::len(%PYARG_1)); +// @snippet qcryptographichash-adddata + +// @snippet qsocketdescriptor +#ifdef WIN32 +using DescriptorType = Qt::HANDLE; +#else +using DescriptorType = int; +#endif +// @snippet qsocketdescriptor + +// @snippet qsocketnotifier +PyObject *socket = %PYARG_1; +if (socket != nullptr) { + // We use qintptr as PyLong, but we check for int + // since it is currently an alias to be Python2 compatible. + // Internally, ints are qlonglongs. + if (%CHECKTYPE[int](socket)) { + int cppSocket = %CONVERTTOCPP[int](socket); + qintptr socket = (qintptr)cppSocket; + %0 = new %TYPE(socket, %2, %3); + } else { + PyErr_SetString(PyExc_TypeError, + "QSocketNotifier: first argument (socket) must be an int."); + } +} +// @snippet qsocketnotifier + +// @snippet qtranslator-load +Py_ssize_t size; +uchar *ptr = reinterpret_cast<uchar *>(Shiboken::Buffer::getPointer(%PYARG_1, &size)); +%RETURN_TYPE %0 = %CPPSELF.%FUNCTION_NAME(const_cast<const uchar *>(ptr), size); +%PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0); +// @snippet qtranslator-load + +// @snippet qtimer-singleshot-1 +// %FUNCTION_NAME() - disable generation of c++ function call +(void) %2; // remove warning about unused variable +Shiboken::AutoDecRef emptyTuple(PyTuple_New(0)); +PyObject *pyTimer = reinterpret_cast<PyTypeObject *>(Shiboken::SbkType<QTimer>())->tp_new(Shiboken::SbkType<QTimer>(), emptyTuple, 0); +reinterpret_cast<PyTypeObject *>(Shiboken::SbkType<QTimer>())->tp_init(pyTimer, emptyTuple, 0); + +auto timer = %CONVERTTOCPP[QTimer *](pyTimer); +//XXX /|\ omitting this space crashes shiboken! +Shiboken::AutoDecRef result( + PyObject_CallMethod(pyTimer, + const_cast<char *>("connect"), + const_cast<char *>("OsOs"), + pyTimer, + SIGNAL(timeout()), + %PYARG_2, + %3) +); +Shiboken::Object::releaseOwnership((SbkObject *)pyTimer); +Py_XDECREF(pyTimer); +timer->setSingleShot(true); +timer->connect(timer, SIGNAL(timeout()), timer, SLOT(deleteLater())); +timer->start(%1); +// @snippet qtimer-singleshot-1 + +// @snippet qtimer-singleshot-2 +// %FUNCTION_NAME() - disable generation of c++ function call +Shiboken::AutoDecRef emptyTuple(PyTuple_New(0)); +PyObject *pyTimer = reinterpret_cast<PyTypeObject *>(Shiboken::SbkType<QTimer>())->tp_new(Shiboken::SbkType<QTimer>(), emptyTuple, 0); +reinterpret_cast<PyTypeObject *>(Shiboken::SbkType<QTimer>())->tp_init(pyTimer, emptyTuple, 0); +QTimer * timer = %CONVERTTOCPP[QTimer *](pyTimer); +timer->setSingleShot(true); + +if (PyObject_TypeCheck(%2, PySideSignalInstanceTypeF())) { + PySideSignalInstance *signalInstance = reinterpret_cast<PySideSignalInstance *>(%2); + Shiboken::AutoDecRef signalSignature(Shiboken::String::fromFormat("2%s", PySide::Signal::getSignature(signalInstance))); + Shiboken::AutoDecRef result( + PyObject_CallMethod(pyTimer, + const_cast<char *>("connect"), + const_cast<char *>("OsOO"), + pyTimer, + SIGNAL(timeout()), + PySide::Signal::getObject(signalInstance), + signalSignature.object()) + ); +} else { + Shiboken::AutoDecRef result( + PyObject_CallMethod(pyTimer, + const_cast<char *>("connect"), + const_cast<char *>("OsO"), + pyTimer, + SIGNAL(timeout()), + %PYARG_2) + ); +} + +timer->connect(timer, SIGNAL(timeout()), timer, SLOT(deleteLater()), Qt::DirectConnection); +Shiboken::Object::releaseOwnership(reinterpret_cast<SbkObject *>(pyTimer)); +Py_XDECREF(pyTimer); +timer->start(%1); +// @snippet qtimer-singleshot-2 + +// @snippet qprocess-startdetached +qint64 pid; +%RETURN_TYPE retval = %TYPE::%FUNCTION_NAME(%1, %2, %3, &pid); +%PYARG_0 = PyTuple_New(2); +PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[%RETURN_TYPE](retval)); +PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[qint64](pid)); +// @snippet qprocess-startdetached + +// @snippet qcoreapplication-init +static void QCoreApplicationConstructor(PyObject *self, PyObject *pyargv, QCoreApplicationWrapper **cptr) +{ + static int argc; + static char **argv; + PyObject *stringlist = PyTuple_GET_ITEM(pyargv, 0); + if (Shiboken::listToArgcArgv(stringlist, &argc, &argv, "PySideApp")) { + *cptr = new QCoreApplicationWrapper(argc, argv); + Shiboken::Object::releaseOwnership(reinterpret_cast<SbkObject *>(self)); + PySide::registerCleanupFunction(&PySide::destroyQCoreApplication); + } +} +// @snippet qcoreapplication-init + +// @snippet qcoreapplication-1 +QCoreApplicationConstructor(%PYSELF, args, &%0); +// @snippet qcoreapplication-1 + +// @snippet qcoreapplication-2 +PyObject *empty = PyTuple_New(2); +if (!PyTuple_SetItem(empty, 0, PyList_New(0))) { + QCoreApplicationConstructor(%PYSELF, empty, &%0); +} +// @snippet qcoreapplication-2 + +// @snippet qcoreapplication-instance +PyObject *pyApp = Py_None; +if (qApp) { + pyApp = reinterpret_cast<PyObject *>( + Shiboken::BindingManager::instance().retrieveWrapper(qApp)); + if (!pyApp) + pyApp = %CONVERTTOPYTHON[QCoreApplication *](qApp); + // this will keep app live after python exit (extra ref) +} +// PYSIDE-571: make sure that we return the singleton "None" +if (Py_TYPE(pyApp) == Py_TYPE(Py_None)) + Py_DECREF(MakeQAppWrapper(nullptr)); +%PYARG_0 = pyApp; +Py_XINCREF(%PYARG_0); +// @snippet qcoreapplication-instance + +// @snippet qdatastream-readrawdata +QByteArray data; +data.resize(%2); +int result = 0; +Py_BEGIN_ALLOW_THREADS +result = %CPPSELF.%FUNCTION_NAME(data.data(), data.size()); +Py_END_ALLOW_THREADS +if (result == -1) { + Py_INCREF(Py_None); + %PYARG_0 = Py_None; +} else { + %PYARG_0 = PyBytes_FromStringAndSize(data.data(), result); +} +// @snippet qdatastream-readrawdata + +// @snippet qdatastream-writerawdata +int r = 0; +Py_BEGIN_ALLOW_THREADS +r = %CPPSELF.%FUNCTION_NAME(%1, Shiboken::String::len(%PYARG_1)); +Py_END_ALLOW_THREADS +%PYARG_0 = %CONVERTTOPYTHON[int](r); +// @snippet qdatastream-writerawdata + +// @snippet releaseownership +Shiboken::Object::releaseOwnership(%PYARG_0); +// @snippet releaseownership + +// @snippet qanimationgroup-clear +for (int counter = 0, count = %CPPSELF.animationCount(); counter < count; ++counter ) { + QAbstractAnimation *animation = %CPPSELF.animationAt(counter); + PyObject *obj = %CONVERTTOPYTHON[QAbstractAnimation *](animation); + Shiboken::Object::setParent(nullptr, obj); + Py_DECREF(obj); +} +%CPPSELF.clear(); +// @snippet qanimationgroup-clear + +// @snippet qeasingcurve +PySideEasingCurveFunctor::init(); +// @snippet qeasingcurve + +// @snippet qeasingcurve-setcustomtype +QEasingCurve::EasingFunction func = PySideEasingCurveFunctor::createCustomFuntion(%PYSELF, %PYARG_1); +if (func) + %CPPSELF.%FUNCTION_NAME(func); +// @snippet qeasingcurve-setcustomtype + +// @snippet qeasingcurve-customtype +//%FUNCTION_NAME() +%PYARG_0 = PySideEasingCurveFunctor::callable(%PYSELF); +// @snippet qeasingcurve-customtype + +// @snippet qsignaltransition +if (PyObject_TypeCheck(%1, PySideSignalInstanceTypeF())) { + PyObject *dataSource = PySide::Signal::getObject((PySideSignalInstance *)%PYARG_1); + Shiboken::AutoDecRef obType(PyObject_Type(dataSource)); + QObject * sender = %CONVERTTOCPP[QObject *](dataSource); + //XXX /|\ omitting this space crashes shiboken! + if (sender) { + const char *dataSignature = PySide::Signal::getSignature((PySideSignalInstance *)%PYARG_1); + QByteArray signature(dataSignature); // Append SIGNAL flag (2) + signature.prepend('2'); + %0 = new QSignalTransitionWrapper(sender, signature, %2); + } +} +// @snippet qsignaltransition + +// @snippet qstate-addtransition-1 +QString signalName(%2); +if (PySide::SignalManager::registerMetaMethod(%1, signalName.mid(1).toLatin1().data(), QMetaMethod::Signal)) { + QSignalTransition *%0 = %CPPSELF->addTransition(%1, %2, %3); + %PYARG_0 = %CONVERTTOPYTHON[QSignalTransition *](%0); +} else { + Py_INCREF(Py_None); + %PYARG_0 = Py_None; +} +// @snippet qstate-addtransition-1 + +// @snippet qstate-addtransition-2 +// Obviously the label used by the following goto is a very awkward solution, +// since it refers to a name very tied to the generator implementation. +// Check bug #362 for more information on this +// http://bugs.openbossa.org/show_bug.cgi?id=362 +if (!PyObject_TypeCheck(%1, PySideSignalInstanceTypeF())) + goto Sbk_%TYPEFunc_%FUNCTION_NAME_TypeError; +PySideSignalInstance *signalInstance = reinterpret_cast<PySideSignalInstance *>(%1); +auto sender = %CONVERTTOCPP[QObject *](PySide::Signal::getObject(signalInstance)); +QSignalTransition *%0 = %CPPSELF->%FUNCTION_NAME(sender, PySide::Signal::getSignature(signalInstance),%2); +%PYARG_0 = %CONVERTTOPYTHON[QSignalTransition *](%0); +// @snippet qstate-addtransition-2 + +// @snippet qstatemachine-configuration +%PYARG_0 = PySet_New(0); +for (auto *abs_state : %CPPSELF.configuration()) { + Shiboken::AutoDecRef obj(%CONVERTTOPYTHON[QAbstractState *](abs_state)); + Shiboken::Object::setParent(self, obj); + PySet_Add(%PYARG_0, obj); +} +// @snippet qstatemachine-configuration + +// @snippet qstatemachine-defaultanimations +%PYARG_0 = PyList_New(0); +for (auto *abs_anim : %CPPSELF.defaultAnimations()) { + Shiboken::AutoDecRef obj(%CONVERTTOPYTHON[QAbstractAnimation *](abs_anim)); + Shiboken::Object::setParent(self, obj); + PyList_Append(%PYARG_0, obj); +} +// @snippet qstatemachine-defaultanimations + +// @snippet qt-signal +%PYARG_0 = Shiboken::String::fromFormat("2%s",QMetaObject::normalizedSignature(%1).constData()); +// @snippet qt-signal + +// @snippet qt-slot +%PYARG_0 = Shiboken::String::fromFormat("1%s",QMetaObject::normalizedSignature(%1).constData()); +// @snippet qt-slot + +// @snippet qt-registerresourcedata +QT_BEGIN_NAMESPACE +extern bool +qRegisterResourceData(int, + const unsigned char *, + const unsigned char *, + const unsigned char *); + +extern bool +qUnregisterResourceData(int, + const unsigned char *, + const unsigned char *, + const unsigned char *); +QT_END_NAMESPACE +// @snippet qt-registerresourcedata + +// @snippet qt-qregisterresourcedata +%RETURN_TYPE %0 = %FUNCTION_NAME(%1, reinterpret_cast<uchar *>(PyBytes_AS_STRING(%PYARG_2)), + reinterpret_cast<uchar *>(PyBytes_AS_STRING(%PYARG_3)), + reinterpret_cast<uchar *>(PyBytes_AS_STRING(%PYARG_4))); +%PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0); +// @snippet qt-qregisterresourcedata + +// @snippet qt-qunregisterresourcedata +%RETURN_TYPE %0 = %FUNCTION_NAME(%1, reinterpret_cast<uchar *>(PyBytes_AS_STRING(%PYARG_2)), + reinterpret_cast<uchar *>(PyBytes_AS_STRING(%PYARG_3)), + reinterpret_cast<uchar *>(PyBytes_AS_STRING(%PYARG_4))); +%PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0); +// @snippet qt-qunregisterresourcedata + +// @snippet use-stream-for-format-security +// Uses the stream version for security reasons +// see gcc man page at -Wformat-security +Py_BEGIN_ALLOW_THREADS +%FUNCTION_NAME() << %1; +Py_END_ALLOW_THREADS +// @snippet use-stream-for-format-security + +// @snippet qresource-registerResource + auto ptr = reinterpret_cast<uchar *>(Shiboken::Buffer::getPointer(%PYARG_1)); + %RETURN_TYPE %0 = %CPPSELF.%FUNCTION_NAME(const_cast<const uchar *>(ptr), %2); + %PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0); +// @snippet qresource-registerResource + +// @snippet qstring-return +%PYARG_0 = %CONVERTTOPYTHON[QString](%1); +// @snippet qstring-return + +// @snippet stream-write-method +Py_BEGIN_ALLOW_THREADS +(*%CPPSELF) << %1; +Py_END_ALLOW_THREADS +// @snippet stream-write-method + +// @snippet stream-read-method +%RETURN_TYPE _cpp_result; +Py_BEGIN_ALLOW_THREADS +(*%CPPSELF) >> _cpp_result; +Py_END_ALLOW_THREADS +%PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](_cpp_result); +// @snippet stream-read-method + +// @snippet return-qstring-ref +QString &res = *%0; +%PYARG_0 = %CONVERTTOPYTHON[QString](res); +// @snippet return-qstring-ref + +// @snippet return-readData +%RETURN_TYPE %0 = 0; +if (PyBytes_Check(%PYARG_0)) { + %0 = PyBytes_GET_SIZE((PyObject *)%PYARG_0); + memcpy(%1, PyBytes_AS_STRING((PyObject *)%PYARG_0), %0); +} else if (Shiboken::String::check(%PYARG_0)) { + %0 = Shiboken::String::len((PyObject *)%PYARG_0); + memcpy(%1, Shiboken::String::toCString((PyObject *)%PYARG_0), %0); +} +// @snippet return-readData + +// @snippet qiodevice-readData +QByteArray ba(1 + int(%2), char(0)); +Py_BEGIN_ALLOW_THREADS +%CPPSELF.%FUNCTION_NAME(ba.data(), int(%2)); +Py_END_ALLOW_THREADS +%PYARG_0 = Shiboken::String::fromCString(ba.constData()); +// @snippet qiodevice-readData + +// @snippet qt-module-shutdown +{ // Avoid name clash + Shiboken::AutoDecRef regFunc(static_cast<PyObject *>(nullptr)); + Shiboken::AutoDecRef atexit(Shiboken::Module::import("atexit")); + if (atexit.isNull()) { + qWarning("Module atexit not found for registering __moduleShutdown"); + PyErr_Clear(); + }else{ + regFunc.reset(PyObject_GetAttrString(atexit, "register")); + if (regFunc.isNull()) { + qWarning("Function atexit.register not found for registering __moduleShutdown"); + PyErr_Clear(); + } + } + if (!atexit.isNull() && !regFunc.isNull()){ + PyObject *shutDownFunc = PyObject_GetAttrString(module, "__moduleShutdown"); + Shiboken::AutoDecRef args(PyTuple_New(1)); + PyTuple_SET_ITEM(args, 0, shutDownFunc); + Shiboken::AutoDecRef retval(PyObject_Call(regFunc, args, 0)); + Q_ASSERT(!retval.isNull()); + } +} +// @snippet qt-module-shutdown + + +/********************************************************************* + * CONVERSIONS + ********************************************************************/ + +// @snippet conversion-pybool +%out = %OUTTYPE(%in == Py_True); +// @snippet conversion-pybool + +// @snippet conversion-pylong +%out = %OUTTYPE(PyLong_AsLong(%in)); +// @snippet conversion-pylong + +// @snippet conversion-pylong-unsigned +%out = %OUTTYPE(PyLong_AsUnsignedLong(%in)); +// @snippet conversion-pylong-unsigned + +// @snippet conversion-pylong-quintptr +#if QT_POINTER_SIZE == 8 +%out = %OUTTYPE(PyLong_AsUnsignedLongLong(%in)); +#else +%out = %OUTTYPE(PyLong_AsUnsignedLong(%in)); +#endif +// @snippet conversion-pylong-quintptr + +// @snippet conversion-pyunicode +#ifndef Py_LIMITED_API +Py_UNICODE *unicode = PyUnicode_AS_UNICODE(%in); +# if defined(Py_UNICODE_WIDE) +// cast as Py_UNICODE can be a different type +# if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) +%out = QString::fromUcs4(reinterpret_cast<const char32_t *>(unicode)); +# else +%out = QString::fromUcs4(reinterpret_cast<const uint *>(unicode)); +# endif // Qt 6 +# else // Py_UNICODE_WIDE +# if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) +%out = QString::fromUtf16(reinterpret_cast<const char16_t *>(unicode), PepUnicode_GetLength(%in)); +# else +%out = QString::fromUtf16(reinterpret_cast<const ushort *>(unicode), PepUnicode_GetLength(%in)); +# endif // Qt 6 +# endif +#else +wchar_t *temp = PyUnicode_AsWideCharString(%in, NULL); +%out = QString::fromWCharArray(temp); +PyMem_Free(temp); +#endif +// @snippet conversion-pyunicode + +// @snippet conversion-pynone +%out = %OUTTYPE(); +// @snippet conversion-pynone + +// @snippet conversion-pystring-char +char c = %CONVERTTOCPP[char](%in); +%out = %OUTTYPE(c); +// @snippet conversion-pystring-char + +// @snippet conversion-pyint +int i = %CONVERTTOCPP[int](%in); +%out = %OUTTYPE(i); +// @snippet conversion-pyint + +// @snippet conversion-qlonglong +// PYSIDE-1250: For QVariant, if the type fits into an int; use int preferably. +qlonglong in = %CONVERTTOCPP[qlonglong](%in); +constexpr qlonglong intMax = qint64(std::numeric_limits<int>::max()); +constexpr qlonglong intMin = qint64(std::numeric_limits<int>::min()); +%out = in >= intMin && in <= intMax ? %OUTTYPE(int(in)) : %OUTTYPE(in); +// @snippet conversion-qlonglong + +// @snippet conversion-qstring +QString in = %CONVERTTOCPP[QString](%in); +%out = %OUTTYPE(in); +// @snippet conversion-qstring + +// @snippet conversion-qbytearray +QByteArray in = %CONVERTTOCPP[QByteArray](%in); +%out = %OUTTYPE(in); +// @snippet conversion-qbytearray + +// @snippet conversion-pyfloat +double in = %CONVERTTOCPP[double](%in); +%out = %OUTTYPE(in); +// @snippet conversion-pyfloat + +// @snippet conversion-sbkobject +// a class supported by QVariant? +const QMetaType metaType = QVariant_resolveMetaType(Py_TYPE(%in)); +if (metaType.isValid()) { + QVariant var(metaType); + Shiboken::Conversions::SpecificConverter converter(metaType.name()); + converter.toCpp(pyIn, var.data()); + %out = var; +} else { + // If the type was not encountered, return a default PyObjectWrapper + %out = QVariant::fromValue(PySide::PyObjectWrapper(%in)); +} +// @snippet conversion-sbkobject + +// @snippet conversion-pydict +QVariant ret = QVariant_convertToVariantMap(%in); +%out = ret.isValid() ? ret : QVariant::fromValue(PySide::PyObjectWrapper(%in)); +// @snippet conversion-pydict + +// @snippet conversion-pylist +QVariant ret = QVariant_convertToVariantList(%in); +%out = ret.isValid() ? ret : QVariant::fromValue(PySide::PyObjectWrapper(%in)); +// @snippet conversion-pylist + +// @snippet conversion-pyobject +// Is a shiboken type not known by Qt +%out = QVariant::fromValue(PySide::PyObjectWrapper(%in)); +// @snippet conversion-pyobject + +// @snippet conversion-qjsonobject-pydict +QVariant dict = QVariant_convertToVariantMap(%in); +QJsonValue val = QJsonValue::fromVariant(dict); +%out = val.toObject(); +// @snippet conversion-qjsonobject-pydict + +// @snippet conversion-qpair-pysequence +%out.first = %CONVERTTOCPP[%OUTTYPE_0](PySequence_Fast_GET_ITEM(%in, 0)); +%out.second = %CONVERTTOCPP[%OUTTYPE_1](PySequence_Fast_GET_ITEM(%in, 1)); +// @snippet conversion-qpair-pysequence + +// @snippet conversion-qdate-pydate +int day = PyDateTime_GET_DAY(%in); +int month = PyDateTime_GET_MONTH(%in); +int year = PyDateTime_GET_YEAR(%in); +%out = %OUTTYPE(year, month, day); +// @snippet conversion-qdate-pydate + +// @snippet conversion-qdatetime-pydatetime +int day = PyDateTime_GET_DAY(%in); +int month = PyDateTime_GET_MONTH(%in); +int year = PyDateTime_GET_YEAR(%in); +int hour = PyDateTime_DATE_GET_HOUR(%in); +int min = PyDateTime_DATE_GET_MINUTE(%in); +int sec = PyDateTime_DATE_GET_SECOND(%in); +int usec = PyDateTime_DATE_GET_MICROSECOND(%in); +%out = %OUTTYPE(QDate(year, month, day), QTime(hour, min, sec, usec/1000)); +// @snippet conversion-qdatetime-pydatetime + +// @snippet conversion-qtime-pytime +int hour = PyDateTime_TIME_GET_HOUR(%in); +int min = PyDateTime_TIME_GET_MINUTE(%in); +int sec = PyDateTime_TIME_GET_SECOND(%in); +int usec = PyDateTime_TIME_GET_MICROSECOND(%in); +%out = %OUTTYPE(hour, min, sec, usec/1000); +// @snippet conversion-qtime-pytime + +// @snippet conversion-qbytearray-pybytes +%out = %OUTTYPE(PyBytes_AS_STRING(%in), PyBytes_GET_SIZE(%in)); +// @snippet conversion-qbytearray-pybytes + +// @snippet conversion-qbytearray-pybytearray +%out = %OUTTYPE(PyByteArray_AsString(%in), PyByteArray_Size(%in)); +// @snippet conversion-qbytearray-pybytearray + +// @snippet conversion-qbytearray-pystring +%out = %OUTTYPE(Shiboken::String::toCString(%in), Shiboken::String::len(%in)); +// @snippet conversion-qbytearray-pystring + +/********************************************************************* + * NATIVE TO TARGET CONVERSIONS + ********************************************************************/ + +// @snippet return-pybool +return PyBool_FromLong((bool)%in); +// @snippet return-pybool + +// @snippet return-pybytes +return PyBytes_FromStringAndSize(%in.constData(), %in.size()); +// @snippet return-pybytes + +// @snippet return-pylong +return PyLong_FromLong(%in); +// @snippet return-pylong + +// @snippet return-pylong-unsigned +return PyLong_FromUnsignedLong(%in); +// @snippet return-pylong-unsigned + +// @snippet return-pylong-quintptr +#if QT_POINTER_SIZE == 8 +return PyLong_FromUnsignedLongLong(%in); +#else +return PyLong_FromUnsignedLong(%in); +#endif +// @snippet return-pylong-quintptr + +// @snippet return-pyunicode +QByteArray ba = %in.toUtf8(); +return PyUnicode_FromStringAndSize(ba.constData(), ba.size()); +// @snippet return-pyunicode + +// @snippet return-pyunicode-qchar +wchar_t c = (wchar_t)%in.unicode(); +return PyUnicode_FromWideChar(&c, 1); +// @snippet return-pyunicode-qchar + +// @snippet return-qvariant +if (!%in.isValid()) + Py_RETURN_NONE; + +if (qstrcmp(%in.typeName(), "QVariantList") == 0) { + QList<QVariant> var = %in.value<QVariantList>(); + return %CONVERTTOPYTHON[QList<QVariant>](var); +} + +if (qstrcmp(%in.typeName(), "QStringList") == 0) { + QStringList var = %in.value<QStringList>(); + return %CONVERTTOPYTHON[QList<QString>](var); +} + +if (qstrcmp(%in.typeName(), "QVariantMap") == 0) { + QMap<QString, QVariant> var = %in.value<QVariantMap>(); + return %CONVERTTOPYTHON[QMap<QString, QVariant>](var); +} + +Shiboken::Conversions::SpecificConverter converter(cppInRef.typeName()); +if (converter) { + void *ptr = cppInRef.data(); + return converter.toPython(ptr); +} +PyErr_Format(PyExc_RuntimeError, "Can't find converter for '%s'.", %in.typeName()); +return 0; +// @snippet return-qvariant + +// @snippet return-qvariant-type +const char *typeName = QMetaType(%in).name(); +PyObject *%out; +PyTypeObject *pyType = nullptr; +if (typeName) + pyType = Shiboken::Conversions::getPythonTypeObject(typeName); +%out = pyType ? (reinterpret_cast<PyObject *>(pyType)) : Py_None; +Py_INCREF(%out); +return %out; +// @snippet return-qvariant-type + +// @snippet return-qjsonobject +// The QVariantMap returned by QJsonObject seems to cause a segfault, so +// using QJsonObject.toVariantMap() won't work. +// Wrapping it in a QJsonValue first allows it to work +QJsonValue val(%in); +QVariant ret = val.toVariant(); + +return %CONVERTTOPYTHON[QVariant](ret); +// @snippet return-qjsonobject + +// @snippet return-qpair +PyObject *%out = PyTuple_New(2); +PyTuple_SET_ITEM(%out, 0, %CONVERTTOPYTHON[%INTYPE_0](%in.first)); +PyTuple_SET_ITEM(%out, 1, %CONVERTTOPYTHON[%INTYPE_1](%in.second)); +return %out; +// @snippet return-qpair + +// @snippet qthread_pthread_cleanup +#ifdef Q_OS_UNIX +# include <stdio.h> +# include <pthread.h> +static void qthread_pthread_cleanup(void *arg) +{ + // PYSIDE 1282: When terminating a thread using QThread::terminate() + // (pthread_cancel()), QThread::run() is aborted and the lock is released, + // but ~GilState() is still executed for some reason. Prevent it from + // releasing. + auto gil = reinterpret_cast<Shiboken::GilState *>(arg); + gil->abandon(); +} +#endif // Q_OS_UNIX +// @snippet qthread_pthread_cleanup + +// @snippet qthread_pthread_cleanup_install +#ifdef Q_OS_UNIX +pthread_cleanup_push(qthread_pthread_cleanup, &gil); +#endif +// @snippet qthread_pthread_cleanup_install + +// @snippet qthread_pthread_cleanup_uninstall +#ifdef Q_OS_UNIX +pthread_cleanup_pop(0); +#endif +// @snippet qthread_pthread_cleanup_uninstall + +// @snippet qlibraryinfo_build +#if defined(Py_LIMITED_API) +auto suffix = PyUnicode_FromString(" [limited API]"); +auto oldResult = pyResult; +pyResult = PyUnicode_Concat(pyResult, suffix); +Py_DECREF(oldResult); +Py_DECREF(suffix); +#endif +// @snippet qlibraryinfo_build |