1 /************************************************************************
3 * Copyright 2010 Jakob Leben (jakob.leben@gmail.com)
5 * This file is part of SuperCollider Qt GUI.
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 ************************************************************************/
22 #ifndef QC_SIGNALSPY_H
23 #define QC_SIGNALSPY_H
26 #include "QObjectProxy.h"
28 #include <PyrKernel.h>
29 #include <PyrSymbol.h>
30 #include <VMGlobals.h>
36 #include <QMetaObject>
37 #include <QMetaMethod>
40 class QcSignalSpy
: public QObject
45 QcSignalSpy( QObjectProxy
*proxy
, const char *sigName
,
46 Qt::ConnectionType conType
= Qt::QueuedConnection
)
47 : QObject( proxy
), _proxy( proxy
), _sigId( -1 )
52 const QMetaObject
*mo
= _proxy
->object()->metaObject();
54 QByteArray signal
= QMetaObject::normalizedSignature( sigName
);
55 int sigId
= mo
->indexOfSignal( signal
);
58 qcDebugMsg( 0, QString("WARNING: No such signal to connect: '%1'").arg(signal
.constData()) );
62 int slotId
= QObject::staticMetaObject
.methodCount();
64 if( !QMetaObject::connect( _proxy
->object(), sigId
, this, slotId
,
67 qcErrorMsg( "QMetaObject::connect returned false. Unable to connect." );
71 QMetaMethod mm
= mo
->method( sigId
);
73 QList
<QByteArray
> params
= mm
.parameterTypes();
75 for( int i
= 0; i
< params
.count(); ++i
) {
76 int type
= QMetaType::type( params
.at(i
).constData() );
77 if( type
== QMetaType::Void
)
78 qcErrorMsg( QString("QObject:connect: Don't know how to handle '%1', "
79 "use qRegisterMetaType to register it.")
80 .arg(params
.at(i
).constData()) );
87 int qt_metacall( QMetaObject::Call call
, int methodId
, void **argData
)
89 methodId
= QObject::qt_metacall( call
, methodId
, argData
);
94 if( call
== QMetaObject::InvokeMetaMethod
) {
95 Q_ASSERT( methodId
== 0 );
98 #if QT_VERSION >= 0x040700
99 args
.reserve( _argTypes
.count() );
102 for (int i
= 0; i
< _argTypes
.count(); ++i
) {
103 QMetaType::Type type
= static_cast<QMetaType::Type
>(_argTypes
.at(i
));
104 args
<< QVariant( type
, argData
[i
+ 1] );
115 inline int indexOfSignal () const { return _sigId
; }
117 inline bool isValid () const { return _sigId
> 0; }
121 virtual void react( QList
<QVariant
> & args
) = 0;
123 QObjectProxy
*_proxy
;
125 QList
<int> _argTypes
;
128 class QcMethodSignalHandler
: public QcSignalSpy
131 QcMethodSignalHandler( QObjectProxy
*proxy
, const char *sigName
, PyrSymbol
*handler
,
132 Qt::ConnectionType conType
= Qt::QueuedConnection
)
133 : QcSignalSpy( proxy
, sigName
, conType
), _handler( handler
)
136 inline PyrSymbol
*method() { return _handler
; }
140 virtual void react( QList
<QVariant
> & args
) {
142 qcDebugMsg( 1, QString("SIGNAL: '%1' handled by method '%2'")
143 .arg( _proxy
->object() ?
144 _proxy
->object()->metaObject()->method( _sigId
).signature() :
149 _proxy
->invokeScMethod( _handler
, args
);
152 PyrSymbol
* _handler
;
155 class QcFunctionSignalHandler
: public QcSignalSpy
158 QcFunctionSignalHandler( QObjectProxy
*proxy
, const char *sigName
, PyrObject
*handler
,
159 Qt::ConnectionType conType
= Qt::QueuedConnection
)
160 : QcSignalSpy( proxy
, sigName
, conType
), _handler( handler
)
163 inline PyrObject
*function() { return _handler
; }
167 virtual void react( QList
<QVariant
> & args
) {
169 qcDebugMsg( 1, QString("SIGNAL: '%1' handled by a Function")
170 .arg( _proxy
->object() ?
171 _proxy
->object()->metaObject()->method( _sigId
).signature() :
175 args
.prepend( QVariant::fromValue( _handler
) );
177 _proxy
->invokeScMethod( s_doFunction
, args
);
180 PyrObject
* _handler
;
184 #endif //QC_SIGNALSPY_H