示例#1
0
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);
}
示例#2
0
/*!
  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
  }
}
示例#3
0
void qsKillTimer( QSEnv *env )
{
    QuickInterpreter *ip = QuickInterpreter::fromEnv(env);
    int id = (int) env->arg(0).toNumber();

    ip->timers()->remove(id);
    ip->killTimer(id);
}
示例#4
0
void QSCompletionObject::resolve()
{
    if ( type == TQSObject ) {
	QuickInterpreter *ip = QuickInterpreter::fromEnv( qsobj.env() );
	if( qsobj.isA( ip->wrapperClass() ) ) {
	    type = TQObject;
	    qobj = *ip->wrapperClass()->objectVector( &qsobj );
	}
    }
}
示例#5
0
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();
}
示例#6
0
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;
}
示例#7
0
/*******************************************************************************
 * 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 );
}
示例#8
0
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();
}