diff options
Diffstat (limited to 'sources/pyside6/PySide6/glue/qtcore.cpp')
-rw-r--r-- | sources/pyside6/PySide6/glue/qtcore.cpp | 210 |
1 files changed, 8 insertions, 202 deletions
diff --git a/sources/pyside6/PySide6/glue/qtcore.cpp b/sources/pyside6/PySide6/glue/qtcore.cpp index 14025e72a..692062637 100644 --- a/sources/pyside6/PySide6/glue/qtcore.cpp +++ b/sources/pyside6/PySide6/glue/qtcore.cpp @@ -44,6 +44,7 @@ // @snippet include-pyside #include <pyside.h> #include <limits> +#include "glue/core_snippets_p.h" // @snippet include-pyside // @snippet qsettings-value @@ -148,90 +149,6 @@ return %out; // @snippet conversion-qmetatype-pytypeobject // @snippet qvariant-conversion -static QMetaType QVariant_resolveMetaType(PyTypeObject *type) -{ - if (PyObject_TypeCheck(type, SbkObjectType_TypeF())) { - const char *typeName = Shiboken::ObjectType::getOriginalName(type); - if (!typeName) - return {}; - const bool valueType = '*' != typeName[qstrlen(typeName) - 1]; - // Do not convert user type of value - if (valueType && Shiboken::ObjectType::isUserType(type)) - return {}; - QMetaType metaType = QMetaType::fromName(typeName); - if (metaType.isValid()) - return metaType; - // Do not resolve types to value type - if (valueType) - return {}; - // Find in base types. First check tp_bases, and only after check tp_base, because - // tp_base does not always point to the first base class, but rather to the first - // that has added any python fields or slots to its object layout. - // See https://mail.python.org/pipermail/python-list/2009-January/520733.html - if (type->tp_bases) { - for (int i = 0, size = PyTuple_GET_SIZE(type->tp_bases); i < size; ++i) { - auto baseType = reinterpret_cast<PyTypeObject *>(PyTuple_GET_ITEM(type->tp_bases, i)); - const QMetaType derived = QVariant_resolveMetaType(baseType); - if (derived.isValid()) - return derived; - } - } else if (type->tp_base) { - return QVariant_resolveMetaType(type->tp_base); - } - } - return {}; -} -static QVariant QVariant_convertToValueList(PyObject *list) -{ - if (PySequence_Size(list) < 0) { - // clear the error if < 0 which means no length at all - PyErr_Clear(); - return QVariant(); - } - - Shiboken::AutoDecRef element(PySequence_GetItem(list, 0)); - - const QMetaType metaType = QVariant_resolveMetaType(element.cast<PyTypeObject *>()); - if (metaType.isValid()) { - QByteArray listTypeName("QList<"); - listTypeName += metaType.name(); - listTypeName += '>'; - QMetaType metaType = QMetaType::fromName(listTypeName); - if (metaType.isValid()) { - Shiboken::Conversions::SpecificConverter converter(listTypeName); - if (converter) { - QVariant var(metaType); - converter.toCpp(list, &var); - return var; - } - qWarning() << "Type converter for :" << listTypeName << "not registered."; - } - } - return QVariant(); -} -static bool QVariant_isStringList(PyObject *list) -{ - if (!PySequence_Check(list)) { - // If it is not a list or a derived list class - // we assume that will not be a String list neither. - return false; - } - - if (PySequence_Size(list) < 0) { - // clear the error if < 0 which means no length at all - PyErr_Clear(); - return false; - } - - Shiboken::AutoDecRef fast(PySequence_Fast(list, "Failed to convert QVariantList")); - const Py_ssize_t size = PySequence_Fast_GET_SIZE(fast.object()); - for (Py_ssize_t i = 0; i < size; ++i) { - PyObject *item = PySequence_Fast_GET_ITEM(fast.object(), i); - if (!%CHECKTYPE[QString](item)) - return false; - } - return true; -} static QVariant QVariant_convertToVariantMap(PyObject *map) { Py_ssize_t pos = 0; @@ -281,30 +198,6 @@ double _abs = qAbs(%1); %PYARG_0 = %CONVERTTOPYTHON[double](_abs); // @snippet qt-qabs -// @snippet qt-postroutine -namespace PySide { -static QStack<PyObject *> globalPostRoutineFunctions; -void globalPostRoutineCallback() -{ - Shiboken::GilState state; - for (auto *callback : globalPostRoutineFunctions) { - Shiboken::AutoDecRef result(PyObject_CallObject(callback, nullptr)); - Py_DECREF(callback); - } - globalPostRoutineFunctions.clear(); -} -void addPostRoutine(PyObject *callback) -{ - if (PyCallable_Check(callback)) { - globalPostRoutineFunctions << callback; - Py_INCREF(callback); - } else { - PyErr_SetString(PyExc_TypeError, "qAddPostRoutine: The argument must be a callable object."); - } -} -} // namespace -// @snippet qt-postroutine - // @snippet qt-addpostroutine PySide::addPostRoutine(%1); // @snippet qt-addpostroutine @@ -600,109 +493,22 @@ qRegisterMetaType<QList<int> >("QList<int>"); %PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0); // @snippet qobject-metaobject -// @snippet qobject-findchild-1 -static bool _findChildTypeMatch(const QObject *child, PyTypeObject *desiredType) -{ - auto *pyChildType = PySide::getTypeForQObject(child); - return pyChildType != nullptr && PyType_IsSubtype(pyChildType, desiredType); -} - -static inline bool _findChildrenComparator(const QObject *child, - const QRegularExpression &name) -{ - return name.match(child->objectName()).hasMatch(); -} - -static inline bool _findChildrenComparator(const QObject *child, - const QString &name) -{ - return name.isNull() || name == child->objectName(); -} - -static QObject *_findChildHelper(const QObject *parent, const QString &name, - PyTypeObject *desiredType, - Qt::FindChildOptions options) -{ - for (auto *child : parent->children()) { - if (_findChildrenComparator(child, name) - && _findChildTypeMatch(child, desiredType)) { - return child; - } - } - - if (options.testFlag(Qt::FindChildrenRecursively)) { - for (auto *child : parent->children()) { - QObject *obj = _findChildHelper(child, name, desiredType, options); - if (obj) - return obj; - } - } - return nullptr; -} - -template<typename T> // QString/QRegularExpression -static void _findChildrenHelper(const QObject *parent, const T& name, PyTypeObject *desiredType, - Qt::FindChildOptions options, - PyObject *result) -{ - for (const auto *child : parent->children()) { - if (_findChildrenComparator(child, name) && - _findChildTypeMatch(child, desiredType)) { - Shiboken::AutoDecRef pyChild(%CONVERTTOPYTHON[QObject *](child)); - PyList_Append(result, pyChild.object()); - } - if (options.testFlag(Qt::FindChildrenRecursively)) - _findChildrenHelper(child, name, desiredType, options, result); - } -} -// @snippet qobject-findchild-1 - // @snippet qobject-findchild-2 -QObject *child = _findChildHelper(%CPPSELF, %2, reinterpret_cast<PyTypeObject *>(%PYARG_1), %3); +QObject *child = qObjectFindChild(%CPPSELF, %2, reinterpret_cast<PyTypeObject *>(%PYARG_1), %3); %PYARG_0 = %CONVERTTOPYTHON[QObject *](child); // @snippet qobject-findchild-2 // @snippet qobject-findchildren %PYARG_0 = PyList_New(0); -_findChildrenHelper(%CPPSELF, %2, reinterpret_cast<PyTypeObject *>(%PYARG_1), %3, %PYARG_0); +qObjectFindChildren(%CPPSELF, %2, reinterpret_cast<PyTypeObject *>(%PYARG_1), %3, + [%PYARG_0](QObject *child) { + Shiboken::AutoDecRef pyChild(%CONVERTTOPYTHON[QObject *](child)); + PyList_Append(%PYARG_0, pyChild.object()); + }); // @snippet qobject-findchildren -////////////////////////////////////////////////////////////////////////////// -// PYSIDE-131: Use the class name as context where the calling function is -// living. Derived Python classes have the wrong context. -// -// The original patch uses Python introspection to look up the current -// function (from the frame stack) in the class __dict__ along the mro. -// -// The problem is that looking into the frame stack works for Python -// functions, only. For including builtin function callers, the following -// approach turned out to be much simpler: -// -// Walk the __mro__ -// - translate the string -// - if the translated string is changed: -// - return the translation. - // @snippet qobject-tr -PyTypeObject *type = reinterpret_cast<PyTypeObject *>(%PYSELF); -PyObject *mro = type->tp_mro; -auto len = PyTuple_GET_SIZE(mro); -QString result = QString::fromUtf8(%1); -QString oldResult = result; -static auto *sbkObjectType = reinterpret_cast<PyTypeObject *>(SbkObject_TypeF()); -for (Py_ssize_t idx = 0; idx < len - 1; ++idx) { - // Skip the last class which is `object`. - auto *type = reinterpret_cast<PyTypeObject *>(PyTuple_GET_ITEM(mro, idx)); - if (type == sbkObjectType) - continue; - const char *context = type->tp_name; - const char *dotpos = strrchr(context, '.'); - if (dotpos != nullptr) - context = dotpos + 1; - result = QCoreApplication::translate(context, %1, %2, %3); - if (result != oldResult) - break; -} +const QString result = qObjectTr(reinterpret_cast<PyTypeObject *>(%PYSELF), %1, %2, %3); %PYARG_0 = %CONVERTTOPYTHON[QString](result); // @snippet qobject-tr |