##// END OF EJS Templates
improved wrapper check to avoid crashes on virtual methods while python object gets deleted...
improved wrapper check to avoid crashes on virtual methods while python object gets deleted git-svn-id: svn://svn.code.sf.net/p/pythonqt/code/trunk@245 ea8d5007-eb21-0410-b261-ccb3ea6e24a9

File last commit:

r203:64a9f70b03c9
r204:7ce280c51c17
Show More
PythonQtMethodInfo.cpp
378 lines | 13.2 KiB | text/x-c | CppLexer
/ src / PythonQtMethodInfo.cpp
ezust
reorganized SVN tree into branches, tags and trunk...
r0 /*
*
florianlink
updated old license information and current date...
r133 * Copyright (C) 2010 MeVis Medical Solutions AG All Rights Reserved.
ezust
reorganized SVN tree into branches, tags and trunk...
r0 *
* 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
*
florianlink
updated old license information and current date...
r133 * Contact information: MeVis Medical Solutions AG, Universitaetsallee 29,
ezust
reorganized SVN tree into branches, tags and trunk...
r0 * 28359 Bremen, Germany or:
*
* http://www.mevis.de
*
*/
//----------------------------------------------------------------------------------
/*!
// \file PythonQtMethodInfo.cpp
// \author Florian Link
// \author Last changed by $Author: florian $
// \date 2006-05
*/
//----------------------------------------------------------------------------------
#include "PythonQtMethodInfo.h"
florianlink
cleanup of code and addition of (yet unused) classinfo passed to method/slot info to allow local enum support on creation...
r54 #include "PythonQtClassInfo.h"
ezust
reorganized SVN tree into branches, tags and trunk...
r0 #include <iostream>
QHash<QByteArray, PythonQtMethodInfo*> PythonQtMethodInfo::_cachedSignatures;
QHash<QByteArray, QByteArray> PythonQtMethodInfo::_parameterNameAliases;
florianlink
cleanup of code and addition of (yet unused) classinfo passed to method/slot info to allow local enum support on creation...
r54 PythonQtMethodInfo::PythonQtMethodInfo(const QMetaMethod& meta, PythonQtClassInfo* classInfo)
ezust
reorganized SVN tree into branches, tags and trunk...
r0 {
#ifdef PYTHONQT_DEBUG
QByteArray sig(meta.signature());
sig = sig.mid(sig.indexOf('('));
QByteArray fullSig = QByteArray(meta.typeName()) + " " + sig;
std::cout << "caching " << fullSig.data() << std::endl;
#endif
ParameterInfo type;
florianlink
cache enumWrappers in method infos and make use of the extra information for better enum overloading...
r55 fillParameterInfo(type, QByteArray(meta.typeName()), classInfo);
ezust
reorganized SVN tree into branches, tags and trunk...
r0 _parameters.append(type);
QList<QByteArray> names = meta.parameterTypes();
florianlink
added error handling for virtual method overloads, added more global functions (qsrand etc.), added support for exec_ etc (python keyword overlap resolution), change virtual method handling, this will require code regeneration (I will do that tomorrow)...
r67 foreach (const QByteArray& name, names) {
florianlink
cache enumWrappers in method infos and make use of the extra information for better enum overloading...
r55 fillParameterInfo(type, name, classInfo);
ezust
reorganized SVN tree into branches, tags and trunk...
r0 _parameters.append(type);
}
}
florianlink
added error handling for virtual method overloads, added more global functions (qsrand etc.), added support for exec_ etc (python keyword overlap resolution), change virtual method handling, this will require code regeneration (I will do that tomorrow)...
r67 PythonQtMethodInfo::PythonQtMethodInfo(const QByteArray& typeName, const QList<QByteArray>& args)
{
ParameterInfo type;
fillParameterInfo(type, typeName, NULL);
_parameters.append(type);
foreach (const QByteArray& name, args) {
fillParameterInfo(type, name, NULL);
_parameters.append(type);
}
}
florianlink
cleanup of code and addition of (yet unused) classinfo passed to method/slot info to allow local enum support on creation...
r54 const PythonQtMethodInfo* PythonQtMethodInfo::getCachedMethodInfo(const QMetaMethod& signal, PythonQtClassInfo* classInfo)
ezust
reorganized SVN tree into branches, tags and trunk...
r0 {
QByteArray sig(signal.signature());
sig = sig.mid(sig.indexOf('('));
QByteArray fullSig = QByteArray(signal.typeName()) + " " + sig;
PythonQtMethodInfo* result = _cachedSignatures.value(fullSig);
if (!result) {
florianlink
cleanup of code and addition of (yet unused) classinfo passed to method/slot info to allow local enum support on creation...
r54 result = new PythonQtMethodInfo(signal, classInfo);
ezust
reorganized SVN tree into branches, tags and trunk...
r0 _cachedSignatures.insert(fullSig, result);
}
return result;
}
florianlink
added error handling for virtual method overloads, added more global functions (qsrand etc.), added support for exec_ etc (python keyword overlap resolution), change virtual method handling, this will require code regeneration (I will do that tomorrow)...
r67 const PythonQtMethodInfo* PythonQtMethodInfo::getCachedMethodInfoFromArgumentList(int numArgs, const char** args)
florianlink
- added support for deriving CPP classes in Python and to override all public and protected virtual functions from PythonQt...
r24 {
florianlink
added error handling for virtual method overloads, added more global functions (qsrand etc.), added support for exec_ etc (python keyword overlap resolution), change virtual method handling, this will require code regeneration (I will do that tomorrow)...
r67 QByteArray typeName = args[0];
QList<QByteArray> arguments;
QByteArray fullSig = typeName;
fullSig += "(";
for (int i =1;i<numArgs; i++) {
if (i>1) {
fullSig += ",";
}
florianlink
Updated from current MeVisLab development...
r173 QByteArray arg(args[i]);
fullSig += arg;
arguments << arg;
florianlink
added error handling for virtual method overloads, added more global functions (qsrand etc.), added support for exec_ etc (python keyword overlap resolution), change virtual method handling, this will require code regeneration (I will do that tomorrow)...
r67 }
fullSig += ")";
PythonQtMethodInfo* result = _cachedSignatures.value(fullSig);
if (!result) {
result = new PythonQtMethodInfo(typeName, arguments);
_cachedSignatures.insert(fullSig, result);
}
return result;
florianlink
- added support for deriving CPP classes in Python and to override all public and protected virtual functions from PythonQt...
r24 }
florianlink
cache enumWrappers in method infos and make use of the extra information for better enum overloading...
r55 void PythonQtMethodInfo::fillParameterInfo(ParameterInfo& type, const QByteArray& orgName, PythonQtClassInfo* classInfo)
ezust
reorganized SVN tree into branches, tags and trunk...
r0 {
QByteArray name = orgName;
florianlink
cache enumWrappers in method infos and make use of the extra information for better enum overloading...
r55 type.enumWrapper = NULL;
ezust
reorganized SVN tree into branches, tags and trunk...
r0 int len = name.length();
if (len>0) {
if (strncmp(name.constData(), "const ", 6)==0) {
name = name.mid(6);
len -= 6;
type.isConst = true;
} else {
type.isConst = false;
}
florianlink
fixed support for more than one * indirection via pointerCount, QPixmap crashed on char** constructor, which was thought to be * only...
r134 char pointerCount = 0;
florianlink
syncing with my current work, updating to 1.2, see changelog...
r10 bool hadReference = false;
// remove * and & from the end of the string, handle & and * the same way
ezust
reorganized SVN tree into branches, tags and trunk...
r0 while (name.at(len-1) == '*') {
len--;
florianlink
fixed support for more than one * indirection via pointerCount, QPixmap crashed on char** constructor, which was thought to be * only...
r134 pointerCount++;
florianlink
syncing with my current work, updating to 1.2, see changelog...
r10 }
while (name.at(len-1) == '&') {
len--;
hadReference = true;
ezust
reorganized SVN tree into branches, tags and trunk...
r0 }
if (len!=name.length()) {
name = name.left(len);
}
florianlink
fixed support for more than one * indirection via pointerCount, QPixmap crashed on char** constructor, which was thought to be * only...
r134 type.pointerCount = pointerCount;
florianlink
syncing with my current work, updating to 1.2, see changelog...
r10
ezust
reorganized SVN tree into branches, tags and trunk...
r0 QByteArray alias = _parameterNameAliases.value(name);
if (!alias.isEmpty()) {
name = alias;
}
type.typeId = nameToType(name);
florianlink
fixed support for more than one * indirection via pointerCount, QPixmap crashed on char** constructor, which was thought to be * only...
r134 if ((type.pointerCount == 0) && type.typeId == Unknown) {
ezust
reorganized SVN tree into branches, tags and trunk...
r0 type.typeId = QMetaType::type(name.constData());
if (type.typeId == QMetaType::Void) {
type.typeId = Unknown;
}
}
type.name = name;
florianlink
cache enumWrappers in method infos and make use of the extra information for better enum overloading...
r55
if (type.typeId == PythonQtMethodInfo::Unknown || type.typeId >= QMetaType::User) {
bool isLocalEnum;
// TODOXXX: make use of this flag!
florianlink
added automatic conversion to QColor,QPen,QCursor and QBrush from enums and colors...
r64 type.enumWrapper = PythonQtClassInfo::findEnumWrapper(type.name, classInfo, &isLocalEnum);
florianlink
cache enumWrappers in method infos and make use of the extra information for better enum overloading...
r55 }
ezust
reorganized SVN tree into branches, tags and trunk...
r0 } else {
type.typeId = QMetaType::Void;
florianlink
fixed support for more than one * indirection via pointerCount, QPixmap crashed on char** constructor, which was thought to be * only...
r134 type.pointerCount = 0;
ezust
reorganized SVN tree into branches, tags and trunk...
r0 type.isConst = false;
}
}
int PythonQtMethodInfo::nameToType(const char* name)
{
if (_parameterTypeDict.isEmpty()) {
// we could also use QMetaType::nameToType, but that does a string compare search
// and does not support QVariant
// QMetaType names
_parameterTypeDict.insert("long", QMetaType::Long);
_parameterTypeDict.insert("int", QMetaType::Int);
_parameterTypeDict.insert("short", QMetaType::Short);
_parameterTypeDict.insert("char", QMetaType::Char);
_parameterTypeDict.insert("ulong", QMetaType::ULong);
_parameterTypeDict.insert("unsigned long", QMetaType::ULong);
_parameterTypeDict.insert("uint", QMetaType::UInt);
_parameterTypeDict.insert("unsigned int", QMetaType::UInt);
_parameterTypeDict.insert("ushort", QMetaType::UShort);
_parameterTypeDict.insert("unsigned short", QMetaType::UShort);
_parameterTypeDict.insert("uchar", QMetaType::UChar);
_parameterTypeDict.insert("unsigned char", QMetaType::UChar);
_parameterTypeDict.insert("bool", QMetaType::Bool);
_parameterTypeDict.insert("float", QMetaType::Float);
_parameterTypeDict.insert("double", QMetaType::Double);
_parameterTypeDict.insert("qreal", QMetaType::Double);
_parameterTypeDict.insert("QChar", QMetaType::QChar);
_parameterTypeDict.insert("QByteArray", QMetaType::QByteArray);
_parameterTypeDict.insert("QString", QMetaType::QString);
_parameterTypeDict.insert("", QMetaType::Void);
_parameterTypeDict.insert("void", QMetaType::Void);
florianlink
merged various changes from MeVisLab repository...
r180
// GL types
_parameterTypeDict.insert("GLenum", QMetaType::UInt);
_parameterTypeDict.insert("GLboolean", QMetaType::UChar);
_parameterTypeDict.insert("GLbitfield", QMetaType::UInt);
_parameterTypeDict.insert("GLbyte", QMetaType::Char);
_parameterTypeDict.insert("GLubyte", QMetaType::UChar);
_parameterTypeDict.insert("GLshort", QMetaType::Short);
_parameterTypeDict.insert("GLushort", QMetaType::UShort);
_parameterTypeDict.insert("GLint", QMetaType::Int);
_parameterTypeDict.insert("GLuint", QMetaType::UInt);
_parameterTypeDict.insert("GLsizei", QMetaType::UInt);
_parameterTypeDict.insert("GLclampf", QMetaType::Float);
_parameterTypeDict.insert("GLfloat", QMetaType::Float);
_parameterTypeDict.insert("GLclampd", QMetaType::Double);
_parameterTypeDict.insert("GLdouble", QMetaType::Double);
_parameterTypeDict.insert("GLvoid", QMetaType::Void);
if (QT_POINTER_SIZE == 8) {
_parameterTypeDict.insert("qgl_GLintptr", QMetaType::LongLong);
_parameterTypeDict.insert("qgl_GLsizeiptr", QMetaType::LongLong);
} else {
_parameterTypeDict.insert("qgl_GLintptr", QMetaType::Int);
_parameterTypeDict.insert("qgl_GLsizeiptr", QMetaType::Int);
}
ezust
reorganized SVN tree into branches, tags and trunk...
r0 // QVariant names
_parameterTypeDict.insert("Q_LLONG", QMetaType::LongLong);
_parameterTypeDict.insert("Q_ULLONG", QMetaType::ULongLong);
_parameterTypeDict.insert("qlonglong", QMetaType::LongLong);
_parameterTypeDict.insert("qulonglong", QMetaType::ULongLong);
_parameterTypeDict.insert("qint64", QMetaType::LongLong);
_parameterTypeDict.insert("quint64", QMetaType::ULongLong);
_parameterTypeDict.insert("QVariantMap", QMetaType::QVariantMap);
_parameterTypeDict.insert("QVariantList", QMetaType::QVariantList);
_parameterTypeDict.insert("QMap<QString,QVariant>", QMetaType::QVariantMap);
_parameterTypeDict.insert("QList<QVariant>", QMetaType::QVariantList);
_parameterTypeDict.insert("QStringList", QMetaType::QStringList);
_parameterTypeDict.insert("QBitArray", QMetaType::QBitArray);
_parameterTypeDict.insert("QDate", QMetaType::QDate);
_parameterTypeDict.insert("QTime", QMetaType::QTime);
_parameterTypeDict.insert("QDateTime", QMetaType::QDateTime);
_parameterTypeDict.insert("QUrl", QMetaType::QUrl);
_parameterTypeDict.insert("QLocale", QMetaType::QLocale);
_parameterTypeDict.insert("QRect", QMetaType::QRect);
florianlink
updated to upstream state in MeVisLab repository...
r157 _parameterTypeDict.insert("QRectF", QMetaType::QRectF);
ezust
reorganized SVN tree into branches, tags and trunk...
r0 _parameterTypeDict.insert("QSize", QMetaType::QSize);
florianlink
updated to upstream state in MeVisLab repository...
r157 _parameterTypeDict.insert("QSizeF", QMetaType::QSizeF);
ezust
reorganized SVN tree into branches, tags and trunk...
r0 _parameterTypeDict.insert("QLine", QMetaType::QLine);
florianlink
updated to upstream state in MeVisLab repository...
r157 _parameterTypeDict.insert("QLineF", QMetaType::QLineF);
ezust
reorganized SVN tree into branches, tags and trunk...
r0 _parameterTypeDict.insert("QPoint", QMetaType::QPoint);
florianlink
updated to upstream state in MeVisLab repository...
r157 _parameterTypeDict.insert("QPointF", QMetaType::QPointF);
ezust
reorganized SVN tree into branches, tags and trunk...
r0 _parameterTypeDict.insert("QRegExp", QMetaType::QRegExp);
_parameterTypeDict.insert("QFont", QMetaType::QFont);
_parameterTypeDict.insert("QPixmap", QMetaType::QPixmap);
_parameterTypeDict.insert("QBrush", QMetaType::QBrush);
_parameterTypeDict.insert("QColor", QMetaType::QColor);
_parameterTypeDict.insert("QCursor", QMetaType::QCursor);
_parameterTypeDict.insert("QPalette", QMetaType::QPalette);
_parameterTypeDict.insert("QIcon", QMetaType::QIcon);
florianlink
updated to upstream state in MeVisLab repository...
r157 _parameterTypeDict.insert("QImage", QMetaType::QImage);
ezust
reorganized SVN tree into branches, tags and trunk...
r0 _parameterTypeDict.insert("QRegion", QMetaType::QRegion);
_parameterTypeDict.insert("QBitmap", QMetaType::QBitmap);
_parameterTypeDict.insert("QSizePolicy", QMetaType::QSizePolicy);
_parameterTypeDict.insert("QKeySequence", QMetaType::QKeySequence);
_parameterTypeDict.insert("QPen", QMetaType::QPen);
_parameterTypeDict.insert("QTextLength", QMetaType::QTextLength);
_parameterTypeDict.insert("QTextFormat", QMetaType::QTextFormat);
_parameterTypeDict.insert("QMatrix", QMetaType::QMatrix);
_parameterTypeDict.insert("QVariant", PythonQtMethodInfo::Variant);
// own special types... (none so far, could be e.g. ObjectList
}
QHash<QByteArray, int>::const_iterator it = _parameterTypeDict.find(name);
if (it!=_parameterTypeDict.end()) {
return it.value();
} else {
return PythonQtMethodInfo::Unknown;
}
}
void PythonQtMethodInfo::cleanupCachedMethodInfos()
{
QHashIterator<QByteArray, PythonQtMethodInfo *> i(_cachedSignatures);
while (i.hasNext()) {
delete i.next().value();
}
florianlink
cleared cached signature hash to avoid dangling pointers...
r203 _cachedSignatures.clear();
ezust
reorganized SVN tree into branches, tags and trunk...
r0 }
void PythonQtMethodInfo::addParameterTypeAlias(const QByteArray& alias, const QByteArray& name)
{
_parameterNameAliases.insert(alias, name);
}
//-------------------------------------------------------------------------------------------------
florianlink
- added support for deriving CPP classes in Python and to override all public and protected virtual functions from PythonQt...
r24 void PythonQtSlotInfo::deleteOverloadsAndThis()
{
PythonQtSlotInfo* cur = this;
while(cur->nextInfo()) {
PythonQtSlotInfo* next = cur->nextInfo();
delete cur;
cur = next;
}
}
florianlink
- removed argument to fullSignature...
r23 QString PythonQtSlotInfo::fullSignature()
ezust
reorganized SVN tree into branches, tags and trunk...
r0 {
florianlink
- removed argument to fullSignature...
r23 bool skipFirstArg = isInstanceDecorator();
ezust
reorganized SVN tree into branches, tags and trunk...
r0 QString result = _meta.typeName();
QByteArray sig = slotName();
QList<QByteArray> names = _meta.parameterNames();
bool isStatic = false;
bool isConstructor = false;
bool isDestructor = false;
if (_type == ClassDecorator) {
if (sig.startsWith("new_")) {
florianlink
merged contributions from https://github.com/commontk/PythonQt/compare/svn-mirror...patched...
r163 sig = sig.mid(4);
ezust
reorganized SVN tree into branches, tags and trunk...
r0 isConstructor = true;
} else if (sig.startsWith("delete_")) {
florianlink
merged contributions from https://github.com/commontk/PythonQt/compare/svn-mirror...patched...
r163 sig = sig.mid(7);
ezust
reorganized SVN tree into branches, tags and trunk...
r0 isDestructor = true;
} else if(sig.startsWith("static_")) {
isStatic = true;
florianlink
merged contributions from https://github.com/commontk/PythonQt/compare/svn-mirror...patched...
r163 sig = sig.mid(7);
ezust
reorganized SVN tree into branches, tags and trunk...
r0 int idx = sig.indexOf("_");
if (idx>=0) {
sig = sig.mid(idx+1);
}
}
}
result += QByteArray(" ") + sig;
result += "(";
int lastEntry = _parameters.count()-1;
for (int i = skipFirstArg?2:1; i<_parameters.count(); i++) {
if (_parameters.at(i).isConst) {
result += "const ";
}
result += _parameters.at(i).name;
florianlink
fixed support for more than one * indirection via pointerCount, QPixmap crashed on char** constructor, which was thought to be * only...
r134 if (_parameters.at(i).pointerCount) {
QByteArray stars;
stars.fill('*', _parameters.at(i).pointerCount);
result += stars;
ezust
reorganized SVN tree into branches, tags and trunk...
r0 }
if (!names.at(i-1).isEmpty()) {
result += " ";
result += names.at(i-1);
}
if (i!=lastEntry) {
result += ", ";
}
}
result += ")";
if (isStatic) {
result = QString("static ") + result;
}
if (isConstructor) {
// result = QString("constructor ") + result;
}
if (isDestructor) {
result = QString("~") + result;
}
return result;
}
QByteArray PythonQtSlotInfo::slotName()
{
QByteArray sig(_meta.signature());
int idx = sig.indexOf('(');
sig = sig.left(idx);
return sig;
}