diff options
25 files changed, 821 insertions, 1315 deletions
diff --git a/sources/pyside2/PySide2/QtCore/CMakeLists.txt b/sources/pyside2/PySide2/QtCore/CMakeLists.txt index 745d50083..08604aa87 100644 --- a/sources/pyside2/PySide2/QtCore/CMakeLists.txt +++ b/sources/pyside2/PySide2/QtCore/CMakeLists.txt @@ -181,14 +181,8 @@ ${QtCore_GEN_DIR}/qtcore_module_wrapper.cpp ) set(QtCore_glue_sources - "${QtCore_SOURCE_DIR}/glue/qbytearray_bufferprotocol.cpp" - "${QtCore_SOURCE_DIR}/glue/qbytearray_mgetitem.cpp" - "${QtCore_SOURCE_DIR}/glue/qbytearray_msetitem.cpp" - "${QtCore_SOURCE_DIR}/glue/qcoreapplication_init.cpp" "${QtCore_SOURCE_DIR}/glue/qeasingcurve_glue.cpp" "${QtCore_SOURCE_DIR}/glue/qeasingcurve_glue.h" - "${QtCore_SOURCE_DIR}/glue/qobject_connect.cpp" - "${QtCore_SOURCE_DIR}/glue/qobject_findchild.cpp" ) configure_file("${QtCore_SOURCE_DIR}/typesystem_core.xml.in" diff --git a/sources/pyside2/PySide2/QtCore/glue/qbytearray_bufferprotocol.cpp b/sources/pyside2/PySide2/QtCore/glue/qbytearray_bufferprotocol.cpp deleted file mode 100644 index ed5fef3ae..000000000 --- a/sources/pyside2/PySide2/QtCore/glue/qbytearray_bufferprotocol.cpp +++ /dev/null @@ -1,73 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 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$ -** -****************************************************************************/ - -#if PY_VERSION_HEX < 0x03000000 - -// QByteArray buffer protocol functions -// see: http://www.python.org/dev/peps/pep-3118/ - -extern "C" { - -static Py_ssize_t SbkQByteArray_segcountproc(PyObject* self, Py_ssize_t* lenp) -{ - if (lenp) - *lenp = Py_TYPE(self)->tp_as_sequence->sq_length(self); - return 1; -} - -static Py_ssize_t SbkQByteArray_readbufferproc(PyObject* self, Py_ssize_t segment, void** ptrptr) -{ - if (segment || !Shiboken::Object::isValid(self)) - return -1; - - QByteArray* cppSelf = %CONVERTTOCPP[QByteArray*](self); - *ptrptr = reinterpret_cast<void*>(cppSelf->data()); - return cppSelf->size(); -} - -PyBufferProcs SbkQByteArrayBufferProc = { - /*bf_getreadbuffer*/ &SbkQByteArray_readbufferproc, - /*bf_getwritebuffer*/ (writebufferproc) &SbkQByteArray_readbufferproc, - /*bf_getsegcount*/ &SbkQByteArray_segcountproc, - /*bf_getcharbuffer*/ (charbufferproc) &SbkQByteArray_readbufferproc -}; - -} - -#endif diff --git a/sources/pyside2/PySide2/QtCore/glue/qbytearray_mgetitem.cpp b/sources/pyside2/PySide2/QtCore/glue/qbytearray_mgetitem.cpp deleted file mode 100644 index 9612f41b0..000000000 --- a/sources/pyside2/PySide2/QtCore/glue/qbytearray_mgetitem.cpp +++ /dev/null @@ -1,87 +0,0 @@ -/**************************************************************************** -** -** 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$ -** -****************************************************************************/ - -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; - -#ifdef IS_PY3K - PyObject *key = _key; -#else - PySliceObject *key = reinterpret_cast<PySliceObject *>(_key); -#endif - if (PySlice_GetIndicesEx(key, %CPPSELF.count(), &start, &stop, &step, &slicelength) < 0) { - return NULL; - } - - 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 NULL; -} diff --git a/sources/pyside2/PySide2/QtCore/glue/qbytearray_msetitem.cpp b/sources/pyside2/PySide2/QtCore/glue/qbytearray_msetitem.cpp deleted file mode 100644 index 1349f40f1..000000000 --- a/sources/pyside2/PySide2/QtCore/glue/qbytearray_msetitem.cpp +++ /dev/null @@ -1,158 +0,0 @@ -/**************************************************************************** -** -** 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$ -** -****************************************************************************/ - -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 -#ifdef IS_PY3K - if (PyBytes_Check(_value)) { - if (Py_SIZE(_value) != 1) { - PyErr_SetString(PyExc_ValueError, "bytes must be of size 1"); -#else - if (PyString_CheckExact(_value)) { - if (Py_SIZE(_value) != 1) { - PyErr_SetString(PyExc_ValueError, "str must be of size 1"); -#endif - 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 *>(SbkPySide2_QtCoreTypes[SBK_QBYTEARRAY_IDX])) { - if (PyObject_Length(_value) != 1) { - PyErr_SetString(PyExc_ValueError, "QByteArray must be of size 1"); - return -1; - } - } else { -#ifdef IS_PY3K - PyErr_SetString(PyExc_ValueError, "a bytes, bytearray, QByteArray of size 1 is required"); -#else - PyErr_SetString(PyExc_ValueError, "a str, bytearray, QByteArray of size 1 is required"); -#endif - 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; - -#ifdef IS_PY3K - PyObject *key = _key; -#else - PySliceObject *key = reinterpret_cast<PySliceObject *>(_key); -#endif - 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 NULL, 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 == NULL || _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 *>(SbkPySide2_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, value_length, 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; -#ifdef IS_PY3K - if (PyLong_Check(item)) { -#else - if (PyLong_Check(item) || PyInt_Check(item)) { -#endif - int overflow; - long ival = PyLong_AsLongAndOverflow(item, &overflow); - // Not suppose to bigger than 255 because only bytes, bytearray, QByteArray were accept - const char *el = reinterpret_cast<const char*>(&ival); - temp = QByteArray(el); - } 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; -} - - diff --git a/sources/pyside2/PySide2/QtCore/glue/qcoreapplication_init.cpp b/sources/pyside2/PySide2/QtCore/glue/qcoreapplication_init.cpp deleted file mode 100644 index 9bdaa011e..000000000 --- a/sources/pyside2/PySide2/QtCore/glue/qcoreapplication_init.cpp +++ /dev/null @@ -1,50 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 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$ -** -****************************************************************************/ - -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); - } -} diff --git a/sources/pyside2/PySide2/QtCore/glue/qobject_connect.cpp b/sources/pyside2/PySide2/QtCore/glue/qobject_connect.cpp deleted file mode 100644 index 20f3720bf..000000000 --- a/sources/pyside2/PySide2/QtCore/glue/qobject_connect.cpp +++ /dev/null @@ -1,227 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 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$ -** -****************************************************************************/ - -static bool isDecorator(PyObject* method, PyObject* self) -{ - Shiboken::AutoDecRef methodName(PyObject_GetAttrString(method, "__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 = 0; - *self = 0; - } - - 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; - } - - if (usingGlobalReceiver) { - PySide::SignalManager& signalManager = PySide::SignalManager::instance(); - *receiver = signalManager.globalReceiver(source, callback); - *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; - Py_BEGIN_ALLOW_THREADS - connection = QObject::connect(source, signal - 1, receiver, slot - 1, type); - Py_END_ALLOW_THREADS - 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 = 0; - PyObject* self = 0; - QByteArray callbackSig; - bool usingGlobalReceiver = getReceiver(source, signal, callback, &receiver, &self, &callbackSig); - if (receiver == 0 && self == 0) - 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((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; - Py_BEGIN_ALLOW_THREADS - connection = QMetaObject::connect(source, signalIndex, receiver, slotIndex, type); - Py_END_ALLOW_THREADS - 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 = 0; - PyObject* self = 0; - QByteArray callbackSig; - QMetaMethod slotMethod; - bool usingGlobalReceiver = getReceiver(NULL, signal, callback, &receiver, &self, &callbackSig); - if (receiver == 0 && self == 0) - 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; - Py_BEGIN_ALLOW_THREADS - disconnected = QMetaObject::disconnectOne(source, signalIndex, receiver, slotIndex); - Py_END_ALLOW_THREADS - - 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; -} diff --git a/sources/pyside2/PySide2/QtCore/glue/qobject_findchild.cpp b/sources/pyside2/PySide2/QtCore/glue/qobject_findchild.cpp deleted file mode 100644 index b32d104fd..000000000 --- a/sources/pyside2/PySide2/QtCore/glue/qobject_findchild.cpp +++ /dev/null @@ -1,78 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 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$ -** -****************************************************************************/ - -static QObject* _findChildHelper(const QObject* parent, const QString& name, PyTypeObject* desiredType) -{ - foreach(QObject* child, parent->children()) { - Shiboken::AutoDecRef pyChild(%CONVERTTOPYTHON[QObject*](child)); - if (PyType_IsSubtype(Py_TYPE(pyChild), desiredType) - && (name.isNull() || name == child->objectName())) { - return child; - } - } - - QObject* obj; - foreach(QObject* child, parent->children()) { - obj = _findChildHelper(child, name, desiredType); - if (obj) - return obj; - } - return 0; -} - -static inline bool _findChildrenComparator(const QObject*& child, const QRegExp& name) -{ - return name.indexIn(child->objectName()) != -1; -} - -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) -{ - foreach(const QObject* 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); - } -} diff --git a/sources/pyside2/PySide2/QtCore/typesystem_core_common.xml b/sources/pyside2/PySide2/QtCore/typesystem_core_common.xml index ca9a56c6e..25f5c3e65 100644 --- a/sources/pyside2/PySide2/QtCore/typesystem_core_common.xml +++ b/sources/pyside2/PySide2/QtCore/typesystem_core_common.xml @@ -1607,7 +1607,7 @@ </modify-argument> <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qobject-connect-3"/> </modify-function> - <inject-code class="native" position="beginning" file="glue/qobject_connect.cpp"/> + <inject-code class="native" position="beginning" file="../glue/qtcore.cpp" snippet="qobject-connect"/> <add-function signature="connect(const QObject*,const char*,PyCallable*,Qt::ConnectionType)" return-type="bool" static="yes"> <modify-argument index="4"> <rename to="type"/> @@ -1642,7 +1642,7 @@ </add-function> - <inject-code class="native" file="glue/qobject_findchild.cpp"/> + <inject-code class="native" file="../glue/qtcore.cpp" snippet="qobject-findchild-1"/> <add-function signature="findChild(PyTypeObject*,const QString&)" return-type="PyObject*"> <inject-documentation format="target" mode="append"> To find the child of a certain QObject, the first argument of this function should be the child's type, and the second the name of the child: @@ -1657,7 +1657,7 @@ child2 = parent.findChild(QWidget, "child_widget") </inject-documentation> - <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qobject-findchild"/> + <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qobject-findchild-2"/> <modify-argument index="return"> <parent index="this" action="add"/> </modify-argument> @@ -1961,7 +1961,7 @@ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qbytearray-3"/> </add-function> <!-- buffer protocol --> - <inject-code class="native" position="beginning" file="glue/qbytearray_bufferprotocol.cpp"/> + <inject-code class="native" position="beginning" file="../glue/qtcore.cpp" snippet="qbytearray-bufferprotocol"/> <inject-code class="target" position="end" file="../glue/qtcore.cpp" snippet="qbytearray-py3"/> <modify-function signature="data()"> @@ -2114,13 +2114,13 @@ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qbytearray-getitem"/> </add-function> <add-function signature="__mgetitem__"> - <inject-code class="target" position="beginning" file="glue/qbytearray_mgetitem.cpp"/> + <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qbytearray-mgetitem"/> </add-function> <add-function signature="__setitem__"> <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qbytearray-setitem"/> </add-function> <add-function signature="__msetitem__"> - <inject-code class="target" position="beginning" file="glue/qbytearray_msetitem.cpp"/> + <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qbytearray-msetitem"/> </add-function> </value-type> <value-type name="QTextBoundaryFinder"> @@ -2515,7 +2515,7 @@ <modify-argument index="2" invalidate-after-use="yes"/> </modify-function> <modify-function signature="QCoreApplication(int &,char **,int)" access="private"/> - <inject-code class="native" file="glue/qcoreapplication_init.cpp" position="beginning"/> + <inject-code class="native" position="beginning" file="../glue/qtcore.cpp" snippet="qcoreapplication-init"/> <modify-function signature="postEvent(QObject*,QEvent*,int)"> <modify-argument index="2"> <define-ownership owner="c++"/> diff --git a/sources/pyside2/PySide2/QtGui/CMakeLists.txt b/sources/pyside2/PySide2/QtGui/CMakeLists.txt index 1e5366733..38768ab0a 100644 --- a/sources/pyside2/PySide2/QtGui/CMakeLists.txt +++ b/sources/pyside2/PySide2/QtGui/CMakeLists.txt @@ -222,10 +222,6 @@ else() message(STATUS "Qt5Gui: Adding Desktop OpenGL classes") endif() -set(QtGui_glue_sources - "${QtGui_SOURCE_DIR}/glue/qguiapplication_init.cpp" -) - configure_file("${QtGui_SOURCE_DIR}/typesystem_gui.xml.in" "${QtGui_BINARY_DIR}/typesystem_gui.xml" @ONLY) @@ -257,7 +253,7 @@ create_pyside_module(QtGui QPYTEXTOBJECT_MOC ${QtGui_BINARY_DIR}/typesystem_gui.xml QtGui_DROPPED_ENTRIES - QtGui_glue_sources) + "") install(FILES ${pyside2_SOURCE_DIR}/qpytextobject.h DESTINATION include/PySide2/QtGui/) diff --git a/sources/pyside2/PySide2/QtGui/glue/qguiapplication_init.cpp b/sources/pyside2/PySide2/QtGui/glue/qguiapplication_init.cpp deleted file mode 100644 index ae5dd22d2..000000000 --- a/sources/pyside2/PySide2/QtGui/glue/qguiapplication_init.cpp +++ /dev/null @@ -1,50 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 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$ -** -****************************************************************************/ - -static void QGuiApplicationConstructor(PyObject *self, PyObject *pyargv, QGuiApplicationWrapper **cptr) -{ - static int argc; - static char **argv; - PyObject *stringlist = PyTuple_GET_ITEM(pyargv, 0); - if (Shiboken::listToArgcArgv(stringlist, &argc, &argv, "PySideApp")) { - *cptr = new QGuiApplicationWrapper(argc, argv, 0); - Shiboken::Object::releaseOwnership(reinterpret_cast<SbkObject*>(self)); - PySide::registerCleanupFunction(&PySide::destroyQCoreApplication); - } -} diff --git a/sources/pyside2/PySide2/QtGui/typesystem_gui_common.xml b/sources/pyside2/PySide2/QtGui/typesystem_gui_common.xml index f417b8e74..d7bdf0412 100644 --- a/sources/pyside2/PySide2/QtGui/typesystem_gui_common.xml +++ b/sources/pyside2/PySide2/QtGui/typesystem_gui_common.xml @@ -2534,7 +2534,7 @@ <add-function signature="QGuiApplication()"> <inject-code file="../glue/qtgui.cpp" snippet="qguiapplication-2"/> </add-function> - <inject-code class="native" file="glue/qguiapplication_init.cpp" position="beginning"/> + <inject-code class="native" position="beginning" file="../glue/qtgui.cpp" snippet="qguiapplication-init"/> </object-type> diff --git a/sources/pyside2/PySide2/QtUiTools/CMakeLists.txt b/sources/pyside2/PySide2/QtUiTools/CMakeLists.txt index bedbf74af..0040c000e 100644 --- a/sources/pyside2/PySide2/QtUiTools/CMakeLists.txt +++ b/sources/pyside2/PySide2/QtUiTools/CMakeLists.txt @@ -8,7 +8,6 @@ ${QtUiTools_GEN_DIR}/qtuitools_module_wrapper.cpp set(QtUiTools_glue_sources "${QtUiTools_SOURCE_DIR}/glue/plugins.h" - "${QtUiTools_SOURCE_DIR}/glue/uitools_loadui.cpp" ) set(QtUiTools_include_dirs ${QtUiTools_SOURCE_DIR} diff --git a/sources/pyside2/PySide2/QtUiTools/glue/uitools_loadui.cpp b/sources/pyside2/PySide2/QtUiTools/glue/uitools_loadui.cpp deleted file mode 100644 index c078eacee..000000000 --- a/sources/pyside2/PySide2/QtUiTools/glue/uitools_loadui.cpp +++ /dev/null @@ -1,91 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 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$ -** -****************************************************************************/ - -/* - * Based on code provided by: - * Antonio Valentino <antonio.valentino at tiscali.it> - * Frédéric <frederic.mantegazza at gbiloba.org> - */ - -#include <shiboken.h> -#include <QUiLoader> -#include <QFile> -#include <QWidget> - -static void createChildrenNameAttributes(PyObject* root, QObject* object) -{ - foreach (QObject* child, object->children()) { - const QByteArray name = child->objectName().toLocal8Bit(); - - if (!name.isEmpty() && !name.startsWith("_") && !name.startsWith("qt_")) { - bool hasAttr = PyObject_HasAttrString(root, name.constData()); - if (!hasAttr) { - Shiboken::AutoDecRef pyChild(%CONVERTTOPYTHON[QObject*](child)); - PyObject_SetAttrString(root, name.constData(), pyChild); - } - createChildrenNameAttributes(root, child); - } - createChildrenNameAttributes(root, child); - } -} - -static PyObject* QUiLoadedLoadUiFromDevice(QUiLoader* self, QIODevice* dev, QWidget* parent) -{ - QWidget* wdg = self->load(dev, parent); - - if (wdg) { - PyObject* pyWdg = %CONVERTTOPYTHON[QWidget*](wdg); - createChildrenNameAttributes(pyWdg, wdg); - if (parent) { - Shiboken::AutoDecRef pyParent(%CONVERTTOPYTHON[QWidget*](parent)); - Shiboken::Object::setParent(pyParent, pyWdg); - } - return pyWdg; - } - - if (!PyErr_Occurred()) - PyErr_SetString(PyExc_RuntimeError, "Unable to open/read ui device"); - return 0; -} - -static PyObject* QUiLoaderLoadUiFromFileName(QUiLoader* self, const QString& uiFile, QWidget* parent) -{ - QFile fd(uiFile); - return QUiLoadedLoadUiFromDevice(self, &fd, parent); -} diff --git a/sources/pyside2/PySide2/QtUiTools/typesystem_uitools.xml b/sources/pyside2/PySide2/QtUiTools/typesystem_uitools.xml index 648a38cd5..8086da01e 100644 --- a/sources/pyside2/PySide2/QtUiTools/typesystem_uitools.xml +++ b/sources/pyside2/PySide2/QtUiTools/typesystem_uitools.xml @@ -48,7 +48,7 @@ <extra-includes> <include file-name="glue/plugins.h" location="local"/> </extra-includes> - <inject-code class="native" position="beginning" file="glue/uitools_loadui.cpp"/> + <inject-code class="native" position="beginning" file="../glue/qtuitools.cpp" snippet="uitools-loadui"/> <inject-code file="../glue/qtuitools.cpp" snippet="quiloader"/> <add-function signature="registerCustomWidget(PyObject*)" return-type="void"> <modify-argument index="1"> diff --git a/sources/pyside2/PySide2/QtWidgets/CMakeLists.txt b/sources/pyside2/PySide2/QtWidgets/CMakeLists.txt index 78db04ded..5f10d5988 100644 --- a/sources/pyside2/PySide2/QtWidgets/CMakeLists.txt +++ b/sources/pyside2/PySide2/QtWidgets/CMakeLists.txt @@ -207,14 +207,6 @@ ${SPECIFIC_OS_FILES} ${QtWidgets_GEN_DIR}/qtwidgets_module_wrapper.cpp ) -set(QtWidgets_glue_sources - "${QtWidgets_SOURCE_DIR}/glue/qapplication_init.cpp" - "${QtWidgets_SOURCE_DIR}/glue/qlayout_help_functions.cpp" - "${QtWidgets_SOURCE_DIR}/glue/qmenu_glue.cpp" - "${QtWidgets_SOURCE_DIR}/glue/qmenubar_glue.cpp" - "${QtWidgets_SOURCE_DIR}/glue/qwidget_glue.cpp" -) - configure_file("${QtWidgets_SOURCE_DIR}/typesystem_widgets.xml.in" "${QtWidgets_BINARY_DIR}/typesystem_widgets.xml" @ONLY) @@ -248,4 +240,4 @@ create_pyside_module(QtWidgets "" ${QtWidgets_BINARY_DIR}/typesystem_widgets.xml "" - QtWidgets_glue_sources) + "") diff --git a/sources/pyside2/PySide2/QtWidgets/glue/qapplication_init.cpp b/sources/pyside2/PySide2/QtWidgets/glue/qapplication_init.cpp deleted file mode 100644 index aef11f2c7..000000000 --- a/sources/pyside2/PySide2/QtWidgets/glue/qapplication_init.cpp +++ /dev/null @@ -1,50 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 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$ -** -****************************************************************************/ - -static void QApplicationConstructor(PyObject *self, PyObject *pyargv, QApplicationWrapper **cptr) -{ - static int argc; - static char **argv; - PyObject *stringlist = PyTuple_GET_ITEM(pyargv, 0); - if (Shiboken::listToArgcArgv(stringlist, &argc, &argv, "PySideApp")) { - *cptr = new QApplicationWrapper(argc, argv, 0); - Shiboken::Object::releaseOwnership(reinterpret_cast<SbkObject*>(self)); - PySide::registerCleanupFunction(&PySide::destroyQCoreApplication); - } -} diff --git a/sources/pyside2/PySide2/QtWidgets/glue/qlayout_help_functions.cpp b/sources/pyside2/PySide2/QtWidgets/glue/qlayout_help_functions.cpp deleted file mode 100644 index d542b881c..000000000 --- a/sources/pyside2/PySide2/QtWidgets/glue/qlayout_help_functions.cpp +++ /dev/null @@ -1,161 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 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$ -** -****************************************************************************/ - -void addLayoutOwnership(QLayout* layout, QLayoutItem* item); -void removeLayoutOwnership(QLayout* layout, QWidget* widget); - -inline QByteArray retrieveObjectName(PyObject* obj) -{ - Shiboken::AutoDecRef objName(PyObject_Str(obj)); - return Shiboken::String::toCString(objName); -} - -inline void addLayoutOwnership(QLayout* layout, QWidget* widget) -{ - //transfer ownership to parent widget - QWidget *lw = layout->parentWidget(); - QWidget *pw = widget->parentWidget(); - - Shiboken::AutoDecRef pyChild(%CONVERTTOPYTHON[QWidget*](widget)); - - //Transfer parent to layout widget - if (pw && lw && pw != lw) - Shiboken::Object::setParent(0, pyChild); - - if (!lw && !pw) { - //keep the reference while the layout is orphan - Shiboken::AutoDecRef pyParent(%CONVERTTOPYTHON[QWidget*](layout)); - Shiboken::Object::keepReference(reinterpret_cast<SbkObject*>(pyParent.object()), retrieveObjectName(pyParent).data(), pyChild, true); - } else { - if (!lw) - lw = pw; - Shiboken::AutoDecRef pyParent(%CONVERTTOPYTHON[QWidget*](lw)); - Shiboken::Object::setParent(pyParent, pyChild); - } -} - -inline void addLayoutOwnership(QLayout* layout, QLayout* other) -{ - //transfer all children widgets from other to layout parent widget - QWidget* parent = layout->parentWidget(); - if (!parent) { - //keep the reference while the layout is orphan - Shiboken::AutoDecRef pyParent(%CONVERTTOPYTHON[QLayout*](layout)); - Shiboken::AutoDecRef pyChild(%CONVERTTOPYTHON[QLayout*](other)); - Shiboken::Object::keepReference(reinterpret_cast<SbkObject*>(pyParent.object()), retrieveObjectName(pyParent).data(), pyChild, true); - return; - } - - for (int i=0, i_max=other->count(); i < i_max; i++) { - QLayoutItem* item = other->itemAt(i); - if (PyErr_Occurred() || !item) - return; - addLayoutOwnership(layout, item); - } - - Shiboken::AutoDecRef pyParent(%CONVERTTOPYTHON[QLayout*](layout)); - Shiboken::AutoDecRef pyChild(%CONVERTTOPYTHON[QLayout*](other)); - Shiboken::Object::setParent(pyParent, pyChild); -} - -inline void addLayoutOwnership(QLayout* layout, QLayoutItem* item) -{ - if (!item) - return; - - QWidget* w = item->widget(); - if (w) - addLayoutOwnership(layout, w); - else { - QLayout* l = item->layout(); - if (l) - addLayoutOwnership(layout, l); - } - - Shiboken::AutoDecRef pyParent(%CONVERTTOPYTHON[QLayout*](layout)); - Shiboken::AutoDecRef pyChild(%CONVERTTOPYTHON[QLayoutItem*](item)); - Shiboken::Object::setParent(pyParent, pyChild); -} - -static void removeWidgetFromLayout(QLayout* layout, QWidget* widget) -{ - QWidget* parent = widget->parentWidget(); - - if (!parent) { - //remove reference on layout - Shiboken::AutoDecRef pyParent(%CONVERTTOPYTHON[QWidget*](layout)); - Shiboken::AutoDecRef pyChild(%CONVERTTOPYTHON[QWidget*](widget)); - Shiboken::Object::removeReference(reinterpret_cast<SbkObject*>(pyParent.object()), retrieveObjectName(pyParent).data(), pyChild); - } else { - //give the ownership to parent - Shiboken::AutoDecRef pyParent(%CONVERTTOPYTHON[QWidget*](parent)); - Shiboken::AutoDecRef pyChild(%CONVERTTOPYTHON[QWidget*](widget)); - Shiboken::Object::setParent(pyParent, pyChild); - } -} - -inline void removeLayoutOwnership(QLayout* layout, QLayoutItem* item) -{ - QWidget* w = item->widget(); - if (w) - removeWidgetFromLayout(layout, w); - else { - QLayout* l = item->layout(); - if (l && item != l) - removeLayoutOwnership(layout, l); - } - - Shiboken::AutoDecRef pyChild(%CONVERTTOPYTHON[QLayoutItem*](item)); - Shiboken::Object::invalidate(pyChild); - Shiboken::Object::setParent(0, pyChild); -} - -inline void removeLayoutOwnership(QLayout* layout, QWidget* widget) -{ - if (!widget) - return; - - for (int i=0, i_max=layout->count(); i < i_max; i++) { - QLayoutItem* item = layout->itemAt(i); - if (PyErr_Occurred() || !item) - return; - if (item->widget() == widget) - removeLayoutOwnership(layout, item); - } -} diff --git a/sources/pyside2/PySide2/QtWidgets/glue/qmenu_glue.cpp b/sources/pyside2/PySide2/QtWidgets/glue/qmenu_glue.cpp deleted file mode 100644 index 4e9c8c3b7..000000000 --- a/sources/pyside2/PySide2/QtWidgets/glue/qmenu_glue.cpp +++ /dev/null @@ -1,64 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 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$ -** -****************************************************************************/ - -inline PyObject* addActionWithPyObject(QMenu* self, const QIcon& icon, const QString& text, PyObject* callback, const QKeySequence& shortcut) -{ - QAction* act = new QAction(text, self); - - if (!icon.isNull()) - act->setIcon(icon); - - if (!shortcut.isEmpty()) - act->setShortcut(shortcut); - - self->addAction(act); - - PyObject* pyAct = %CONVERTTOPYTHON[QAction*](act); - Shiboken::AutoDecRef result(PyObject_CallMethod(pyAct, - const_cast<char *>("connect"), - const_cast<char *>("OsO"), - pyAct, - SIGNAL(triggered()), callback)); - if (result.isNull()) { - Py_DECREF(pyAct); - return 0; - } - - return pyAct; -} diff --git a/sources/pyside2/PySide2/QtWidgets/glue/qmenubar_glue.cpp b/sources/pyside2/PySide2/QtWidgets/glue/qmenubar_glue.cpp deleted file mode 100644 index 8cdbc2e01..000000000 --- a/sources/pyside2/PySide2/QtWidgets/glue/qmenubar_glue.cpp +++ /dev/null @@ -1,62 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 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$ -** -****************************************************************************/ - -inline PyObject* -addActionWithPyObject(QMenuBar* self, const QString& text, PyObject* callback) -{ - QAction* act = new QAction(text, self); - - self->addAction(act); - - PyObject* pyAct = %CONVERTTOPYTHON[QAction*](act); - PyObject* result = PyObject_CallMethod(pyAct, - const_cast<char *>("connect"), - const_cast<char *>("OsO"), - pyAct, - SIGNAL(triggered(bool)), callback); - - if (result == 0 || result == Py_False) { - if (result) - Py_DECREF(result); - Py_DECREF(pyAct); - return 0; - } - - return pyAct; -} diff --git a/sources/pyside2/PySide2/QtWidgets/glue/qwidget_glue.cpp b/sources/pyside2/PySide2/QtWidgets/glue/qwidget_glue.cpp deleted file mode 100644 index 674e34cfe..000000000 --- a/sources/pyside2/PySide2/QtWidgets/glue/qwidget_glue.cpp +++ /dev/null @@ -1,104 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 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$ -** -****************************************************************************/ - -static QString retrieveObjectName(PyObject *obj) -{ - Shiboken::AutoDecRef objName(PyObject_Str(obj)); - return QString(Shiboken::String::toCString(objName)); -} - - -/** - * Tranfer objects ownership from layout to widget - **/ -static inline void qwidgetReparentLayout(QWidget *parent, QLayout *layout) -{ - Shiboken::AutoDecRef pyParent(%CONVERTTOPYTHON[QWidget*](parent)); - - for (int i=0; i < layout->count(); i++) { - QLayoutItem* item = layout->itemAt(i); - if (PyErr_Occurred() || !item) - return; - - QWidget* w = item->widget(); - if (w) { - QWidget* pw = w->parentWidget(); - if (pw != parent) { - Shiboken::AutoDecRef pyChild(%CONVERTTOPYTHON[QWidget*](w)); - Shiboken::Object::setParent(pyParent, pyChild); - } - } else { - QLayout* l = item->layout(); - if (l) - qwidgetReparentLayout(parent, l); - } - } - - Shiboken::AutoDecRef pyChild(%CONVERTTOPYTHON[QLayout*](layout)); - Shiboken::Object::setParent(pyParent, pyChild); - //remove previous references - Shiboken::Object::keepReference(reinterpret_cast<SbkObject*>(pyChild.object()), qPrintable(retrieveObjectName(pyChild)), Py_None); -} - -static inline void qwidgetSetLayout(QWidget *self, QLayout *layout) -{ - if (!layout || self->layout()) - return; - - QObject* oldParent = layout->parent(); - if (oldParent && oldParent != self) { - if (oldParent->isWidgetType()) { - // remove old parent policy - Shiboken::AutoDecRef pyLayout(%CONVERTTOPYTHON[QLayout*](layout)); - Shiboken::Object::setParent(Py_None, pyLayout); - } else { - PyErr_Format(PyExc_RuntimeError, "QWidget::setLayout: Attempting to set QLayout \"%s\" on %s \"%s\", when the QLayout already has a parent", - qPrintable(layout->objectName()), self->metaObject()->className(), qPrintable(self->objectName())); - return; - } - } - - if (oldParent != self) { - qwidgetReparentLayout(self, layout); - if (PyErr_Occurred()) - return; - - self->setLayout(layout); - } -} diff --git a/sources/pyside2/PySide2/QtWidgets/typesystem_widgets_common.xml b/sources/pyside2/PySide2/QtWidgets/typesystem_widgets_common.xml index d22d694cc..13cc6f7cf 100644 --- a/sources/pyside2/PySide2/QtWidgets/typesystem_widgets_common.xml +++ b/sources/pyside2/PySide2/QtWidgets/typesystem_widgets_common.xml @@ -800,7 +800,7 @@ </modify-function> </object-type> <object-type name="QMenu"> - <inject-code class="native" position="beginning" file="glue/qmenu_glue.cpp"/> + <inject-code class="native" position="beginning" file="../glue/qtwidgets.cpp" snippet="qmenu-glue"/> <modify-function signature="exec()" rename="exec_" allow-thread="yes"/> <modify-function signature="exec(const QPoint&,QAction*)" rename="exec_" allow-thread="yes"/> @@ -882,7 +882,7 @@ </object-type> <object-type name="QMenuBar"> - <inject-code class="native" position="beginning" file="glue/qmenubar_glue.cpp"/> + <inject-code class="native" position="beginning" file="../glue/qtwidgets.cpp" snippet="qmenubar-glue"/> <modify-function signature="addAction(const QString&)"> <modify-argument index="return"> <parent index="this" action="add"/> @@ -1247,7 +1247,7 @@ </object-type> <object-type name="QLayout"> - <inject-code class="native" position="beginning" file="glue/qlayout_help_functions.cpp"/> + <inject-code class="native" position="beginning" file="../glue/qtwidgets.cpp" snippet="qlayout-help-functions"/> <enum-type name="SizeConstraint"/> @@ -1332,7 +1332,7 @@ </object-type> <object-type name="QStackedLayout"> - <inject-code class="native" position="beginning" file="glue/qlayout_help_functions.cpp"/> + <inject-code class="native" position="beginning" file="../glue/qtwidgets.cpp" snippet="qlayout-help-functions"/> <enum-type name="StackingMode"/> <modify-function signature="insertWidget(int,QWidget*)"> <inject-code class="target" position="beginning" file="../glue/qtwidgets.cpp" snippet="addownership-2"/> @@ -1340,7 +1340,7 @@ </object-type> <object-type name="QBoxLayout"> - <inject-code class="native" position="beginning" file="glue/qlayout_help_functions.cpp"/> + <inject-code class="native" position="beginning" file="../glue/qtwidgets.cpp" snippet="qlayout-help-functions"/> <enum-type name="Direction"/> @@ -1370,7 +1370,7 @@ </object-type> <object-type name="QGridLayout"> - <inject-code class="native" position="beginning" file="glue/qlayout_help_functions.cpp"/> + <inject-code class="native" position="beginning" file="../glue/qtwidgets.cpp" snippet="qlayout-help-functions"/> <modify-function signature="itemAtPosition (int,int)const"> <modify-argument index="return"> <define-ownership owner="default"/> @@ -2028,7 +2028,7 @@ <include file-name="QMessageBox" location="global"/> </extra-includes> - <inject-code class="native" file="glue/qwidget_glue.cpp" position="beginning"/> + <inject-code class="native" position="beginning" file="../glue/qtwidgets.cpp" snippet="qwidget-glue"/> <enum-type name="RenderFlag" flags="RenderFlags"/> @@ -2947,7 +2947,7 @@ <inject-code class="target" position="end" file="../glue/qtwidgets.cpp" snippet="qapplication-setStyle"/> </modify-function> <modify-function signature="exec()" rename="exec_" allow-thread="yes"/> - <inject-code class="native" file="glue/qapplication_init.cpp" position="beginning"/> + <inject-code class="native" position="beginning" file="../glue/qtwidgets.cpp" snippet="qapplication-init"/> </object-type> <object-type name="QCommandLinkButton"/> @@ -2960,7 +2960,7 @@ </modify-function> </object-type> <object-type name="QFormLayout"> - <inject-code class="native" position="beginning" file="glue/qlayout_help_functions.cpp"/> + <inject-code class="native" position="beginning" file="../glue/qtwidgets.cpp" snippet="qlayout-help-functions"/> <enum-type name="FieldGrowthPolicy"/> <enum-type name="ItemRole"/> diff --git a/sources/pyside2/PySide2/glue/qtcore.cpp b/sources/pyside2/PySide2/glue/qtcore.cpp index 73b9476d1..47895bdda 100644 --- a/sources/pyside2/PySide2/glue/qtcore.cpp +++ b/sources/pyside2/PySide2/glue/qtcore.cpp @@ -75,7 +75,7 @@ static const char *QVariant_resolveMetaType(PyTypeObject *type, int *typeId) } // Do not resolve types to value type if (valueType) - return 0; + return nullptr; // 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. @@ -93,7 +93,7 @@ static const char *QVariant_resolveMetaType(PyTypeObject *type, int *typeId) } } *typeId = 0; - return 0; + return nullptr; } static QVariant QVariant_convertToValueList(PyObject *list) { @@ -224,8 +224,8 @@ static QStack<PyObject*> globalPostRoutineFunctions; void globalPostRoutineCallback() { Shiboken::GilState state; - foreach (PyObject *callback, globalPostRoutineFunctions) { - Shiboken::AutoDecRef result(PyObject_CallObject(callback, NULL)); + for (auto *callback : globalPostRoutineFunctions) { + Shiboken::AutoDecRef result(PyObject_CallObject(callback, nullptr)); Py_DECREF(callback); } globalPostRoutineFunctions.clear(); @@ -259,6 +259,197 @@ 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_GetAttrString(method, "__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; + } + + if (usingGlobalReceiver) { + PySide::SignalManager& signalManager = PySide::SignalManager::instance(); + *receiver = signalManager.globalReceiver(source, callback); + *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; + Py_BEGIN_ALLOW_THREADS + connection = QObject::connect(source, signal - 1, receiver, slot - 1, type); + Py_END_ALLOW_THREADS + 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((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; + Py_BEGIN_ALLOW_THREADS + connection = QMetaObject::connect(source, signalIndex, receiver, slotIndex, type); + Py_END_ALLOW_THREADS + 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; + Py_BEGIN_ALLOW_THREADS + disconnected = QMetaObject::disconnectOne(source, signalIndex, receiver, slotIndex); + Py_END_ALLOW_THREADS + + 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); @@ -514,10 +705,51 @@ qRegisterMetaType<QVector<int> >("QVector<int>"); %PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0); // @snippet qobject-metaobject -// @snippet qobject-findchild +// @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 QRegExp& name) +{ + return name.indexIn(child->objectName()) != -1; +} + +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, (PyTypeObject*)%PYARG_1); %PYARG_0 = %CONVERTTOPYTHON[QObject*](child); -// @snippet qobject-findchild +// @snippet qobject-findchild-2 // @snippet qobject-findchildren-1 %PYARG_0 = PyList_New(0); @@ -560,6 +792,214 @@ if (ret > 0 && ((strcmp(%1, SIGNAL(destroyed())) == 0) || (strcmp(%1, SIGNAL(des %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; + +#ifdef IS_PY3K + PyObject *key = _key; +#else + PySliceObject *key = reinterpret_cast<PySliceObject *>(_key); +#endif + 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 +#ifdef IS_PY3K + if (PyBytes_Check(_value)) { + if (Py_SIZE(_value) != 1) { + PyErr_SetString(PyExc_ValueError, "bytes must be of size 1"); +#else + if (PyString_CheckExact(_value)) { + if (Py_SIZE(_value) != 1) { + PyErr_SetString(PyExc_ValueError, "str must be of size 1"); +#endif + 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 *>(SbkPySide2_QtCoreTypes[SBK_QBYTEARRAY_IDX])) { + if (PyObject_Length(_value) != 1) { + PyErr_SetString(PyExc_ValueError, "QByteArray must be of size 1"); + return -1; + } + } else { +#ifdef IS_PY3K + PyErr_SetString(PyExc_ValueError, "a bytes, bytearray, QByteArray of size 1 is required"); +#else + PyErr_SetString(PyExc_ValueError, "a str, bytearray, QByteArray of size 1 is required"); +#endif + 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; + +#ifdef IS_PY3K + PyObject *key = _key; +#else + PySliceObject *key = reinterpret_cast<PySliceObject *>(_key); +#endif + 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 *>(SbkPySide2_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, value_length, 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; +#ifdef IS_PY3K + if (PyLong_Check(item)) { +#else + if (PyLong_Check(item) || PyInt_Check(item)) { +#endif + int overflow; + long ival = PyLong_AsLongAndOverflow(item, &overflow); + // Not suppose to bigger than 255 because only bytes, bytearray, QByteArray were accept + const char *el = reinterpret_cast<const char*>(&ival); + temp = QByteArray(el); + } 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 +#if PY_VERSION_HEX < 0x03000000 + +// QByteArray buffer protocol functions +// see: http://www.python.org/dev/peps/pep-3118/ + +extern "C" { + +static Py_ssize_t SbkQByteArray_segcountproc(PyObject* self, Py_ssize_t* lenp) +{ + if (lenp) + *lenp = Py_TYPE(self)->tp_as_sequence->sq_length(self); + return 1; +} + +static Py_ssize_t SbkQByteArray_readbufferproc(PyObject* self, Py_ssize_t segment, void** ptrptr) +{ + if (segment || !Shiboken::Object::isValid(self)) + return -1; + + QByteArray* cppSelf = %CONVERTTOCPP[QByteArray*](self); + *ptrptr = reinterpret_cast<void*>(cppSelf->data()); + return cppSelf->size(); +} + +PyBufferProcs SbkQByteArrayBufferProc = { + /*bf_getreadbuffer*/ &SbkQByteArray_readbufferproc, + /*bf_getwritebuffer*/ (writebufferproc) &SbkQByteArray_readbufferproc, + /*bf_getsegcount*/ &SbkQByteArray_segcountproc, + /*bf_getcharbuffer*/ (charbufferproc) &SbkQByteArray_readbufferproc +}; + +} + +#endif +// @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); @@ -635,8 +1075,8 @@ if (PyUnicode_CheckExact(%PYARG_1)) { // @snippet qbytearray-repr PyObject *aux = PyBytes_FromStringAndSize(%CPPSELF.constData(), %CPPSELF.size()); -if (aux == NULL) { - return NULL; +if (aux == nullptr) { + return nullptr; } QByteArray b(Py_TYPE(%PYSELF)->tp_name); #ifdef IS_PY3K @@ -685,8 +1125,8 @@ if (PyBytes_Check(%PYARG_1)) { // @snippet qbytearray-str PyObject *aux = PyBytes_FromStringAndSize(%CPPSELF.constData(), %CPPSELF.size()); -if (aux == NULL) { - return NULL; +if (aux == nullptr) { + return nullptr; } #ifdef IS_PY3K %PYARG_0 = PyObject_Repr(aux); @@ -845,6 +1285,20 @@ long result; %PYARG_0 = %CONVERTTOPYTHON[long](result); // @snippet qprocess-pid +// @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 @@ -959,7 +1413,7 @@ QSignalTransition *%0 = %CPPSELF->%FUNCTION_NAME(sender, PySide::Signal::getSign // @snippet qstatemachine-configuration %PYARG_0 = PySet_New(0); -foreach (QAbstractState *abs_state, %CPPSELF.configuration()) { +for (auto *abs_state : %CPPSELF.configuration()) { Shiboken::AutoDecRef obj(%CONVERTTOPYTHON[QAbstractState*](abs_state)); Shiboken::Object::setParent(self, obj); PySet_Add(%PYARG_0, obj); @@ -968,7 +1422,7 @@ foreach (QAbstractState *abs_state, %CPPSELF.configuration()) { // @snippet qstatemachine-defaultanimations %PYARG_0 = PyList_New(0); -foreach (QAbstractAnimation *abs_anim, %CPPSELF.defaultAnimations()) { +for (auto *abs_anim : %CPPSELF.defaultAnimations()) { Shiboken::AutoDecRef obj(%CONVERTTOPYTHON[QAbstractAnimation*](abs_anim)); Shiboken::Object::setParent(self, obj); PyList_Append(%PYARG_0, obj); diff --git a/sources/pyside2/PySide2/glue/qtgui.cpp b/sources/pyside2/PySide2/glue/qtgui.cpp index 759d0a85a..a34bcff43 100644 --- a/sources/pyside2/PySide2/glue/qtgui.cpp +++ b/sources/pyside2/PySide2/glue/qtgui.cpp @@ -117,7 +117,7 @@ if (doc) { // @snippet qpolygon-reduce PyObject *points = PyList_New(%CPPSELF.count()); -for (int i = 0, max = %CPPSELF.count(); i < max; ++i){ +for (int i = 0, i_max = %CPPSELF.count(); i < i_max; ++i){ int x, y; %CPPSELF.point(i, &x, &y); QPoint pt = QPoint(x, y); @@ -485,6 +485,20 @@ PyErr_SetString(PyExc_IndexError, "Invalid matrix index."); return 0; // @snippet qmatrix4x4-mgetitem +// @snippet qguiapplication-init +static void QGuiApplicationConstructor(PyObject *self, PyObject *pyargv, QGuiApplicationWrapper **cptr) +{ + static int argc; + static char **argv; + PyObject *stringlist = PyTuple_GET_ITEM(pyargv, 0); + if (Shiboken::listToArgcArgv(stringlist, &argc, &argv, "PySideApp")) { + *cptr = new QGuiApplicationWrapper(argc, argv, 0); + Shiboken::Object::releaseOwnership(reinterpret_cast<SbkObject*>(self)); + PySide::registerCleanupFunction(&PySide::destroyQCoreApplication); + } +} +// @snippet qguiapplication-init + // @snippet qguiapplication-1 QGuiApplicationConstructor(%PYSELF, args, &%0); // @snippet qguiapplication-1 diff --git a/sources/pyside2/PySide2/glue/qtuitools.cpp b/sources/pyside2/PySide2/glue/qtuitools.cpp index 0a2feb262..d0469e97d 100644 --- a/sources/pyside2/PySide2/glue/qtuitools.cpp +++ b/sources/pyside2/PySide2/glue/qtuitools.cpp @@ -36,6 +36,59 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ +// @snippet uitools-loadui +/* + * Based on code provided by: + * Antonio Valentino <antonio.valentino at tiscali.it> + * Frédéric <frederic.mantegazza at gbiloba.org> + */ + +#include <shiboken.h> +#include <QUiLoader> +#include <QFile> +#include <QWidget> + +static void createChildrenNameAttributes(PyObject* root, QObject* object) +{ + for (auto *child : object->children()) { + const QByteArray name = child->objectName().toLocal8Bit(); + + if (!name.isEmpty() && !name.startsWith("_") && !name.startsWith("qt_")) { + if (!PyObject_HasAttrString(root, name.constData())) { + Shiboken::AutoDecRef pyChild(%CONVERTTOPYTHON[QObject*](child)); + PyObject_SetAttrString(root, name.constData(), pyChild); + } + createChildrenNameAttributes(root, child); + } + createChildrenNameAttributes(root, child); + } +} + +static PyObject* QUiLoadedLoadUiFromDevice(QUiLoader* self, QIODevice* dev, QWidget* parent) +{ + QWidget* wdg = self->load(dev, parent); + + if (wdg) { + PyObject* pyWdg = %CONVERTTOPYTHON[QWidget*](wdg); + createChildrenNameAttributes(pyWdg, wdg); + if (parent) { + Shiboken::AutoDecRef pyParent(%CONVERTTOPYTHON[QWidget*](parent)); + Shiboken::Object::setParent(pyParent, pyWdg); + } + return pyWdg; + } + + if (!PyErr_Occurred()) + PyErr_SetString(PyExc_RuntimeError, "Unable to open/read ui device"); + return nullptr; +} + +static PyObject* QUiLoaderLoadUiFromFileName(QUiLoader* self, const QString& uiFile, QWidget* parent) +{ + QFile fd(uiFile); + return QUiLoadedLoadUiFromDevice(self, &fd, parent); +} +// @snippet uitools-loadui // @snippet quiloader Q_IMPORT_PLUGIN(PyCustomWidgets); diff --git a/sources/pyside2/PySide2/glue/qtwidgets.cpp b/sources/pyside2/PySide2/glue/qtwidgets.cpp index 7ec0ca266..b44be183d 100644 --- a/sources/pyside2/PySide2/glue/qtwidgets.cpp +++ b/sources/pyside2/PySide2/glue/qtwidgets.cpp @@ -110,6 +110,34 @@ PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[%RETURN_TYPE](retval_)); PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[%ARG5_TYPE](%5)); // @snippet qfiledialog-return +// @snippet qmenu-glue +inline PyObject* addActionWithPyObject(QMenu* self, const QIcon& icon, const QString& text, PyObject* callback, const QKeySequence& shortcut) +{ + QAction* act = self->addAction(text); + + if (!icon.isNull()) + act->setIcon(icon); + + if (!shortcut.isEmpty()) + act->setShortcut(shortcut); + + self->addAction(act); + + PyObject* pyAct = %CONVERTTOPYTHON[QAction*](act); + Shiboken::AutoDecRef result(PyObject_CallMethod(pyAct, + const_cast<char *>("connect"), + const_cast<char *>("OsO"), + pyAct, + SIGNAL(triggered()), callback)); + if (result.isNull()) { + Py_DECREF(pyAct); + return nullptr; + } + + return pyAct; +} +// @snippet qmenu-glue + // @snippet qmenu-addaction-1 %PYARG_0 = addActionWithPyObject(%CPPSELF, QIcon(), %1, %2, %3); // @snippet qmenu-addaction-1 @@ -125,7 +153,7 @@ PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[%ARG5_TYPE](%5)); // @snippet qmenu-clear Shiboken::BindingManager& bm = Shiboken::BindingManager::instance(); const auto &actions = %CPPSELF.actions(); -for (QAction *act : actions) { +for (auto *act : actions) { if (auto wrapper = bm.retrieveWrapper(act)) { auto pyObj = reinterpret_cast<PyObject *>(wrapper); Py_INCREF(pyObj); @@ -136,9 +164,35 @@ for (QAction *act : actions) { } // @snippet qmenu-clear +// @snippet qmenubar-glue +inline PyObject* +addActionWithPyObject(QMenuBar* self, const QString& text, PyObject* callback) +{ + QAction* act = self->addAction(text); + + self->addAction(act); + + PyObject* pyAct = %CONVERTTOPYTHON[QAction*](act); + PyObject* result = PyObject_CallMethod(pyAct, + const_cast<char *>("connect"), + const_cast<char *>("OsO"), + pyAct, + SIGNAL(triggered(bool)), callback); + + if (result == nullptr || result == Py_False) { + if (result) + Py_DECREF(result); + Py_DECREF(pyAct); + return nullptr; + } + + return pyAct; +} +// @snippet qmenubar-glue + // @snippet qmenubar-clear const auto &actions = %CPPSELF.actions(); -for (QAction *act : actions) { +for (auto *act : actions) { Shiboken::AutoDecRef pyAct(%CONVERTTOPYTHON[QAction*](act)); Shiboken::Object::setParent(NULL, pyAct); Shiboken::Object::invalidate(pyAct); @@ -175,6 +229,131 @@ if (_widget) { } // @snippet qtoolbox-removeitem +// @snippet qlayout-help-functions +void addLayoutOwnership(QLayout* layout, QLayoutItem* item); +void removeLayoutOwnership(QLayout* layout, QWidget* widget); + +inline QByteArray retrieveObjectName(PyObject* obj) +{ + Shiboken::AutoDecRef objName(PyObject_Str(obj)); + return Shiboken::String::toCString(objName); +} + +inline void addLayoutOwnership(QLayout* layout, QWidget* widget) +{ + //transfer ownership to parent widget + QWidget *lw = layout->parentWidget(); + QWidget *pw = widget->parentWidget(); + + Shiboken::AutoDecRef pyChild(%CONVERTTOPYTHON[QWidget*](widget)); + + //Transfer parent to layout widget + if (pw && lw && pw != lw) + Shiboken::Object::setParent(0, pyChild); + + if (!lw && !pw) { + //keep the reference while the layout is orphan + Shiboken::AutoDecRef pyParent(%CONVERTTOPYTHON[QWidget*](layout)); + Shiboken::Object::keepReference(reinterpret_cast<SbkObject*>(pyParent.object()), retrieveObjectName(pyParent).data(), pyChild, true); + } else { + if (!lw) + lw = pw; + Shiboken::AutoDecRef pyParent(%CONVERTTOPYTHON[QWidget*](lw)); + Shiboken::Object::setParent(pyParent, pyChild); + } +} + +inline void addLayoutOwnership(QLayout* layout, QLayout* other) +{ + //transfer all children widgets from other to layout parent widget + QWidget* parent = layout->parentWidget(); + if (!parent) { + //keep the reference while the layout is orphan + Shiboken::AutoDecRef pyParent(%CONVERTTOPYTHON[QLayout*](layout)); + Shiboken::AutoDecRef pyChild(%CONVERTTOPYTHON[QLayout*](other)); + Shiboken::Object::keepReference(reinterpret_cast<SbkObject*>(pyParent.object()), retrieveObjectName(pyParent).data(), pyChild, true); + return; + } + + for (int i=0, i_max=other->count(); i < i_max; i++) { + QLayoutItem* item = other->itemAt(i); + if (PyErr_Occurred() || !item) + return; + addLayoutOwnership(layout, item); + } + + Shiboken::AutoDecRef pyParent(%CONVERTTOPYTHON[QLayout*](layout)); + Shiboken::AutoDecRef pyChild(%CONVERTTOPYTHON[QLayout*](other)); + Shiboken::Object::setParent(pyParent, pyChild); +} + +inline void addLayoutOwnership(QLayout* layout, QLayoutItem* item) +{ + if (!item) + return; + + QWidget* w = item->widget(); + if (w) + addLayoutOwnership(layout, w); + else { + QLayout* l = item->layout(); + if (l) + addLayoutOwnership(layout, l); + } + + Shiboken::AutoDecRef pyParent(%CONVERTTOPYTHON[QLayout*](layout)); + Shiboken::AutoDecRef pyChild(%CONVERTTOPYTHON[QLayoutItem*](item)); + Shiboken::Object::setParent(pyParent, pyChild); +} + +static void removeWidgetFromLayout(QLayout* layout, QWidget* widget) +{ + QWidget* parent = widget->parentWidget(); + + if (!parent) { + //remove reference on layout + Shiboken::AutoDecRef pyParent(%CONVERTTOPYTHON[QWidget*](layout)); + Shiboken::AutoDecRef pyChild(%CONVERTTOPYTHON[QWidget*](widget)); + Shiboken::Object::removeReference(reinterpret_cast<SbkObject*>(pyParent.object()), retrieveObjectName(pyParent).data(), pyChild); + } else { + //give the ownership to parent + Shiboken::AutoDecRef pyParent(%CONVERTTOPYTHON[QWidget*](parent)); + Shiboken::AutoDecRef pyChild(%CONVERTTOPYTHON[QWidget*](widget)); + Shiboken::Object::setParent(pyParent, pyChild); + } +} + +inline void removeLayoutOwnership(QLayout* layout, QLayoutItem* item) +{ + QWidget* w = item->widget(); + if (w) + removeWidgetFromLayout(layout, w); + else { + QLayout* l = item->layout(); + if (l && item != l) + removeLayoutOwnership(layout, l); + } + + Shiboken::AutoDecRef pyChild(%CONVERTTOPYTHON[QLayoutItem*](item)); + Shiboken::Object::invalidate(pyChild); + Shiboken::Object::setParent(0, pyChild); +} + +inline void removeLayoutOwnership(QLayout* layout, QWidget* widget) +{ + if (!widget) + return; + + for (int i=0, i_max=layout->count(); i < i_max; i++) { + QLayoutItem* item = layout->itemAt(i); + if (PyErr_Occurred() || !item) + return; + if (item->widget() == widget) + removeLayoutOwnership(layout, item); + } +} +// @snippet qlayout-help-functions + // @snippet qlayout-setalignment %CPPSELF.setAlignment(%1); // @snippet qlayout-setalignment @@ -209,7 +388,7 @@ PyTuple_SET_ITEM(%PYARG_0, 3, %CONVERTTOPYTHON[int](d)); QGraphicsItem* parentItem = %1->parentItem(); Shiboken::AutoDecRef parent(%CONVERTTOPYTHON[QGraphicsItem*](parentItem)); const auto &childItems = %1->childItems(); -for (QGraphicsItem *item : childItems) +for (auto *item : childItems) Shiboken::Object::setParent(parent, %CONVERTTOPYTHON[QGraphicsItem*](item)); %BEGIN_ALLOW_THREADS %CPPSELF.%FUNCTION_NAME(%1); @@ -227,7 +406,7 @@ Shiboken::Object::keepReference((SbkObject*)%PYARG_0, "setWidget(QWidget*)1", %P // @snippet qgraphicsscene-clear const QList<QGraphicsItem*> items = %CPPSELF.items(); Shiboken::BindingManager& bm = Shiboken::BindingManager::instance(); -for (QGraphicsItem *item : items) { +for (auto *item : items) { SbkObject* obj = bm.retrieveWrapper(item); if (obj) { if (reinterpret_cast<PyObject*>(obj)->ob_refcnt > 1) // If the refcnt is 1 the object will vannish anyway. @@ -241,7 +420,7 @@ for (QGraphicsItem *item : items) { // @snippet qtreewidget-clear QTreeWidgetItem *rootItem = %CPPSELF.invisibleRootItem(); Shiboken::BindingManager &bm = Shiboken::BindingManager::instance(); -for (int i = 0; i < rootItem->childCount(); ++i) { +for (int i = 0, i_count = rootItem->childCount(); i < i_count; ++i) { QTreeWidgetItem *item = rootItem->child(i); SbkObject* wrapper = bm.retrieveWrapper(item); if (wrapper) @@ -271,6 +450,72 @@ for (int i = 0, count = %CPPSELF.count(); i < count; ++i) { %CPPSELF.%FUNCTION_NAME(); // @snippet qlistwidget-clear +// @snippet qwidget-glue +static QString retrieveObjectName(PyObject *obj) +{ + Shiboken::AutoDecRef objName(PyObject_Str(obj)); + return QString(Shiboken::String::toCString(objName)); +} + + +// Transfer objects ownership from layout to widget +static inline void qwidgetReparentLayout(QWidget *parent, QLayout *layout) +{ + Shiboken::AutoDecRef pyParent(%CONVERTTOPYTHON[QWidget*](parent)); + + for (int i=0, i_count = layout->count(); i < i_count; i++) { + QLayoutItem* item = layout->itemAt(i); + if (PyErr_Occurred() || !item) + return; + + QWidget* w = item->widget(); + if (w) { + QWidget* pw = w->parentWidget(); + if (pw != parent) { + Shiboken::AutoDecRef pyChild(%CONVERTTOPYTHON[QWidget*](w)); + Shiboken::Object::setParent(pyParent, pyChild); + } + } else { + QLayout* l = item->layout(); + if (l) + qwidgetReparentLayout(parent, l); + } + } + + Shiboken::AutoDecRef pyChild(%CONVERTTOPYTHON[QLayout*](layout)); + Shiboken::Object::setParent(pyParent, pyChild); + //remove previous references + Shiboken::Object::keepReference(reinterpret_cast<SbkObject*>(pyChild.object()), qPrintable(retrieveObjectName(pyChild)), Py_None); +} + +static inline void qwidgetSetLayout(QWidget *self, QLayout *layout) +{ + if (!layout || self->layout()) + return; + + QObject* oldParent = layout->parent(); + if (oldParent && oldParent != self) { + if (oldParent->isWidgetType()) { + // remove old parent policy + Shiboken::AutoDecRef pyLayout(%CONVERTTOPYTHON[QLayout*](layout)); + Shiboken::Object::setParent(Py_None, pyLayout); + } else { + PyErr_Format(PyExc_RuntimeError, "QWidget::setLayout: Attempting to set QLayout \"%s\" on %s \"%s\", when the QLayout already has a parent", + qPrintable(layout->objectName()), self->metaObject()->className(), qPrintable(self->objectName())); + return; + } + } + + if (oldParent != self) { + qwidgetReparentLayout(self, layout); + if (PyErr_Occurred()) + return; + + self->setLayout(layout); + } +} +// @snippet qwidget-glue + // @snippet qwidget-setstyle Shiboken::Object::keepReference(reinterpret_cast<SbkObject*>(%PYSELF), "__style__", %PYARG_1); // @snippet qwidget-setstyle @@ -290,6 +535,20 @@ if (myStyle && qApp) { } // @snippet qwidget-style +// @snippet qapplication-init +static void QApplicationConstructor(PyObject *self, PyObject *pyargv, QApplicationWrapper **cptr) +{ + static int argc; + static char **argv; + PyObject *stringlist = PyTuple_GET_ITEM(pyargv, 0); + if (Shiboken::listToArgcArgv(stringlist, &argc, &argv, "PySideApp")) { + *cptr = new QApplicationWrapper(argc, argv, 0); + Shiboken::Object::releaseOwnership(reinterpret_cast<SbkObject*>(self)); + PySide::registerCleanupFunction(&PySide::destroyQCoreApplication); + } +} +// @snippet qapplication-init + // @snippet qapplication-setStyle if (qApp) { Shiboken::AutoDecRef pyApp(%CONVERTTOPYTHON[QApplication*](qApp)); @@ -355,7 +614,7 @@ Shiboken::AutoDecRef result(PyObject_CallMethod(%PYARG_0, QList<PyObject* > lst; Shiboken::BindingManager& bm = Shiboken::BindingManager::instance(); const auto &toolButtonChildren = %CPPSELF.findChildren<QToolButton*>(); -for (QToolButton *child : toolButtonChildren) { +for (auto *child : toolButtonChildren) { if (bm.hasWrapper(child)) { PyObject* pyChild = %CONVERTTOPYTHON[QToolButton*](child); Shiboken::Object::setParent(0, pyChild); @@ -365,14 +624,14 @@ for (QToolButton *child : toolButtonChildren) { //Remove actions const auto &actions = %CPPSELF.actions(); -for (QAction *act : actions) { +for (auto *act : actions) { Shiboken::AutoDecRef pyAct(%CONVERTTOPYTHON[QAction*](act)); Shiboken::Object::setParent(NULL, pyAct); Shiboken::Object::invalidate(pyAct); } %CPPSELF.clear(); -for (PyObject *obj : lst) { +for (auto *obj : lst) { Shiboken::Object::invalidate(reinterpret_cast<SbkObject* >(obj)); Py_XDECREF(obj); } |