From 427c7147d23fa21c6e8bd08407b1badc48b49c3c Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Mon, 22 May 2017 16:44:51 +0200 Subject: move everying into sources/pyside2 (5.9 edition) in preparation for a subtree merge. this should not be necessary to do in a separate commit, but git is a tad stupid about following history correctly without it. --- sources/pyside2/libpyside/pysideslot.cpp | 220 +++++++++++++++++++++++++++++++ 1 file changed, 220 insertions(+) create mode 100644 sources/pyside2/libpyside/pysideslot.cpp (limited to 'sources/pyside2/libpyside/pysideslot.cpp') diff --git a/sources/pyside2/libpyside/pysideslot.cpp b/sources/pyside2/libpyside/pysideslot.cpp new file mode 100644 index 000000000..c562e41e2 --- /dev/null +++ b/sources/pyside2/libpyside/pysideslot.cpp @@ -0,0 +1,220 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of PySide2. +** +** $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$ +** +****************************************************************************/ + +#include "dynamicqmetaobject_p.h" +#include "pysidesignal_p.h" +#include "pysideslot_p.h" + +#include +#include +#include + +#define SLOT_DEC_NAME "Slot" + +typedef struct +{ + PyObject_HEAD + char* slotName; + char* args; + char* resultType; +} PySideSlot; + +extern "C" +{ + +static int slotTpInit(PyObject*, PyObject*, PyObject*); +static PyObject* slotCall(PyObject*, PyObject*, PyObject*); + +// Class Definition ----------------------------------------------- +static PyTypeObject PySideSlotType = { + PyVarObject_HEAD_INIT(0, 0) + "PySide2.QtCore." SLOT_DEC_NAME, /*tp_name*/ + sizeof(PySideSlot), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + 0, /*tp_dealloc*/ + 0, /*tp_print*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash */ + slotCall, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT, /*tp_flags*/ + SLOT_DEC_NAME, /*tp_doc */ + 0, /*tp_traverse */ + 0, /*tp_clear */ + 0, /*tp_richcompare */ + 0, /*tp_weaklistoffset */ + 0, /*tp_iter */ + 0, /*tp_iternext */ + 0, /*tp_methods */ + 0, /*tp_members */ + 0, /*tp_getset */ + 0, /*tp_base */ + 0, /*tp_dict */ + 0, /*tp_descr_get */ + 0, /*tp_descr_set */ + 0, /*tp_dictoffset */ + slotTpInit, /*tp_init */ + 0, /*tp_alloc */ + PyType_GenericNew, /*tp_new */ + 0, /*tp_free */ + 0, /*tp_is_gc */ + 0, /*tp_bases */ + 0, /*tp_mro */ + 0, /*tp_cache */ + 0, /*tp_subclasses */ + 0, /*tp_weaklist */ + 0, /*tp_del */ + 0 /*tp_version_tag*/ +}; + +int slotTpInit(PyObject *self, PyObject *args, PyObject *kw) +{ + static PyObject *emptyTuple = 0; + static const char *kwlist[] = {"name", "result", 0}; + char* argName = 0; + PyObject* argResult = 0; + + if (emptyTuple == 0) + emptyTuple = PyTuple_New(0); + + if (!PyArg_ParseTupleAndKeywords(emptyTuple, kw, "|sO:QtCore." SLOT_DEC_NAME, (char**) kwlist, &argName, &argResult)) + return 0; + + PySideSlot *data = reinterpret_cast(self); + for(Py_ssize_t i = 0, i_max = PyTuple_Size(args); i < i_max; i++) { + PyObject *argType = PyTuple_GET_ITEM(args, i); + char *typeName = PySide::Signal::getTypeName(argType); + if (typeName) { + if (data->args) { + data->args = reinterpret_cast(realloc(data->args, (strlen(data->args) + 1 + strlen(typeName)) * sizeof(char*))); + data->args = strcat(data->args, ","); + data->args = strcat(data->args, typeName); + free(typeName); + } else { + data->args = typeName; + } + } else { + PyErr_Format(PyExc_TypeError, "Unknown signal argument type: %s", argType->ob_type->tp_name); + return -1; + } + } + + if (argName) + data->slotName = strdup(argName); + + if (argResult) + data->resultType = PySide::Signal::getTypeName(argResult); + else + data->resultType = strdup("void"); + + return 1; +} + +PyObject *slotCall(PyObject *self, PyObject *args, PyObject * /* kw */) +{ + static PyObject* pySlotName = 0; + PyObject* callback; + callback = PyTuple_GetItem(args, 0); + Py_INCREF(callback); + + if (PyFunction_Check(callback)) { + PySideSlot *data = reinterpret_cast(self); + + if (!data->slotName) { + PyObject *funcName = reinterpret_cast(callback)->func_name; + data->slotName = strdup(Shiboken::String::toCString(funcName)); + } + + + QByteArray returnType = QMetaObject::normalizedType(data->resultType); + QByteArray signature = QString().sprintf("%s(%s)", data->slotName, data->args).toUtf8(); + signature = returnType + " " + signature; + + if (!pySlotName) + pySlotName = Shiboken::String::fromCString(PYSIDE_SLOT_LIST_ATTR); + + PyObject *pySignature = Shiboken::String::fromCString(signature); + PyObject *signatureList = 0; + if (PyObject_HasAttr(callback, pySlotName)) { + signatureList = PyObject_GetAttr(callback, pySlotName); + } else { + signatureList = PyList_New(0); + PyObject_SetAttr(callback, pySlotName, signatureList); + Py_DECREF(signatureList); + } + + PyList_Append(signatureList, pySignature); + Py_DECREF(pySignature); + + //clear data + free(data->slotName); + data->slotName = 0; + free(data->resultType); + data->resultType = 0; + free(data->args); + data->args = 0; + return callback; + } + return callback; +} + +} // extern "C" + +namespace PySide { namespace Slot { + +void init(PyObject* module) +{ + if (PyType_Ready(&PySideSlotType) < 0) + return; + + Py_INCREF(&PySideSlotType); + PyModule_AddObject(module, SLOT_DEC_NAME, reinterpret_cast(&PySideSlotType)); +} + +} // namespace Slot +} // namespace PySide -- cgit v1.2.3