PythonQtClassInfo.cpp
643 lines
| 19.6 KiB
| text/x-c
|
CppLexer
/ src / PythonQtClassInfo.cpp
ezust
|
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
|
r10 | _parentClassInfo = NULL; | ||
_parentClassInfoResolved = false; | ||||
_decoratorProvider = NULL; | ||||
_decoratorProviderCB = NULL; | ||||
if (wrappedClassName.isEmpty()) { | ||||
_metaTypeId = -1; | ||||
} else { | ||||
_metaTypeId = QMetaType::type(wrappedClassName); | ||||
} | ||||
ezust
|
r0 | } | ||
PythonQtClassInfo::~PythonQtClassInfo() | ||||
florianlink
|
r10 | { | ||
clearCachedMembers(); | ||||
} | ||||
void PythonQtClassInfo::clearCachedMembers() | ||||
ezust
|
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
|
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
|
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
|
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
|
r0 | PythonQtMemberInfo PythonQtClassInfo::member(const char* memberName) | ||
{ | ||||
PythonQtMemberInfo info = _cachedMembers.value(memberName); | ||||
if (info._type != PythonQtMemberInfo::Invalid) { | ||||
return info; | ||||
} else { | ||||
bool found = false; | ||||
florianlink
|
r10 | |||
found = lookForPropertyAndCache(memberName); | ||||
if (!found) { | ||||
found = lookForMethodAndCache(memberName); | ||||
ezust
|
r0 | } | ||
florianlink
|
r10 | if (!found) { | ||
if (_meta) { | ||||
// check enums in our meta object directly | ||||
found = lookForEnumAndCache(_meta, memberName); | ||||
ezust
|
r0 | } | ||
florianlink
|
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
|
r0 | } | ||
florianlink
|
r10 | if (!info->_parentClassInfoResolved) { | ||
info->resolveParentClassInfo(); | ||||
} | ||||
info = info->_parentClassInfo; | ||||
ezust
|
r0 | } | ||
} | ||||
} | ||||
if (!found) { | ||||
florianlink
|
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
|
r0 | } | ||
} | ||||
florianlink
|
r10 | |||
return _cachedMembers.value(memberName); | ||||
ezust
|
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
|
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) { | ||||
sigStart += 4 + 1 + strlen(className()); | ||||
isClassDeco = true; | ||||
} else if (qstrncmp(sigStart, "delete_", 7)==0) { | ||||
sigStart += 7 + 1 + strlen(className()); | ||||
isClassDeco = true; | ||||
} | ||||
// 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
|
r0 | |||
QStringList PythonQtClassInfo::memberList(bool metaOnly) | ||||
{ | ||||
florianlink
|
r10 | resolveParentClassInfo(); | ||
decorator(); | ||||
ezust
|
r0 | QStringList l; | ||
QString h; | ||||
florianlink
|
r10 | if (_wrappedClassName.isEmpty() && _meta) { | ||
ezust
|
r0 | int i; | ||
int numProperties = _meta->propertyCount(); | ||||
for (i = 0; i < numProperties; i++) { | ||||
QMetaProperty p = _meta->property(i); | ||||
l << QString(p.name()); | ||||
} | ||||
} | ||||
florianlink
|
r10 | // normal slots of QObject (or wrapper QObject) | ||
if (!metaOnly && _meta) { | ||||
ezust
|
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
|
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
|
r0 | // look for decorators | ||
QList<const char*> names; | ||||
if (!_wrappedClassName.isEmpty()) { | ||||
florianlink
|
r10 | // CPP wrapper case: | ||
ezust
|
r0 | names << _wrappedClassName.constData(); | ||
florianlink
|
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
|
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
|
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
|
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
|
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
|
r0 | } | ||
} | ||||
return false; | ||||
} | ||||
QString PythonQtClassInfo::help() | ||||
{ | ||||
florianlink
|
r10 | resolveParentClassInfo(); | ||
decorator(); | ||||
ezust
|
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
|
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
|
r0 | } | ||
} | ||||
florianlink
|
r10 | |||
// TODO xxx : decorators and enums from decorator() are missing... | ||||
// maybe we can reuse memberlist()? | ||||
ezust
|
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
|
r10 | if (_meta && _meta->enumeratorCount()) { | ||
ezust
|
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
|
r10 | if (_wrappedClassName.isEmpty() && _meta) { | ||
ezust
|
r0 | int numMethods = _meta->methodCount(); | ||
if (numMethods>0) { | ||||
h += "Signals:\n"; | ||||
florianlink
|
r10 | for (int i = 0; i < numMethods; i++) { | ||
ezust
|
r0 | QMetaMethod m = _meta->method(i); | ||
if (m.methodType() == QMetaMethod::Signal) { | ||||
h += QString(m.signature()) + "\n"; | ||||
} | ||||
} | ||||
} | ||||
} | ||||
return h; | ||||
} | ||||
PythonQtSlotInfo* PythonQtClassInfo::constructors() | ||||
{ | ||||
if (!_constructors) { | ||||
florianlink
|
r10 | // force creation of lazy decorator, which will register the decorators | ||
decorator(); | ||||
ezust
|
r0 | _constructors = PythonQt::priv()->getConstructorSlot(!_wrappedClassName.isEmpty()?_wrappedClassName:QByteArray(_meta->className())); | ||
} | ||||
return _constructors; | ||||
} | ||||
void PythonQtClassInfo::setMetaObject(const QMetaObject* meta) | ||||
{ | ||||
_meta = meta; | ||||
florianlink
|
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
|
r0 | } | ||