Path: blob/devel/ElmerGUI/PythonQt/src/PythonQtSignalReceiver.cpp
3206 views
/*1*2* Copyright (C) 2006 MeVis Research GmbH All Rights Reserved.3*4* This library is free software; you can redistribute it and/or5* modify it under the terms of the GNU Lesser General Public6* License as published by the Free Software Foundation; either7* version 2.1 of the License, or (at your option) any later version.8*9* This library is distributed in the hope that it will be useful,10* but WITHOUT ANY WARRANTY; without even the implied warranty of11* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU12* Lesser General Public License for more details.13*14* Further, this software is distributed without any warranty that it is15* free of the rightful claim of any third person regarding infringement16* or the like. Any license provided herein, whether implied or17* otherwise, applies only to this software file. Patent licenses, if18* any, provided herein do not apply to combinations of this program with19* other software, or any other product whatsoever.20*21* You should have received a copy of the GNU Lesser General Public22* License along with this library; if not, write to the Free Software23* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA24*25* Contact information: MeVis Research GmbH, Universitaetsallee 29,26* 28359 Bremen, Germany or:27*28* http://www.mevis.de29*30*/3132//----------------------------------------------------------------------------------33/*!34// \file PythonQtSignalReceiver.cpp35// \author Florian Link36// \author Last changed by $Author: florian $37// \date 2006-0538*/39//----------------------------------------------------------------------------------4041#include "PythonQtSignalReceiver.h"42#include "PythonQtClassInfo.h"43#include "PythonQtMethodInfo.h"44#include "PythonQtConversion.h"45#include <QMetaObject>46#include <QMetaMethod>4748void PythonQtSignalTarget::call(void **arguments) const49{50const PythonQtMethodInfo* m = methodInfo();51// paramterCount includes return value:52int count = m->parameterCount();5354PyObject* pargs = NULL;55if (count>1) {56pargs = PyTuple_New(count-1);57}58bool err = false;59// transform Qt values to Python60const QList<PythonQtMethodInfo::ParameterInfo>& params = m->parameters();61for (int i = 1; i < count; i++) {62const PythonQtMethodInfo::ParameterInfo& param = params.at(i);63PyObject* arg = PythonQtConv::ConvertQtValueToPython(param, arguments[i]);64if (arg) {65// steals reference, no unref66PyTuple_SetItem(pargs, i-1,arg);67} else {68err = true;69break;70}71}7273if (!err) {74PyErr_Clear();75PyObject* result = PyObject_CallObject(_callable, pargs);76if (result) {77// ok78Py_DECREF(result);79} else {80PythonQt::self()->handleError();81}82}83if (pargs) {84// free the arguments again85Py_DECREF(pargs);86}87}8889//------------------------------------------------------------------------------9091PythonQtSignalReceiver::PythonQtSignalReceiver(QObject* obj):PythonQtSignalReceiverBase(obj)92{93_obj = obj;94_slotCount = staticMetaObject.methodOffset();95}9697PythonQtSignalReceiver::~PythonQtSignalReceiver()98{99}100101102bool PythonQtSignalReceiver::addSignalHandler(const char* signal, PyObject* callable)103{104bool flag = false;105int sigId = getSignalIndex(signal);106if (sigId>=0) {107// create PythonQtMethodInfo from signal108QMetaMethod meta = _obj->metaObject()->method(sigId);109const PythonQtMethodInfo* signalInfo = PythonQtMethodInfo::getCachedMethodInfo(meta);110PythonQtSignalTarget t(sigId, signalInfo, _slotCount, callable);111_targets.append(t);112// now connect to ourselves with the new slot id113QMetaObject::connect(_obj, sigId, this, _slotCount, Qt::AutoConnection, 0);114115_slotCount++;116flag = true;117}118return flag;119}120121bool PythonQtSignalReceiver::removeSignalHandler(const char* signal, PyObject* callable)122{123bool found = false;124int sigId = getSignalIndex(signal);125if (sigId>=0) {126QMutableListIterator<PythonQtSignalTarget> i(_targets);127while (i.hasNext()) {128if (i.next().isSame(sigId, callable)) {129i.remove();130found = true;131break;132}133}134}135return found;136}137138void PythonQtSignalReceiver::removeSignalHandlers()139{140_targets.clear();141}142143int PythonQtSignalReceiver::getSignalIndex(const char* signal)144{145int sigId = _obj->metaObject()->indexOfSignal(signal+1);146if (sigId<0) {147QByteArray tmpSig = QMetaObject::normalizedSignature(signal+1);148sigId = _obj->metaObject()->indexOfSignal(tmpSig);149}150return sigId;151}152153int PythonQtSignalReceiver::qt_metacall(QMetaObject::Call c, int id, void **arguments)154{155// mlabDebugConst("PythonQt", "PythonQtSignalReceiver invoke " << _obj->className() << " " << _obj->name() << " " << id);156if (c != QMetaObject::InvokeMetaMethod) {157QObject::qt_metacall(c, id, arguments);158}159160bool found = false;161foreach(const PythonQtSignalTarget& t, _targets) {162if (t.slotId() == id) {163found = true;164t.call(arguments);165break;166}167}168return 0;169}170171172173