aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@qt.io>2021-11-23 19:08:06 +0100
committerFriedemann Kleint <Friedemann.Kleint@qt.io>2021-11-24 10:54:20 +0100
commit3636b306dc0638470473f37a1bb6291f6db7bf2d (patch)
tree1f3ac2107c224bff4c2d1e324f5f8b6d24110f57
parent42ca2d6052624445559ae44fa3f5d57ca591fb52 (diff)
PySide6: Move some code from the core snippets into a static source file
Split out code which does not use any code snippet placeholders into a separate source file for better maintainability. Change-Id: Id8d923b8faf58783f28e56b4bf4397117c39c51b Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Christian Tismer <tismer@stackless.com>
-rw-r--r--sources/pyside6/PySide6/QtCore/CMakeLists.txt7
-rw-r--r--sources/pyside6/PySide6/QtCore/glue/core_snippets.cpp275
-rw-r--r--sources/pyside6/PySide6/QtCore/glue/core_snippets_p.h87
-rw-r--r--sources/pyside6/PySide6/QtCore/typesystem_core_common.xml3
-rw-r--r--sources/pyside6/PySide6/glue/qtcore.cpp210
5 files changed, 376 insertions, 206 deletions
diff --git a/sources/pyside6/PySide6/QtCore/CMakeLists.txt b/sources/pyside6/PySide6/QtCore/CMakeLists.txt
index 00ed9a62c..dba4261f1 100644
--- a/sources/pyside6/PySide6/QtCore/CMakeLists.txt
+++ b/sources/pyside6/PySide6/QtCore/CMakeLists.txt
@@ -1,6 +1,9 @@
project(QtCore)
-set(QtCore_gluecode "${QtCore_SOURCE_DIR}/glue/qeasingcurve_glue.cpp")
+set(QtCore_static_sources
+ "${QtCore_SOURCE_DIR}/glue/qeasingcurve_glue.cpp"
+ "${QtCore_SOURCE_DIR}/glue/core_snippets.cpp"
+)
if(ENABLE_WIN)
set(SPECIFIC_OS_FILES
@@ -208,7 +211,7 @@ create_pyside_module(NAME QtCore
LIBRARIES QtCore_libraries
TYPESYSTEM_PATH QtCore_SOURCE_DIR
SOURCES QtCore_SRC
- STATIC_SOURCES QtCore_gluecode
+ STATIC_SOURCES QtCore_static_sources
TYPESYSTEM_NAME ${QtCore_BINARY_DIR}/typesystem_core.xml
GLUE_SOURCES QtCore_glue_sources
)
diff --git a/sources/pyside6/PySide6/QtCore/glue/core_snippets.cpp b/sources/pyside6/PySide6/QtCore/glue/core_snippets.cpp
new file mode 100644
index 000000000..86cfec1f8
--- /dev/null
+++ b/sources/pyside6/PySide6/QtCore/glue/core_snippets.cpp
@@ -0,0 +1,275 @@
+/****************************************************************************
+**
+** 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 "core_snippets_p.h"
+#include "pyside.h"
+
+#include "shiboken.h"
+#include "basewrapper.h"
+#include "autodecref.h"
+
+#include <QtCore/QCoreApplication>
+#include <QtCore/QDebug>
+#include <QtCore/QMetaType>
+#include <QtCore/QObject>
+#include <QtCore/QRegularExpression>
+#include <QtCore/QStack>
+#include <QtCore/QVariant>
+
+// Helpers for QVariant conversion
+
+QMetaType QVariant_resolveMetaType(PyTypeObject *type)
+{
+ if (!PyObject_TypeCheck(type, SbkObjectType_TypeF()))
+ return {};
+ 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 (Py_ssize_t 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 {};
+}
+
+QVariant QVariant_convertToValueList(PyObject *list)
+{
+ if (PySequence_Size(list) < 0) {
+ // clear the error if < 0 which means no length at all
+ PyErr_Clear();
+ return {};
+ }
+
+ Shiboken::AutoDecRef element(PySequence_GetItem(list, 0));
+
+ QMetaType metaType = QVariant_resolveMetaType(element.cast<PyTypeObject *>());
+ if (!metaType.isValid())
+ return {};
+
+ const QByteArray listTypeName = QByteArrayLiteral("QList<") + metaType.name() + '>';
+ metaType = QMetaType::fromName(listTypeName);
+ if (!metaType.isValid())
+ return {};
+
+ Shiboken::Conversions::SpecificConverter converter(listTypeName);
+ if (!converter) {
+ qWarning("Type converter for: %s not registered.", listTypeName.constData());
+ return {};
+ }
+
+ QVariant var(metaType);
+ converter.toCpp(list, &var);
+ return var;
+}
+
+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 (PyUnicode_Check(item) == 0)
+ return false;
+ }
+ return true;
+}
+
+// Helpers for qAddPostRoutine
+
+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 PySide
+
+// Helpers for QObject::findChild(ren)()
+
+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();
+}
+
+QObject *qObjectFindChild(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()) {
+ if (auto *obj = qObjectFindChild(child, name, desiredType, options))
+ return obj;
+ }
+ }
+ return nullptr;
+}
+
+template<typename T> // QString/QRegularExpression
+static void _findChildrenHelper(const QObject *parent, const T& name, PyTypeObject *desiredType,
+ Qt::FindChildOptions options, FindChildHandler handler)
+{
+ for (auto *child : parent->children()) {
+ if (_findChildrenComparator(child, name) && _findChildTypeMatch(child, desiredType))
+ handler(child);
+ if (options.testFlag(Qt::FindChildrenRecursively))
+ _findChildrenHelper(child, name, desiredType, options, handler);
+ }
+}
+
+void qObjectFindChildren(const QObject *parent, const QString &name,
+ PyTypeObject *desiredType, Qt::FindChildOptions options,
+ FindChildHandler handler)
+{
+ _findChildrenHelper(parent, name, desiredType, options, handler);
+}
+
+void qObjectFindChildren(const QObject *parent, const QRegularExpression &pattern,
+ PyTypeObject *desiredType, Qt::FindChildOptions options,
+ FindChildHandler handler)
+{
+ _findChildrenHelper(parent, pattern, desiredType, options, handler);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// Helpers for translation:
+// 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.
+
+QString qObjectTr(PyTypeObject *type, const char *sourceText, const char *disambiguation, int n)
+{
+ PyObject *mro = type->tp_mro;
+ auto len = PyTuple_GET_SIZE(mro);
+ QString result = QString::fromUtf8(sourceText);
+ 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, sourceText, disambiguation, n);
+ if (result != oldResult)
+ break;
+ }
+ return result;
+}
diff --git a/sources/pyside6/PySide6/QtCore/glue/core_snippets_p.h b/sources/pyside6/PySide6/QtCore/glue/core_snippets_p.h
new file mode 100644
index 000000000..9956288ad
--- /dev/null
+++ b/sources/pyside6/PySide6/QtCore/glue/core_snippets_p.h
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** 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 CORE_SNIPPETS_P_H
+#define CORE_SNIPPETS_P_H
+
+#include "pysidemacros.h"
+
+#include <sbkpython.h>
+
+#include <QtCore/qnamespace.h>
+
+#include <functional>
+
+QT_FORWARD_DECLARE_CLASS(QMetaType)
+QT_FORWARD_DECLARE_CLASS(QObject)
+QT_FORWARD_DECLARE_CLASS(QRegularExpression)
+QT_FORWARD_DECLARE_CLASS(QVariant);
+
+// Helpers for QVariant conversion
+
+QMetaType QVariant_resolveMetaType(PyTypeObject *type);
+
+QVariant QVariant_convertToValueList(PyObject *list);
+
+bool QVariant_isStringList(PyObject *list);
+
+// Helpers for qAddPostRoutine
+namespace PySide {
+void globalPostRoutineCallback();
+void addPostRoutine(PyObject *callback);
+}
+
+// Helpers for QObject::findChild(ren)()
+QObject *qObjectFindChild(const QObject *parent, const QString &name,
+ PyTypeObject *desiredType, Qt::FindChildOptions options);
+
+using FindChildHandler = std::function<void(QObject *)>;
+
+void qObjectFindChildren(const QObject *parent, const QString &name,
+ PyTypeObject *desiredType, Qt::FindChildOptions options,
+ FindChildHandler handler);
+
+void qObjectFindChildren(const QObject *parent, const QRegularExpression &pattern,
+ PyTypeObject *desiredType, Qt::FindChildOptions options,
+ FindChildHandler handler);
+
+// Helpers for translation
+QString qObjectTr(PyTypeObject *type, const char *sourceText, const char *disambiguation, int n);
+
+#endif // CORE_SNIPPETS_P_H
diff --git a/sources/pyside6/PySide6/QtCore/typesystem_core_common.xml b/sources/pyside6/PySide6/QtCore/typesystem_core_common.xml
index 4b9f31da1..81b6c65d0 100644
--- a/sources/pyside6/PySide6/QtCore/typesystem_core_common.xml
+++ b/sources/pyside6/PySide6/QtCore/typesystem_core_common.xml
@@ -629,7 +629,6 @@
<inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qt-qabs"/>
</add-function>
- <inject-code class="native" position="beginning" file="../glue/qtcore.cpp" snippet="qt-postroutine"/>
<add-function signature="qAddPostRoutine(PyObject*)">
<inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qt-addpostroutine"/>
</add-function>
@@ -1567,6 +1566,7 @@
<include file-name="QThread" location="global"/>
<include file-name="QCoreApplication" location="global"/>
<include file-name="signalmanager.h" location="local"/>
+ <include file-name="glue/core_snippets_p.h" location="local"/>
</extra-includes>
<modify-function signature="metaObject()const">
<inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qobject-metaobject"/>
@@ -1655,7 +1655,6 @@
</add-function>
- <inject-code class="native" file="../glue/qtcore.cpp" snippet="qobject-findchild-1"/>
<add-function signature="findChild(PyTypeObject*@type@,const QString&amp;@name@={},Qt::FindChildOptions@options@=Qt::FindChildrenRecursively)"
return-type="PyObject*">
<inject-documentation format="target" mode="append">
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