void qsa_slot_callback(QObject *_this, int callId, int paramCount, const QMetaType::Type *types, const QByteArray *typeNames, void *argumentList[]) { // printf("qsa_slot_callback, id=%d\n", callId); QuickInterpreter *ip = static_cast<QuickInterpreter *>(_this); QSAConnection connection = ip->scriptSlot(callId); Q_ASSERT(connection.sender); Q_ASSERT(connection.signal.length()); Q_ASSERT(connection.function_ref.isValid()); QSEnv *env = ip->env(); QSList arguments; for (int i=1; i<paramCount; ++i) { QSATypeInfo info; info.name = typeNames[i]; info.id = types[i]; QSObject val = convert_qt2qsa(env, argumentList[i], info, _this); Q_ASSERT(val.isValid()); arguments.append(val); } QSObject func_base = QSFuncRefClass::refBase(connection.function_ref); QString func_name = QSFuncRefClass::refMember(connection.function_ref).name(); ip->call(func_base, func_name, arguments); }
/*! Adds the Qt Script function \a qtscriptFunction (fully qualified) as a transient signal handler for the C++ signal \a signal of the object \a sender. Example: \code interpreter->addTransientSignalHandler( myButton, SIGNAL( clicked() ), "classA.obj.calculate" ); \endcode \sa removeTransientSignalHandler() */ void QSInterpreter::addTransientSignalHandler(QObject *sender, const char *signal, const char *qtscriptFunction) { QuickInterpreter *ip = interpreter(); QString func = QString::fromLatin1(qtscriptFunction); func.left(func.find('(')); QSObject senderObj = ip->wrap(sender); QSObject obj = ip->object(func); if (!obj.isFunction()) { qDebug("QSInterpreter::addTransientSignalHandler(): '%s' not a function", qtscriptFunction); return; } QSObject base = QSFuncRefClass::refBase(obj); QSMember member = QSFuncRefClass::refMember(obj); QSWrapperShared *sh = ip->wrapperClass()->shared(&senderObj); if (!sh->setEventHandler(ip, QString::fromLatin1(signal + 1), 0, member.name(), base)) { #if defined( QT_CHECK_STATE ) qWarning("QSInterpreter::addTransientSignalHandler(), " "failed to add signal handler: '%s' to '%s'", signal + 1, qtscriptFunction); #endif } }
void qsKillTimer( QSEnv *env ) { QuickInterpreter *ip = QuickInterpreter::fromEnv(env); int id = (int) env->arg(0).toNumber(); ip->timers()->remove(id); ip->killTimer(id); }
void QSCompletionObject::resolve() { if ( type == TQSObject ) { QuickInterpreter *ip = QuickInterpreter::fromEnv( qsobj.env() ); if( qsobj.isA( ip->wrapperClass() ) ) { type = TQObject; qobj = *ip->wrapperClass()->objectVector( &qsobj ); } } }
void qsKillTimers( QSEnv *env ) { QuickInterpreter *ip = QuickInterpreter::fromEnv(env); QHash<int, QSObject> *timers = ip->timers(); for (QHash<int, QSObject>::ConstIterator it = timers->begin(); it != timers->end(); ++it) { ip->killTimer(it.key()); } timers->clear(); }
QString QSAEditor::cppClassForScript( const QString &className ) const { #ifdef QSA_COMPLETION_DEBUG printf("QSACompletion::cppClassForScript( %s ), interpreter: %p\n", className.latin1(), qsInterp); #endif QuickInterpreter *ip = get_quick_interpreter( qsInterp ? qsInterp : QSInterpreter::defaultInterpreter() ); if( !ip ) return QString::null; QMap<QString,QString> names = ip->dispatchObjectFactory()->instanceDescriptors(); QMap<QString,QString>::ConstIterator cppName = names.find( className ); if( cppName != names.end() ) return *cppName; return QString::null; }
/******************************************************************************* * Timers */ QSObject qsStartTimer( QSEnv *env ) { QSObject hnd = env->arg( 1 ); if ( hnd.isFunction() ) { QuickInterpreter *ip = QuickInterpreter::fromEnv(env); int interval = (int) env->arg(0).toNumber(); int id = ip->startTimer(interval); QHash<int, QSObject> *timers = ip->timers(); timers->insert(id, hnd); return env->createNumber(id); } QString msg = QString::fromLatin1("Can only install functions as event handler"); return env->throwError( TypeError, msg ); }
static QSObject qsa_connect(QSEnv *env) { const QSList *args = env->arguments(); QuickInterpreter *ip = QuickInterpreter::fromEnv(env); QObject *sender = 0; QByteArray signal; if (args->size() >= 2) { QSObject qsSender = args->at(0); sender = qsSender.isA(ip->wrapperClass()) ? QSWrapperClass::object(&qsSender) : 0; if (!sender) return env->throwError("connection failed, sender is not of type QObject"); QString signal_string = "2" + args->at(1).toString(); signal = QMetaObject::normalizedSignature(signal_string.toLatin1()); } bool ok = false; if (args->size() == 3) { // C++ -> Script connection QSObject function_ref = args->at(2); // resolve function as a name if (!function_ref.isFunction()) function_ref = env->resolveValue(args->at(2).toString()); if (!function_ref.isValid()) return env->throwError("connection failed, argument 3 is not a function"); ok = ip->addConnection(sender, signal, function_ref); if (!ok) { const QMetaObject *meta_object = sender->metaObject(); if (meta_object->indexOfSignal(signal) < 0) { return env->throwError(QString("connection failed, no such signal %1::%2") .arg(meta_object->className()) .arg(signal.constData() + 1)); } } } else if (args->size() == 4) { // C++ -> C++ connection QSObject qsReceiver = args->at(2); QObject *receiver = qsReceiver.isA(ip->wrapperClass()) ? QSWrapperClass::object(&qsReceiver) : 0; if (!receiver) return env->throwError("connection failed, reciver is not of type QObject"); QString slot_string = "1" + args->at(3).toString(); QByteArray slot = QMetaObject::normalizedSignature(slot_string.toLatin1()); ok = QObject::connect(sender, signal, receiver, slot); if (!ok) { if (!QMetaObject::checkConnectArgs(signal, slot)) return env->throwError("connection failed, parameters does not match"); else return env->throwError("connection failed, unknown error"); } } else { return env->throwError("connection failed, expected 3 or 4 arguments"); } if (!ok) return env->throwError("connection failed"); return env->createBoolean(true); }
static QSObject qsConnectCommon( QSEnv *env, QSObject &arg0, QSObject &arg2, QSWrapperShared *&sendObj, QSWrapperShared *&recObj, const QPtrVector<QObject> *&sendIfaces, const QPtrVector<QObject> *&recIfaces, QString &sig, QString &sl, int &signal_index, QObject *&sender, const QString &func ) { const QSList &args = *env->arguments(); QuickInterpreter *ip = QuickInterpreter::fromEnv( env ); const QString overloads = QString::fromLatin1( "Following overloads are possible:\n" "%1( sender : QObject, signal : String, receiver : QObject, slot : String )\n" "%2( sender : QObject, signal : String, function : DeclaredFunction )" ). arg( func ).arg( func ); if ( args.size() < 3 || args.size() > 4 ) { QString msg = QString::fromLatin1("No matching overload found. ") + overloads; return env->throwError( SyntaxError, msg ); } QSWrapperClass *wClass = ip->wrapperClass(); if ( !args[0].isA( wClass ) ) { QString msg = QString::fromLatin1("No matching overload found. 'sender' must be of type QObject but is of type ") + args[0].typeName() + QString::fromLatin1("\n") + overloads; return env->throwError( TypeError, msg ); } if ( args.size() == 3 && !args[2].isFunction() ) { QString msg = QString::fromLatin1("No matching overloads found. Third argument in this overload " "must be of type function but is of type ") + args[2].typeName() + QString::fromLatin1("\n") + overloads; return env->throwError( TypeError, msg ); } arg0 = args[0]; arg2 = args[2]; sendObj = wClass->shared( &arg0 ); recObj = arg2.isA( wClass ) ? wClass->shared( &arg2 ) : 0; sendIfaces = sendObj->interfaceObjects(); recIfaces = recObj ? recObj->interfaceObjects() : 0; // signal and slot in string representation sig = args[1].toString(); sl = ( args.size()>3 ? args[3] : env->createUndefined() ).toString(); // find sender and signal sender = 0; signal_index = -1; const char *sigName = sig.ascii(); int i; for ( i = (int)sendIfaces->count()-1; i >= 0; --i ) { sender = sendIfaces->at( i ); signal_index = sender->metaObject()->findSignal( sigName, TRUE ); if ( signal_index > 0 ) break; } if ( signal_index == -1 ) { // didn't find the signal- this signature might be in Qt // Script syntax, so lets's try to find out if we can connect QString sn = sig; QString arg = sig.mid( sig.find( '(' ) + 1 ); arg = arg.left( arg.findRev( ')' ) ); QStringList args = QStringList::split( ',', arg ); sn = sig.left( sig.find( '(' ) ); for ( i = (int)sendIfaces->count()-1; i >= 0; --i ) { sender = sendIfaces->at( i ); for ( int j = 0; j < (int)sender->metaObject()->numSignals( TRUE ); ++j ) { const QMetaData *md = sender->metaObject()->signal( j, TRUE ); QString mdn = QString::fromLatin1(md->name); mdn = mdn.left( mdn.find( '(' ) ); if ( mdn != sn ) continue; const QUMethod *method = md->method; bool ok = method->count == (int)args.count(); for ( int k = 0; k < method->count; ++k ) { QUParameter p = method->parameters[k]; QString s = *args.at( k ); int sep; if ( ( sep = s.find( ':' ) ) != -1 ) s = s.mid( sep + 1 ); s = s.simplifyWhiteSpace(); if ( s == QString::fromLatin1(p.type->desc()) || s == QString::fromLatin1((const char*)p.typeExtra)) continue; if ( s == QString::fromLatin1("Number") && ( qstrcmp( p.type->desc(), "int" ) == 0 || qstrcmp( p.type->desc(), "long" ) == 0 || qstrcmp( p.type->desc(), "double" ) == 0 || qstrcmp( p.type->desc(), "float" ) == 0 || qstrcmp( p.type->desc(), "short" ) == 0 || qstrcmp( p.type->desc(), "uint" ) == 0 || qstrcmp( p.type->desc(), "ushort" ) == 0 || qstrcmp( p.type->desc(), "ulong" ) == 0 || qstrcmp( p.type->desc(), "unsigned int" ) == 0 || qstrcmp( p.type->desc(), "unsigned short" ) == 0 || qstrcmp( p.type->desc(), "unsigned long" ) == 0 ) ) continue; s.prepend( QString::fromLatin1("Q") ); if (s == QString::fromLatin1(p.type->desc()) || s == QString::fromLatin1((const char*)p.typeExtra)) continue; ok = FALSE; break; } if ( !ok ) continue; signal_index = j; sig = sender->metaObject()->signal( j, TRUE )->name; break; } if ( signal_index != -1 ) break; } } return QSObject(); }