/*! Returns the current execution context of the interpreter. This is either a QObject pointer or 0. */ QObject *QSInterpreter::currentContext() const { QSObject o = d->interpreter->env()->currentScope(); if (o.isA(d->interpreter->wrapperClass())) return d->interpreter->wrapperClass()->shared(&o)->objects[0]; return 0; }
QVector<QObject *> QSAEditor::queryQObject( const QVector<QObject *> &objects, const QString &property ) const { QSObject obj = interpreter()->wrap( objects[0] ); if ( obj.isA( interpreter()->wrapperClass() ) ) { QSMember m; if ( interpreter()->wrapperClass()->member( &obj, property, &m ) ) { QSObject o = interpreter()->wrapperClass()->fetchValue( &obj, m ); if ( o.isA( interpreter()->wrapperClass() ) ) return *interfaceObjects( o ); } else if ( interpreter()->applicationClass()->member( &obj, property, &m ) ) { QSObject o = interpreter()->applicationClass()->fetchValue( &obj, m ); if ( o.isA( interpreter()->wrapperClass() ) ) return *interfaceObjects( o ); } } return QVector<QObject *>(); }
QStringList QuickInterpreter::classesOf(QSObject &obj) const { const QSClass *cls = classOf(obj); QStringList lst; for (int i = 0; i < cls->numStaticVariables(); ++i) { QSObject o = cls->staticMember(i); if (o.isA(env()->typeClass()) && QSTypeClass::classValue(&o)->asClass()) lst << QSTypeClass::classValue(&o)->identifier(); } return lst; }
QSEqualsResult QSStringClass::isEqual( const QSObject &a, const QSObject &b ) const { Q_ASSERT( a.isA( this ) ); if ( b.isString() ) return (QSEqualsResult) (a.sVal() == b.sVal() || (a.sVal().isEmpty() && b.sVal().isEmpty())); else if ( b.isNumber() ) return ( QSEqualsResult ) ( a.sVal() == b.toString() ); else if ( !b.isPrimitive() ) return isEqual( a, b.toPrimitive() ); else return EqualsUndefined; }
QSObject QSAEditor::queryQSObject( QSObject &ctx, const QString &property ) const { QString s = property; QSObject ctxValue = ctx.get( s ); if ( ctxValue.isA( env()->typeClass() ) ) { return ctxValue; } if ( s.indexOf( '[' ) != -1 ) return QSArray( env() ); else if ( s == QString::fromLatin1("false") || s == QString::fromLatin1("true") ) return env()->createBoolean( false ); else if ( s[0] == '\'' || s[0] == '\"' ) return env()->createString( QString::fromLatin1("") ); return ctxValue; }
bool QuickDispatchObjectFactory::createInstance(const QString &className, const QValueList<QVariant> &args, QPtrVector<QObject> *result) { if (!d->objectsCache.contains(className)) return FALSE; QSArgumentList qsArgs; for (QValueList<QVariant>::ConstIterator it = args.begin(); it != args.end(); ++it) { if ((*it).type() == QVariant::String) { static const int length_of_Pointer = 7; static const QString pointer_header = QString::fromLatin1("Pointer"); QString s = (*it).toString(); if (s.left(length_of_Pointer) == pointer_header) { QStringList l = QStringList::split(':', s); if (l.count() == 3) { if (l[2] != QString::fromLatin1("QObject")) { ulong lng = l[1].toULong(); void *ptr = (void *)lng; qsArgs.append(QSArgument(ptr)); } else { ulong lng = l[1].toULong(); QObject *o = (QObject *)lng; qsArgs.append(QSArgument(o)); } continue; } } } qsArgs.append(QSArgument(*it)); } QSObjectFactory *factory = d->objectsCache[ className ]; QObject *ctx = 0; QSObject obj = interpreter()->env()->currentScope(); if (obj.isA(interpreter()->wrapperClass())) ctx = interpreter()->wrapperClass()->shared(&obj)->objects[0]; QObject *o = factory->create(className, qsArgs, ctx); if (o) { addObject(o, result); return TRUE; } return FALSE; }
QSEqualsResult QSNumberClass::isEqual( const QSObject &a, const QSObject &b ) const { Q_ASSERT( a.isA( this ) ); if ( b.isNumber() ) { double n1 = a.dVal(); double n2 = b.dVal(); if ( isNaN( n1 ) || isNaN( n2 ) ) return EqualsNotEqual; else return ( QSEqualsResult ) ( n1 == n2 ); // ### compare -0 agains +0 } else if ( b.isString() ) { return ( QSEqualsResult ) ( a.dVal() == b.toNumber() ); } else if ( !b.isPrimitive() ) { return isEqual( a, b.toPrimitive() ); } else { return EqualsUndefined; } }
QRegExp* QSRegExpClass::regExp( QSEnv *e ) { QSObject t = e->thisValue(); Q_ASSERT( t.isA( e->regexpClass() ) ); return &((QSRegExpShared*)t.shVal())->reg; }
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); }
QSEqualsResult QSRectClass::isEqual(const QSObject &a, const QSObject &b) const { if (!b.isA(this)) return EqualsNotEqual; return (QSEqualsResult)(*rect(&a) == *rect(&b)); }
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(); }