diff options
Diffstat (limited to 'sources/pyside2/PySide2/glue/qtcore.cpp')
-rw-r--r-- | sources/pyside2/PySide2/glue/qtcore.cpp | 108 |
1 files changed, 73 insertions, 35 deletions
diff --git a/sources/pyside2/PySide2/glue/qtcore.cpp b/sources/pyside2/PySide2/glue/qtcore.cpp index 306a2239c..78de3d5d5 100644 --- a/sources/pyside2/PySide2/glue/qtcore.cpp +++ b/sources/pyside2/PySide2/glue/qtcore.cpp @@ -76,7 +76,7 @@ if (kwds || numArgs > 1) { PyTypeObject *typeObj = reinterpret_cast<PyTypeObject*>(%PYARG_3); -if (typeObj) { +if (typeObj && !Shiboken::ObjectType::checkType(typeObj)) { if (typeObj == &PyList_Type) { QByteArray out_ba = out.toByteArray(); if (!out_ba.isEmpty()) { @@ -122,8 +122,14 @@ if (typeObj) { Py_INCREF(Py_False); %PYARG_0 = Py_False; } + } else { + // TODO: PyDict_Type and PyTuple_Type + PyErr_SetString(PyExc_TypeError, + "Invalid type parameter.\n" + "\tUse 'list', 'bytes', 'str', 'int', 'float', 'bool', " + "or a Qt-derived type"); + return nullptr; } - // TODO: PyDict_Type and PyTuple_Type } else { if (!out.isValid()) { @@ -793,12 +799,35 @@ qRegisterMetaType<QVector<int> >("QVector<int>"); // @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 inline bool _findChildrenComparator(const QObject *child, + const QRegExp &name) +{ + return name.indexIn(child->objectName()) != -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())) { + if (_findChildrenComparator(child, name) + && _findChildTypeMatch(child, desiredType)) { return child; } } @@ -811,28 +840,15 @@ static QObject *_findChildHelper(const QObject *parent, const QString &name, PyT 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 QRegularExpression &name) -{ - return name.match(child->objectName()).hasMatch(); -} - -static inline bool _findChildrenComparator(const QObject *&child, const QString &name) -{ - return name.isNull() || name == child->objectName(); -} - -template<typename T> +template<typename T> // QString/QRegularExpression/QRegExp 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)) + if (_findChildrenComparator(child, name) + && _findChildTypeMatch(child, desiredType)) { + Shiboken::AutoDecRef pyChild(%CONVERTTOPYTHON[QObject *](child)); PyList_Append(result, pyChild); + } _findChildrenHelper(child, name, desiredType, result); } } @@ -848,19 +864,41 @@ QObject *child = _findChildHelper(%CPPSELF, %2, reinterpret_cast<PyTypeObject *> _findChildrenHelper(%CPPSELF, %2, reinterpret_cast<PyTypeObject *>(%PYARG_1), %PYARG_0); // @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 -QString result; -if (QCoreApplication::instance()) { - PyObject *klass = PyObject_GetAttr(%PYSELF, Shiboken::PyMagicName::class_()); - PyObject *cname = PyObject_GetAttr(klass, Shiboken::PyMagicName::name()); - result = QString(QCoreApplication::instance()->translate(Shiboken::String::toCString(cname), - /* %1, %2, QCoreApplication::CodecForTr, %3)); */ - %1, %2, %3)); - - Py_DECREF(klass); - Py_DECREF(cname); -} else { - result = QString(QString::fromLatin1(%1)); +PyTypeObject *type = Py_TYPE(%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; } %PYARG_0 = %CONVERTTOPYTHON[QString](result); // @snippet qobject-tr |