diff options
author | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2021-11-18 15:05:17 +0100 |
---|---|---|
committer | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2021-12-08 08:48:50 +0100 |
commit | 862948599999e4e5701452a3f479182606e16a89 (patch) | |
tree | 585769e3cc6891334ab340ff82c16e7352e41b06 /sources/pyside6/PySide6 | |
parent | 244477a81445bf6f38cda3f8fe213daaa5908166 (diff) |
Move the QML registration code into a library
This makes the code easier to maintain.
Task-number: PYSIDE-1709
Change-Id: Idb75143a7e6d218637ab75463db88b6135cd4086
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
Reviewed-by: Cristian Maureira-Fredes <cristian.maureira-fredes@qt.io>
Diffstat (limited to 'sources/pyside6/PySide6')
-rw-r--r-- | sources/pyside6/PySide6/QtQml/CMakeLists.txt | 9 | ||||
-rw-r--r-- | sources/pyside6/PySide6/QtQml/pysideqmllistproperty.cpp | 319 | ||||
-rw-r--r-- | sources/pyside6/PySide6/QtQml/pysideqmllistproperty.h | 47 | ||||
-rw-r--r-- | sources/pyside6/PySide6/QtQml/pysideqmlmetacallerror.cpp | 96 | ||||
-rw-r--r-- | sources/pyside6/PySide6/QtQml/pysideqmlmetacallerror_p.h | 57 | ||||
-rw-r--r-- | sources/pyside6/PySide6/QtQml/pysideqmlregistertype.cpp | 455 | ||||
-rw-r--r-- | sources/pyside6/PySide6/QtQml/pysideqmlregistertype.h | 109 | ||||
-rw-r--r-- | sources/pyside6/PySide6/QtQml/pysideqmlregistertype_p.h | 47 | ||||
-rw-r--r-- | sources/pyside6/PySide6/QtQml/pysideqmluncreatable.cpp | 196 | ||||
-rw-r--r-- | sources/pyside6/PySide6/QtQml/pysideqmluncreatable.h | 69 | ||||
-rw-r--r-- | sources/pyside6/PySide6/QtQml/typesystem_qml.xml | 7 | ||||
-rw-r--r-- | sources/pyside6/PySide6/glue/qtqml.cpp | 4 |
12 files changed, 6 insertions, 1409 deletions
diff --git a/sources/pyside6/PySide6/QtQml/CMakeLists.txt b/sources/pyside6/PySide6/QtQml/CMakeLists.txt index 05a1cc94a..4d8b88330 100644 --- a/sources/pyside6/PySide6/QtQml/CMakeLists.txt +++ b/sources/pyside6/PySide6/QtQml/CMakeLists.txt @@ -1,10 +1,6 @@ project(QtQml) -set(QtQml_static_sources "${QtQml_SOURCE_DIR}/pysideqmlregistertype.cpp" - "${QtQml_SOURCE_DIR}/pysideqmlmetacallerror.cpp" - "${QtQml_SOURCE_DIR}/pysideqmllistproperty.cpp" - "${QtQml_SOURCE_DIR}/pysideqmluncreatable.cpp" - "${QtQml_SOURCE_DIR}/pysideqmlvolatilebool.cpp") +set(QtQml_static_sources "${QtQml_SOURCE_DIR}/pysideqmlvolatilebool.cpp") set(QtQml_SRC ${QtQml_GEN_DIR}/qjsengine_wrapper.cpp @@ -47,11 +43,12 @@ set(QtQml_include_dirs ${QtQml_SOURCE_DIR} ${Qt${QT_MAJOR_VERSION}Qml_INCLUDE_DIRS} ${Qt${QT_MAJOR_VERSION}Qml_PRIVATE_INCLUDE_DIRS} ${libpyside_SOURCE_DIR} + ${libpysideqml_SOURCE_DIR} ${QtCore_GEN_DIR} ${QtNetwork_GEN_DIR} ${QtQml_GEN_DIR}) -set(QtQml_libraries pyside6 +set(QtQml_libraries pyside6 pyside6qml ${Qt${QT_MAJOR_VERSION}Core_LIBRARIES} ${Qt${QT_MAJOR_VERSION}Network_LIBRARIES} ${Qt${QT_MAJOR_VERSION}Qml_LIBRARIES}) diff --git a/sources/pyside6/PySide6/QtQml/pysideqmllistproperty.cpp b/sources/pyside6/PySide6/QtQml/pysideqmllistproperty.cpp deleted file mode 100644 index f817d26b5..000000000 --- a/sources/pyside6/PySide6/QtQml/pysideqmllistproperty.cpp +++ /dev/null @@ -1,319 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2021 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$ -** -****************************************************************************/ - -#include "pysideqmllistproperty.h" -#include "pysideqmlregistertype_p.h" - -#include <shiboken.h> -#include <signature.h> - -#include <pysideproperty.h> - -#include <QtCore/QObject> -#include <QtQml/QQmlListProperty> - -// Forward declarations. -static void propListMetaCall(PySideProperty *pp, PyObject *self, QMetaObject::Call call, - void **args); - -extern "C" -{ - -// This is the user data we store in the property. -struct QmlListProperty -{ - PyTypeObject *type; - PyObject *append; - PyObject *count; - PyObject *at; - PyObject *clear; - PyObject *replace; - PyObject *removeLast; -}; - -static int propListTpInit(PyObject *self, PyObject *args, PyObject *kwds) -{ - static const char *kwlist[] = {"type", "append", "count", "at", "clear", "replace", "removeLast", 0}; - PySideProperty *pySelf = reinterpret_cast<PySideProperty *>(self); - QmlListProperty *data = new QmlListProperty; - memset(data, 0, sizeof(QmlListProperty)); - - if (!PyArg_ParseTupleAndKeywords(args, kwds, - "O|OOOOOO:QtQml.ListProperty", (char **) kwlist, - &data->type, - &data->append, - &data->count, - &data->at, - &data->clear, - &data->replace, - &data->removeLast)) { - delete data; - return -1; - } - - PyTypeObject *qobjectType = qObjectType(); - - if (!PySequence_Contains(data->type->tp_mro, reinterpret_cast<PyObject *>(qobjectType))) { - PyErr_Format(PyExc_TypeError, "A type inherited from %s expected, got %s.", - qobjectType->tp_name, data->type->tp_name); - delete data; - return -1; - } - - if ((data->append && data->append != Py_None && !PyCallable_Check(data->append)) || - (data->count && data->count != Py_None && !PyCallable_Check(data->count)) || - (data->at && data->at != Py_None && !PyCallable_Check(data->at)) || - (data->clear && data->clear != Py_None && !PyCallable_Check(data->clear)) || - (data->replace && data->replace != Py_None && !PyCallable_Check(data->replace)) || - (data->removeLast && data->removeLast != Py_None && !PyCallable_Check(data->removeLast))) { - PyErr_Format(PyExc_TypeError, "Non-callable parameter given"); - delete data; - return -1; - } - - PySide::Property::setMetaCallHandler(pySelf, &propListMetaCall); - PySide::Property::setTypeName(pySelf, "QQmlListProperty<QObject>"); - PySide::Property::setUserData(pySelf, data); - - return 0; -} - -void propListTpFree(void *self) -{ - auto pySelf = reinterpret_cast<PySideProperty *>(self); - delete reinterpret_cast<QmlListProperty *>(PySide::Property::userData(pySelf)); - // calls base type constructor - Py_TYPE(pySelf)->tp_base->tp_free(self); -} - -static PyType_Slot PropertyListType_slots[] = { - {Py_tp_init, reinterpret_cast<void *>(propListTpInit)}, - {Py_tp_free, reinterpret_cast<void *>(propListTpFree)}, - {Py_tp_dealloc, reinterpret_cast<void *>(Sbk_object_dealloc)}, - {0, nullptr} -}; -static PyType_Spec PropertyListType_spec = { - "2:PySide6.QtQml.ListProperty", - sizeof(PySideProperty), - 0, - Py_TPFLAGS_DEFAULT, - PropertyListType_slots, -}; - - -PyTypeObject *PropertyListTypeF(void) -{ - static Shiboken::AutoDecRef bases(Py_BuildValue("(O)", PySidePropertyTypeF())); - static auto *type = SbkType_FromSpecWithBases(&PropertyListType_spec, bases); - return type; -} - -} // extern "C" - -// Implementation of QQmlListProperty<T>::AppendFunction callback -void propListAppender(QQmlListProperty<QObject> *propList, QObject *item) -{ - Shiboken::GilState state; - - Shiboken::AutoDecRef args(PyTuple_New(2)); - PyTypeObject *qobjectType = qObjectType(); - PyTuple_SET_ITEM(args, 0, - Shiboken::Conversions::pointerToPython(qobjectType, propList->object)); - PyTuple_SET_ITEM(args, 1, - Shiboken::Conversions::pointerToPython(qobjectType, item)); - - auto data = reinterpret_cast<QmlListProperty *>(propList->data); - Shiboken::AutoDecRef retVal(PyObject_CallObject(data->append, args)); - - if (PyErr_Occurred()) - PyErr_Print(); -} - -// Implementation of QQmlListProperty<T>::CountFunction callback -qsizetype propListCount(QQmlListProperty<QObject> *propList) -{ - Shiboken::GilState state; - - Shiboken::AutoDecRef args(PyTuple_New(1)); - PyTuple_SET_ITEM(args, 0, - Shiboken::Conversions::pointerToPython(qObjectType(), propList->object)); - - auto data = reinterpret_cast<QmlListProperty *>(propList->data); - Shiboken::AutoDecRef retVal(PyObject_CallObject(data->count, args)); - - // Check return type - if (PyErr_Occurred()) { - PyErr_Print(); - return 0; - } - - int cppResult = 0; - auto *converter = Shiboken::Conversions::PrimitiveTypeConverter<qsizetype>(); - if (auto *pythonToCpp = Shiboken::Conversions::isPythonToCppConvertible(converter, retVal)) - pythonToCpp(retVal, &cppResult); - return cppResult; -} - -// Implementation of QQmlListProperty<T>::AtFunction callback -QObject *propListAt(QQmlListProperty<QObject> *propList, qsizetype index) -{ - Shiboken::GilState state; - - Shiboken::AutoDecRef args(PyTuple_New(2)); - PyTypeObject *qobjectType = qObjectType(); - PyTuple_SET_ITEM(args, 0, - Shiboken::Conversions::pointerToPython(qobjectType, propList->object)); - auto *converter = Shiboken::Conversions::PrimitiveTypeConverter<qsizetype>(); - PyTuple_SET_ITEM(args, 1, - Shiboken::Conversions::copyToPython(converter, &index)); - - auto data = reinterpret_cast<QmlListProperty *>(propList->data); - Shiboken::AutoDecRef retVal(PyObject_CallObject(data->at, args)); - - QObject *result = 0; - if (PyErr_Occurred()) - PyErr_Print(); - else if (PyType_IsSubtype(Py_TYPE(retVal), data->type)) - Shiboken::Conversions::pythonToCppPointer(qobjectType, retVal, &result); - return result; -} - -// Implementation of QQmlListProperty<T>::ClearFunction callback -void propListClear(QQmlListProperty<QObject> * propList) -{ - Shiboken::GilState state; - - Shiboken::AutoDecRef args(PyTuple_New(1)); - PyTypeObject *qobjectType = qObjectType(); - PyTuple_SET_ITEM(args, 0, - Shiboken::Conversions::pointerToPython(qobjectType, propList->object)); - - auto data = reinterpret_cast<QmlListProperty *>(propList->data); - Shiboken::AutoDecRef retVal(PyObject_CallObject(data->clear, args)); - - if (PyErr_Occurred()) - PyErr_Print(); -} - -// Implementation of QQmlListProperty<T>::ReplaceFunction callback -void propListReplace(QQmlListProperty<QObject> *propList, qsizetype index, QObject *value) -{ - Shiboken::GilState state; - - Shiboken::AutoDecRef args(PyTuple_New(3)); - PyTypeObject *qobjectType = qObjectType(); - PyTuple_SET_ITEM(args, 0, - Shiboken::Conversions::pointerToPython(qobjectType, propList->object)); - auto *converter = Shiboken::Conversions::PrimitiveTypeConverter<qsizetype>(); - PyTuple_SET_ITEM(args, 1, - Shiboken::Conversions::copyToPython(converter, &index)); - PyTuple_SET_ITEM(args, 2, - Shiboken::Conversions::pointerToPython(qobjectType, value)); - - auto data = reinterpret_cast<QmlListProperty *>(propList->data); - Shiboken::AutoDecRef retVal(PyObject_CallObject(data->replace, args)); - - if (PyErr_Occurred()) - PyErr_Print(); -} - -// Implementation of QQmlListProperty<T>::RemoveLastFunction callback -void propListRemoveLast(QQmlListProperty<QObject> *propList) -{ - Shiboken::GilState state; - - Shiboken::AutoDecRef args(PyTuple_New(1)); - PyTypeObject *qobjectType = qObjectType(); - PyTuple_SET_ITEM(args, 0, - Shiboken::Conversions::pointerToPython(qobjectType, propList->object)); - - auto data = reinterpret_cast<QmlListProperty *>(propList->data); - Shiboken::AutoDecRef retVal(PyObject_CallObject(data->removeLast, args)); - - if (PyErr_Occurred()) - PyErr_Print(); -} - -// qt_metacall specialization for ListProperties -static void propListMetaCall(PySideProperty *pp, PyObject *self, - QMetaObject::Call call, void **args) -{ - if (call != QMetaObject::ReadProperty) - return; - - auto data = reinterpret_cast<QmlListProperty *>(PySide::Property::userData(pp)); - QObject *qobj; - PyTypeObject *qobjectType = qObjectType(); - Shiboken::Conversions::pythonToCppPointer(qobjectType, self, &qobj); - QQmlListProperty<QObject> declProp( - qobj, data, - data->append && data->append != Py_None ? &propListAppender : nullptr, - data->count && data->count != Py_None ? &propListCount : nullptr, - data->at && data->at != Py_None ? &propListAt : nullptr, - data->clear && data->clear != Py_None ? &propListClear : nullptr, - data->replace && data->replace != Py_None ? &propListReplace : nullptr, - data->removeLast && data->removeLast != Py_None ? &propListRemoveLast : nullptr); - - // Copy the data to the memory location requested by the meta call - void *v = args[0]; - *reinterpret_cast<QQmlListProperty<QObject> *>(v) = declProp; -} - -static const char *PropertyList_SignatureStrings[] = { - "PySide6.QtQml.ListProperty(self,type:type,append:typing.Callable," - "at:typing.Callable=None,clear:typing.Callable=None,count:typing.Callable=None)", - nullptr // Sentinel -}; - -void initQtQmlListProperty(PyObject *module) -{ - // Export QmlListProperty type - if (InitSignatureStrings(PropertyListTypeF(), PropertyList_SignatureStrings) < 0) { - PyErr_Print(); - qWarning() << "Error initializing PropertyList type."; - return; - } - - // Register QQmlListProperty metatype for use in QML - qRegisterMetaType<QQmlListProperty<QObject>>(); - - Py_INCREF(reinterpret_cast<PyObject *>(PropertyListTypeF())); - PyModule_AddObject(module, PepType_GetNameStr(PropertyListTypeF()), - reinterpret_cast<PyObject *>(PropertyListTypeF())); -} diff --git a/sources/pyside6/PySide6/QtQml/pysideqmllistproperty.h b/sources/pyside6/PySide6/QtQml/pysideqmllistproperty.h deleted file mode 100644 index bfae04bfc..000000000 --- a/sources/pyside6/PySide6/QtQml/pysideqmllistproperty.h +++ /dev/null @@ -1,47 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2021 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$ -** -****************************************************************************/ - -#ifndef PYSIDEQMLLISTPROPERTY_H -#define PYSIDEQMLLISTPROPERTY_H - -#include <sbkpython.h> - -void initQtQmlListProperty(PyObject *module); - -#endif // PYSIDEQMLLISTPROPERTY_H diff --git a/sources/pyside6/PySide6/QtQml/pysideqmlmetacallerror.cpp b/sources/pyside6/PySide6/QtQml/pysideqmlmetacallerror.cpp deleted file mode 100644 index ec3de6c24..000000000 --- a/sources/pyside6/PySide6/QtQml/pysideqmlmetacallerror.cpp +++ /dev/null @@ -1,96 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2021 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$ -** -****************************************************************************/ - -#include "pysideqmlmetacallerror_p.h" - -#include <sbkpython.h> -#include <sbkstring.h> -#include <autodecref.h> - -#include <QtCore/QObject> -#include <QtCore/QString> - -#include <QtQml/QQmlEngine> -#include <QtQml/QQmlListProperty> - -#if __has_include (<private/qv4engine_p.h>) -# define QML_PRIVATE_API_SUPPORT -# include <private/qv4engine_p.h> -# include <private/qv4context_p.h> -# include <private/qqmldata_p.h> -#endif - -namespace PySide { - -std::optional<int> qmlMetaCallErrorHandler(QObject *object) -{ -#ifdef QML_PRIVATE_API_SUPPORT - // This JS engine grabber based off of Qt 5.5's `qjsEngine` function - QQmlData *data = QQmlData::get(object, false); - if (!data || data->jsWrapper.isNullOrUndefined()) - return {}; - - QV4::ExecutionEngine *engine = data->jsWrapper.engine(); - if (engine->currentStackFrame == nullptr) - return {}; - - PyObject *errType, *errValue, *errTraceback; - PyErr_Fetch(&errType, &errValue, &errTraceback); - // PYSIDE-464: The error is only valid before PyErr_Restore, - // PYSIDE-464: therefore we take local copies. - Shiboken::AutoDecRef objStr(PyObject_Str(errValue)); - const QString errString = QLatin1String(Shiboken::String::toCString(objStr)); - const bool isSyntaxError = errType == PyExc_SyntaxError; - const bool isTypeError = errType == PyExc_TypeError; - PyErr_Restore(errType, errValue, errTraceback); - - PyErr_Print(); // Note: PyErr_Print clears the error. - - if (isSyntaxError) - return engine->throwSyntaxError(errString); - if (isTypeError) - return engine->throwTypeError(errString); - return engine->throwError(errString); -#else - Q_UNUSED(object); - return {}; -#endif // QML_PRIVATE_API_SUPPORT -} - -} // namespace PySide diff --git a/sources/pyside6/PySide6/QtQml/pysideqmlmetacallerror_p.h b/sources/pyside6/PySide6/QtQml/pysideqmlmetacallerror_p.h deleted file mode 100644 index 9ecb0f6eb..000000000 --- a/sources/pyside6/PySide6/QtQml/pysideqmlmetacallerror_p.h +++ /dev/null @@ -1,57 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2021 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$ -** -****************************************************************************/ - -#ifndef PYSIDEQMLMETACALLERROR_P_H -#define PYSIDEQMLMETACALLERROR_P_H - -#include <optional> - -#include <QtCore/QtGlobal> - -QT_FORWARD_DECLARE_CLASS(QObject) - -namespace PySide { - -// Helper for SignalManager::qt_metacall(): -// Bubbles Python exceptions up to the Javascript engine, if called from one -std::optional<int> qmlMetaCallErrorHandler(QObject *object); - -} // namespace PySide - -#endif // PYSIDEQMLMETACALLERROR_P_H diff --git a/sources/pyside6/PySide6/QtQml/pysideqmlregistertype.cpp b/sources/pyside6/PySide6/QtQml/pysideqmlregistertype.cpp deleted file mode 100644 index 84fec16b6..000000000 --- a/sources/pyside6/PySide6/QtQml/pysideqmlregistertype.cpp +++ /dev/null @@ -1,455 +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$ -** -****************************************************************************/ - -#include "pysideqmlregistertype.h" -#include "pysideqmlregistertype_p.h" -#include "pysideqmluncreatable.h" - -#include <limits> - -// shiboken -#include <shiboken.h> -#include <sbkstring.h> - -// pyside -#include <pyside.h> -#include <pysideqobject.h> -#include <pyside_p.h> - -#include <QtCore/QMutex> -#include <QtCore/QTypeRevision> - -#include <QtQml/qqml.h> -#include <QtQml/QJSValue> -#include <QtQml/QQmlListProperty> - -// Mutex used to avoid race condition on PySide::nextQObjectMemoryAddr. -static QMutex nextQmlElementMutex; - -static void createInto(void *memory, void *type) -{ - QMutexLocker locker(&nextQmlElementMutex); - PySide::setNextQObjectMemoryAddr(memory); - Shiboken::GilState state; - PyObject *obj = PyObject_CallObject(reinterpret_cast<PyObject *>(type), 0); - if (!obj || PyErr_Occurred()) - PyErr_Print(); - PySide::setNextQObjectMemoryAddr(0); -} - -PyTypeObject *qObjectType() -{ - static PyTypeObject *const result = - Shiboken::Conversions::getPythonTypeObject("QObject*"); - assert(result); - return result; -} - -static PyTypeObject *qQmlEngineType() -{ - static PyTypeObject *const result = - Shiboken::Conversions::getPythonTypeObject("QQmlEngine*"); - assert(result); - return result; -} - -static PyTypeObject *qQJSValueType() -{ - static PyTypeObject *const result = - Shiboken::Conversions::getPythonTypeObject("QJSValue*"); - assert(result); - return result; -} - -int PySide::qmlRegisterType(PyObject *pyObj, const char *uri, int versionMajor, - int versionMinor, const char *qmlName, const char *noCreationReason, - bool creatable) -{ - using namespace Shiboken; - - PyTypeObject *qobjectType = qObjectType(); - - PyTypeObject *pyObjType = reinterpret_cast<PyTypeObject *>(pyObj); - if (!PySequence_Contains(pyObjType->tp_mro, reinterpret_cast<PyObject *>(qobjectType))) { - PyErr_Format(PyExc_TypeError, "A type inherited from %s expected, got %s.", - qobjectType->tp_name, pyObjType->tp_name); - return -1; - } - - const QMetaObject *metaObject = PySide::retrieveMetaObject(pyObjType); - Q_ASSERT(metaObject); - - QQmlPrivate::RegisterType type; - - // Allow registering Qt Quick items. - bool registered = false; - QuickRegisterItemFunction quickRegisterItemFunction = getQuickRegisterItemFunction(); - if (quickRegisterItemFunction) { - registered = - quickRegisterItemFunction(pyObj, uri, versionMajor, versionMinor, - qmlName, creatable, noCreationReason, &type); - } - - // Register as simple QObject rather than Qt Quick item. - if (!registered) { - // Incref the type object, don't worry about decref'ing it because - // there's no way to unregister a QML type. - Py_INCREF(pyObj); - - type.structVersion = 0; - - // FIXME: Fix this to assign new type ids each time. - type.typeId = QMetaType(QMetaType::QObjectStar); - type.listId = QMetaType::fromType<QQmlListProperty<QObject> >(); - type.attachedPropertiesFunction = QQmlPrivate::attachedPropertiesFunc<QObject>(); - type.attachedPropertiesMetaObject = QQmlPrivate::attachedPropertiesMetaObject<QObject>(); - - type.parserStatusCast = - QQmlPrivate::StaticCastSelector<QObject, QQmlParserStatus>::cast(); - type.valueSourceCast = - QQmlPrivate::StaticCastSelector<QObject, QQmlPropertyValueSource>::cast(); - type.valueInterceptorCast = - QQmlPrivate::StaticCastSelector<QObject, QQmlPropertyValueInterceptor>::cast(); - - int objectSize = static_cast<int>(PySide::getSizeOfQObject( - reinterpret_cast<PyTypeObject *>(pyObj))); - type.objectSize = objectSize; - type.create = creatable ? createInto : nullptr; - type.noCreationReason = QString::fromUtf8(noCreationReason); - type.userdata = pyObj; - type.uri = uri; - type.version = QTypeRevision::fromVersion(versionMajor, versionMinor); - type.elementName = qmlName; - - type.extensionObjectCreate = 0; - type.extensionMetaObject = 0; - type.customParser = 0; - } - type.metaObject = metaObject; // Snapshot may have changed. - - int qmlTypeId = QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type); - if (qmlTypeId == -1) { - PyErr_Format(PyExc_TypeError, "QML meta type registration of \"%s\" failed.", - qmlName); - } - return qmlTypeId; -} - -int PySide::qmlRegisterSingletonType(PyObject *pyObj, const char *uri, int versionMajor, - int versionMinor, const char *qmlName, PyObject *callback, - bool isQObject, bool hasCallback) -{ - using namespace Shiboken; - - if (hasCallback) { - if (!PyCallable_Check(callback)) { - PyErr_Format(PyExc_TypeError, "Invalid callback specified."); - return -1; - } - - AutoDecRef funcCode(PyObject_GetAttrString(callback, "__code__")); - AutoDecRef argCount(PyObject_GetAttrString(funcCode, "co_argcount")); - - int count = PyLong_AsLong(argCount); - - if (count != 1) { - PyErr_Format(PyExc_TypeError, "Callback has a bad parameter count."); - return -1; - } - - // Make sure the callback never gets deallocated - Py_INCREF(callback); - } - - const QMetaObject *metaObject = nullptr; - - if (isQObject) { - PyTypeObject *pyObjType = reinterpret_cast<PyTypeObject *>(pyObj); - - if (!isQObjectDerived(pyObjType, true)) - return -1; - - // If we don't have a callback we'll need the pyObj to stay allocated indefinitely - if (!hasCallback) - Py_INCREF(pyObj); - - metaObject = PySide::retrieveMetaObject(pyObjType); - Q_ASSERT(metaObject); - } - - QQmlPrivate::RegisterSingletonType type; - type.structVersion = 0; - - type.uri = uri; - type.version = QTypeRevision::fromVersion(versionMajor, versionMinor); - type.typeName = qmlName; - type.instanceMetaObject = metaObject; - - if (isQObject) { - // FIXME: Fix this to assign new type ids each time. - type.typeId = QMetaType(QMetaType::QObjectStar); - - type.qObjectApi = - [callback, pyObj, hasCallback](QQmlEngine *engine, QJSEngine *) -> QObject * { - Shiboken::GilState gil; - AutoDecRef args(PyTuple_New(hasCallback ? 1 : 0)); - - if (hasCallback) { - PyTuple_SET_ITEM(args, 0, Conversions::pointerToPython( - qQmlEngineType(), engine)); - } - - AutoDecRef retVal(PyObject_CallObject(hasCallback ? callback : pyObj, args)); - - // Make sure the callback returns something we can convert, else the entire application will crash. - if (retVal.isNull() || - Conversions::isPythonToCppPointerConvertible(qObjectType(), retVal) == nullptr) { - PyErr_Format(PyExc_TypeError, "Callback returns invalid value."); - return nullptr; - } - - QObject *obj = nullptr; - Conversions::pythonToCppPointer(qObjectType(), retVal, &obj); - - if (obj != nullptr) - Py_INCREF(retVal); - - return obj; - }; - } else { - type.scriptApi = - [callback](QQmlEngine *engine, QJSEngine *) -> QJSValue { - Shiboken::GilState gil; - AutoDecRef args(PyTuple_New(1)); - - PyTuple_SET_ITEM(args, 0, Conversions::pointerToPython( - qQmlEngineType(), engine)); - - AutoDecRef retVal(PyObject_CallObject(callback, args)); - - PyTypeObject *qjsvalueType = qQJSValueType(); - - // Make sure the callback returns something we can convert, else the entire application will crash. - if (retVal.isNull() || - Conversions::isPythonToCppPointerConvertible(qjsvalueType, retVal) == nullptr) { - PyErr_Format(PyExc_TypeError, "Callback returns invalid value."); - return QJSValue(QJSValue::UndefinedValue); - } - - QJSValue *val = nullptr; - Conversions::pythonToCppPointer(qjsvalueType, retVal, &val); - - Py_INCREF(retVal); - - return *val; - }; - } - - return QQmlPrivate::qmlregister(QQmlPrivate::SingletonRegistration, &type); -} - -int PySide::qmlRegisterSingletonInstance(PyObject *pyObj, const char *uri, int versionMajor, - int versionMinor, const char *qmlName, - PyObject *instanceObject) -{ - using namespace Shiboken; - - // Check if the Python Type inherit from QObject - PyTypeObject *pyObjType = reinterpret_cast<PyTypeObject *>(pyObj); - - if (!isQObjectDerived(pyObjType, true)) - return -1; - - // Convert the instanceObject (PyObject) into a QObject - QObject *instanceQObject = PySide::convertToQObject(instanceObject, true); - if (instanceQObject == nullptr) - return -1; - - // Create Singleton Functor to pass the QObject to the Type registration step - // similarly to the case when we have a callback - QQmlPrivate::SingletonFunctor registrationFunctor; - registrationFunctor.m_object = instanceQObject; - - const QMetaObject *metaObject = PySide::retrieveMetaObject(pyObjType); - Q_ASSERT(metaObject); - - QQmlPrivate::RegisterSingletonType type; - type.structVersion = 0; - - type.uri = uri; - type.version = QTypeRevision::fromVersion(versionMajor, versionMinor); - type.typeName = qmlName; - type.instanceMetaObject = metaObject; - - // FIXME: Fix this to assign new type ids each time. - type.typeId = QMetaType(QMetaType::QObjectStar); - type.qObjectApi = registrationFunctor; - - - return QQmlPrivate::qmlregister(QQmlPrivate::SingletonRegistration, &type); -} - -static std::string getGlobalString(const char *name) -{ - using Shiboken::AutoDecRef; - - PyObject *globals = PyEval_GetGlobals(); - - AutoDecRef pyName(Py_BuildValue("s", name)); - - PyObject *globalVar = PyDict_GetItem(globals, pyName); - - if (globalVar == nullptr || !PyUnicode_Check(globalVar)) - return ""; - - const char *stringValue = _PepUnicode_AsString(globalVar); - return stringValue != nullptr ? stringValue : ""; -} - -static int getGlobalInt(const char *name) -{ - using Shiboken::AutoDecRef; - - PyObject *globals = PyEval_GetGlobals(); - - AutoDecRef pyName(Py_BuildValue("s", name)); - - PyObject *globalVar = PyDict_GetItem(globals, pyName); - - if (globalVar == nullptr || !PyLong_Check(globalVar)) - return -1; - - long value = PyLong_AsLong(globalVar); - - if (value > std::numeric_limits<int>::max() || value < std::numeric_limits<int>::min()) - return -1; - - return value; -} - -enum class RegisterMode { - Normal, - Anonymous, - Uncreatable, - Singleton -}; - -static PyObject *qmlElementMacroHelper(PyObject *pyObj, - const char *decoratorName, - RegisterMode mode = RegisterMode::Normal, - const char *noCreationReason = nullptr) -{ - if (!PyType_Check(pyObj)) { - PyErr_Format(PyExc_TypeError, "This decorator can only be used on classes."); - return nullptr; - } - - PyTypeObject *pyObjType = reinterpret_cast<PyTypeObject *>(pyObj); - const char *typeName = pyObjType->tp_name; - if (!PySequence_Contains(pyObjType->tp_mro, reinterpret_cast<PyObject *>(qObjectType()))) { - PyErr_Format(PyExc_TypeError, "This decorator can only be used with classes inherited from QObject, got %s.", - typeName); - return nullptr; - } - - std::string importName = getGlobalString("QML_IMPORT_NAME"); - int majorVersion = getGlobalInt("QML_IMPORT_MAJOR_VERSION"); - int minorVersion = getGlobalInt("QML_IMPORT_MINOR_VERSION"); - - if (importName.empty()) { - PyErr_Format(PyExc_TypeError, "You need specify QML_IMPORT_NAME in order to use %s.", - decoratorName); - return nullptr; - } - - if (majorVersion == -1) { - PyErr_Format(PyExc_TypeError, "You need specify QML_IMPORT_MAJOR_VERSION in order to use %s.", - decoratorName); - return nullptr; - } - - // Specifying a minor version is optional - if (minorVersion == -1) - minorVersion = 0; - - const char *uri = importName.c_str(); - const int result = mode == RegisterMode::Singleton - ? PySide::qmlRegisterSingletonType(pyObj, uri, majorVersion, minorVersion, - typeName, nullptr, - PySide::isQObjectDerived(pyObjType, false), - false) - : PySide::qmlRegisterType(pyObj, uri, majorVersion, minorVersion, - mode != RegisterMode::Anonymous ? typeName : nullptr, - noCreationReason, - mode == RegisterMode::Normal); - - if (result == -1) { - PyErr_Format(PyExc_TypeError, "%s: Failed to register type %s.", - decoratorName, typeName); - } - - return pyObj; -} - -// FIXME: Store this in PySide::TypeUserData once it is moved to libpyside? -static QList<PyObject *> decoratedSingletons; - -PyObject *PySide::qmlElementMacro(PyObject *pyObj) -{ - const char *noCreationReason = nullptr; - RegisterMode mode = RegisterMode::Normal; - if (decoratedSingletons.contains(pyObj)) - mode = RegisterMode::Singleton; - else if ((noCreationReason = PySide::qmlNoCreationReason(pyObj))) - mode = RegisterMode::Uncreatable; - return qmlElementMacroHelper(pyObj, "QmlElement", mode, noCreationReason); -} - -PyObject *PySide::qmlAnonymousMacro(PyObject *pyObj) -{ - return qmlElementMacroHelper(pyObj, "QmlAnonymous", - RegisterMode::Anonymous); -} - -PyObject *PySide::qmlSingletonMacro(PyObject *pyObj) -{ - decoratedSingletons.append(pyObj); - Py_INCREF(pyObj); - return pyObj; -} diff --git a/sources/pyside6/PySide6/QtQml/pysideqmlregistertype.h b/sources/pyside6/PySide6/QtQml/pysideqmlregistertype.h deleted file mode 100644 index 643033237..000000000 --- a/sources/pyside6/PySide6/QtQml/pysideqmlregistertype.h +++ /dev/null @@ -1,109 +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$ -** -****************************************************************************/ - -#ifndef PYSIDEQMLREGISTERTYPE_H -#define PYSIDEQMLREGISTERTYPE_H - -#include <sbkpython.h> - -namespace PySide -{ - -extern void *nextQmlElementMemoryAddr; - -/** - * PySide implementation of qmlRegisterType<T> function. - * - * \param pyObj Python type to be registered. - * \param uri QML element uri. - * \param versionMajor QML component major version. - * \param versionMinor QML component minor version. - * \param qmlName QML element name - * \return the metatype id of the registered type. - */ -int qmlRegisterType(PyObject *pyObj, const char *uri, int versionMajor, int versionMinor, - const char *qmlName, const char *noCreationReason = nullptr, bool creatable = true); - -/** - * PySide implementation of qmlRegisterSingletonType<T> function. - * - * \param pyObj Python type to be registered. - * \param uri QML element uri. - * \param versionMajor QML component major version. - * \param versionMinor QML component minor version. - * \param qmlName QML element name - * \param callback Registration callback - * \return the metatype id of the registered type. - */ -int qmlRegisterSingletonType(PyObject *pyObj,const char *uri, int versionMajor, int versionMinor, const char *qmlName, - PyObject *callback, bool isQObject, bool hasCallback); - -/** - * PySide implementation of qmlRegisterSingletonInstance<T> function. - * - * \param pyObj Python type to be registered. - * \param uri QML element uri. - * \param versionMajor QML component major version. - * \param versionMinor QML component minor version. - * \param qmlName QML element name - * \param instanceObject singleton object to be registered. - * \return the metatype id of the registered type. - */ -int qmlRegisterSingletonInstance(PyObject *pyObj, const char *uri, int versionMajor, - int versionMinor, const char *qmlName, PyObject *instanceObject); - - -/** - * PySide implementation of the QML_ELEMENT macro - * - * \param pyObj Python type to be registered - */ -PyObject *qmlElementMacro(PyObject *pyObj); - -/// PySide implementation of the QML_ANONYMOUS macro -/// \param pyObj Python type to be registered -PyObject *qmlAnonymousMacro(PyObject *pyObj); - -/// PySide implementation of the QML_SINGLETON macro -/// \param pyObj Python type to be registered -PyObject *qmlSingletonMacro(PyObject *pyObj); - -} // namespace PySide - -#endif // PYSIDEQMLREGISTERTYPE_H diff --git a/sources/pyside6/PySide6/QtQml/pysideqmlregistertype_p.h b/sources/pyside6/PySide6/QtQml/pysideqmlregistertype_p.h deleted file mode 100644 index d357a0392..000000000 --- a/sources/pyside6/PySide6/QtQml/pysideqmlregistertype_p.h +++ /dev/null @@ -1,47 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2021 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$ -** -****************************************************************************/ - -#ifndef PYSIDEQMLREGISTERTYPE_P_H -#define PYSIDEQMLREGISTERTYPE_P_H - -#include <sbkpython.h> - -PyTypeObject *qObjectType(); - -#endif // PYSIDEQMLREGISTERTYPE_P_H diff --git a/sources/pyside6/PySide6/QtQml/pysideqmluncreatable.cpp b/sources/pyside6/PySide6/QtQml/pysideqmluncreatable.cpp deleted file mode 100644 index e59476146..000000000 --- a/sources/pyside6/PySide6/QtQml/pysideqmluncreatable.cpp +++ /dev/null @@ -1,196 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2021 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$ -** -****************************************************************************/ - -#include "pysideqmluncreatable.h" - -#include <shiboken.h> -#include <signature.h> -#include <sbkcppstring.h> - -#include <string> -#include <unordered_map> - -#include <QtCore/QtGlobal> - -struct PySideQmlUncreatablePrivate -{ - std::string reason; -}; - -using UncreatableReasonMap = std::unordered_map<PyObject *, std::string>; - -// Types and their nocreationReason. FIXME: Store this in PySide::TypeUserData -// once it is moved to libpyside? -UncreatableReasonMap &uncreatableReasonMap() -{ - static UncreatableReasonMap result; - return result; -} - -extern "C" -{ - -// The call operator is passed the class type and registers the reason -// in the uncreatableReasonMap() -static PyObject *classCall(PyObject *self, PyObject *args, PyObject * /* kw */) -{ - if (!PyTuple_Check(args) || PyTuple_Size(args) != 1) { - PyErr_Format(PyExc_TypeError, - "The QmlUncreatable decorator takes exactly 1 positional argument (%zd given)", - PyTuple_Size(args)); - return nullptr; - } - - PyObject *klass = PyTuple_GetItem(args, 0); - // This will sometimes segfault if you mistakenly use it on a function declaration - if (!PyType_Check(klass)) { - PyErr_SetString(PyExc_TypeError, - "This decorator can only be used on class declarations"); - return nullptr; - } - - PyTypeObject *klassType = reinterpret_cast<PyTypeObject *>(klass); - if (!Shiboken::ObjectType::checkType(klassType)) { - PyErr_SetString(PyExc_TypeError, - "This decorator can only be used on classes that are subclasses of QObject"); - return nullptr; - } - - auto data = reinterpret_cast<PySideQmlUncreatable *>(self); - uncreatableReasonMap().insert({klass, data->d->reason}); - - Py_INCREF(klass); - return klass; -} - -static PyObject *qmlUncreatableTpNew(PyTypeObject *subtype, PyObject * /* args */, - PyObject * /* kwds */) -{ - auto *me = reinterpret_cast<PySideQmlUncreatable *>(subtype->tp_alloc(subtype, 0)); - me->d = new PySideQmlUncreatablePrivate; - return reinterpret_cast<PyObject *>(me); -} - -static int qmlUncreatableTpInit(PyObject *self, PyObject *args, PyObject * /* kwds */) -{ - PySideQmlUncreatable *data = reinterpret_cast<PySideQmlUncreatable *>(self); - PySideQmlUncreatablePrivate *pData = data->d; - - bool ok = false; - const auto argsCount = PyTuple_Size(args); - if (argsCount == 0) { - ok = true; // QML-generated reason - } else if (argsCount == 1) { - PyObject *arg = PyTuple_GET_ITEM(args, 0); - if (arg == Py_None) { - ok = true; // QML-generated reason - } else if (PyUnicode_Check(arg)) { - ok = true; - Shiboken::String::toCppString(arg, &(pData->reason)); - } - } - - if (!ok) { - PyErr_Format(PyExc_TypeError, - "QmlUncreatable() takes a single string argument or no argument"); - return -1; - } - - return 0; -} - -static void qmlUncreatableFree(void *self) -{ - auto pySelf = reinterpret_cast<PyObject *>(self); - auto data = reinterpret_cast<PySideQmlUncreatable *>(self); - - delete data->d; - Py_TYPE(pySelf)->tp_base->tp_free(self); -} - -static PyType_Slot PySideQmlUncreatableType_slots[] = { - {Py_tp_call, reinterpret_cast<void *>(classCall)}, - {Py_tp_init, reinterpret_cast<void *>(qmlUncreatableTpInit)}, - {Py_tp_new, reinterpret_cast<void *>(qmlUncreatableTpNew)}, - {Py_tp_free, reinterpret_cast<void *>(qmlUncreatableFree)}, - {Py_tp_dealloc, reinterpret_cast<void *>(Sbk_object_dealloc)}, - {0, nullptr} -}; - -static PyType_Spec PySideQmlUncreatableType_spec = { - "2:PySide6.QtCore.qmlUncreatable", - sizeof(PySideQmlUncreatable), - 0, - Py_TPFLAGS_DEFAULT, - PySideQmlUncreatableType_slots, -}; - -PyTypeObject *PySideQmlUncreatableTypeF(void) -{ - static auto *type = SbkType_FromSpec(&PySideQmlUncreatableType_spec); - return type; -} - -} // extern "C" - -static const char *qmlUncreatable_SignatureStrings[] = { - "PySide6.QtQml.QmlUncreatable(self,reason:str)", - nullptr // Sentinel -}; - -void initQmlUncreatable(PyObject *module) -{ - if (InitSignatureStrings(PySideQmlUncreatableTypeF(), qmlUncreatable_SignatureStrings) < 0) - return; - - Py_INCREF(PySideQmlUncreatableTypeF()); - PyModule_AddObject(module, "QmlUncreatable", - reinterpret_cast<PyObject *>(PySideQmlUncreatableTypeF())); -} - -namespace PySide -{ -const char *qmlNoCreationReason(PyObject *type) -{ - const auto &map = uncreatableReasonMap(); - auto it = map.find(type); - return it != map.cend() ? it->second.c_str() : nullptr; -} - -} // PySide diff --git a/sources/pyside6/PySide6/QtQml/pysideqmluncreatable.h b/sources/pyside6/PySide6/QtQml/pysideqmluncreatable.h deleted file mode 100644 index 89a5f1223..000000000 --- a/sources/pyside6/PySide6/QtQml/pysideqmluncreatable.h +++ /dev/null @@ -1,69 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2021 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$ -** -****************************************************************************/ - -#ifndef PYSIDEQMLUNCREATABLE_H -#define PYSIDEQMLUNCREATABLE_H - -#include <sbkpython.h> - -// The QmlUncreatable decorator modifies QmlElement to register an uncreatable -// type. Due to the (reverse) execution order of decorators, it needs to follow -// QmlElement. -extern "C" -{ - extern PyTypeObject *PySideQmlUncreatableTypeF(void); - - struct PySideQmlUncreatablePrivate; - struct PySideQmlUncreatable - { - PyObject_HEAD - PySideQmlUncreatablePrivate* d; - }; - -} // extern "C" - -void initQmlUncreatable(PyObject *module); - -namespace PySide -{ - // Return the reason if a type is not creatable. - const char *qmlNoCreationReason(PyObject *type); -} // PySide - -#endif // PYSIDEQMLUNCREATABLE_H diff --git a/sources/pyside6/PySide6/QtQml/typesystem_qml.xml b/sources/pyside6/PySide6/QtQml/typesystem_qml.xml index 30d21d86f..c292389e9 100644 --- a/sources/pyside6/PySide6/QtQml/typesystem_qml.xml +++ b/sources/pyside6/PySide6/QtQml/typesystem_qml.xml @@ -56,12 +56,9 @@ </inject-code> <inject-code class="native" position="beginning"> - #include "pysideqmlregistertype.h" - #include "pysideqmllistproperty.h" - #include "pysideqmluncreatable.h" + #include <pysideqml.h> + #include <pysideqmlregistertype.h> #include "pysideqmlvolatilebool.h" - #include "pysideqmlmetacallerror_p.h" - #include <signalmanager.h> </inject-code> <!-- This is to inform the generator that the VolatileBool python type exists --> diff --git a/sources/pyside6/PySide6/glue/qtqml.cpp b/sources/pyside6/PySide6/glue/qtqml.cpp index d32265d2e..12b394133 100644 --- a/sources/pyside6/PySide6/glue/qtqml.cpp +++ b/sources/pyside6/PySide6/glue/qtqml.cpp @@ -73,10 +73,8 @@ int %0 = PySide::qmlRegisterType(%ARGUMENT_NAMES, false); // @snippet qmlregisteruncreatabletype // @snippet init -initQtQmlListProperty(module); -initQmlUncreatable(module); +PySide::Qml::init(module); initQtQmlVolatileBool(module); -PySide::SignalManager::setQmlMetaCallErrorHandler(PySide::qmlMetaCallErrorHandler); // @snippet init // @snippet qjsengine-toscriptvalue |