##// END OF EJS Templates
changed implementation to allow deriving python classes from PythonQt classes...
changed implementation to allow deriving python classes from PythonQt classes (it is still work in progress and is not very useful yet without having shell classes that reimplement the C++ virtual functions) git-svn-id: svn://svn.code.sf.net/p/pythonqt/code/trunk@58 ea8d5007-eb21-0410-b261-ccb3ea6e24a9

File last commit:

r18:44e5ff2700cb
r22:29d38290403f
Show More
PythonQtClassInfo.cpp
658 lines | 20.0 KiB | text/x-c | CppLexer
/ src / PythonQtClassInfo.cpp
ezust
reorganized SVN tree into branches, tags and trunk...
r0 /*
*
* Copyright (C) 2006 MeVis Research GmbH All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* Further, this software is distributed without any warranty that it is
* free of the rightful claim of any third person regarding infringement
* or the like. Any license provided herein, whether implied or
* otherwise, applies only to this software file. Patent licenses, if
* any, provided herein do not apply to combinations of this program with
* other software, or any other product whatsoever.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Contact information: MeVis Research GmbH, Universitaetsallee 29,
* 28359 Bremen, Germany or:
*
* http://www.mevis.de
*
*/
//----------------------------------------------------------------------------------
/*!
// \file PythonQt.cpp
// \author Florian Link
// \author Last changed by $Author: florian $
// \date 2006-05
*/
//----------------------------------------------------------------------------------
#include "PythonQtClassInfo.h"
#include "PythonQtMethodInfo.h"
#include "PythonQt.h"
#include <QMetaMethod>
QHash<QByteArray, int> PythonQtMethodInfo::_parameterTypeDict;
PythonQtClassInfo::PythonQtClassInfo(const QMetaObject* meta, const QByteArray& wrappedClassName) {
_meta = meta;
_wrappedClassName = wrappedClassName;
_constructors = NULL;
florianlink
syncing with my current work, updating to 1.2, see changelog...
r10 _parentClassInfo = NULL;
_parentClassInfoResolved = false;
_decoratorProvider = NULL;
_decoratorProviderCB = NULL;
florianlink
- wrapped instances are now wrapped by class specific subtypes to facilitate future deriving from python...
r18 _pythonQtClassWrapper = NULL;
florianlink
syncing with my current work, updating to 1.2, see changelog...
r10 if (wrappedClassName.isEmpty()) {
_metaTypeId = -1;
} else {
_metaTypeId = QMetaType::type(wrappedClassName);
}
ezust
reorganized SVN tree into branches, tags and trunk...
r0 }
PythonQtClassInfo::~PythonQtClassInfo()
florianlink
syncing with my current work, updating to 1.2, see changelog...
r10 {
clearCachedMembers();
}
void PythonQtClassInfo::clearCachedMembers()
ezust
reorganized SVN tree into branches, tags and trunk...
r0 {
QHashIterator<QByteArray, PythonQtMemberInfo> i(_cachedMembers);
while (i.hasNext()) {
PythonQtMemberInfo member = i.next().value();
if (member._type== PythonQtMemberInfo::Slot) {
PythonQtSlotInfo* info = member._slot;
while (info) {
PythonQtSlotInfo* next = info->nextInfo();
delete info;
info = next;
}
}
}
}
florianlink
syncing with my current work, updating to 1.2, see changelog...
r10 void PythonQtClassInfo::resolveParentClassInfo()
{
if (!_parentClassInfoResolved) {
_parentClassInfoResolved = true;
if (isCPPWrapper()) {
if (!_wrappedClassName.isEmpty()) {
_parentClassInfo = PythonQt::priv()->getClassInfo(_wrappedParentClassName);
}
} else {
if (_meta->superClass()) {
_parentClassInfo = PythonQt::priv()->getClassInfo(_meta->superClass());
}
}
}
}
ezust
reorganized SVN tree into branches, tags and trunk...
r0 int PythonQtClassInfo::findCharOffset(const char* sigStart, char someChar)
{
const char* sigEnd = sigStart;
char c;
do {
c = *sigEnd++;
} while (c!=someChar && c!=0);
return sigEnd-sigStart-1;
}
florianlink
syncing with my current work, updating to 1.2, see changelog...
r10 bool PythonQtClassInfo::lookForPropertyAndCache(const char* memberName)
{
bool found = false;
bool nameMapped = false;
const char* attributeName = memberName;
// look for properties
int i = _meta->indexOfProperty(attributeName);
if (i==-1) {
// try to map name to objectName
if (qstrcmp(attributeName, "name")==0) {
attributeName = "objectName";
nameMapped = true;
i = _meta->indexOfProperty(attributeName);
}
}
if (i!=-1) {
PythonQtMemberInfo newInfo(_meta->property(i));
_cachedMembers.insert(attributeName, newInfo);
if (nameMapped) {
_cachedMembers.insert(memberName, newInfo);
}
#ifdef PYTHONQT_DEBUG
std::cout << "caching property " << memberName << " on " << _meta->className() << std::endl;
#endif
found = true;
}
return found;
}
PythonQtSlotInfo* PythonQtClassInfo::findDecoratorSlotsFromDecoratorProvider(const char* memberName, PythonQtSlotInfo* tail, bool &found, QHash<QByteArray, PythonQtMemberInfo>& memberCache) {
QObject* decoratorProvider = decorator();
if (decoratorProvider) {
const QMetaObject* meta = decoratorProvider->metaObject();
int memberNameLen = strlen(memberName);
int numMethods = meta->methodCount();
int startFrom = QObject::staticMetaObject.methodCount();
for (int i = startFrom; i < numMethods; i++) {
QMetaMethod m = meta->method(i);
if ((m.methodType() == QMetaMethod::Method ||
m.methodType() == QMetaMethod::Slot) && m.access() == QMetaMethod::Public) {
const char* sigStart = m.signature();
bool isClassDeco = false;
if (qstrncmp(sigStart, "static_", 7)==0) {
// skip the static_classname_ part of the string
sigStart += 7 + 1 + strlen(className());
isClassDeco = true;
} else if (qstrncmp(sigStart, "new_", 4)==0) {
isClassDeco = true;
} else if (qstrncmp(sigStart, "delete_", 7)==0) {
isClassDeco = true;
}
// find the first '('
int offset = findCharOffset(sigStart, '(');
// XXX no checking is currently done if the slots have correct first argument or not...
// check if same length and same name
if (memberNameLen == offset && qstrncmp(memberName, sigStart, offset)==0) {
found = true;
PythonQtSlotInfo* info = new PythonQtSlotInfo(m, i, decoratorProvider, isClassDeco?PythonQtSlotInfo::ClassDecorator:PythonQtSlotInfo::InstanceDecorator);
if (tail) {
tail->setNextInfo(info);
} else {
PythonQtMemberInfo newInfo(info);
memberCache.insert(memberName, newInfo);
}
tail = info;
}
}
}
}
return tail;
}
bool PythonQtClassInfo::lookForMethodAndCache(const char* memberName)
{
bool found = false;
int memberNameLen = strlen(memberName);
PythonQtSlotInfo* tail = NULL;
if (_meta) {
int numMethods = _meta->methodCount();
for (int i = 0; i < numMethods; i++) {
QMetaMethod m = _meta->method(i);
if ((m.methodType() == QMetaMethod::Method ||
m.methodType() == QMetaMethod::Slot) && m.access() == QMetaMethod::Public) {
const char* sigStart = m.signature();
// find the first '('
int offset = findCharOffset(sigStart, '(');
// check if same length and same name
if (memberNameLen == offset && qstrncmp(memberName, sigStart, offset)==0) {
found = true;
PythonQtSlotInfo* info = new PythonQtSlotInfo(m, i);
if (tail) {
tail->setNextInfo(info);
} else {
PythonQtMemberInfo newInfo(info);
_cachedMembers.insert(memberName, newInfo);
}
tail = info;
}
}
}
}
// look for dynamic decorators in this class and in derived classes
PythonQtClassInfo* info = this;
while (info) {
tail = info->findDecoratorSlotsFromDecoratorProvider(memberName, tail, found, _cachedMembers);
if (!info->_parentClassInfoResolved) {
info->resolveParentClassInfo();
}
info = info->_parentClassInfo;
}
// look for decorators
if (!_wrappedClassName.isEmpty()) {
tail = findDecoratorSlots(_wrappedClassName.constData(), memberName, memberNameLen, tail, found);
}
const QMetaObject* meta = _meta;
while (meta) {
tail = findDecoratorSlots(meta->className(), memberName, memberNameLen, tail, found);
meta = meta->superClass();
}
return found;
}
bool PythonQtClassInfo::lookForEnumAndCache(const QMetaObject* meta, const char* memberName)
{
bool found = false;
// look for enum values
int enumCount = meta->enumeratorCount();
for (int i=0;i<enumCount; i++) {
QMetaEnum e = meta->enumerator(i);
for (int j=0; j < e.keyCount(); j++) {
if (qstrcmp(e.key(j), memberName)==0) {
PythonQtMemberInfo newInfo(e.value(j));
_cachedMembers.insert(memberName, newInfo);
#ifdef PYTHONQT_DEBUG
std::cout << "caching enum " << memberName << " on " << meta->className() << std::endl;
#endif
found = true;
}
}
}
return found;
}
ezust
reorganized SVN tree into branches, tags and trunk...
r0 PythonQtMemberInfo PythonQtClassInfo::member(const char* memberName)
{
PythonQtMemberInfo info = _cachedMembers.value(memberName);
if (info._type != PythonQtMemberInfo::Invalid) {
return info;
} else {
bool found = false;
florianlink
syncing with my current work, updating to 1.2, see changelog...
r10
found = lookForPropertyAndCache(memberName);
if (!found) {
found = lookForMethodAndCache(memberName);
ezust
reorganized SVN tree into branches, tags and trunk...
r0 }
florianlink
syncing with my current work, updating to 1.2, see changelog...
r10 if (!found) {
if (_meta) {
// check enums in our meta object directly
found = lookForEnumAndCache(_meta, memberName);
ezust
reorganized SVN tree into branches, tags and trunk...
r0 }
florianlink
syncing with my current work, updating to 1.2, see changelog...
r10 if (!found) {
// check enums in the class hierachy of CPP classes
// look for dynamic decorators in this class and in derived classes
PythonQtClassInfo* info = this;
while (info && !found) {
QObject* deco = info->decorator();
if (deco) {
// call on ourself for caching, but with different metaObject():
found = lookForEnumAndCache(deco->metaObject(), memberName);
ezust
reorganized SVN tree into branches, tags and trunk...
r0 }
florianlink
syncing with my current work, updating to 1.2, see changelog...
r10 if (!info->_parentClassInfoResolved) {
info->resolveParentClassInfo();
}
info = info->_parentClassInfo;
ezust
reorganized SVN tree into branches, tags and trunk...
r0 }
}
}
if (!found) {
florianlink
syncing with my current work, updating to 1.2, see changelog...
r10 // we store a NotFound member, so that we get a quick result for non existing members (e.g. operator_equal lookup)
info._type = PythonQtMemberInfo::NotFound;
_cachedMembers.insert(memberName, info);
ezust
reorganized SVN tree into branches, tags and trunk...
r0 }
}
florianlink
syncing with my current work, updating to 1.2, see changelog...
r10
return _cachedMembers.value(memberName);
ezust
reorganized SVN tree into branches, tags and trunk...
r0 }
PythonQtSlotInfo* PythonQtClassInfo::findDecoratorSlots(const char* classname, const char* memberName, int memberNameLen, PythonQtSlotInfo* tail, bool& found)
{
QListIterator<PythonQtSlotInfo*> it(PythonQt::priv()->getDecoratorSlots(classname));
while (it.hasNext()) {
PythonQtSlotInfo* infoOrig = it.next();
const char* sigStart = infoOrig->metaMethod()->signature();
if (qstrncmp("static_", sigStart, 7)==0) {
sigStart += 7;
sigStart += findCharOffset(sigStart, '_')+1;
}
int offset = findCharOffset(sigStart, '(');
if (memberNameLen == offset && qstrncmp(memberName, sigStart, offset)==0) {
//make a copy, otherwise we will have trouble on overloads!
PythonQtSlotInfo* info = new PythonQtSlotInfo(*infoOrig);
found = true;
if (tail) {
tail->setNextInfo(info);
} else {
PythonQtMemberInfo newInfo(info);
_cachedMembers.insert(memberName, newInfo);
}
tail = info;
}
}
return tail;
}
florianlink
syncing with my current work, updating to 1.2, see changelog...
r10 void PythonQtClassInfo::listDecoratorSlotsFromDecoratorProvider(QStringList& list, bool metaOnly) {
QObject* decoratorProvider = decorator();
if (decoratorProvider) {
const QMetaObject* meta = decoratorProvider->metaObject();
int numMethods = meta->methodCount();
int startFrom = QObject::staticMetaObject.methodCount();
for (int i = startFrom; i < numMethods; i++) {
QMetaMethod m = meta->method(i);
if ((m.methodType() == QMetaMethod::Method ||
m.methodType() == QMetaMethod::Slot) && m.access() == QMetaMethod::Public) {
const char* sigStart = m.signature();
bool isClassDeco = false;
if (qstrncmp(sigStart, "static_", 7)==0) {
// skip the static_classname_ part of the string
sigStart += 7 + 1 + strlen(className());
isClassDeco = true;
} else if (qstrncmp(sigStart, "new_", 4)==0) {
florianlink
code cleanup and rename of PythonQtWrapper to PythonQtInstanceWrapper and PythonQtMetaObjectWrapper to PythonQtClassWrapper, since these names match much better what these classes wrap, regarding that we are wrapping CPP objects as well...
r16 continue;
florianlink
syncing with my current work, updating to 1.2, see changelog...
r10 } else if (qstrncmp(sigStart, "delete_", 7)==0) {
florianlink
code cleanup and rename of PythonQtWrapper to PythonQtInstanceWrapper and PythonQtMetaObjectWrapper to PythonQtClassWrapper, since these names match much better what these classes wrap, regarding that we are wrapping CPP objects as well...
r16 continue;
florianlink
syncing with my current work, updating to 1.2, see changelog...
r10 }
// find the first '('
int offset = findCharOffset(sigStart, '(');
// XXX no checking is currently done if the slots have correct first argument or not...
if (!metaOnly || isClassDeco) {
list << QString::fromLatin1(sigStart, offset);
}
}
}
}
}
ezust
reorganized SVN tree into branches, tags and trunk...
r0
QStringList PythonQtClassInfo::memberList(bool metaOnly)
{
florianlink
syncing with my current work, updating to 1.2, see changelog...
r10 resolveParentClassInfo();
decorator();
ezust
reorganized SVN tree into branches, tags and trunk...
r0 QStringList l;
QString h;
florianlink
code cleanup and rename of PythonQtWrapper to PythonQtInstanceWrapper and PythonQtMetaObjectWrapper to PythonQtClassWrapper, since these names match much better what these classes wrap, regarding that we are wrapping CPP objects as well...
r16 if (_wrappedClassName.isEmpty() && _meta && !metaOnly) {
ezust
reorganized SVN tree into branches, tags and trunk...
r0 int i;
int numProperties = _meta->propertyCount();
for (i = 0; i < numProperties; i++) {
QMetaProperty p = _meta->property(i);
l << QString(p.name());
}
}
florianlink
syncing with my current work, updating to 1.2, see changelog...
r10 // normal slots of QObject (or wrapper QObject)
if (!metaOnly && _meta) {
ezust
reorganized SVN tree into branches, tags and trunk...
r0 int numMethods = _meta->methodCount();
bool skipQObj = !_wrappedClassName.isEmpty();
for (int i = skipQObj?QObject::staticMetaObject.methodCount():0; i < numMethods; i++) {
QMetaMethod m = _meta->method(i);
if ((m.methodType() == QMetaMethod::Method ||
m.methodType() == QMetaMethod::Slot) && m.access() == QMetaMethod::Public) {
QByteArray signa(m.signature());
if (signa.startsWith("new_")) continue;
if (signa.startsWith("delete_")) continue;
if (signa.startsWith("static_")) continue;
PythonQtSlotInfo slot(m, i);
l << slot.slotName();
}
}
}
florianlink
syncing with my current work, updating to 1.2, see changelog...
r10
{
// look for dynamic decorators in this class and in derived classes
PythonQtClassInfo* info = this;
while (info) {
info->listDecoratorSlotsFromDecoratorProvider(l, metaOnly);
if (!info->_parentClassInfoResolved) {
info->resolveParentClassInfo();
}
info = info->_parentClassInfo;
}
}
ezust
reorganized SVN tree into branches, tags and trunk...
r0 // look for decorators
QList<const char*> names;
if (!_wrappedClassName.isEmpty()) {
florianlink
syncing with my current work, updating to 1.2, see changelog...
r10 // CPP wrapper case:
ezust
reorganized SVN tree into branches, tags and trunk...
r0 names << _wrappedClassName.constData();
florianlink
syncing with my current work, updating to 1.2, see changelog...
r10 // for CPP classes which are wrapped, we do not want to look for decorators of the wrapping qobjects, since they
// would require a different pointer on the decorator slot call
} else {
// QObject case:
const QMetaObject* meta = _meta;
while (meta) {
if (meta==&QObject::staticMetaObject && !_wrappedClassName.isEmpty()) break;
names << meta->className();
meta = meta->superClass();
}
ezust
reorganized SVN tree into branches, tags and trunk...
r0 }
QListIterator<const char*> nameIt(names);
while (nameIt.hasNext()) {
QListIterator<PythonQtSlotInfo*> it(PythonQt::priv()->getDecoratorSlots(nameIt.next()));
while (it.hasNext()) {
PythonQtSlotInfo* slot = it.next();
if (metaOnly) {
if (slot->isClassDecorator()) {
QByteArray first = slot->slotName();
if (first.startsWith("static_")) {
int idx = first.indexOf('_');
idx = first.indexOf('_', idx+1);
first = first.mid(idx+1);
}
l << first;
}
} else {
l << slot->slotName();
}
}
}
florianlink
syncing with my current work, updating to 1.2, see changelog...
r10
// List enumerator keys...
QList<const QMetaObject*> enumMetaObjects;
if (_meta) {
enumMetaObjects << _meta;
}
// check enums in the class hierachy of CPP classes
PythonQtClassInfo* info = this;
while (info) {
QObject* deco = info->decorator();
if (deco) {
enumMetaObjects << deco->metaObject();
}
if (!info->_parentClassInfoResolved) {
info->resolveParentClassInfo();
}
info = info->_parentClassInfo;
}
foreach(const QMetaObject* meta, enumMetaObjects) {
for (int i = 0; i<meta->enumeratorCount(); i++) {
QMetaEnum e = meta->enumerator(i);
ezust
reorganized SVN tree into branches, tags and trunk...
r0 for (int j=0; j < e.keyCount(); j++) {
l << QString(e.key(j));
}
}
}
return l;
}
const char* PythonQtClassInfo::className()
{
if (!_wrappedClassName.isEmpty()) {
return _wrappedClassName.constData();
} else {
return _meta->className();
}
}
bool PythonQtClassInfo::inherits(const char* name)
{
florianlink
syncing with my current work, updating to 1.2, see changelog...
r10 resolveParentClassInfo();
if (isCPPWrapper()) {
PythonQtClassInfo* info = this;
while (info) {
if (_wrappedClassName == name) {
return true;
}
if (!info->_parentClassInfoResolved) {
info->resolveParentClassInfo();
}
info = info->_parentClassInfo;
}
} else {
const QMetaObject* m = _meta;
while (m) {
if (strcmp(name, m->className())==0) {
return true;
}
m = m->superClass();
ezust
reorganized SVN tree into branches, tags and trunk...
r0 }
}
return false;
}
QString PythonQtClassInfo::help()
{
florianlink
syncing with my current work, updating to 1.2, see changelog...
r10 resolveParentClassInfo();
decorator();
ezust
reorganized SVN tree into branches, tags and trunk...
r0 QString h;
h += QString("--- ") + QString(className()) + QString(" ---\n");
if (_wrappedClassName.isEmpty()) {
h += "Properties:\n";
int i;
int numProperties = _meta->propertyCount();
for (i = 0; i < numProperties; i++) {
QMetaProperty p = _meta->property(i);
h += QString(p.name()) + " (" + QString(p.typeName()) + " )\n";
}
}
if (constructors()) {
h += "Constructors:\n";
PythonQtSlotInfo* constr = constructors();
while (constr) {
h += constr->fullSignature(false) + "\n";
constr = constr->nextInfo();
}
}
h += "Slots:\n";
h += "QString help()\n";
h += "QString className()\n";
florianlink
syncing with my current work, updating to 1.2, see changelog...
r10 if (_meta) {
int numMethods = _meta->methodCount();
for (int i = 0; i < numMethods; i++) {
QMetaMethod m = _meta->method(i);
if ((m.methodType() == QMetaMethod::Method ||
m.methodType() == QMetaMethod::Slot) && m.access() == QMetaMethod::Public) {
QByteArray signa(m.signature());
if (signa.startsWith("new_")) continue;
if (signa.startsWith("delete_")) continue;
if (signa.startsWith("static_")) continue;
PythonQtSlotInfo slot(m, i);
h += slot.fullSignature(false)+ "\n";
}
ezust
reorganized SVN tree into branches, tags and trunk...
r0 }
}
florianlink
syncing with my current work, updating to 1.2, see changelog...
r10
// TODO xxx : decorators and enums from decorator() are missing...
// maybe we can reuse memberlist()?
ezust
reorganized SVN tree into branches, tags and trunk...
r0 // look for decorators
QList<const char*> names;
if (!_wrappedClassName.isEmpty()) {
names << _wrappedClassName.constData();
}
const QMetaObject* meta = _meta;
while (meta) {
names << meta->className();
meta = meta->superClass();
}
QListIterator<const char*> nameIt(names);
while (nameIt.hasNext()) {
QListIterator<PythonQtSlotInfo*> it(PythonQt::priv()->getDecoratorSlots(nameIt.next()));
while (it.hasNext()) {
PythonQtSlotInfo* slot = it.next();
h += slot->fullSignature(slot->isInstanceDecorator()) + "\n";
}
}
florianlink
syncing with my current work, updating to 1.2, see changelog...
r10 if (_meta && _meta->enumeratorCount()) {
ezust
reorganized SVN tree into branches, tags and trunk...
r0 h += "Enums:\n";
for (int i = 0; i<_meta->enumeratorCount(); i++) {
QMetaEnum e = _meta->enumerator(i);
h += QString(e.name()) + " {";
for (int j=0; j < e.keyCount(); j++) {
if (j) { h+= ", "; }
h += e.key(j);
}
h += " }\n";
}
}
florianlink
syncing with my current work, updating to 1.2, see changelog...
r10 if (_wrappedClassName.isEmpty() && _meta) {
ezust
reorganized SVN tree into branches, tags and trunk...
r0 int numMethods = _meta->methodCount();
if (numMethods>0) {
h += "Signals:\n";
florianlink
syncing with my current work, updating to 1.2, see changelog...
r10 for (int i = 0; i < numMethods; i++) {
ezust
reorganized SVN tree into branches, tags and trunk...
r0 QMetaMethod m = _meta->method(i);
if (m.methodType() == QMetaMethod::Signal) {
h += QString(m.signature()) + "\n";
}
}
}
}
return h;
}
PythonQtSlotInfo* PythonQtClassInfo::constructors()
{
if (!_constructors) {
florianlink
syncing with my current work, updating to 1.2, see changelog...
r10 // force creation of lazy decorator, which will register the decorators
decorator();
ezust
reorganized SVN tree into branches, tags and trunk...
r0 _constructors = PythonQt::priv()->getConstructorSlot(!_wrappedClassName.isEmpty()?_wrappedClassName:QByteArray(_meta->className()));
}
return _constructors;
}
void PythonQtClassInfo::setMetaObject(const QMetaObject* meta)
{
_meta = meta;
florianlink
syncing with my current work, updating to 1.2, see changelog...
r10 clearCachedMembers();
}
QObject* PythonQtClassInfo::decorator()
{
if (!_decoratorProvider && _decoratorProviderCB) {
_decoratorProvider = (*_decoratorProviderCB)();
if (_decoratorProvider) {
_decoratorProvider->setParent(PythonQt::priv());
PythonQt::priv()->addDecorators(_decoratorProvider, PythonQtPrivate::ConstructorDecorator | PythonQtPrivate::DestructorDecorator);
}
}
return _decoratorProvider;
ezust
reorganized SVN tree into branches, tags and trunk...
r0 }
florianlink
- added hasOwner method to manage ownership more nicely...
r15
bool PythonQtClassInfo::hasOwnerMethodButNoOwner(void* object)
{
PythonQtMemberInfo info = member("hasOwner");
if (info._type == PythonQtMemberInfo::Slot) {
void* obj = object;
bool result = false;
void* args[2];
args[0] = &result;
args[1] = &obj;
info._slot->decorator()->qt_metacall(QMetaObject::InvokeMetaMethod, info._slot->slotIndex(), args);
return !result;
} else {
return false;
}
}