aboutsummaryrefslogtreecommitdiffstats
path: root/libpyside
diff options
context:
space:
mode:
authorRenato Filho <renato.filho@openbossa.org>2011-05-10 16:42:32 -0300
committerHugo Parente Lima <hugo.pl@gmail.com>2012-03-08 16:54:20 -0300
commitad58b05c54c3f9d2646d8440c098d98931304f8e (patch)
treea4f03f7e91fec00d013d21437ae24b5a90407520 /libpyside
parent143ae88746d80f39140d915b44b8049c201b2775 (diff)
Uses QMetaObject revision 3.
This allow to register signal and slot in any order. Fixes bug #312 Reviewer: Marcelo Lira <marcelo.lira@openbossa.org> Hugo Parente Lima <hugo.pl@gmail.com>
Diffstat (limited to 'libpyside')
-rw-r--r--libpyside/dynamicqmetaobject.cpp191
-rw-r--r--libpyside/dynamicqmetaobject.h4
-rw-r--r--libpyside/dynamicqmetaobject_p.h6
3 files changed, 77 insertions, 124 deletions
diff --git a/libpyside/dynamicqmetaobject.cpp b/libpyside/dynamicqmetaobject.cpp
index 2ba24ac19..73572e3b4 100644
--- a/libpyside/dynamicqmetaobject.cpp
+++ b/libpyside/dynamicqmetaobject.cpp
@@ -38,12 +38,6 @@
#include <QDebug>
#include <QMetaMethod>
-#define MAX_SIGNALS_COUNT 50
-#define MAX_SLOTS_COUNT 50
-
-#define MAX_GLOBAL_SIGNALS_COUNT 500
-#define MAX_GLOBAL_SLOTS_COUNT 500
-
#define EMPTY_META_METHOD "0()"
using namespace PySide;
@@ -71,16 +65,29 @@ enum PropertyFlags {
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
+};
+
class DynamicQMetaObject::DynamicQMetaObjectPrivate
{
public:
- QList<MethodData> m_signals;
- QList<MethodData> m_slots;
+ QList<MethodData> m_methods;
QList<PropertyData> m_properties;
QByteArray m_className;
void updateMetaObject(QMetaObject* metaObj);
- void writeMethodsData(const QList<MethodData>& methods, unsigned int** data, QList<QByteArray>* strings, int* prtIndex, int maxCount, int nullIndex, int flags);
+ void writeMethodsData(const QList<MethodData>& methods, unsigned int** data, QList<QByteArray>* strings, int* prtIndex, int nullIndex, int flags);
};
static int registerString(const QByteArray& s, QList<QByteArray>* strings)
@@ -132,20 +139,6 @@ static bool isQRealType(const char *type)
return strcmp(type, "qreal") == 0;
}
-
-/*
- * Avoid API break keep this on cpp
- */
-static inline int maxSlotsCount(const QByteArray& className)
-{
- return className == GLOBAL_RECEIVER_CLASS_NAME ? MAX_GLOBAL_SIGNALS_COUNT : MAX_SLOTS_COUNT;
-}
-
-static inline int maxSignalsCount(const QByteArray& className)
-{
- return className == GLOBAL_RECEIVER_CLASS_NAME ? MAX_GLOBAL_SIGNALS_COUNT : MAX_SIGNALS_COUNT;
-}
-
uint PropertyData::flags() const
{
const char* typeName = type().data();
@@ -206,7 +199,7 @@ MethodData::MethodData() : m_signature(m_emptySig)
{
}
-MethodData::MethodData(const char* signature, const char* type) : m_signature(signature), m_type(type)
+MethodData::MethodData(QMetaMethod::MethodType mtype, const char* signature, const char* type) : m_signature(signature), m_type(type), m_mtype(mtype)
{
}
@@ -218,12 +211,7 @@ void MethodData::clear()
bool MethodData::operator==(const MethodData& other) const
{
- return m_signature == other.signature();
-}
-
-bool MethodData::operator==(const char* other) const
-{
- return m_signature == other;
+ return ((m_signature == other.signature()) && (m_mtype == other.methodType()));
}
QByteArray MethodData::signature() const
@@ -243,6 +231,11 @@ bool MethodData::isValid() const
return m_signature.size();
}
+QMetaMethod::MethodType MethodData::methodType() const
+{
+ return m_mtype;
+}
+
PropertyData::PropertyData()
: m_notifyId(0), m_data(0)
{
@@ -302,57 +295,36 @@ DynamicQMetaObject::~DynamicQMetaObject()
delete m_d;
}
-void DynamicQMetaObject::addSignal(const char* signal, const char* type)
+void DynamicQMetaObject::addMethod(QMetaMethod::MethodType mtype, const char* signature, const char* type)
{
- int index = m_d->m_signals.indexOf(signal);
- if (index != -1)
- return;
-
- //search for a empty space
+ int index = -1;
+ int counter = 0;
MethodData blank;
- index = m_d->m_signals.indexOf(blank);
- if (index != -1) {
- m_d->m_signals[index] = MethodData(signal, type);
- m_d->updateMetaObject(this);
- return;
- }
- int maxSignals = maxSignalsCount(m_d->m_className);
- if (m_d->m_signals.size() >= maxSignals) {
- qWarning() << "Fail to add dynamic signal to QObject. PySide support at most" << maxSignals << "dynamic signals.";
- return;
+ 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;
+ else if (*it == blank)
+ index = counter;
+ counter++;
}
- m_d->m_signals << MethodData(signal, type);
- m_d->updateMetaObject(this);
-}
-
-void DynamicQMetaObject::addSlot(const char* slot, const char* type)
-{
- int index = m_d->m_slots.indexOf(slot);
+ //has blank method
if (index != -1)
- return;
+ m_d->m_methods[index] = MethodData(mtype, signature, type);
+ else
+ m_d->m_methods << MethodData(mtype, signature, type);
- //search for a empty space
- MethodData blank;
- index = m_d->m_slots.indexOf(blank);
- if (index != -1) {
- m_d->m_slots[index] = MethodData(slot, type);
- } else if (m_d->m_slots.size() < maxSlotsCount(m_d->m_className)) {
- m_d->m_slots << MethodData(slot, type);
- } else {
- qWarning() << "Fail to add dynamic slot to QObject. PySide support at most" << maxSlotsCount(m_d->m_className) << "dynamic slots.";
- return;
- }
m_d->updateMetaObject(this);
}
-void DynamicQMetaObject::removeSlot(uint index)
+void DynamicQMetaObject::removeMethod(QMetaMethod::MethodType mtype, uint index)
{
const char* methodSig = method(index).signature();
- QList<MethodData>::iterator it = m_d->m_slots.begin();
- for (; it != m_d->m_slots.end(); ++it) {
- if (it->signature() == methodSig) {
+ 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->updateMetaObject(this);
break;
@@ -360,6 +332,26 @@ void DynamicQMetaObject::removeSlot(uint index)
}
}
+void DynamicQMetaObject::addSignal(const char* signal, const char* type)
+{
+ addMethod(QMetaMethod::Signal, signal, type);
+}
+
+void DynamicQMetaObject::addSlot(const char* slot, const char* type)
+{
+ addMethod(QMetaMethod::Slot, slot, type);
+}
+
+void DynamicQMetaObject::removeSlot(uint index)
+{
+ removeMethod(QMetaMethod::Slot, index);
+}
+
+void DynamicQMetaObject::removeSignal(uint index)
+{
+ removeMethod(QMetaMethod::Signal, index);
+}
+
void DynamicQMetaObject::addProperty(const char* propertyName, PyObject* data)
{
int index = m_d->m_properties.indexOf(propertyName);
@@ -372,8 +364,8 @@ void DynamicQMetaObject::addProperty(const char* propertyName, PyObject* data)
if (property->d->notify) {
const char* signalNotify = PySide::Property::getNotifyName(property);
if (signalNotify) {
- QByteArray signalSignature(signalNotify);
- notifyId = m_d->m_signals.indexOf(signalNotify);
+ MethodData signalObject(QMetaMethod::Signal, signalNotify, "");
+ notifyId = m_d->m_methods.indexOf(signalObject);
}
}
@@ -388,31 +380,16 @@ void DynamicQMetaObject::addProperty(const char* propertyName, PyObject* data)
m_d->updateMetaObject(this);
}
-void DynamicQMetaObject::removeSignal(uint index)
-{
- //Current Qt implementation does not support runtime remove signal
- QMetaMethod m = method(index);
- foreach(MethodData md, m_d->m_signals) {
- if (md.signature() == m.signature()) {
- md.clear();
- m_d->updateMetaObject(this);
- break;
- }
- }
-}
void DynamicQMetaObject::DynamicQMetaObjectPrivate::writeMethodsData(const QList<MethodData>& methods,
unsigned int** data,
QList<QByteArray>* strings,
int* prtIndex,
- int maxCount,
int nullIndex,
int flags)
{
int index = *prtIndex;
-
int emptyIndex = registerString(EMPTY_META_METHOD, strings);
-
QList<MethodData>::const_iterator it = methods.begin();
for (; it != methods.end(); ++it) {
@@ -423,50 +400,23 @@ void DynamicQMetaObject::DynamicQMetaObjectPrivate::writeMethodsData(const QList
(*data)[index++] = nullIndex; // arguments
(*data)[index++] = (it->type().size() > 0 ? registerString(it->type(), strings) : nullIndex); // normalized type
(*data)[index++] = nullIndex; // tags
- (*data)[index++] = flags;
- }
-
- for (int i = methods.count(); i < maxCount; ++i) {
- (*data)[index++] = emptyIndex; // func name
- (*data)[index++] = nullIndex; // arguments
- (*data)[index++] = nullIndex; // normalized type
- (*data)[index++] = nullIndex; // tags
- (*data)[index++] = flags;
+ (*data)[index++] = flags | (it->methodType() == QMetaMethod::Signal ? MethodSignal : MethodSlot);
}
*prtIndex = index;
}
void DynamicQMetaObject::DynamicQMetaObjectPrivate::updateMetaObject(QMetaObject* metaObj)
{
- // 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
- };
-
- int maxSignals = maxSignalsCount(m_className);
- int maxSlots = maxSlotsCount(m_className);
-
- uint n_signals = maxSignals;
- uint n_methods = n_signals + maxSlots;
+ uint n_methods = m_methods.size();
uint n_properties = m_properties.size();
- int header[] = {5, // revision
+ int header[] = {3, // revision
0, // class name index in m_metadata
0, 0, // classinfo and classinfo index, not used by us
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
- 0, // flags
- n_signals};
+ 0}; // flags
const int HEADER_LENGHT = sizeof(header)/sizeof(int);
header[5] = HEADER_LENGHT;
@@ -481,11 +431,8 @@ void DynamicQMetaObject::DynamicQMetaObjectPrivate::updateMetaObject(QMetaObject
const int NULL_INDEX = registerString("", &strings); // register a null string
int index = HEADER_LENGHT;
- //write signals
- writeMethodsData(m_signals, &data, &strings, &index, maxSignals, NULL_INDEX, AccessPublic | MethodSignal);
-
- //write slots
- writeMethodsData(m_slots, &data, &strings, &index, maxSlots, NULL_INDEX, AccessPublic | MethodSlot);
+ //write signals/slots
+ writeMethodsData(m_methods, &data, &strings, &index, NULL_INDEX, AccessPublic);
if (m_properties.size())
data[7] = index;
diff --git a/libpyside/dynamicqmetaobject.h b/libpyside/dynamicqmetaobject.h
index 7f64a6cf9..2efeef165 100644
--- a/libpyside/dynamicqmetaobject.h
+++ b/libpyside/dynamicqmetaobject.h
@@ -26,6 +26,7 @@
#include "pysidemacros.h"
#include <Python.h>
#include <QMetaObject>
+#include <QMetaMethod>
namespace PySide
{
@@ -36,6 +37,9 @@ public:
DynamicQMetaObject(const char* className, const QMetaObject* metaObject);
~DynamicQMetaObject();
+
+ void addMethod(QMetaMethod::MethodType mtype, const char* signature, const char* type);
+ void removeMethod(QMetaMethod::MethodType mtype, uint index);
void addSignal(const char* signal, const char* type = 0);
void addSlot(const char* slot, const char* type = 0);
void addProperty(const char* property, PyObject* data);
diff --git a/libpyside/dynamicqmetaobject_p.h b/libpyside/dynamicqmetaobject_p.h
index c8c45a1ab..d8a2b6f0d 100644
--- a/libpyside/dynamicqmetaobject_p.h
+++ b/libpyside/dynamicqmetaobject_p.h
@@ -25,6 +25,7 @@
#include <Python.h>
#include <QByteArray>
+#include <QMetaMethod>
#define GLOBAL_RECEIVER_CLASS_NAME "__GlobalReceiver__"
@@ -39,17 +40,18 @@ namespace PySide
* \param signature method signature
* \param type method return type
*/
- MethodData(const char* signature, const char* type = 0);
+ MethodData(QMetaMethod::MethodType mtype, const char* signature, const char* type = 0);
void clear();
bool isValid() const;
QByteArray signature() const;
QByteArray type() const;
+ QMetaMethod::MethodType methodType() const;
bool operator==(const MethodData& other) const;
- bool operator==(const char* other) const;
private:
QByteArray m_signature;
QByteArray m_type;
+ QMetaMethod::MethodType m_mtype;
static const QByteArray m_emptySig;
};