aboutsummaryrefslogtreecommitdiffstats
path: root/sources/pyside2/libpyside
diff options
context:
space:
mode:
Diffstat (limited to 'sources/pyside2/libpyside')
-rw-r--r--sources/pyside2/libpyside/CMakeLists.txt13
-rw-r--r--sources/pyside2/libpyside/PySide2Config-spec.cmake.in1
-rw-r--r--sources/pyside2/libpyside/destroylistener.cpp3
-rw-r--r--sources/pyside2/libpyside/destroylistener.h6
-rw-r--r--sources/pyside2/libpyside/dynamicqmetaobject.cpp991
-rw-r--r--sources/pyside2/libpyside/dynamicqmetaobject.h45
-rw-r--r--sources/pyside2/libpyside/dynamicqmetaobject_p.h5
-rw-r--r--sources/pyside2/libpyside/globalreceiver.cpp329
-rw-r--r--sources/pyside2/libpyside/globalreceiverv2.cpp48
-rw-r--r--sources/pyside2/libpyside/globalreceiverv2.h26
-rw-r--r--sources/pyside2/libpyside/pyside.cpp90
-rw-r--r--sources/pyside2/libpyside/pyside.h12
-rw-r--r--sources/pyside2/libpyside/pyside2.pc.in1
-rw-r--r--sources/pyside2/libpyside/pyside_p.h (renamed from sources/pyside2/libpyside/globalreceiver.h)53
-rw-r--r--sources/pyside2/libpyside/pysideclassinfo.cpp20
-rw-r--r--sources/pyside2/libpyside/pysideclassinfo.h6
-rw-r--r--sources/pyside2/libpyside/pysidemetafunction.cpp7
-rw-r--r--sources/pyside2/libpyside/pysidemetafunction.h7
-rw-r--r--sources/pyside2/libpyside/pysidemetafunction_p.h4
-rw-r--r--sources/pyside2/libpyside/pysideproperty.cpp33
-rw-r--r--sources/pyside2/libpyside/pysideproperty.h4
-rw-r--r--sources/pyside2/libpyside/pysideqflags.cpp12
-rw-r--r--sources/pyside2/libpyside/pysidesignal.cpp41
-rw-r--r--sources/pyside2/libpyside/pysidesignal.h13
-rw-r--r--sources/pyside2/libpyside/pysideslot.cpp9
-rw-r--r--sources/pyside2/libpyside/pysideweakref.cpp2
-rw-r--r--sources/pyside2/libpyside/signalmanager.cpp (renamed from sources/pyside2/libpyside/signalmanager.cpp.in)132
-rw-r--r--sources/pyside2/libpyside/signalmanager.h34
28 files changed, 609 insertions, 1338 deletions
diff --git a/sources/pyside2/libpyside/CMakeLists.txt b/sources/pyside2/libpyside/CMakeLists.txt
index 3069b1ca2..ec6713b62 100644
--- a/sources/pyside2/libpyside/CMakeLists.txt
+++ b/sources/pyside2/libpyside/CMakeLists.txt
@@ -17,6 +17,7 @@ if(${Qt5Quick_FOUND})
endif()
endif()
+set(QML_PRIVATE_API_SUPPORT 0)
if(Qt5Qml_FOUND)
# Used for registering custom QQuickItem classes defined in Python code.
set(QML_SUPPORT 1)
@@ -28,7 +29,6 @@ if(Qt5Qml_FOUND)
set(QML_PRIVATE_API_SUPPORT 1)
set(QML_INCLUDES ${QML_INCLUDES} ${Qt5Qml_PRIVATE_INCLUDE_DIRS})
else()
- set(QML_PRIVATE_API_SUPPORT 0)
message(WARNING "QML private API include files could not be found, support for catching QML exceptions inside Python code will not work.")
endif()
else()
@@ -40,14 +40,10 @@ endif()
qt5_wrap_cpp(DESTROYLISTENER_MOC "destroylistener.h")
-configure_file("${CMAKE_CURRENT_SOURCE_DIR}/signalmanager.cpp.in"
- "${CMAKE_CURRENT_BINARY_DIR}/signalmanager.cpp" @ONLY)
-
set(libpyside_SRC
dynamicqmetaobject.cpp
destroylistener.cpp
- ${CMAKE_CURRENT_BINARY_DIR}/signalmanager.cpp
- globalreceiver.cpp
+ signalmanager.cpp
globalreceiverv2.cpp
pysideclassinfo.cpp
pysidemetafunction.cpp
@@ -86,7 +82,8 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR}
${SHIBOKEN_INCLUDE_DIR}
${SHIBOKEN_PYTHON_INCLUDE_DIR}
${QML_INCLUDES}
- ${Qt5Core_INCLUDE_DIRS})
+ ${Qt5Core_INCLUDE_DIRS}
+ ${Qt5Core_PRIVATE_INCLUDE_DIRS})
add_library(pyside2 SHARED ${libpyside_SRC} ${other_files})
target_link_libraries(pyside2
${SHIBOKEN_PYTHON_LIBRARIES}
@@ -107,6 +104,7 @@ endif()
if(QML_SUPPORT)
target_compile_definitions(pyside2 PUBLIC PYSIDE_QML_SUPPORT=1)
endif()
+target_compile_definitions(pyside2 PRIVATE PYSIDE_QML_PRIVATE_API_SUPPORT=${QML_PRIVATE_API_SUPPORT})
if(PYSIDE_QT_CONF_PREFIX)
set_property(SOURCE pyside.cpp
@@ -122,7 +120,6 @@ endif()
set(libpyside_HEADERS
destroylistener.h
dynamicqmetaobject.h
- globalreceiver.h
pysideclassinfo.h
pysidemacros.h
signalmanager.h
diff --git a/sources/pyside2/libpyside/PySide2Config-spec.cmake.in b/sources/pyside2/libpyside/PySide2Config-spec.cmake.in
index 4281ade5b..afb81f5a6 100644
--- a/sources/pyside2/libpyside/PySide2Config-spec.cmake.in
+++ b/sources/pyside2/libpyside/PySide2Config-spec.cmake.in
@@ -16,3 +16,4 @@ else()
endif()
SET(PYSIDE_PYTHONPATH "@PYTHON_SITE_PACKAGES@")
SET(PYSIDE_TYPESYSTEMS "@CMAKE_INSTALL_PREFIX@/share/PySide2@pyside2_SUFFIX@/typesystems")
+SET(PYSIDE_GLUE "@CMAKE_INSTALL_PREFIX@/share/PySide2@pyside2_SUFFIX@/glue")
diff --git a/sources/pyside2/libpyside/destroylistener.cpp b/sources/pyside2/libpyside/destroylistener.cpp
index 95e53f709..c6dc54713 100644
--- a/sources/pyside2/libpyside/destroylistener.cpp
+++ b/sources/pyside2/libpyside/destroylistener.cpp
@@ -40,10 +40,7 @@
#include <sbkpython.h>
#include "destroylistener.h"
-#include <QObject>
#include <shiboken.h>
-#include <QDebug>
-#include <QMutex>
PySide::DestroyListener* PySide::DestroyListener::m_instance = 0;
diff --git a/sources/pyside2/libpyside/destroylistener.h b/sources/pyside2/libpyside/destroylistener.h
index 0a800451a..b1a0597c5 100644
--- a/sources/pyside2/libpyside/destroylistener.h
+++ b/sources/pyside2/libpyside/destroylistener.h
@@ -40,10 +40,10 @@
#ifndef PYSIDE_DESTROY_LISTENER
#define PYSIDE_DESTROY_LISTENER
-
-#include <QObject>
#include "pysidemacros.h"
+#include <QtCore/QObject>
+
namespace PySide
{
struct DestroyListenerPrivate;
@@ -63,7 +63,7 @@ class PYSIDE_API DestroyListener : public QObject
static DestroyListener* m_instance;
DestroyListenerPrivate* m_d;
DestroyListener(QObject *parent);
- ~DestroyListener();
+ ~DestroyListener() override;
};
}//namespace
diff --git a/sources/pyside2/libpyside/dynamicqmetaobject.cpp b/sources/pyside2/libpyside/dynamicqmetaobject.cpp
index af2f416c6..b664e149b 100644
--- a/sources/pyside2/libpyside/dynamicqmetaobject.cpp
+++ b/sources/pyside2/libpyside/dynamicqmetaobject.cpp
@@ -45,546 +45,376 @@
#include "pysideproperty_p.h"
#include "pysideslot_p.h"
-#include <QByteArray>
-#include <QString>
-#include <QStringList>
-#include <QList>
-#include <QLinkedList>
-#include <QObject>
-#include <cstring>
-#include <QDebug>
-#include <QMetaMethod>
#include <shiboken.h>
+#include <QtCore/QByteArray>
+#include <QtCore/QObject>
+#include <QtCore/QStringList>
+#include <QtCore/QTextStream>
+#include <QtCore/QVector>
+#include <private/qmetaobjectbuilder_p.h>
-#define EMPTY_META_METHOD "0()"
+#include <cstring>
+#include <vector>
using namespace PySide;
-enum PropertyFlags {
- Invalid = 0x00000000,
- Readable = 0x00000001,
- Writable = 0x00000002,
- Resettable = 0x00000004,
- EnumOrFlag = 0x00000008,
- StdCppSet = 0x00000100,
-// Override = 0x00000200,
- Constant = 0x00000400,
- Final = 0x00000800,
- Designable = 0x00001000,
- ResolveDesignable = 0x00002000,
- Scriptable = 0x00004000,
- ResolveScriptable = 0x00008000,
- Stored = 0x00010000,
- ResolveStored = 0x00020000,
- Editable = 0x00040000,
- ResolveEditable = 0x00080000,
- User = 0x00100000,
- ResolveUser = 0x00200000,
- Notify = 0x00400000
-};
-
-// these values are from moc source code, generator.cpp:66
-enum MethodFlags {
- AccessPrivate = 0x00,
- AccessProtected = 0x01,
- AccessPublic = 0x02,
- MethodMethod = 0x00,
- MethodSignal = 0x04,
- MethodSlot = 0x08,
- MethodConstructor = 0x0c,
- MethodCompatibility = 0x10,
- MethodCloned = 0x20,
- MethodScriptable = 0x40
-};
-
-enum MetaDataFlags {
- IsUnresolvedType = 0x80000000,
- TypeNameIndexMask = 0x7FFFFFFF
-};
-
-class DynamicQMetaObject::DynamicQMetaObjectPrivate
+// MetaObjectBuilder: Provides the QMetaObject's returned by
+// QObject::metaObject() for PySide2 objects. There are several
+// scenarios to consider:
+// 1) A plain Qt class (say QTimer) is instantiated. In that case,
+// return the base meta object until a modification is made by
+// adding methods, properties or class info (cf qmetaobject_test.py).
+// In that case, instantiate a QMetaObjectBuilder inheriting the
+// base meta meta object, add the method and return the result
+// of QMetaObjectBuilder::toMetaObject() (with dirty handling should
+// further modifications be made).
+// 2) A Python class inheriting a Qt class is instantiated. For this,
+// instantiate a QMetaObjectBuilder and add the methods/properties
+// found by inspecting the Python class.
+
+class MetaObjectBuilderPrivate
{
public:
- QList<MethodData> m_methods;
- QList<PropertyData> m_properties;
-
- QMap<QByteArray, QByteArray> m_info;
- QByteArray m_className;
- bool m_updated; // when the meta data is not update
- int m_methodOffset;
- int m_propertyOffset;
- int m_dataSize;
- int m_emptyMethod;
- int m_nullIndex;
-
- DynamicQMetaObjectPrivate()
- : m_updated(false), m_methodOffset(0), m_propertyOffset(0),
- m_dataSize(0), m_emptyMethod(-1), m_nullIndex(0) {}
-
- int createMetaData(QMetaObject* metaObj, QLinkedList<QByteArray> &strings);
- void updateMetaObject(QMetaObject* metaObj);
- void writeMethodsData(const QList<MethodData>& methods, unsigned int** data, QLinkedList<QByteArray>& strings, int* prtIndex, int nullIndex, int flags);
- void writeStringData(char *, QLinkedList<QByteArray> &strings);
+ using MetaObjects = std::vector<const QMetaObject *>;
+
+ QMetaObjectBuilder *ensureBuilder();
+ void parsePythonType(PyTypeObject *type);
+ int indexOfMethod(QMetaMethod::MethodType mtype,
+ const QByteArray &signature) const;
+ int indexOfProperty(const QByteArray &name) const;
+ int addSlot(const QByteArray &signature);
+ int addSlot(const QByteArray &signature, const QByteArray &type);
+ int addSignal(const QByteArray &signature);
+ void removeMethod(QMetaMethod::MethodType mtype, int index);
int getPropertyNotifyId(PySideProperty *property) const;
-};
+ int addProperty(const QByteArray &property, PyObject *data);
+ void addInfo(const QByteArray &key, const QByteArray &value);
+ void addInfo(const QMap<QByteArray, QByteArray> &info);
+ void removeProperty(int index);
+ const QMetaObject *update();
-bool sortMethodSignalSlot(const MethodData &m1, const MethodData &m2)
-{
- if (m1.methodType() == QMetaMethod::Signal)
- return m2.methodType() == QMetaMethod::Slot;
- return false;
-}
+ QMetaObjectBuilder *m_builder = nullptr;
+
+ const QMetaObject *m_baseObject = nullptr;
+ MetaObjects m_cachedMetaObjects;
+ bool m_dirty = true;
+};
-static int registerString(const QByteArray& s, QLinkedList<QByteArray>& strings)
+QMetaObjectBuilder *MetaObjectBuilderPrivate::ensureBuilder()
{
- int idx = 0;
- QLinkedList<QByteArray>::const_iterator it = strings.begin();
- QLinkedList<QByteArray>::const_iterator itEnd = strings.end();
- while (it != itEnd) {
- if (strcmp(*it, s) == 0)
- return idx;
- ++idx;
- ++it;
+ if (!m_builder) {
+ m_builder = new QMetaObjectBuilder();
+ m_builder->setClassName(m_baseObject->className());
+ m_builder->setSuperClass(m_baseObject);
}
- strings.append(s);
- return idx;
+ return m_builder;
}
-static int blobSize(QLinkedList<QByteArray> &strings)
+MetaObjectBuilder::MetaObjectBuilder(const char *className, const QMetaObject *metaObject) :
+ m_d(new MetaObjectBuilderPrivate)
{
- int size = strings.size() * sizeof(QByteArrayData);
-
- QByteArray str;
- QByteArray debug_str;
- foreach (const QByteArray &field, strings) {
- str.append(field);
- str.append(char(0));
-
- debug_str.append(field);
- debug_str.append('|');
- }
- //qDebug()<<debug_str;
- size += str.size();
- return size;
+ m_d->m_baseObject = metaObject;
+ m_d->m_builder = new QMetaObjectBuilder();
+ m_d->m_builder->setClassName(className);
+ m_d->m_builder->setSuperClass(metaObject);
+ m_d->m_builder->setClassName(className);
}
-static int aggregateParameterCount(const QList<MethodData> &methods)
+MetaObjectBuilder::MetaObjectBuilder(PyTypeObject *type, const QMetaObject *metaObject)
+ : m_d(new MetaObjectBuilderPrivate)
{
- int sum = 0;
- for (int i = 0; i < methods.size(); ++i)
- sum += methods.at(i).parameterCount() * 2 + 1; // nb_param*2 (type and names) +1 for return type
- return sum;
+ m_d->m_baseObject = metaObject;
+ const char *className = type->tp_name;
+ if (const char *lastDot = strrchr(type->tp_name, '.'))
+ className = lastDot + 1;
+ // Different names indicate a Python class inheriting a Qt class.
+ // Parse the type.
+ if (strcmp(className, metaObject->className()) != 0) {
+ m_d->m_builder = new QMetaObjectBuilder();
+ m_d->m_builder->setClassName(className);
+ m_d->m_builder->setSuperClass(metaObject);
+ m_d->parsePythonType(type);
+ }
}
-static void writeString(char *out, int i, const QByteArray &str,
- const int offsetOfStringdataMember, int &stringdataOffset)
+MetaObjectBuilder::~MetaObjectBuilder()
{
- int size = str.size();
- qptrdiff offset = offsetOfStringdataMember + stringdataOffset
- - i * sizeof(QByteArrayData);
- const QByteArrayData data =
- Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(size, offset);
-
- memcpy(out + i * sizeof(QByteArrayData), &data, sizeof(QByteArrayData));
-
- memcpy(out + offsetOfStringdataMember + stringdataOffset, str.constData(), size);
- out[offsetOfStringdataMember + stringdataOffset + size] = '\0';
-
- stringdataOffset += size + 1;
+ qDeleteAll(m_d->m_cachedMetaObjects);
+ delete m_d->m_builder;
+ delete m_d;
}
-static int qvariant_nameToType(const char* name)
+int MetaObjectBuilderPrivate::indexOfMethod(QMetaMethod::MethodType mtype,
+ const QByteArray &signature) const
{
- if (!name)
- return 0;
-
- if (strcmp(name, "QVariant") == 0)
- return 0xffffffff;
- if (strcmp(name, "QCString") == 0)
- return QMetaType::QByteArray;
- if (strcmp(name, "Q_LLONG") == 0)
- return QMetaType::LongLong;
- if (strcmp(name, "Q_ULLONG") == 0)
- return QMetaType::ULongLong;
- if (strcmp(name, "QIconSet") == 0)
- return QMetaType::QIcon;
-
- uint tp = QMetaType::type(name);
- return tp < QMetaType::User ? tp : 0;
+ int result = -1;
+ if (m_builder) {
+ switch (mtype) {
+ case QMetaMethod::Signal:
+ result = m_builder->indexOfSignal(signature);
+ break;
+ case QMetaMethod::Slot:
+ result = m_builder->indexOfSlot(signature);
+ break;
+ case QMetaMethod::Constructor:
+ result = m_builder->indexOfConstructor(signature);
+ break;
+ case QMetaMethod::Method:
+ result = m_builder->indexOfMethod(signature);
+ break;
+ }
+ if (result >= 0)
+ return result + m_baseObject->methodCount();
+ }
+ switch (mtype) {
+ case QMetaMethod::Signal:
+ result = m_baseObject->indexOfSignal(signature);
+ break;
+ case QMetaMethod::Slot:
+ result = m_baseObject->indexOfSlot(signature);
+ break;
+ case QMetaMethod::Constructor:
+ result = m_baseObject->indexOfConstructor(signature);
+ break;
+ case QMetaMethod::Method:
+ result = m_baseObject->indexOfMethod(signature);
+ break;
+ }
+ return result;
}
-/*
- Returns true if the type is a QVariant types.
-*/
-static bool isVariantType(const char* type)
+int MetaObjectBuilder::indexOfMethod(QMetaMethod::MethodType mtype,
+ const QByteArray &signature) const
{
- return qvariant_nameToType(type) != 0;
+ return m_d->indexOfMethod(mtype, signature);
}
-/*!
- Returns true if the type is qreal.
-*/
-static bool isQRealType(const char *type)
+int MetaObjectBuilderPrivate::indexOfProperty(const QByteArray &name) const
{
- return strcmp(type, "qreal") == 0;
+ if (m_builder) {
+ const int result = m_builder->indexOfProperty(name);
+ if (result >= 0)
+ return m_baseObject->propertyCount() + result;
+ }
+ return m_baseObject->indexOfProperty(name);
}
-uint PropertyData::flags() const
+int MetaObjectBuilder::indexOfProperty(const QByteArray &name) const
{
- const QByteArray btype(type());
- const char* typeName = btype.data();
- uint flags = Invalid;
- if (!isVariantType(typeName))
- flags |= EnumOrFlag;
- else if (!isQRealType(typeName))
- flags |= qvariant_nameToType(typeName) << 24;
-
- if (PySide::Property::isReadable(m_data))
- flags |= Readable;
-
- if (PySide::Property::isWritable(m_data))
- flags |= Writable;
-
- if (PySide::Property::hasReset(m_data))
- flags |= Resettable;
-
- if (PySide::Property::isDesignable(m_data))
- flags |= Designable;
- else
- flags |= ResolveDesignable;
-
- if (PySide::Property::isScriptable(m_data))
- flags |= Scriptable;
- else
- flags |= ResolveScriptable;
-
- if (PySide::Property::isStored(m_data))
- flags |= Stored;
- else
- flags |= ResolveStored;
-
- //EDITABLE
- flags |= ResolveEditable;
-
- if (PySide::Property::isUser(m_data))
- flags |= User;
- else
- flags |= ResolveUser;
-
- if (m_cachedNotifyId != -1)
- flags |= Notify;
-
- if (PySide::Property::isConstant(m_data))
- flags |= Constant;
-
- if (PySide::Property::isFinal(m_data))
- flags |= Final;
-
- return flags;
+ return m_d->indexOfProperty(name);
}
-// const QByteArray with EMPTY_META_METHOD, used to save some memory
-const QByteArray MethodData::m_emptySig(EMPTY_META_METHOD);
-
-MethodData::MethodData()
- : m_signature(m_emptySig)
+static bool checkMethodSignature(const QByteArray &signature)
{
+ // Common mistake not to add parentheses to the signature.
+ const int openParen = signature.indexOf('(');
+ const int closingParen = signature.lastIndexOf(')');
+ const bool ok = openParen != -1 && closingParen != -1 && openParen < closingParen;
+ if (!ok) {
+ const QByteArray message =
+ "MetaObjectBuilder::addMethod: Invalid method signature provided for \""
+ + signature + '"';
+ PyErr_WarnEx(PyExc_RuntimeWarning, message.constData(), 0);
+ }
+ return ok;
}
-MethodData::MethodData(QMetaMethod::MethodType mtype, const QByteArray& signature, const QByteArray& rtype)
- : m_signature(QMetaObject::normalizedSignature(signature.constData()))
- , m_rtype(QMetaObject::normalizedSignature(rtype.constData()))
- , m_mtype(mtype)
+int MetaObjectBuilderPrivate::addSlot(const QByteArray &signature)
{
+ if (!checkMethodSignature(signature))
+ return -1;
+ m_dirty = true;
+ return m_baseObject->methodCount()
+ + ensureBuilder()->addSlot(signature).index();
}
-void MethodData::clear()
+int MetaObjectBuilder::addSlot(const char *signature)
{
- m_signature = m_emptySig;
- m_rtype.clear();
+ return m_d->addSlot(signature);
}
-bool MethodData::isValid() const
+int MetaObjectBuilderPrivate::addSlot(const QByteArray &signature,
+ const QByteArray &type)
{
- return m_signature != m_emptySig;
-}
-
-QList<QByteArray> MethodData::parameterTypes() const
-{
- const char *signature = m_signature.constData();
- QList<QByteArray> list;
- while (*signature && *signature != '(')
- ++signature;
- while (*signature && *signature != ')' && *++signature != ')') {
- const char *begin = signature;
- int level = 0;
- while (*signature && (level > 0 || *signature != ',') && *signature != ')') {
- if (*signature == '<')
- ++level;
- else if (*signature == '>')
- --level;
- ++signature;
- }
- list += QByteArray(begin, signature - begin);
- }
- return list;
+ if (!checkMethodSignature(signature))
+ return -1;
+ m_dirty = true;
+ QMetaMethodBuilder methodBuilder = ensureBuilder()->addSlot(signature);
+ methodBuilder.setReturnType(type);
+ return m_baseObject->methodCount() + methodBuilder.index();
}
-int MethodData::parameterCount() const
+int MetaObjectBuilder::addSlot(const char *signature, const char *type)
{
- return parameterTypes().size();
+ return m_d->addSlot(signature, type);
}
-QByteArray MethodData::name() const
+int MetaObjectBuilderPrivate::addSignal(const QByteArray &signature)
{
- return m_signature.left(qMax(m_signature.indexOf('('), 0));
+ if (!checkMethodSignature(signature))
+ return -1;
+ m_dirty = true;
+ return m_baseObject->methodCount()
+ + ensureBuilder()->addSignal(signature).index();
}
-PropertyData::PropertyData()
- : m_cachedNotifyId(0), m_data(0)
+int MetaObjectBuilder::addSignal(const char *signature)
{
+ return m_d->addSignal(signature);
}
-PropertyData::PropertyData(const char* name, int notifyId, PySideProperty* data)
- : m_name(name), m_cachedNotifyId(notifyId), m_data(data)
+void MetaObjectBuilderPrivate::removeMethod(QMetaMethod::MethodType mtype,
+ int index)
{
+ index -= m_baseObject->methodCount();
+ auto builder = ensureBuilder();
+ Q_ASSERT(index >= 0 && index < builder->methodCount());
+ switch (mtype) {
+ case QMetaMethod::Constructor:
+ builder->removeConstructor(index);
+ break;
+ default:
+ builder->removeMethod(index);
+ break;
+ }
+ m_dirty = true;
}
-QByteArray PropertyData::type() const
+void MetaObjectBuilder::removeMethod(QMetaMethod::MethodType mtype, int index)
{
- return QByteArray(PySide::Property::getTypeName(m_data));
+ m_d->removeMethod(mtype, index);
}
-
-bool PropertyData::isValid() const
+int MetaObjectBuilderPrivate::getPropertyNotifyId(PySideProperty *property) const
{
- return !m_name.isEmpty();
+ int notifyId = -1;
+ if (property->d->notify) {
+ if (const char *signalNotify = PySide::Property::getNotifyName(property))
+ notifyId = indexOfMethod(QMetaMethod::Signal, signalNotify);
+ }
+ return notifyId;
}
-int PropertyData::cachedNotifyId() const
+int MetaObjectBuilderPrivate::addProperty(const QByteArray &propertyName,
+ PyObject *data)
{
- return m_cachedNotifyId;
-}
+ int index = indexOfProperty(propertyName);
+ if (index != -1)
+ return index;
-bool PropertyData::operator==(const PropertyData& other) const
-{
- return m_data == other.m_data;
+ PySideProperty *property = reinterpret_cast<PySideProperty *>(data);
+ int propertyNotifyId = getPropertyNotifyId(property);
+ if (propertyNotifyId >= 0)
+ propertyNotifyId -= m_baseObject->methodCount();
+ auto newProperty =
+ ensureBuilder()->addProperty(propertyName, property->d->typeName,
+ propertyNotifyId);
+ index = newProperty.index() + m_baseObject->propertyCount();
+ m_dirty = true;
+ return index;
}
-bool PropertyData::operator==(const char* name) const
+int MetaObjectBuilder::addProperty(const char *property, PyObject *data)
{
- return m_name == name;
+ return m_d->addProperty(property, data);
}
-
-DynamicQMetaObject::DynamicQMetaObject(PyTypeObject* type, const QMetaObject* base)
- : m_d(new DynamicQMetaObjectPrivate)
+void MetaObjectBuilderPrivate::addInfo(const QByteArray &key,
+ const QByteArray &value)
{
- d.superdata = base;
- d.stringdata = NULL;
- d.data = NULL;
- d.extradata = NULL;
- d.relatedMetaObjects = NULL;
- d.static_metacall = NULL;
-
- m_d->m_className = QByteArray(type->tp_name).split('.').last();
- m_d->m_methodOffset = base->methodCount() - 1;
- m_d->m_propertyOffset = base->propertyCount() - 1;
- parsePythonType(type);
+ ensureBuilder()->addClassInfo(key, value);
+ m_dirty = true;
}
-DynamicQMetaObject::DynamicQMetaObject(const char* className, const QMetaObject* metaObject)
- : m_d(new DynamicQMetaObjectPrivate)
+void MetaObjectBuilder::addInfo(const char *key, const char *value)
{
- d.superdata = metaObject;
- d.stringdata = 0;
- d.data = 0;
- d.extradata = 0;
- d.relatedMetaObjects = NULL;
- d.static_metacall = NULL;
-
- m_d->m_className = className;
- m_d->m_methodOffset = metaObject->methodCount() - 1;
- m_d->m_propertyOffset = metaObject->propertyCount() - 1;
+ m_d->addInfo(key, value);
}
-DynamicQMetaObject::~DynamicQMetaObject()
+void MetaObjectBuilderPrivate::addInfo(const QMap<QByteArray, QByteArray> &info)
{
- free(reinterpret_cast<char *>(const_cast<QByteArrayData *>(d.stringdata)));
- free(const_cast<uint*>(d.data));
- delete m_d;
+ auto builder = ensureBuilder();
+ for (auto i = info.constBegin(), end = info.constEnd(); i != end; ++i)
+ builder->addClassInfo(i.key(), i.value());
+ m_dirty = true;
}
-int DynamicQMetaObject::addMethod(QMetaMethod::MethodType mtype, const char* signature, const char* type)
+void MetaObjectBuilder::addInfo(const QMap<QByteArray, QByteArray> &info)
{
- int index = -1;
- int counter = 0;
-
- QList<MethodData>::iterator it = m_d->m_methods.begin();
- for (; it != m_d->m_methods.end(); ++it) {
- if ((it->signature() == signature) && (it->methodType() == mtype))
- return m_d->m_methodOffset + counter;
- else if (!it->isValid()) {
- index = counter;
- }
- counter++;
- }
-
- // Common mistake not to add parentheses to the signature.
- if ((strchr(signature, ')') == 0) || ((strchr(signature, '(') == 0))) {
- const QString message =
- QLatin1String("DynamicQMetaObject::addMethod: Invalid method signature "
- "provided for ") + QLatin1String(signature);
- const QByteArray messageLatin = message.toLatin1();
- PyErr_WarnEx(PyExc_RuntimeWarning, messageLatin.constData(), 0);
- return -1;
- }
-
- //has blank method
- if (index != -1) {
- m_d->m_methods[index] = MethodData(mtype, signature, type);
- index++;
- } else {
- m_d->m_methods << MethodData(mtype, signature, type);
- index = m_d->m_methods.size();
- }
-
- m_d->m_updated = false;
- return m_d->m_methodOffset + index;
+ m_d->addInfo(info);
}
-void DynamicQMetaObject::removeMethod(QMetaMethod::MethodType mtype, uint index)
+void MetaObjectBuilderPrivate::removeProperty(int index)
{
- const char* methodSig = method(index).methodSignature();
- QList<MethodData>::iterator it = m_d->m_methods.begin();
- for (; it != m_d->m_methods.end(); ++it) {
- if ((it->signature() == methodSig) && (it->methodType() == mtype)){
- it->clear();
- m_d->m_updated = false;
- break;
- }
- }
+ index -= m_baseObject->propertyCount();
+ auto builder = ensureBuilder();
+ Q_ASSERT(index >= 0 && index < builder->propertyCount());
+ builder->removeProperty(index);
+ m_dirty = true;
}
-int DynamicQMetaObject::addSignal(const char* signal, const char* type)
+void MetaObjectBuilder::removeProperty(int index)
{
- return addMethod(QMetaMethod::Signal, signal, type);
+ m_d->removeProperty(index);
}
-int DynamicQMetaObject::addSlot(const char* slot, const char* type)
-{
- return addMethod(QMetaMethod::Slot, slot, type);
-}
-
-void DynamicQMetaObject::removeSlot(uint index)
-{
- removeMethod(QMetaMethod::Slot, index);
-}
-
-void DynamicQMetaObject::removeSignal(uint index)
-{
- removeMethod(QMetaMethod::Signal, index);
-}
+// PYSIDE-315: Instead of sorting the items and maybe breaking indices, we
+// ensure that the signals and slots are sorted by the improved
+// parsePythonType() (signals must go before slots). The order can only
+// become distorted if the class is modified after creation. In that
+// case, we give a warning.
-int DynamicQMetaObject::addProperty(const char* propertyName, PyObject* data)
+static QString msgMethodSortOrder(const QMetaObject *mo, int offendingIndex)
{
- int index = m_d->m_properties.indexOf(propertyName);
- if (index != -1)
- return m_d->m_propertyOffset + index;
-
- // retrieve notifyId
- PySideProperty *property = reinterpret_cast<PySideProperty *>(data);
- const int notifyId = m_d->getPropertyNotifyId(property);
-
- //search for a empty space
- PropertyData blank;
- index = m_d->m_properties.indexOf(blank);
- if (index != -1) {
- m_d->m_properties[index] = PropertyData(propertyName, notifyId, property);
- } else {
- m_d->m_properties << PropertyData(propertyName, notifyId, property);
- index = m_d->m_properties.size();
+ QString result;
+ QTextStream str(&result);
+ str << "\n\n*** Sort Warning ***\nSignals and slots in QMetaObject '"
+ << mo->className()
+ << "' are not ordered correctly, this may lead to issues.\n";
+ const int methodOffset = mo->methodOffset();
+ for (int m = methodOffset, methodCount = mo->methodCount(); m < methodCount; ++m) {
+ const auto method = mo->method(m);
+ str << (m - methodOffset + 1) << (m > offendingIndex ? '!' : ' ')
+ << (method.methodType() == QMetaMethod::Signal ? " Signal " : " Slot ")
+ << method.methodSignature() << '\n';
}
- m_d->m_updated = false;
- return m_d->m_propertyOffset + index;
+ return result;
}
-int DynamicQMetaObject::DynamicQMetaObjectPrivate::getPropertyNotifyId(PySideProperty *property) const
+static void checkMethodOrder(const QMetaObject *metaObject)
{
- int notifyId = -1;
- if (property->d->notify) {
- const char *signalNotify = PySide::Property::getNotifyName(property);
- if (signalNotify) {
- const MethodData signalObject(QMetaMethod::Signal, signalNotify, "");
- notifyId = m_methods.indexOf(signalObject);
+ const int lastMethod = metaObject->methodCount() - 1;
+ for (int m = metaObject->methodOffset(); m < lastMethod; ++m) {
+ if (metaObject->method(m).methodType() == QMetaMethod::Slot
+ && metaObject->method(m + 1).methodType() == QMetaMethod::Signal) {
+ const auto message = msgMethodSortOrder(metaObject, m);
+ PyErr_WarnEx(PyExc_RuntimeWarning, qPrintable(message), 0);
+ // Prevent a warning from being turned into an error. We cannot easily unwind.
+ PyErr_Clear();
+ break;
}
}
- return notifyId;
-}
-
-void DynamicQMetaObject::addInfo(const char* key, const char* value)
-{
- m_d->m_info[key] = value;
}
-void DynamicQMetaObject::addInfo(QMap<QByteArray, QByteArray> info)
+const QMetaObject *MetaObjectBuilderPrivate::update()
{
- QMap<QByteArray, QByteArray>::const_iterator i = info.constBegin();
- while (i != info.constEnd()) {
- m_d->m_info[i.key()] = i.value();
- ++i;
+ if (!m_builder)
+ return m_baseObject;
+ if (m_cachedMetaObjects.empty() || m_dirty) {
+ m_cachedMetaObjects.push_back(m_builder->toMetaObject());
+ checkMethodOrder(m_cachedMetaObjects.back());
+ m_dirty = false;
}
- m_d->m_updated = false;
+ return m_cachedMetaObjects.back();
}
-const QMetaObject* DynamicQMetaObject::update() const
+const QMetaObject *MetaObjectBuilder::update()
{
- if (!m_d->m_updated) {
- m_d->updateMetaObject(const_cast<DynamicQMetaObject*>(this));
- m_d->m_updated = true;
- }
- return this;
+ return m_d->update();
}
-void DynamicQMetaObject::DynamicQMetaObjectPrivate::writeMethodsData(const QList<MethodData>& methods,
- unsigned int** data,
- QLinkedList<QByteArray>& strings,
- int* prtIndex,
- int nullIndex,
- int flags)
-{
- int index = *prtIndex;
- int paramsIndex = index + methods.count() * 5;
-
- QList<MethodData>::const_iterator it = methods.begin();
-
- if (m_emptyMethod == -1)
- m_emptyMethod = registerString(EMPTY_META_METHOD, strings);
-
- for (; it != methods.end(); ++it) {
- int name_idx = 0;
- int argc = it->parameterCount();
- if (it->signature() != EMPTY_META_METHOD)
- name_idx = registerString(it->name(), strings);
- else
- name_idx = m_emptyMethod; // func name
-
- (*data)[index++] = name_idx;
- (*data)[index++] = argc; // argc (previously: arg name)
- (*data)[index++] = paramsIndex; //parameter index
- (*data)[index++] = nullIndex; // tags
- (*data)[index++] = flags | (it->methodType() == QMetaMethod::Signal ? MethodSignal : MethodSlot);
-
- if (it->methodType() == QMetaMethod::Signal)
- (*data)[13] += 1; //signal count
-
- paramsIndex += 1 + argc * 2;
- }
- *prtIndex = index;
-}
-
-void DynamicQMetaObject::parsePythonType(PyTypeObject *type)
+void MetaObjectBuilderPrivate::parsePythonType(PyTypeObject *type)
{
// Get all non-QObject-derived base types in method resolution order, filtering out the types
// that can't have signals, slots or properties.
@@ -594,32 +424,35 @@ void DynamicQMetaObject::parsePythonType(PyTypeObject *type)
const PyObject *mro = type->tp_mro;
const Py_ssize_t basesCount = PyTuple_GET_SIZE(mro);
PyTypeObject *qObjectType = Shiboken::Conversions::getPythonTypeObject("QObject*");
- QVector<PyTypeObject *> basesToCheck;
+
+ std::vector<PyTypeObject *> basesToCheck;
+ // Prepend the actual type that we are parsing.
+ basesToCheck.reserve(1u + basesCount);
+ basesToCheck.push_back(type);
+
+ auto sbkObjTypeF = reinterpret_cast<PyTypeObject *>(SbkObject_TypeF());
+ auto baseObjType = reinterpret_cast<PyTypeObject *>(&PyBaseObject_Type);
for (Py_ssize_t i = 0; i < basesCount; ++i) {
- PyTypeObject *baseType = reinterpret_cast<PyTypeObject *>(PyTuple_GET_ITEM(mro, i));
- if (PyType_IsSubtype(baseType, qObjectType)
- || baseType == reinterpret_cast<PyTypeObject *>(SbkObject_TypeF())
- || baseType == reinterpret_cast<PyTypeObject *>(&PyBaseObject_Type)) {
- continue;
- } else {
- basesToCheck.append(baseType);
+ auto baseType = reinterpret_cast<PyTypeObject *>(PyTuple_GET_ITEM(mro, i));
+ if (baseType != sbkObjTypeF && baseType != baseObjType
+ && PyType_IsSubtype(baseType, qObjectType) == 0) {
+ basesToCheck.push_back(baseType);
}
}
- // Prepend the actual type that we are parsing.
- basesToCheck.prepend(type);
// PYSIDE-315: Handle all signals first, in all involved types.
- for (int baseIndex = 0, baseEnd = basesToCheck.size(); baseIndex < baseEnd; ++baseIndex) {
- PyTypeObject *baseType = basesToCheck[baseIndex];
+ // Leave the properties to be registered after signals because they may depend on
+ // notify signals.
+ for (PyTypeObject *baseType : basesToCheck) {
PyObject *attrs = baseType->tp_dict;
- PyObject *key = 0;
- PyObject *value = 0;
+ PyObject *key = nullptr;
+ PyObject *value = nullptr;
Py_ssize_t pos = 0;
while (PyDict_Next(attrs, &pos, &key, &value)) {
if (Signal::checkType(value)) {
// Register signals.
- PySideSignal *data = reinterpret_cast<PySideSignal *>(value);
+ auto data = reinterpret_cast<PySideSignal *>(value);
const char *signalName = Shiboken::String::toCString(key);
data->signalName = strdup(signalName);
QByteArray sig;
@@ -630,8 +463,8 @@ void DynamicQMetaObject::parsePythonType(PyTypeObject *type)
if (data->signatures[i])
sig += data->signatures[i];
sig += ')';
- if (d.superdata->indexOfSignal(sig) == -1)
- addSignal(sig, "void");
+ if (m_baseObject->indexOfSignal(sig) == -1)
+ m_builder->addSignal(sig);
}
}
}
@@ -641,261 +474,41 @@ void DynamicQMetaObject::parsePythonType(PyTypeObject *type)
// PYSIDE-315: Now take care of the rest.
// Signals and slots should be separated, unless the types are modified, later.
// We check for this using "is_sorted()". Sorting no longer happens at all.
- for (int baseIndex = 0, baseEnd = basesToCheck.size(); baseIndex < baseEnd; ++baseIndex) {
- PyTypeObject *baseType = basesToCheck[baseIndex];
+ for (PyTypeObject *baseType : basesToCheck) {
PyObject *attrs = baseType->tp_dict;
- PyObject *key = 0;
- PyObject *value = 0;
+ PyObject *key = nullptr;
+ PyObject *value = nullptr;
Py_ssize_t pos = 0;
- typedef std::pair<const char *, PyObject *> PropPair;
- QVector<PropPair> properties;
-
while (PyDict_Next(attrs, &pos, &key, &value)) {
if (Property::checkType(value)) {
- // Leave the properties to be registered after signals because they may depend on
- // notify signals.
- int index = d.superdata->indexOfProperty(Shiboken::String::toCString(key));
+ const int index = m_baseObject->indexOfProperty(Shiboken::String::toCString(key));
if (index == -1)
- properties << PropPair(Shiboken::String::toCString(key), value);
+ addProperty(Shiboken::String::toCString(key), value);
} else if (PyFunction_Check(value)) {
// Register slots.
if (PyObject_HasAttr(value, slotAttrName)) {
PyObject *signatureList = PyObject_GetAttr(value, slotAttrName);
for (Py_ssize_t i = 0, i_max = PyList_Size(signatureList); i < i_max; ++i) {
- PyObject *signature = PyList_GET_ITEM(signatureList, i);
- QByteArray sig(Shiboken::String::toCString(signature));
+ PyObject *pySignature = PyList_GET_ITEM(signatureList, i);
+ QByteArray signature(Shiboken::String::toCString(pySignature));
// Split the slot type and its signature.
- QList<QByteArray> slotInfo = sig.split(' ');
- int index = d.superdata->indexOfSlot(slotInfo[1]);
- if (index == -1)
- addSlot(slotInfo[1], slotInfo[0]);
+ QByteArray type;
+ const int spacePos = signature.indexOf(' ');
+ if (spacePos != -1) {
+ type = signature.left(spacePos);
+ signature.remove(0, spacePos + 1);
+ }
+ const int index = m_baseObject->indexOfSlot(signature);
+ if (index == -1) {
+ if (type.isEmpty() || type == "void")
+ addSlot(signature);
+ else
+ addSlot(signature, type);
+ }
}
}
}
}
-
- // Register properties
- foreach (const PropPair &propPair, properties)
- addProperty(propPair.first, propPair.second);
}
}
-
-/*!
- Allocate the meta data table.
- Returns the index in the table corresponding to the header fields count.
-*/
-int DynamicQMetaObject::DynamicQMetaObjectPrivate::createMetaData(QMetaObject* metaObj, QLinkedList<QByteArray> &strings)
-{
- const int n_methods = m_methods.size();
- const int n_properties = m_properties.size();
- const int n_info = m_info.size();
-
- int header[] = {7, // revision (Used by moc, qmetaobjectbuilder and qdbus)
- 0, // class name index in m_metadata
- n_info, 0, // classinfo and classinfo index
- n_methods, 0, // method count and method list index
- n_properties, 0, // prop count and prop indexes
- 0, 0, // enum count and enum index
- 0, 0, // constructors (since revision 2)
- 0, // flags (since revision 3)
- 0}; // signal count (since revision 4)
-
- const int HEADER_LENGHT = sizeof(header)/sizeof(int);
-
- m_dataSize = HEADER_LENGHT;
- m_dataSize += n_info*2; //class info: name, value
- m_dataSize += n_methods*5; //method: name, argc, parameters, tag, flags
- m_dataSize += n_properties*4; //property: name, type, flags
- m_dataSize += 1; //eod
-
- m_dataSize += aggregateParameterCount(m_methods); // types and parameter names
-
- uint* data = reinterpret_cast<uint*>(realloc(const_cast<uint*>(metaObj->d.data), m_dataSize * sizeof(uint)));
-
- Q_ASSERT(data);
- std::memcpy(data, header, sizeof(header));
-
- metaObj->d.data = data;
-
- return HEADER_LENGHT;
-}
-
-// Writes strings to string data struct.
-// The struct consists of an array of QByteArrayData, followed by a char array
-// containing the actual strings. This format must match the one produced by
-// moc (see generator.cpp).
-void DynamicQMetaObject::DynamicQMetaObjectPrivate::writeStringData(char *out, QLinkedList<QByteArray> &strings)
-{
- Q_ASSERT(!(reinterpret_cast<quintptr>(out) & (Q_ALIGNOF(QByteArrayData)-1)));
-
- int offsetOfStringdataMember = strings.size() * sizeof(QByteArrayData);
- int stringdataOffset = 0;
- int i = 0;
- foreach(const QByteArray& str, strings) {
- writeString(out, i, str, offsetOfStringdataMember, stringdataOffset);
- i++;
- }
-}
-
-QList<MethodData>::iterator is_sorted_until(QList<MethodData>::iterator first,
- QList<MethodData>::iterator last,
- bool comp(const MethodData &m1, const MethodData &m2))
-{
- if (first != last) {
- QList<MethodData>::iterator next = first;
- while (++next != last) {
- if (comp(*next, *first))
- return next;
- ++first;
- }
- }
- return last;
-}
-
-bool is_sorted(QList<MethodData>::iterator first, QList<MethodData>::iterator last,
- bool comp(const MethodData &m1, const MethodData &m2))
-{
- return is_sorted_until(first, last, comp) == last;
-}
-
-void DynamicQMetaObject::DynamicQMetaObjectPrivate::updateMetaObject(QMetaObject* metaObj)
-{
- Q_ASSERT(!m_updated);
- uint *data = const_cast<uint*>(metaObj->d.data);
- int index = 0;
- QLinkedList<QByteArray> strings;
- m_dataSize = 0;
-
- // Recompute the size and reallocate memory
- // index is set after the last header field.
- index = createMetaData(metaObj, strings);
- data = const_cast<uint*>(metaObj->d.data);
-
- registerString(m_className, strings); // register class string
- m_nullIndex = registerString("", strings); // register a null string
-
- // Write class info.
- if (m_info.size()) {
- if (data[3] == 0)
- data[3] = index;
-
- QMap<QByteArray, QByteArray>::const_iterator i = m_info.constBegin(); //TODO: info is a hash this can fail
- while (i != m_info.constEnd()) {
- int valueIndex = registerString(i.value(), strings);
- int keyIndex = registerString(i.key(), strings);
- data[index++] = keyIndex;
- data[index++] = valueIndex;
- i++;
- }
- }
-
- // Write methods first, then properties, to be consistent with moc.
- // Write signals/slots (signals must be written first, see indexOfMethodRelative in
- // qmetaobject.cpp).
-
- QList<MethodData>::iterator it;
- // PYSIDE-315: Instead of sorting the items and maybe breaking indices,
- // we ensure that the signals and slots are sorted by the improved parsePythonType().
- // The order can only become distorted if the class is modified after creation.
- // In that case, we give a warning.
- if (!is_sorted(m_methods.begin(), m_methods.end(), sortMethodSignalSlot)) {
- const char *metaObjectName = this->m_className.data();
- PyObject *txt = PyBytes_FromFormat("\n\n*** Sort Warning ***\n"
- "Signals and slots in QMetaObject '%s' are not ordered correctly, "
- "this may lead to issues.\n", metaObjectName);
- it = m_methods.begin();
- QList<MethodData>::iterator end = m_methods.end();
- QList<MethodData>::iterator until = is_sorted_until(m_methods.begin(), m_methods.end(),
- sortMethodSignalSlot);
- for (; it != end; ++it) {
- PyObject *atxt = PyBytes_FromFormat("%d%s %s %s\n", it - m_methods.begin() + 1,
- until >= it + 1 ? " " : "!",
- it->methodType() == QMetaMethod::Signal ? "Signal" : "Slot ",
- it->signature().data() );
- PyBytes_ConcatAndDel(&txt, atxt);
- }
- PyErr_WarnEx(PyExc_RuntimeWarning, PyBytes_AsString(txt), 0);
- Py_DECREF(txt);
- // Prevent a warning from being turned into an error. We cannot easily unwind.
- PyErr_Clear();
- }
-
- if (m_methods.size()) {
- if (data[5] == 0)
- data[5] = index;
-
- writeMethodsData(m_methods, &data, strings, &index, m_nullIndex, AccessPublic);
- }
-
- // Write signal/slots parameters.
- if (m_methods.size()) {
- for (it = m_methods.begin(); it != m_methods.end(); ++it) {
- QList<QByteArray> paramTypeNames = it->parameterTypes();
- int paramCount = paramTypeNames.size();
- for (int i = -1; i < paramCount; ++i) {
- const QByteArray &typeName = (i < 0) ? it->returnType() : paramTypeNames.at(i);
- int typeInfo;
- if (QtPrivate::isBuiltinType(typeName))
- typeInfo = QMetaType::type(typeName);
- else
- typeInfo = IsUnresolvedType | registerString(typeName, strings);
- data[index++] = typeInfo;
- }
-
- // Parameter names (use a null string)
- for (int i = 0; i < paramCount; ++i) {
- data[index++] = m_nullIndex;
- }
- }
- }
-
- // Write properties.
- if (m_properties.size()) {
- if (data[7] == 0)
- data[7] = index;
-
- QList<PropertyData>::const_iterator i = m_properties.constBegin();
- while (i != m_properties.constEnd()) {
- if (i->isValid()) {
- data[index++] = registerString(i->name(), strings); // name
- } else
- data[index++] = m_nullIndex;
-
- // Find out the property type index.
- int typeInfo = m_nullIndex;
- if (i->isValid()) {
- const QByteArray &typeName = i->type();
- if (QtPrivate::isBuiltinType(typeName))
- typeInfo = QMetaType::type(typeName);
- else
- typeInfo = IsUnresolvedType | registerString(typeName, strings);
- }
- data[index++] = typeInfo; // normalized type
-
- data[index++] = i->flags();
- i++;
- }
-
- // Write properties notify.
- i = m_properties.constBegin();
- while (i != m_properties.constEnd()) {
- // Recompute notifyId, because sorting the methods might have changed the relative
- // index.
- const int notifyId = getPropertyNotifyId(i->data());
- data[index++] = notifyId >= 0 ? static_cast<uint>(notifyId) : 0; //signal notify index
- i++;
- }
- }
-
- data[index++] = 0; // the end
-
- // Create the m_metadata string.
- int size = blobSize(strings);
- char *blob =
- reinterpret_cast<char *>(realloc(reinterpret_cast<char *>(const_cast<QByteArrayData *>(metaObj->d.stringdata)), size));
- writeStringData(blob, strings);
-
- metaObj->d.stringdata = reinterpret_cast<const QByteArrayData *>(blob);
- metaObj->d.data = data;
-}
diff --git a/sources/pyside2/libpyside/dynamicqmetaobject.h b/sources/pyside2/libpyside/dynamicqmetaobject.h
index 5ecce50c9..1fbe73ea4 100644
--- a/sources/pyside2/libpyside/dynamicqmetaobject.h
+++ b/sources/pyside2/libpyside/dynamicqmetaobject.h
@@ -40,43 +40,42 @@
#ifndef DYNAMICQMETAOBJECT_H
#define DYNAMICQMETAOBJECT_H
-#include "pysidemacros.h"
#include <sbkpython.h>
-#include <QMetaObject>
-#include <QMetaMethod>
+
+#include <QtCore/QMetaObject>
+#include <QtCore/QMetaMethod>
+
+class MetaObjectBuilderPrivate;
namespace PySide
{
-class DynamicQMetaObject : public QMetaObject
+class MetaObjectBuilder
{
+ Q_DISABLE_COPY(MetaObjectBuilder)
public:
- DynamicQMetaObject(const char* className, const QMetaObject* metaObject);
- DynamicQMetaObject(PyTypeObject* type, const QMetaObject* metaobject);
- ~DynamicQMetaObject();
+ MetaObjectBuilder(const char *className, const QMetaObject *metaObject);
+ MetaObjectBuilder(PyTypeObject *type, const QMetaObject *metaObject);
+ ~MetaObjectBuilder();
- int addMethod(QMetaMethod::MethodType mtype, const char* signature, const char* type);
- void removeMethod(QMetaMethod::MethodType mtype, uint index);
- int addSignal(const char* signal, const char* type = 0);
- int addSlot(const char* slot, const char* type = 0);
- int addProperty(const char* property, PyObject* data);
- void addInfo(const char* key, const char* value);
- void addInfo(QMap<QByteArray, QByteArray> info);
+ int indexOfMethod(QMetaMethod::MethodType mtype, const QByteArray &signature) const;
+ int indexOfProperty(const QByteArray &name) const;
+ int addSlot(const char *signature);
+ int addSlot(const char *signature, const char *type);
+ int addSignal(const char *signature);
+ void removeMethod(QMetaMethod::MethodType mtype, int index);
+ int addProperty(const char *property, PyObject *data);
+ void addInfo(const char *key, const char *value);
+ void addInfo(const QMap<QByteArray, QByteArray> &info);
- void removeSignal(uint idex);
- void removeSlot(uint index);
- void removeProperty(uint index);
+ void removeProperty(int index);
- const QMetaObject* update() const;
+ const QMetaObject *update();
private:
- class DynamicQMetaObjectPrivate;
- DynamicQMetaObjectPrivate* m_d;
-
- void parsePythonType(PyTypeObject *type);
+ MetaObjectBuilderPrivate *m_d;
};
-
}
#endif
diff --git a/sources/pyside2/libpyside/dynamicqmetaobject_p.h b/sources/pyside2/libpyside/dynamicqmetaobject_p.h
index 219ffc4e3..738b950ba 100644
--- a/sources/pyside2/libpyside/dynamicqmetaobject_p.h
+++ b/sources/pyside2/libpyside/dynamicqmetaobject_p.h
@@ -41,8 +41,9 @@
#define DYNAMICMETAPROPERTY_P_H
#include <sbkpython.h>
-#include <QByteArray>
-#include <QMetaMethod>
+
+#include <QtCore/QByteArray>
+#include <QtCore/QMetaMethod>
#define GLOBAL_RECEIVER_CLASS_NAME "__GlobalReceiver__"
diff --git a/sources/pyside2/libpyside/globalreceiver.cpp b/sources/pyside2/libpyside/globalreceiver.cpp
deleted file mode 100644
index ee1f6354a..000000000
--- a/sources/pyside2/libpyside/globalreceiver.cpp
+++ /dev/null
@@ -1,329 +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 "globalreceiver.h"
-#include "dynamicqmetaobject_p.h"
-#include "pysideweakref.h"
-
-#include <QMetaMethod>
-#include <QDebug>
-#include <QEvent>
-#include <QLinkedList>
-#include <autodecref.h>
-#include <sbkconverter.h>
-#include <gilstate.h>
-
-#include "signalmanager.h"
-
-#define RECEIVER_DESTROYED_SLOT_NAME "__receiverDestroyed__(QObject*)"
-
-namespace PySide
-{
-class DynamicSlotData
-{
- public:
- DynamicSlotData(int id, PyObject* callback, GlobalReceiver* parent);
- void addRef(const QObject* o);
- void decRef(const QObject* o);
- void clear();
- int hasRefTo(const QObject* o) const;
- int refCount() const;
- int id() const;
- PyObject* call(PyObject* args);
- ~DynamicSlotData();
- static void onCallbackDestroyed(void* data);
-
- private:
- int m_id;
- bool m_isMethod;
- PyObject* m_callback;
- PyObject* m_pythonSelf;
- PyObject* m_pyClass;
- PyObject* m_weakRef;
- GlobalReceiver* m_parent;
- QLinkedList<const QObject*> m_refs;
-};
-
-}
-
-using namespace PySide;
-
-DynamicSlotData::DynamicSlotData(int id, PyObject* callback, GlobalReceiver* parent)
- : m_id(id), m_pythonSelf(0), m_pyClass(0), m_weakRef(0), m_parent(parent)
-{
- Shiboken::GilState gil;
-
- m_isMethod = PyMethod_Check(callback);
- if (m_isMethod) {
- //Can not store calback pointe because this will be destroyed at the end of the scope
- //To avoid increment intance reference keep the callback information
- m_callback = PyMethod_GET_FUNCTION(callback);
-#ifdef IS_PY3K
- m_pyClass = 0;
-#else
- m_pyClass = PyMethod_GET_CLASS(callback);
-#endif
-
- m_pythonSelf = PyMethod_GET_SELF(callback);
-
- //monitor class from method lifetime
- m_weakRef = WeakRef::create(m_pythonSelf, DynamicSlotData::onCallbackDestroyed, this);
- } else {
- m_callback = callback;
- Py_INCREF(m_callback);
- }
-}
-
-PyObject* DynamicSlotData::call(PyObject* args)
-{
- PyObject* callback = m_callback;
-
- //create a callback based on method data
- Shiboken::GilState gil;
- if (m_isMethod)
-#ifdef IS_PY3K
- callback = PyMethod_New(callback, m_pythonSelf);
-#else
- callback = PyMethod_New(callback, m_pythonSelf, m_pyClass);
-#endif
-
- PyObject* result = PyObject_CallObject(callback, args);
-
- if (m_isMethod)
- Py_DECREF(callback);
-
- return result;
-}
-
-void DynamicSlotData::addRef(const QObject *o)
-{
- m_refs.append(o);
-}
-
-void DynamicSlotData::decRef(const QObject *o)
-{
- m_refs.removeOne(o);
-}
-
-int DynamicSlotData::refCount() const
-{
- return m_refs.size();
-}
-
-int DynamicSlotData::id() const
-{
- return m_id;
-}
-
-int DynamicSlotData::hasRefTo(const QObject *o) const
-{
- return m_refs.count(o);
-}
-
-void DynamicSlotData::clear()
-{
- Shiboken::GilState gil;
- Py_XDECREF(m_weakRef);
- m_weakRef = 0;
- m_refs.clear();
-}
-
-DynamicSlotData::~DynamicSlotData()
-{
- Shiboken::GilState gil;
- clear();
- if (!m_isMethod)
- Py_DECREF(m_callback);
-}
-
-void DynamicSlotData::onCallbackDestroyed(void *data)
-{
- Shiboken::GilState gil;
- DynamicSlotData* self = reinterpret_cast<DynamicSlotData*>(data);
-
- //Disconnect all sources
- QMetaMethod m = self->m_parent->metaObject()->method(self->m_id);
- QByteArray methodName = QByteArray::number(m.methodType()).append(m.methodSignature());
- QLinkedList<const QObject*> sources = self->m_refs;
- foreach(const QObject* src, sources)
- const_cast<QObject*>(src)->disconnect(self->m_parent, methodName);
- self->m_weakRef = 0;
-}
-
-GlobalReceiver::GlobalReceiver()
- : m_metaObject(GLOBAL_RECEIVER_CLASS_NAME, &QObject::staticMetaObject)
-{
- //slot used to be notifyed of object destrouction
- m_metaObject.addSlot(RECEIVER_DESTROYED_SLOT_NAME);
- m_metaObject.update();
- setObjectName(QLatin1String("GLOBAL RECEIVER"));
-}
-
-GlobalReceiver::~GlobalReceiver()
-{
- while(!m_slotReceivers.empty()) {
- DynamicSlotData* data = m_slotReceivers.take(m_slotReceivers.begin().key());
- data->clear();
- delete data;
- }
-}
-
-void GlobalReceiver::connectNotify(QObject* source, int slotId)
-{
- if (m_slotReceivers.contains(slotId)) {
- DynamicSlotData* data = m_slotReceivers[slotId];
- if (!data->hasRefTo(source))
- QObject::connect(source, SIGNAL(destroyed(QObject*)), this, "1" RECEIVER_DESTROYED_SLOT_NAME);
- data->addRef(source);
- }
-}
-
-void GlobalReceiver::disconnectNotify(QObject* source, int slotId)
-{
- if (m_slotReceivers.contains(slotId)) {
- DynamicSlotData *data = m_slotReceivers[slotId];
- data->decRef(source);
- if (data->refCount() == 0)
- removeSlot(slotId);
-
- if (!hasConnectionWith(source))
- QObject::disconnect(source, SIGNAL(destroyed(QObject*)), this, "1" RECEIVER_DESTROYED_SLOT_NAME);
- }
-}
-
-const QMetaObject* GlobalReceiver::metaObject() const
-{
- return m_metaObject.update();
-}
-
-int GlobalReceiver::addSlot(const char* slot, PyObject* callback)
-{
- int slotId = m_metaObject.addSlot(slot);
- if (!m_slotReceivers.contains(slotId))
- m_slotReceivers[slotId] = new DynamicSlotData(slotId, callback, this);
-
- bool isShortCircuit = true;
- for (int i = 0; slot[i]; ++i) {
- if (slot[i] == '(') {
- isShortCircuit = false;
- break;
- }
- }
-
- if (isShortCircuit)
- m_shortCircuitSlots << slotId;
-
- Q_ASSERT(slotId >= QObject::staticMetaObject.methodCount());
- return slotId;
-}
-
-void GlobalReceiver::removeSlot(int slotId)
-{
- if (m_slotReceivers.contains(slotId)) {
- delete m_slotReceivers.take(slotId);
- m_metaObject.removeSlot(slotId);
- m_shortCircuitSlots.remove(slotId);
- }
-}
-
-bool GlobalReceiver::hasConnectionWith(const QObject *object)
-{
- QHash<int, DynamicSlotData*>::iterator i = m_slotReceivers.begin();
- while(i != m_slotReceivers.end()) {
- if (i.value()->hasRefTo(object)) {
- return true;
- }
- i++;
- }
- return false;
-}
-
-int GlobalReceiver::qt_metacall(QMetaObject::Call call, int id, void** args)
-{
- Q_ASSERT(call == QMetaObject::InvokeMetaMethod);
- Q_ASSERT(id >= QObject::staticMetaObject.methodCount());
- QMetaMethod slot = metaObject()->method(id);
- Q_ASSERT(slot.methodType() == QMetaMethod::Slot);
-
- if (strcmp(slot.methodSignature(), RECEIVER_DESTROYED_SLOT_NAME) == 0) {
- QObject *arg = *(QObject**)args[1];
-
- //avoid hash changes during the destruction
- QHash<int, DynamicSlotData*> copy = m_slotReceivers;
- QHash<int, DynamicSlotData*>::iterator i = copy.begin();
- while(i != copy.end()) {
- //Remove all refs
- int refs = i.value()->hasRefTo(arg);
- while(refs) {
- disconnectNotify(arg, i.key());
- refs--;
- }
- i++;
- }
- return -1;
- }
-
- DynamicSlotData* data = m_slotReceivers.value(id);
- if (!data) {
- qWarning() << "Unknown global slot, id:" << id;
- return -1;
- }
-
- Shiboken::GilState gil;
- PyObject* retval = 0;
- if (m_shortCircuitSlots.contains(id)) {
- retval = data->call(reinterpret_cast<PyObject*>(args[1]));
- } else {
- QList<QByteArray> paramTypes = slot.parameterTypes();
- Shiboken::AutoDecRef preparedArgs(PyTuple_New(paramTypes.count()));
- for (int i = 0, max = paramTypes.count(); i < max; ++i) {
- const QByteArray& paramType = paramTypes[i];
- Shiboken::Conversions::SpecificConverter converter(paramType.constData());
- PyTuple_SET_ITEM(preparedArgs.object(), i, converter.toPython(args[i+1]));
- }
- retval = data->call(preparedArgs);
- }
-
- if (!retval)
- PyErr_Print();
- else
- Py_DECREF(retval);
-
- return -1;
-}
diff --git a/sources/pyside2/libpyside/globalreceiverv2.cpp b/sources/pyside2/libpyside/globalreceiverv2.cpp
index 05565e516..43ce50a75 100644
--- a/sources/pyside2/libpyside/globalreceiverv2.cpp
+++ b/sources/pyside2/libpyside/globalreceiverv2.cpp
@@ -40,15 +40,13 @@
#include "globalreceiverv2.h"
#include "dynamicqmetaobject_p.h"
#include "pysideweakref.h"
+#include "signalmanager.h"
-#include <QMetaMethod>
-#include <QDebug>
-#include <QEvent>
-#include <QLinkedList>
#include <autodecref.h>
#include <gilstate.h>
-#include "signalmanager.h"
+#include <QtCore/QMetaMethod>
+#include <QtCore/QSet>
#define RECEIVER_DESTROYED_SLOT_NAME "__receiverDestroyed__(QObject*)"
@@ -62,6 +60,7 @@ namespace PySide
{
class DynamicSlotDataV2
{
+ Q_DISABLE_COPY(DynamicSlotDataV2)
public:
DynamicSlotDataV2(PyObject* callback, GlobalReceiverV2* parent);
~DynamicSlotDataV2();
@@ -128,11 +127,11 @@ QByteArray DynamicSlotDataV2::hash() const
QByteArray DynamicSlotDataV2::hash(PyObject* callback)
{
Shiboken::GilState gil;
- if (PyMethod_Check(callback))
+ if (PyMethod_Check(callback)) {
return QByteArray::number((qlonglong)PyObject_Hash(PyMethod_GET_FUNCTION(callback)))
+ QByteArray::number((qlonglong)PyObject_Hash(PyMethod_GET_SELF(callback)));
- else
- return QByteArray::number((qlonglong)PyObject_Hash(callback));
+ }
+ return QByteArray::number(qlonglong(PyObject_Hash(callback)));
}
PyObject* DynamicSlotDataV2::callback()
@@ -154,18 +153,15 @@ PyObject* DynamicSlotDataV2::callback()
int DynamicSlotDataV2::id(const char* signature) const
{
- if (m_signatures.contains(signature))
- return m_signatures[signature];
- return -1;
+ const auto it = m_signatures.constFind(signature);
+ return it != m_signatures.cend() ? it.value() : -1;
}
int DynamicSlotDataV2::addSlot(const char* signature)
{
int index = id(signature);
- if (index == -1) {
- DynamicQMetaObject *dmo = const_cast<DynamicQMetaObject*>(reinterpret_cast<const DynamicQMetaObject*>(m_parent->metaObject()));
- index = m_signatures[signature] = dmo->addSlot(signature);
- }
+ if (index == -1)
+ index = m_signatures[signature] = m_parent->metaObjectBuilder().addSlot(signature);
return index;
}
@@ -189,8 +185,10 @@ DynamicSlotDataV2::~DynamicSlotDataV2()
Py_DECREF(m_callback);
}
-GlobalReceiverV2::GlobalReceiverV2(PyObject *callback, SharedMap map)
- : QObject(0), m_metaObject(GLOBAL_RECEIVER_CLASS_NAME, &QObject::staticMetaObject), m_sharedMap(map)
+GlobalReceiverV2::GlobalReceiverV2(PyObject *callback, SharedMap map) :
+ QObject(nullptr),
+ m_metaObject(GLOBAL_RECEIVER_CLASS_NAME, &QObject::staticMetaObject),
+ m_sharedMap(std::move(map))
{
m_data = new DynamicSlotDataV2(callback, this);
m_metaObject.addSlot(RECEIVER_DESTROYED_SLOT_NAME);
@@ -202,7 +200,7 @@ GlobalReceiverV2::GlobalReceiverV2(PyObject *callback, SharedMap map)
DESTROY_SIGNAL_ID = QObject::staticMetaObject.indexOfSignal("destroyed(QObject*)");
if (DESTROY_SLOT_ID == 0)
- DESTROY_SLOT_ID = m_metaObject.indexOfSlot(RECEIVER_DESTROYED_SLOT_NAME);
+ DESTROY_SLOT_ID = m_metaObject.indexOfMethod(QMetaMethod::Slot, RECEIVER_DESTROYED_SLOT_NAME);
}
@@ -251,7 +249,7 @@ void GlobalReceiverV2::incRef(const QObject* link)
void GlobalReceiverV2::decRef(const QObject* link)
{
- if (m_refs.size() <= 0)
+ if (m_refs.empty())
return;
@@ -268,7 +266,7 @@ void GlobalReceiverV2::decRef(const QObject* link)
}
}
- if (m_refs.size() == 0)
+ if (m_refs.empty())
Py_BEGIN_ALLOW_THREADS
delete this;
Py_END_ALLOW_THREADS
@@ -285,9 +283,9 @@ int GlobalReceiverV2::refCount(const QObject* link) const
void GlobalReceiverV2::notify()
{
- QSet<const QObject*> objs = QSet<const QObject*>::fromList(m_refs);
+ const auto objSet = QSet<const QObject*>::fromList(m_refs);
Py_BEGIN_ALLOW_THREADS
- foreach(const QObject* o, objs) {
+ for (const QObject *o : objSet) {
QMetaObject::disconnect(o, DESTROY_SIGNAL_ID, this, DESTROY_SLOT_ID);
QMetaObject::connect(o, DESTROY_SIGNAL_ID, this, DESTROY_SLOT_ID);
}
@@ -306,7 +304,7 @@ QByteArray GlobalReceiverV2::hash(PyObject* callback)
const QMetaObject* GlobalReceiverV2::metaObject() const
{
- return m_metaObject.update();
+ return const_cast<GlobalReceiverV2 *>(this)->m_metaObject.update();
}
int GlobalReceiverV2::qt_metacall(QMetaObject::Call call, int id, void** args)
@@ -328,9 +326,9 @@ int GlobalReceiverV2::qt_metacall(QMetaObject::Call call, int id, void** args)
}
if (id == DESTROY_SLOT_ID) {
- if (m_refs.size() == 0)
+ if (m_refs.empty())
return -1;
- QObject *obj = *(QObject**)args[1];
+ QObject *obj = *reinterpret_cast<QObject**>(args[1]);
incRef(); //keep the object live (safe ref)
m_refs.removeAll(obj); // remove all refs to this object
decRef(); //remove the safe ref
diff --git a/sources/pyside2/libpyside/globalreceiverv2.h b/sources/pyside2/libpyside/globalreceiverv2.h
index 880719d6f..b92be93a8 100644
--- a/sources/pyside2/libpyside/globalreceiverv2.h
+++ b/sources/pyside2/libpyside/globalreceiverv2.h
@@ -41,15 +41,14 @@
#define GLOBALRECEIVER_V2_H
#include <sbkpython.h>
-#include <QObject>
-#include <QHash>
-#include <QSet>
-#include <QSharedPointer>
-#include <QLinkedList>
-#include <QByteArray>
#include "dynamicqmetaobject.h"
+#include <QtCore/QByteArray>
+#include <QtCore/QObject>
+#include <QtCore/QMap>
+#include <QtCore/QSharedPointer>
+
namespace PySide
{
@@ -78,13 +77,13 @@ public:
/**
* Destructor
**/
- ~GlobalReceiverV2();
+ ~GlobalReceiverV2() override;
/**
* Reimplemented function from QObject
**/
- int qt_metacall(QMetaObject::Call call, int id, void** args);
- const QMetaObject* metaObject() const;
+ int qt_metacall(QMetaObject::Call call, int id, void** args) override;
+ const QMetaObject* metaObject() const override;
/**
* Add a extra slot to this object
@@ -122,22 +121,25 @@ public:
int refCount(const QObject* link) const;
/**
- * Use to retrive the unique hash of this GlobalReceiver object
+ * Use to retrieve the unique hash of this GlobalReceiver object
*
* @return a string with a unique id based on GlobalReceiver contents
**/
QByteArray hash() const;
/**
- * Use to retrive the unique hash of the PyObject based on GlobalReceiver rules
+ * Use to retrieve the unique hash of the PyObject based on GlobalReceiver rules
*
* @param callback The Python callable object used to calculate the id
* @return a string with a unique id based on GlobalReceiver contents
**/
static QByteArray hash(PyObject* callback);
+ const MetaObjectBuilder &metaObjectBuilder() const { return m_metaObject; }
+ MetaObjectBuilder &metaObjectBuilder() { return m_metaObject; }
+
private:
- DynamicQMetaObject m_metaObject;
+ MetaObjectBuilder m_metaObject;
DynamicSlotDataV2 *m_data;
QList<const QObject*> m_refs;
SharedMap m_sharedMap;
diff --git a/sources/pyside2/libpyside/pyside.cpp b/sources/pyside2/libpyside/pyside.cpp
index b4f7d8771..6e4a3efd4 100644
--- a/sources/pyside2/libpyside/pyside.cpp
+++ b/sources/pyside2/libpyside/pyside.cpp
@@ -38,6 +38,7 @@
****************************************************************************/
#include "pyside.h"
+#include "pyside_p.h"
#include "signalmanager.h"
#include "pysideclassinfo_p.h"
#include "pysideproperty_p.h"
@@ -51,23 +52,24 @@
#include "destroylistener.h"
#include <autodecref.h>
-#include <qapp_macro.h>
#include <basewrapper.h>
+#include <bindingmanager.h>
+#include <gilstate.h>
#include <sbkconverter.h>
#include <sbkstring.h>
-#include <gilstate.h>
-#include <bindingmanager.h>
+#include <qapp_macro.h>
+
+#include <QtCore/QByteArray>
+#include <QtCore/QCoreApplication>
+#include <QtCore/QDir>
+#include <QtCore/QFileInfo>
+#include <QtCore/QSharedPointer>
+#include <QtCore/QStack>
+
#include <algorithm>
-#include <typeinfo>
#include <cstring>
#include <cctype>
-#include <QByteArray>
-#include <QCoreApplication>
-#include <QDebug>
-#include <QDir>
-#include <QFileInfo>
-#include <QSharedPointer>
-#include <QStack>
+#include <typeinfo>
static QStack<PySide::CleanupFunction> cleanupFunctionList;
static void* qobjectNextAddr;
@@ -188,29 +190,21 @@ void destroyQCoreApplication()
MakeSingletonQAppWrapper(NULL);
}
-struct TypeUserData {
- TypeUserData(PyTypeObject* type, const QMetaObject* metaobject) : mo(type, metaobject) {}
- DynamicQMetaObject mo;
- std::size_t cppObjSize;
-};
-
std::size_t getSizeOfQObject(SbkObjectType* type)
{
- using namespace Shiboken::ObjectType;
- TypeUserData* userData = reinterpret_cast<TypeUserData*>(getTypeUserData(reinterpret_cast<SbkObjectType*>(type)));
- return userData->cppObjSize;
+ return retrieveTypeUserData(type)->cppObjSize;
}
-void initDynamicMetaObject(SbkObjectType* type, const QMetaObject* base, const std::size_t& cppObjSize)
+void initDynamicMetaObject(SbkObjectType* type, const QMetaObject* base, std::size_t cppObjSize)
{
//create DynamicMetaObject based on python type
- TypeUserData* userData = new TypeUserData(reinterpret_cast<PyTypeObject*>(type), base);
- userData->cppObjSize = cppObjSize;
+ auto userData =
+ new TypeUserData(reinterpret_cast<PyTypeObject*>(type), base, cppObjSize);
userData->mo.update();
Shiboken::ObjectType::setTypeUserData(type, userData, Shiboken::callCppDestructor<TypeUserData>);
//initialize staticQMetaObject property
- void* metaObjectPtr = &userData->mo;
+ void *metaObjectPtr = const_cast<QMetaObject *>(userData->mo.update());
static SbkConverter* converter = Shiboken::Conversions::getConverter("QMetaObject");
if (!converter)
return;
@@ -218,6 +212,36 @@ void initDynamicMetaObject(SbkObjectType* type, const QMetaObject* base, const s
PyObject_SetAttrString(reinterpret_cast<PyObject*>(type), "staticMetaObject", pyMetaObject);
}
+TypeUserData *retrieveTypeUserData(SbkObjectType *sbkTypeObj)
+{
+ return reinterpret_cast<TypeUserData *>(Shiboken::ObjectType::getTypeUserData(sbkTypeObj));
+}
+
+TypeUserData *retrieveTypeUserData(PyTypeObject *pyTypeObj)
+{
+ return retrieveTypeUserData(reinterpret_cast<SbkObjectType *>(pyTypeObj));
+}
+
+TypeUserData *retrieveTypeUserData(PyObject *pyObj)
+{
+ auto pyTypeObj = PyType_Check(pyObj)
+ ? reinterpret_cast<PyTypeObject *>(pyObj) : Py_TYPE(pyObj);
+ return retrieveTypeUserData(pyTypeObj);
+}
+
+const QMetaObject *retrieveMetaObject(PyTypeObject *pyTypeObj)
+{
+ TypeUserData *userData = retrieveTypeUserData(pyTypeObj);
+ return userData ? userData->mo.update() : nullptr;
+}
+
+const QMetaObject *retrieveMetaObject(PyObject *pyObj)
+{
+ auto pyTypeObj = PyType_Check(pyObj)
+ ? reinterpret_cast<PyTypeObject *>(pyObj) : Py_TYPE(pyObj);
+ return retrieveMetaObject(pyTypeObj);
+}
+
void initDynamicMetaObject(SbkObjectType* type, const QMetaObject* base)
{
initDynamicMetaObject(type, base, 0);
@@ -230,25 +254,21 @@ void initQObjectSubType(SbkObjectType *type, PyObject *args, PyObject * /* kwds
PyObject* bases = PyTuple_GET_ITEM(args, 1);
int numBases = PyTuple_GET_SIZE(bases);
- QMetaObject* baseMo = 0;
- SbkObjectType* qobjBase = 0;
+
+ TypeUserData *userData = nullptr;
for (int i = 0; i < numBases; ++i) {
PyTypeObject* base = reinterpret_cast<PyTypeObject*>(PyTuple_GET_ITEM(bases, i));
if (PyType_IsSubtype(base, qObjType)) {
- baseMo = reinterpret_cast<QMetaObject*>(Shiboken::ObjectType::getTypeUserData(reinterpret_cast<SbkObjectType*>(base)));
- qobjBase = reinterpret_cast<SbkObjectType*>(base);
- reinterpret_cast<DynamicQMetaObject*>(baseMo)->update();
+ userData = retrieveTypeUserData(base);
break;
}
}
- if (!baseMo) {
+ if (!userData) {
qWarning("Sub class of QObject not inheriting QObject!? Crash will happen when using %s.", className.constData());
return;
}
-
- TypeUserData* userData = reinterpret_cast<TypeUserData*>(Shiboken::ObjectType::getTypeUserData(qobjBase));
- initDynamicMetaObject(type, baseMo, userData->cppObjSize);
+ initDynamicMetaObject(type, userData->mo.update(), userData->cppObjSize);
}
PyObject* getMetaDataFromQObject(QObject* cppSelf, PyObject* self, PyObject* name)
@@ -299,7 +319,7 @@ PyObject* getMetaDataFromQObject(QObject* cppSelf, PyObject* self, PyObject* nam
}
}
}
- if (signalList.size() > 0) {
+ if (!signalList.empty()) {
PyObject* pySignal = reinterpret_cast<PyObject*>(Signal::newObjectFromMethod(self, signalList));
PyObject_SetAttr(self, name, pySignal);
return pySignal;
@@ -366,7 +386,7 @@ PyObject* getWrapperForQObject(QObject* cppSelf, SbkObjectType* sbk_type)
// set and check if it's created after the set call
QVariant existing = cppSelf->property(invalidatePropertyName);
if (!existing.isValid()) {
- QSharedPointer<any_t> shared_with_del((any_t*)cppSelf, invalidatePtr);
+ QSharedPointer<any_t> shared_with_del(reinterpret_cast<any_t*>(cppSelf), invalidatePtr);
cppSelf->setProperty(invalidatePropertyName, QVariant::fromValue(shared_with_del));
pyOut = reinterpret_cast<PyObject *>(Shiboken::BindingManager::instance().retrieveWrapper(cppSelf));
if (pyOut) {
diff --git a/sources/pyside2/libpyside/pyside.h b/sources/pyside2/libpyside/pyside.h
index e2e108ed8..b53048eba 100644
--- a/sources/pyside2/libpyside/pyside.h
+++ b/sources/pyside2/libpyside/pyside.h
@@ -41,16 +41,15 @@
#define PYSIDE_H
#include <sbkpython.h>
+
#include <pysidemacros.h>
#ifdef PYSIDE_QML_SUPPORT
-# include <qqml.h>
+# include <QtQml/qqml.h>
#endif
-#include <QMetaType>
-#include <QHash>
-#include <QList>
-#include <QLoggingCategory>
+#include <QtCore/QMetaType>
+#include <QtCore/QHash>
struct SbkObjectType;
@@ -101,7 +100,8 @@ struct initQtMetaType<T, false> {
};
PYSIDE_DEPRECATED(PYSIDE_API void initDynamicMetaObject(SbkObjectType* type, const QMetaObject* base));
-PYSIDE_API void initDynamicMetaObject(SbkObjectType* type, const QMetaObject* base, const std::size_t& cppObjSize);
+PYSIDE_API void initDynamicMetaObject(SbkObjectType* type, const QMetaObject* base,
+ std::size_t cppObjSize);
PYSIDE_API void initQObjectSubType(SbkObjectType* type, PyObject* args, PyObject* kwds);
/// Return the size in bytes of a type that inherits QObject.
diff --git a/sources/pyside2/libpyside/pyside2.pc.in b/sources/pyside2/libpyside/pyside2.pc.in
index 37a115989..ecbe0bbc8 100644
--- a/sources/pyside2/libpyside/pyside2.pc.in
+++ b/sources/pyside2/libpyside/pyside2.pc.in
@@ -3,6 +3,7 @@ exec_prefix=@CMAKE_INSTALL_PREFIX@
libdir=@LIB_INSTALL_DIR@
includedir=@CMAKE_INSTALL_PREFIX@/include/PySide2@pyside2_SUFFIX@
typesystemdir=@CMAKE_INSTALL_PREFIX@/share/PySide2@pyside2_SUFFIX@/typesystems
+gluedir=@CMAKE_INSTALL_PREFIX@/share/PySide2@pyside2_SUFFIX@/glue
pythonpath=@PYTHON_SITE_PACKAGES@
Name: PySide2@pyside2_SUFFIX@
diff --git a/sources/pyside2/libpyside/globalreceiver.h b/sources/pyside2/libpyside/pyside_p.h
index 426d40bfe..1084a40a1 100644
--- a/sources/pyside2/libpyside/globalreceiver.h
+++ b/sources/pyside2/libpyside/pyside_p.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt for Python.
@@ -37,44 +37,35 @@
**
****************************************************************************/
-#ifndef GLOBALRECEIVER_H
-#define GLOBALRECEIVER_H
+#ifndef PYSIDE_P_H
+#define PYSIDE_P_H
-#include <sbkpython.h>
-#include <QObject>
-#include <QHash>
-#include <QSet>
-#include "dynamicqmetaobject.h"
+#include <pysidemacros.h>
-namespace PySide
-{
+#include <dynamicqmetaobject.h>
-class DynamicSlotData;
+struct SbkObjectType;
-class GlobalReceiver : public QObject
+namespace PySide
{
-public:
- GlobalReceiver();
- ~GlobalReceiver();
- int qt_metacall(QMetaObject::Call call, int id, void** args);
- const QMetaObject* metaObject() const;
- int addSlot(const char* slot, PyObject* callback);
- void removeSlot(int slotId);
- void connectNotify(QObject* sender, int slotId);
- void disconnectNotify(QObject* sender, int slotId);
- bool hasConnectionWith(const QObject* object);
-protected:
- using QObject::connectNotify;
- using QObject::disconnectNotify;
+// Struct associated with QObject's via Shiboken::Object::getTypeUserData()
+struct TypeUserData
+{
+ explicit TypeUserData(PyTypeObject* type, const QMetaObject* metaobject, std::size_t size) :
+ mo(type, metaobject), cppObjSize(size) {}
-private:
- DynamicQMetaObject m_metaObject;
- QSet<int> m_shortCircuitSlots;
- QHash<int, DynamicSlotData* > m_slotReceivers;
+ MetaObjectBuilder mo;
+ std::size_t cppObjSize;
};
-}
+TypeUserData *retrieveTypeUserData(SbkObjectType *sbkTypeObj);
+TypeUserData *retrieveTypeUserData(PyTypeObject *pyTypeObj);
+TypeUserData *retrieveTypeUserData(PyObject *pyObj);
+// For QML
+PYSIDE_API const QMetaObject *retrieveMetaObject(PyTypeObject *pyTypeObj);
+PYSIDE_API const QMetaObject *retrieveMetaObject(PyObject *pyObj);
-#endif
+} //namespace PySide
+#endif // PYSIDE_P_H
diff --git a/sources/pyside2/libpyside/pysideclassinfo.cpp b/sources/pyside2/libpyside/pysideclassinfo.cpp
index 5593825c3..4edf0fa91 100644
--- a/sources/pyside2/libpyside/pysideclassinfo.cpp
+++ b/sources/pyside2/libpyside/pysideclassinfo.cpp
@@ -38,12 +38,13 @@
****************************************************************************/
#include <sbkpython.h>
+
#include "pysideclassinfo.h"
+#include "pyside_p.h"
#include "pysideclassinfo_p.h"
#include "dynamicqmetaobject.h"
#include <shiboken.h>
-#include <QDebug>
#define CLASSINFO_CLASS_NAME "ClassInfo"
@@ -74,9 +75,8 @@ static PyType_Spec PySideClassInfoType_spec = {
PyTypeObject *PySideClassInfoTypeF(void)
{
- static PyTypeObject *type = nullptr;
- if (!type)
- type = (PyTypeObject *)PyType_FromSpec(&PySideClassInfoType_spec);
+ static PyTypeObject *type =
+ reinterpret_cast<PyTypeObject *>(PyType_FromSpec(&PySideClassInfoType_spec));
return type;
}
@@ -97,8 +97,7 @@ PyObject *classCall(PyObject *self, PyObject *args, PyObject * /* kw */)
return 0;
}
- PyObject* klass;
- klass = PyTuple_GetItem(args, 0);
+ PyObject *klass = PyTuple_GetItem(args, 0);
bool validClass = false;
// This will sometimes segfault if you mistakenly use it on a function declaration
@@ -107,10 +106,11 @@ PyObject *classCall(PyObject *self, PyObject *args, PyObject * /* kw */)
return 0;
}
- if (Shiboken::ObjectType::checkType(reinterpret_cast<PyTypeObject*>(klass))) {
- PySide::DynamicQMetaObject* mo = reinterpret_cast<PySide::DynamicQMetaObject*>(Shiboken::ObjectType::getTypeUserData(reinterpret_cast<SbkObjectType*>(klass)));
- if (mo) {
- mo->addInfo(PySide::ClassInfo::getMap(data));
+ PyTypeObject *klassType = reinterpret_cast<PyTypeObject*>(klass);
+ if (Shiboken::ObjectType::checkType(klassType)) {
+ if (auto userData = PySide::retrieveTypeUserData(klassType)) {
+ PySide::MetaObjectBuilder &mo = userData->mo;
+ mo.addInfo(PySide::ClassInfo::getMap(data));
pData->m_alreadyWrapped = true;
validClass = true;
}
diff --git a/sources/pyside2/libpyside/pysideclassinfo.h b/sources/pyside2/libpyside/pysideclassinfo.h
index 910dd9f82..ff60b91c3 100644
--- a/sources/pyside2/libpyside/pysideclassinfo.h
+++ b/sources/pyside2/libpyside/pysideclassinfo.h
@@ -41,9 +41,11 @@
#define PYSIDE_CLASSINFO_H
#include <pysidemacros.h>
+
#include <sbkpython.h>
-#include <QMap>
-#include <QByteArray>
+
+#include <QtCore/QMap>
+#include <QtCore/QByteArray>
extern "C"
{
diff --git a/sources/pyside2/libpyside/pysidemetafunction.cpp b/sources/pyside2/libpyside/pysidemetafunction.cpp
index a9fbbc7fc..4cdc7ec16 100644
--- a/sources/pyside2/libpyside/pysidemetafunction.cpp
+++ b/sources/pyside2/libpyside/pysidemetafunction.cpp
@@ -36,14 +36,13 @@
** $QT_END_LICENSE$
**
****************************************************************************/
-#include <sbkpython.h>
+
#include "pysidemetafunction.h"
#include "pysidemetafunction_p.h"
#include <shiboken.h>
-#include <QObject>
-#include <QMetaMethod>
-#include <QDebug>
+
+#include <QtCore/QMetaMethod>
extern "C"
{
diff --git a/sources/pyside2/libpyside/pysidemetafunction.h b/sources/pyside2/libpyside/pysidemetafunction.h
index 020f02d49..1085ecb5e 100644
--- a/sources/pyside2/libpyside/pysidemetafunction.h
+++ b/sources/pyside2/libpyside/pysidemetafunction.h
@@ -40,13 +40,12 @@
#ifndef PYSIDE_METAFUNCTION_H
#define PYSIDE_METAFUNCTION_H
-#include <QObject>
-#include <QString>
-#include <QStringList>
-
#include <pysidemacros.h>
+
#include <sbkpython.h>
+#include <QtCore/QObject>
+
extern "C"
{
extern PYSIDE_API PyTypeObject *PySideMetaFunctionTypeF(void);
diff --git a/sources/pyside2/libpyside/pysidemetafunction_p.h b/sources/pyside2/libpyside/pysidemetafunction_p.h
index c3b8fe0c7..442e05ea7 100644
--- a/sources/pyside2/libpyside/pysidemetafunction_p.h
+++ b/sources/pyside2/libpyside/pysidemetafunction_p.h
@@ -41,8 +41,8 @@
#define PYSIDE_METAFUNCTION_P_H
#include <sbkpython.h>
-#include <QList>
-#include <QByteArray>
+
+#include <QtCore/QtGlobal>
QT_BEGIN_NAMESPACE
class QObject;
diff --git a/sources/pyside2/libpyside/pysideproperty.cpp b/sources/pyside2/libpyside/pysideproperty.cpp
index 279e09ec1..091b0c447 100644
--- a/sources/pyside2/libpyside/pysideproperty.cpp
+++ b/sources/pyside2/libpyside/pysideproperty.cpp
@@ -45,8 +45,6 @@
#include "pysidesignal_p.h"
#include <shiboken.h>
-#include <QDebug>
-
#define QPROPERTY_CLASS_NAME "Property"
@@ -173,7 +171,8 @@ int qpropertyTpInit(PyObject* self, PyObject* args, PyObject* kwds)
"designable", "scriptable", "stored", "user",
"constant", "final", 0};
if (!PyArg_ParseTupleAndKeywords(args, kwds,
- "O|OOOOsObbbbbb:QtCore.QProperty", (char**) kwlist,
+ "O|OOOOsObbbbbb:QtCore.QProperty",
+ const_cast<char**>(kwlist),
/*OO*/ &type, &(pData->fget),
/*OOO*/ &(pData->fset), &(pData->freset), &(pData->fdel),
/*s*/ &(pData->doc),
@@ -197,14 +196,13 @@ int qpropertyTpInit(PyObject* self, PyObject* args, PyObject* kwds)
Py_XINCREF(pData->fdel);
Py_XINCREF(pData->notify);
return 1;
- } else {
- pData->fget = 0;
- pData->fset = 0;
- pData->freset = 0;
- pData->fdel = 0;
- pData->notify = 0;
- return -1;
}
+ pData->fget = nullptr;
+ pData->fset = nullptr;
+ pData->freset = nullptr;
+ pData->fdel = nullptr;
+ pData->notify = nullptr;
+ return -1;
}
void qpropertyDeAlloc(PyObject* self)
@@ -225,10 +223,9 @@ PyObject *qPropertyCall(PyObject *self, PyObject *args, PyObject * /* kw */)
Py_INCREF(self);
return self;
- } else {
- PyErr_SetString(PyExc_TypeError, "Invalid property usage.");
- return 0;
}
+ PyErr_SetString(PyExc_TypeError, "Invalid property usage.");
+ return nullptr;
}
PyObject* qPropertySetter(PyObject* self, PyObject* callback)
@@ -242,10 +239,9 @@ PyObject* qPropertySetter(PyObject* self, PyObject* callback)
Py_INCREF(callback);
return callback;
- } else {
- PyErr_SetString(PyExc_TypeError, "Invalid property setter agument.");
- return 0;
}
+ PyErr_SetString(PyExc_TypeError, "Invalid property setter agument.");
+ return nullptr;
}
PyObject* qPropertyGetter(PyObject* self, PyObject* callback)
@@ -259,10 +255,9 @@ PyObject* qPropertyGetter(PyObject* self, PyObject* callback)
Py_INCREF(callback);
return callback;
- } else {
- PyErr_SetString(PyExc_TypeError, "Invalid property getter agument.");
- return 0;
}
+ PyErr_SetString(PyExc_TypeError, "Invalid property getter agument.");
+ return nullptr;
}
static int qpropertyTraverse(PyObject* self, visitproc visit, void* arg)
diff --git a/sources/pyside2/libpyside/pysideproperty.h b/sources/pyside2/libpyside/pysideproperty.h
index d77416abe..0ea5e84d6 100644
--- a/sources/pyside2/libpyside/pysideproperty.h
+++ b/sources/pyside2/libpyside/pysideproperty.h
@@ -41,8 +41,10 @@
#define PYSIDE_PROPERTY_H
#include <pysidemacros.h>
+
#include <sbkpython.h>
-#include <QObject>
+
+#include <QtCore/QMetaObject>
extern "C"
{
diff --git a/sources/pyside2/libpyside/pysideqflags.cpp b/sources/pyside2/libpyside/pysideqflags.cpp
index 684628e57..cb57031b0 100644
--- a/sources/pyside2/libpyside/pysideqflags.cpp
+++ b/sources/pyside2/libpyside/pysideqflags.cpp
@@ -38,8 +38,9 @@
****************************************************************************/
#include "pysideqflags.h"
-#include <sbkenum.h>
+
#include <autodecref.h>
+#include <sbkenum.h>
extern "C" {
struct SbkConverter;
@@ -174,13 +175,8 @@ namespace QFlags
newspec->itemsize = SbkNewQFlagsType_spec.itemsize;
newspec->flags = SbkNewQFlagsType_spec.flags;
int idx = -1;
-#ifdef IS_PY3K
-# define SLOT slot
-#else
-# define SLOT slot_
-#endif
- while (numberMethods[++idx].SLOT) {
- assert(SbkNewQFlagsType_slots[idx].SLOT == numberMethods[idx].SLOT);
+ while (numberMethods[++idx].slot) {
+ assert(SbkNewQFlagsType_slots[idx].slot == numberMethods[idx].slot);
SbkNewQFlagsType_slots[idx].pfunc = numberMethods[idx].pfunc;
}
newspec->slots = SbkNewQFlagsType_spec.slots;
diff --git a/sources/pyside2/libpyside/pysidesignal.cpp b/sources/pyside2/libpyside/pysidesignal.cpp
index c3dc65968..e7fd389a8 100644
--- a/sources/pyside2/libpyside/pysidesignal.cpp
+++ b/sources/pyside2/libpyside/pysidesignal.cpp
@@ -43,7 +43,12 @@
#include "signalmanager.h"
#include <shiboken.h>
-#include <QDebug>
+
+#include <QtCore/QObject>
+#include <QtCore/QMetaMethod>
+#include <QtCore/QMetaObject>
+
+#include <utility>
#define SIGNAL_CLASS_NAME "Signal"
#define SIGNAL_INSTANCE_NAME "SignalInstance"
@@ -54,14 +59,15 @@ namespace Signal {
//aux
class SignalSignature {
public:
- SignalSignature() : m_attributes(QMetaMethod::Compatibility) {}
- SignalSignature(QByteArray parameterTypes) : m_parameterTypes(parameterTypes),
- m_attributes(QMetaMethod::Compatibility) {}
- SignalSignature(QByteArray parameterTypes, QMetaMethod::Attributes attributes) :
- m_parameterTypes(parameterTypes),
+ SignalSignature() = default;
+ explicit SignalSignature(QByteArray parameterTypes) :
+ m_parameterTypes(std::move(parameterTypes)) {}
+ explicit SignalSignature(QByteArray parameterTypes, QMetaMethod::Attributes attributes) :
+ m_parameterTypes(std::move(parameterTypes)),
m_attributes(attributes) {}
+
QByteArray m_parameterTypes;
- QMetaMethod::Attributes m_attributes;
+ QMetaMethod::Attributes m_attributes = QMetaMethod::Compatibility;
};
static char* buildSignature(const char*, const char*);
@@ -412,8 +418,7 @@ PyObject* signalInstanceConnect(PyObject* self, PyObject* args, PyObject* kwds)
PyObject* result = PyObject_CallObject(pyMethod, tupleArgs);
if (result == Py_True || result == Py_False)
return result;
- else
- Py_XDECREF(result);
+ Py_XDECREF(result);
}
if (!PyErr_Occurred()) // PYSIDE-79: inverse the logic. A Null return needs an error.
PyErr_Format(PyExc_RuntimeError, "Failed to connect signal %s.", source->d->signature);
@@ -661,9 +666,10 @@ char* getTypeName(PyObject* type)
typeName = strdup("PyObject");
}
return typeName;
- } else if (type == Py_None) { // Must be checked before as Shiboken::String::check accepts Py_None
+ }
+ if (type == Py_None) // Must be checked before as Shiboken::String::check accepts Py_None
return strdup("void");
- } else if (Shiboken::String::check(type)) {
+ if (Shiboken::String::check(type)) {
const char *result = Shiboken::String::toCString(type);
if (!strcmp(result, "qreal"))
result = sizeof(qreal) == sizeof(double) ? "double" : "float";
@@ -778,7 +784,7 @@ PySideSignalInstance* newObjectFromMethod(PyObject* source, const QList<QMetaMet
{
PySideSignalInstance* root = 0;
PySideSignalInstance* previous = 0;
- foreach (const QMetaMethod &m, methodList) {
+ for (const QMetaMethod &m : methodList) {
PySideSignalInstance* item = PyObject_New(PySideSignalInstance, PySideSignalInstanceTypeF());
if (!root)
root = item;
@@ -835,7 +841,7 @@ template<typename T>
static typename T::value_type join(T t, const char* sep)
{
typename T::value_type res;
- if (!t.size())
+ if (t.isEmpty())
return res;
typename T::const_iterator it = t.begin();
@@ -894,7 +900,7 @@ void registerSignals(SbkObjectType* pyObj, const QMetaObject* metaObject)
self->signaturesSize = 0;
self->signatures = 0;
self->signatureAttributes = 0;
- self->initialized = 0;
+ self->initialized = false;
self->homonymousMethod = 0;
// Empty signatures comes first! So they will be the default signal signature
@@ -949,9 +955,9 @@ QStringList getArgsFromSignature(const char* signature, bool* isShortCircuit)
if (isShortCircuit)
*isShortCircuit = !qsignature.contains(QLatin1Char('('));
- if (qsignature.contains(QLatin1String("()")) || qsignature.contains(QLatin1String("(void)"))) {
+ if (qsignature.contains(QLatin1String("()")) || qsignature.contains(QLatin1String("(void)")))
return result;
- } else if (qsignature.contains(QLatin1Char('('))) {
+ if (qsignature.contains(QLatin1Char('('))) {
static QRegExp regex(QLatin1String(".+\\((.*)\\)"));
//get args types
QString types = qsignature;
@@ -1047,9 +1053,8 @@ QString codeCallbackName(PyObject* callback, const QString& funcName)
PyObject* self = PyMethod_GET_SELF(callback);
PyObject* func = PyMethod_GET_FUNCTION(callback);
return funcName + QString::number(quint64(self), 16) + QString::number(quint64(func), 16);
- } else {
- return funcName + QString::number(quint64(callback), 16);
}
+ return funcName + QString::number(quint64(callback), 16);
}
} //namespace Signal
diff --git a/sources/pyside2/libpyside/pysidesignal.h b/sources/pyside2/libpyside/pysidesignal.h
index abbefbb1a..a2d58a27c 100644
--- a/sources/pyside2/libpyside/pysidesignal.h
+++ b/sources/pyside2/libpyside/pysidesignal.h
@@ -40,14 +40,19 @@
#ifndef PYSIDE_SIGNAL_H
#define PYSIDE_SIGNAL_H
-#include <QObject>
-#include <QString>
-#include <QStringList>
-
#include <pysidemacros.h>
+
#include <sbkpython.h>
#include <basewrapper.h>
+#include <QtCore/QList>
+#include <QtCore/QMetaMethod>
+
+QT_BEGIN_NAMESPACE
+struct QMetaObject;
+class QObject;
+QT_END_NAMESPACE
+
extern "C"
{
extern PYSIDE_API PyTypeObject *PySideSignalTypeF(void);
diff --git a/sources/pyside2/libpyside/pysideslot.cpp b/sources/pyside2/libpyside/pysideslot.cpp
index 6ae664c42..6f6658cf8 100644
--- a/sources/pyside2/libpyside/pysideslot.cpp
+++ b/sources/pyside2/libpyside/pysideslot.cpp
@@ -42,8 +42,9 @@
#include "pysideslot_p.h"
#include <shiboken.h>
-#include <QString>
-#include <QMetaObject>
+
+#include <QtCore/QMetaObject>
+#include <QtCore/QString>
#define SLOT_DEC_NAME "Slot"
@@ -96,8 +97,10 @@ int slotTpInit(PyObject *self, PyObject *args, PyObject *kw)
if (emptyTuple == 0)
emptyTuple = PyTuple_New(0);
- if (!PyArg_ParseTupleAndKeywords(emptyTuple, kw, "|sO:QtCore." SLOT_DEC_NAME, (char**) kwlist, &argName, &argResult))
+ if (!PyArg_ParseTupleAndKeywords(emptyTuple, kw, "|sO:QtCore." SLOT_DEC_NAME,
+ const_cast<char**>(kwlist), &argName, &argResult)) {
return 0;
+ }
PySideSlot *data = reinterpret_cast<PySideSlot*>(self);
for(Py_ssize_t i = 0, i_max = PyTuple_Size(args); i < i_max; i++) {
diff --git a/sources/pyside2/libpyside/pysideweakref.cpp b/sources/pyside2/libpyside/pysideweakref.cpp
index 6c38d39c4..6b5073db8 100644
--- a/sources/pyside2/libpyside/pysideweakref.cpp
+++ b/sources/pyside2/libpyside/pysideweakref.cpp
@@ -65,7 +65,7 @@ static PyType_Spec PySideCallableObjectType_spec = {
};
-static PyTypeObject *PySideCallableObjectTypeF(void)
+static PyTypeObject *PySideCallableObjectTypeF()
{
static PyTypeObject *type =
(PyTypeObject *)PyType_FromSpec(&PySideCallableObjectType_spec);
diff --git a/sources/pyside2/libpyside/signalmanager.cpp.in b/sources/pyside2/libpyside/signalmanager.cpp
index c67bc6369..8925ffd35 100644
--- a/sources/pyside2/libpyside/signalmanager.cpp.in
+++ b/sources/pyside2/libpyside/signalmanager.cpp
@@ -43,25 +43,25 @@
#include "pysideproperty.h"
#include "pysideproperty_p.h"
#include "pyside.h"
+#include "pyside_p.h"
#include "dynamicqmetaobject.h"
#include "pysidemetafunction_p.h"
-#include <QtCore>
-#include <QHash>
-#include <QStringList>
-#include <QMetaMethod>
#include <autodecref.h>
-#include <gilstate.h>
-#include <QDebug>
-#include <limits>
-#include <algorithm>
#include <basewrapper.h>
#include <bindingmanager.h>
+#include <gilstate.h>
#include <sbkconverter.h>
#include <sbkstring.h>
+#include <QtCore/QDebug>
+#include <QtCore/QHash>
+
+#include <algorithm>
+#include <limits>
+
// These private headers are needed to throw JavaScript exceptions
-#if @QML_PRIVATE_API_SUPPORT@
+#if PYSIDE_QML_PRIVATE_API_SUPPORT
#include <private/qv4engine_p.h>
#include <private/qv4context_p.h>
#include <private/qqmldata_p.h>
@@ -76,7 +76,6 @@
#define PYSIDE_SLOT '1'
#define PYSIDE_SIGNAL '2'
#include "globalreceiverv2.h"
-#include "globalreceiver.h"
#define PYTHON_TYPE "PyObject"
@@ -91,7 +90,7 @@ namespace {
static void destroyMetaObject(PyObject* obj)
{
void* ptr = PyCapsule_GetPointer(obj, 0);
- PySide::DynamicQMetaObject* meta = reinterpret_cast<PySide::DynamicQMetaObject*>(ptr);
+ auto meta = reinterpret_cast<PySide::MetaObjectBuilder*>(ptr);
SbkObject* wrapper = Shiboken::BindingManager::instance().retrieveWrapper(meta);
if (wrapper)
Shiboken::BindingManager::instance().releaseWrapper(wrapper);
@@ -101,7 +100,7 @@ namespace {
#else
static void destroyMetaObject(void* obj)
{
- PySide::DynamicQMetaObject* meta = reinterpret_cast<PySide::DynamicQMetaObject*>(obj);
+ auto meta = reinterpret_cast<PySide::MetaObjectBuilder*>(obj);
SbkObject* wrapper = Shiboken::BindingManager::instance().retrieveWrapper(meta);
if (wrapper)
Shiboken::BindingManager::instance().releaseWrapper(wrapper);
@@ -142,11 +141,16 @@ PyObjectWrapper::~PyObjectWrapper()
Py_XDECREF(m_me);
}
-PyObjectWrapper& PyObjectWrapper::operator=(const PySide::PyObjectWrapper& other)
+void PyObjectWrapper::reset(PyObject *o)
{
- Py_XINCREF(other.m_me);
+ Py_XINCREF(o);
Py_XDECREF(m_me);
- m_me = other.m_me;
+ m_me = o;
+}
+
+PyObjectWrapper& PyObjectWrapper::operator=(const PySide::PyObjectWrapper& other)
+{
+ reset(other.m_me);
return *this;
}
@@ -205,10 +209,9 @@ QDataStream &operator>>(QDataStream& in, PyObjectWrapper& myObj)
in >> repr;
Shiboken::AutoDecRef pyCode(PyBytes_FromStringAndSize(repr.data(), repr.size()));
Shiboken::AutoDecRef value(PyObject_CallFunctionObjArgs(eval_func, pyCode.object(), 0));
- if (!value.object()) {
- value = Py_None;
- }
- myObj = PyObjectWrapper(value);
+ if (!value.object())
+ value.reset(Py_None);
+ myObj.reset(value);
return in;
}
@@ -220,9 +223,6 @@ struct SignalManager::SignalManagerPrivate
{
SharedMap m_globalReceivers;
- //Deprecated
- GlobalReceiver m_globalReceiver;
-
SignalManagerPrivate()
{
m_globalReceivers = SharedMap( new QMap<QByteArray, GlobalReceiverV2*>() );
@@ -304,44 +304,21 @@ SignalManager& SignalManager::instance()
return me;
}
-QObject* SignalManager::globalReceiver()
-{
- return &m_d->m_globalReceiver;
-}
-
-void SignalManager::globalReceiverConnectNotify(QObject* source, int slotIndex)
-{
- m_d->m_globalReceiver.connectNotify(source, slotIndex);
-}
-
-void SignalManager::globalReceiverDisconnectNotify(QObject* source, int slotIndex)
-{
- m_d->m_globalReceiver.disconnectNotify(source, slotIndex);
-}
-
-void SignalManager::addGlobalSlot(const char* slot, PyObject* callback)
-{
- addGlobalSlotGetIndex(slot, callback);
-}
-
-int SignalManager::addGlobalSlotGetIndex(const char* slot, PyObject* callback)
-{
- return m_d->m_globalReceiver.addSlot(slot, callback);
-}
-
QObject* SignalManager::globalReceiver(QObject *sender, PyObject *callback)
{
SharedMap globalReceivers = m_d->m_globalReceivers;
QByteArray hash = GlobalReceiverV2::hash(callback);
GlobalReceiverV2* gr = 0;
- if (!globalReceivers->contains(hash)) {
- gr = (*globalReceivers)[hash] = new GlobalReceiverV2(callback, globalReceivers);
+ auto it = globalReceivers->find(hash);
+ if (it == globalReceivers->end()) {
+ gr = new GlobalReceiverV2(callback, globalReceivers);
+ globalReceivers->insert(hash, gr);
if (sender) {
gr->incRef(sender); // create a link reference
gr->decRef(); // remove extra reference
}
} else {
- gr = (*globalReceivers)[hash];
+ gr = it.value();
if (sender)
gr->incRef(sender);
}
@@ -465,7 +442,7 @@ int SignalManager::qt_metacall(QObject* object, QMetaObject::Call call, int id,
if (PyErr_Occurred()) {
-#if @QML_PRIVATE_API_SUPPORT@
+#if PYSIDE_QML_PRIVATE_API_SUPPORT
// This JS engine grabber based off of Qt 5.5's `qjsEngine` function
QQmlData *data = QQmlData::get(object, false);
@@ -572,9 +549,26 @@ bool SignalManager::registerMetaMethod(QObject* source, const char* signature, Q
return (ret != -1);
}
+static MetaObjectBuilder *metaBuilderFromDict(PyObject* dict)
+{
+ if (!dict || !PyDict_Contains(dict, metaObjectAttr))
+ return nullptr;
+
+ PyObject *pyBuilder = PyDict_GetItem(dict, metaObjectAttr);
+#ifdef IS_PY3K
+ return reinterpret_cast<MetaObjectBuilder *>(PyCapsule_GetPointer(pyBuilder, nullptr));
+#else
+ return reinterpret_cast<MetaObjectBuilder *>(PyCObject_AsVoidPtr(pyBuilder));
+#endif
+}
+
int SignalManager::registerMetaMethodGetIndex(QObject* source, const char* signature, QMetaMethod::MethodType type)
{
- Q_ASSERT(source);
+ if (!source) {
+ qWarning("SignalManager::registerMetaMethodGetIndex(\"%s\") called with source=nullptr.",
+ signature);
+ return -1;
+ }
const QMetaObject* metaObject = source->metaObject();
int methodIndex = metaObject->indexOfMethod(signature);
// Create the dynamic signal is needed
@@ -584,13 +578,13 @@ int SignalManager::registerMetaMethodGetIndex(QObject* source, const char* signa
qWarning() << "Invalid Signal signature:" << signature;
return -1;
} else {
- DynamicQMetaObject *dmo = 0;
PyObject *pySelf = reinterpret_cast<PyObject*>(self);
PyObject* dict = self->ob_dict;
+ MetaObjectBuilder *dmo = metaBuilderFromDict(dict);
// Create a instance meta object
- if (!dict || !PyDict_Contains(dict, metaObjectAttr)) {
- dmo = new DynamicQMetaObject(Py_TYPE(pySelf), metaObject);
+ if (!dmo) {
+ dmo = new MetaObjectBuilder(Py_TYPE(pySelf), metaObject);
#ifdef IS_PY3K
PyObject* pyDmo = PyCapsule_New(dmo, 0, destroyMetaObject);
#else
@@ -599,8 +593,6 @@ int SignalManager::registerMetaMethodGetIndex(QObject* source, const char* signa
PyObject_SetAttr(pySelf, metaObjectAttr, pyDmo);
Py_DECREF(pyDmo);
- } else {
- dmo = reinterpret_cast<DynamicQMetaObject*>(const_cast<QMetaObject*>(metaObject));
}
if (type == QMetaMethod::Signal)
@@ -612,32 +604,16 @@ int SignalManager::registerMetaMethodGetIndex(QObject* source, const char* signa
return methodIndex;
}
-bool SignalManager::hasConnectionWith(const QObject *object)
-{
- return m_d->m_globalReceiver.hasConnectionWith(object);
-}
-
-const QMetaObject* SignalManager::retriveMetaObject(PyObject *self)
+const QMetaObject* SignalManager::retrieveMetaObject(PyObject *self)
{
Shiboken::GilState gil;
- DynamicQMetaObject *mo = 0;
Q_ASSERT(self);
- PyObject* dict = reinterpret_cast<SbkObject*>(self)->ob_dict;
- if (dict && PyDict_Contains(dict, metaObjectAttr)) {
- PyObject *pyMo = PyDict_GetItem(dict, metaObjectAttr);
-
-#ifdef IS_PY3K
- mo = reinterpret_cast<DynamicQMetaObject*>(PyCapsule_GetPointer(pyMo, 0));
-#else
- mo = reinterpret_cast<DynamicQMetaObject*>(PyCObject_AsVoidPtr(pyMo));
-#endif
- } else {
- mo = reinterpret_cast<DynamicQMetaObject*>(Shiboken::Object::getTypeUserData(reinterpret_cast<SbkObject*>(self)));
- }
+ MetaObjectBuilder *builder = metaBuilderFromDict(reinterpret_cast<SbkObject*>(self)->ob_dict);
+ if (!builder)
+ builder = &(retrieveTypeUserData(self)->mo);
- mo->update();
- return mo;
+ return builder->update();
}
namespace {
diff --git a/sources/pyside2/libpyside/signalmanager.h b/sources/pyside2/libpyside/signalmanager.h
index 5948a7df1..229ddb91d 100644
--- a/sources/pyside2/libpyside/signalmanager.h
+++ b/sources/pyside2/libpyside/signalmanager.h
@@ -41,10 +41,12 @@
#define SIGNALMANAGER_H
#include "pysidemacros.h"
+
#include <sbkpython.h>
-#include <Qt>
-#include <QStringList>
-#include <QMetaMethod>
+
+#include <QtCore/QMetaMethod>
+
+QT_FORWARD_DECLARE_CLASS(QDataStream)
namespace PySide
{
@@ -53,12 +55,19 @@ namespace PySide
class PYSIDE_API PyObjectWrapper
{
public:
+ PyObjectWrapper(PyObjectWrapper&&) = delete;
+ PyObjectWrapper& operator=(PyObjectWrapper &&) = delete;
+
PyObjectWrapper();
- PyObjectWrapper(PyObject* me);
+ explicit PyObjectWrapper(PyObject* me);
PyObjectWrapper(const PyObjectWrapper &other);
+ PyObjectWrapper& operator=(const PyObjectWrapper &other);
+
+ void reset(PyObject *o);
+
~PyObjectWrapper();
operator PyObject*() const;
- PyObjectWrapper& operator=(const PyObjectWrapper &other);
+
private:
PyObject* m_me;
};
@@ -68,6 +77,7 @@ PYSIDE_API QDataStream &operator>>(QDataStream& in, PyObjectWrapper& myObj);
class PYSIDE_API SignalManager
{
+ Q_DISABLE_COPY(SignalManager)
public:
static SignalManager& instance();
@@ -84,7 +94,7 @@ public:
static int registerMetaMethodGetIndex(QObject* source, const char* signature, QMetaMethod::MethodType type);
// used to discovery metaobject
- static const QMetaObject* retriveMetaObject(PyObject* self);
+ static const QMetaObject* retrieveMetaObject(PyObject* self);
// Used to discovery if SignalManager was connected with object "destroyed()" signal.
int countConnectionsWith(const QObject *object);
@@ -95,24 +105,12 @@ public:
// Utility function to call a python method usign args received in qt_metacall
static int callPythonMetaMethod(const QMetaMethod& method, void** args, PyObject* obj, bool isShortCuit);
- PYSIDE_DEPRECATED(QObject* globalReceiver());
- PYSIDE_DEPRECATED(void addGlobalSlot(const char* slot, PyObject* callback));
- PYSIDE_DEPRECATED(int addGlobalSlotGetIndex(const char* slot, PyObject* callback));
-
- PYSIDE_DEPRECATED(void globalReceiverConnectNotify(QObject *sender, int slotIndex));
- PYSIDE_DEPRECATED(void globalReceiverDisconnectNotify(QObject *sender, int slotIndex));
- PYSIDE_DEPRECATED(bool hasConnectionWith(const QObject *object));
-
private:
struct SignalManagerPrivate;
SignalManagerPrivate* m_d;
SignalManager();
~SignalManager();
-
- // disable copy
- SignalManager(const SignalManager&);
- SignalManager operator=(const SignalManager&);
};
}