⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 qscriptextqobject.cpp

📁 奇趣公司比较新的qt/emd版本
💻 CPP
📖 第 1 页 / 共 4 页
字号:
/******************************************************************************** Copyright (C) 1992-2007 Trolltech ASA. All rights reserved.**** This file is part of the QtScript module of the Qt Toolkit.**** This file may be used under the terms of the GNU General Public** License version 2.0 as published by the Free Software Foundation** and appearing in the file LICENSE.GPL included in the packaging of** this file.  Please review the following information to ensure GNU** General Public Licensing requirements will be met:** http://trolltech.com/products/qt/licenses/licensing/opensource/**** If you are unsure which license is appropriate for your use, please** review the following information:** http://trolltech.com/products/qt/licenses/licensing/licensingoverview** or contact the sales department at sales@trolltech.com.**** In addition, as a special exception, Trolltech gives you certain** additional rights. These rights are described in the Trolltech GPL** Exception version 1.0, which can be found at** http://www.trolltech.com/products/qt/gplexception/ and in the file** GPL_EXCEPTION.txt in this package.**** In addition, as a special exception, Trolltech, as the sole copyright** holder for Qt Designer, grants users of the Qt/Eclipse Integration** plug-in the right for the Qt/Eclipse Integration to link to** functionality provided by Qt Designer and its related libraries.**** Trolltech reserves all rights not expressly granted herein.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.******************************************************************************/#include "qscriptextqobject_p.h"#ifndef QT_NO_SCRIPT#include "qscriptengine_p.h"#include "qscriptvalueimpl_p.h"#include "qscriptcontext_p.h"#include "qscriptmember_p.h"#include "qscriptobject_p.h"#include "qscriptable.h"#include "qscriptable_p.h"#include <QtCore/QtDebug>#include <QtCore/QMetaMethod>#include <QtCore/QRegExp>#include <QtCore/QVarLengthArray>#include "qscriptextqobject_p.h"// we use bits 15..12 of property flagsenum {    PROPERTY_ID      = 0 << 12,    DYNAPROPERTY_ID  = 1 << 12,    METHOD_ID        = 2 << 12,    CHILD_ID         = 3 << 12,    ID_MASK          = 7 << 12,    MAYBE_OVERLOADED = 8 << 12};static const bool GeneratePropertyFunctions = true;QByteArray QScriptMetaType::name() const{    if (!m_name.isEmpty())        return m_name;    else if (m_kind == Variant)        return "QVariant";    return QByteArray();}namespace QScript {class QtPropertyFunction: public QScriptFunction{public:    QtPropertyFunction(const QMetaObject *meta, int index)        : m_meta(meta), m_index(index)        { }    ~QtPropertyFunction() { }    virtual void execute(QScriptContextPrivate *context);    virtual Type type() const { return QScriptFunction::QtProperty; }private:    const QMetaObject *m_meta;    int m_index;};class QObjectPrototype : public QObject{    Q_OBJECTpublic:    QObjectPrototype(QObject *parent = 0)        : QObject(parent) { }    ~QObjectPrototype() { }};static inline QByteArray methodName(const QMetaMethod &method){    QByteArray signature = method.signature();    return signature.left(signature.indexOf('('));}static inline QVariant variantFromValue(int targetType, const QScriptValueImpl &value){    QVariant v(targetType, (void *)0);    QScriptEngine *eng = value.engine();    Q_ASSERT(eng);    if (QScriptEnginePrivate::get(eng)->convert(value, targetType, v.data()))        return v;    if (uint(targetType) == QVariant::LastType)        return value.toVariant();    if (value.isVariant()) {        v = value.toVariant();        if (v.canConvert(QVariant::Type(targetType))) {            v.convert(QVariant::Type(targetType));            return v;        }        QByteArray typeName = v.typeName();        if (typeName.endsWith('*')            && (QMetaType::type(typeName.left(typeName.size()-1)) == targetType)) {            return QVariant(targetType, *reinterpret_cast<void* *>(v.data()));        }    }    return QVariant();}ExtQObject::Instance *ExtQObject::Instance::get(const QScriptValueImpl &object, QScriptClassInfo *klass){    if (! klass || klass == object.classInfo())        return static_cast<Instance*> (object.objectData().data());    return 0;}void ExtQObject::Instance::execute(QScriptContextPrivate *context){    if (!value) {        context->throwError(QLatin1String("cannot call function of deleted QObject"));        return;    }    const QMetaObject *meta = value->metaObject();    // look for qscript_call()    QByteArray qscript_call = QByteArray("qscript_call");    int index;    for (index = meta->methodCount() - 1; index >= 0; --index) {        if (methodName(meta->method(index)) == qscript_call)            break;    }    if (index < 0) {        context->throwError(QScriptContext::TypeError,                            QLatin1String("not a function"));        return;    }    QtFunction fun(value, index, /*maybeOverloaded=*/true);    fun.execute(context);}static inline QScriptable *scriptableFromQObject(QObject *qobj){    void *ptr = qobj->qt_metacast("QScriptable");    return reinterpret_cast<QScriptable*>(ptr);}static bool isObjectProperty(const QScriptValueImpl &object, const char *name){    QScriptEnginePrivate *eng = QScriptEnginePrivate::get(object.engine());    QScriptNameIdImpl *nameId = eng->nameId(QLatin1String(name));    QScript::Member member;    QScriptValueImpl base;    return object.resolve(nameId, &member, &base, QScriptValue::ResolveLocal)        && member.testFlags(QScript::Member::ObjectProperty);}static bool hasMethodAccess(const QMetaMethod &method){    return (method.access() != QMetaMethod::Private);}class ExtQObjectData: public QScriptClassData{public:    ExtQObjectData(QScriptEnginePrivate *, QScriptClassInfo *classInfo)        : m_classInfo(classInfo)    {    }    virtual bool resolve(const QScriptValueImpl &object, QScriptNameIdImpl *nameId,                         QScript::Member *member, QScriptValueImpl *)    {        ExtQObject::Instance *inst = ExtQObject::Instance::get(object, m_classInfo);        QObject *qobject = inst->value;        if (! qobject) {            // the object was deleted. We return true so we can            // throw an error in get()/put()            member->native(nameId, /*id=*/-1, /*flags=*/0);            return true;        }        const QScriptEngine::QObjectWrapOptions &opt = inst->options;        const QMetaObject *meta = qobject->metaObject();        QScriptEnginePrivate *eng = QScriptEnginePrivate::get(object.engine());#ifndef Q_SCRIPT_NO_QMETAOBJECT_CACHE        QScriptMetaObject *metaCache = eng->cachedMetaObject(meta);        if (metaCache->findMember(nameId, member)) {            bool ignore = false;            switch (member->flags() & ID_MASK) {            case PROPERTY_ID:                ignore = (opt & QScriptEngine::ExcludeSuperClassProperties)                         && (member->id() < meta->propertyOffset());                break;            case METHOD_ID:                ignore = (opt & QScriptEngine::ExcludeSuperClassMethods)                         && (member->id() < meta->methodOffset());                break;            // we don't cache dynamic properties nor children,            // so no need to handle DYNAPROPERTY_ID and CHILD_ID            default:                break;            }            if (!ignore)                return true;        }#endif        QString memberName = eng->toString(nameId);        QByteArray name = memberName.toLatin1();        int index = -1;        if (name.contains('(')) {            QByteArray normalized = QMetaObject::normalizedSignature(name);            if (-1 != (index = meta->indexOfMethod(normalized))) {                QMetaMethod method = meta->method(index);                if (hasMethodAccess(method)) {                    member->native(nameId, index,                                   QScriptValue::QObjectMember                                   | METHOD_ID);#ifndef Q_SCRIPT_NO_QMETAOBJECT_CACHE                    metaCache->registerMember(nameId, *member);#endif                    if (!(opt & QScriptEngine::ExcludeSuperClassMethods)                        || (index >= meta->methodOffset())) {                        return true;                    }                }            }        }        index = meta->indexOfProperty(name);        if (index != -1) {            QMetaProperty prop = meta->property(index);            if (prop.isScriptable()) {                member->native(nameId, index,                               QScriptValue::Undeletable                               | (!prop.isWritable()                                  ? QScriptValue::ReadOnly                                  : QScriptValue::PropertyFlag(0))                               | (GeneratePropertyFunctions                                  ? (QScriptValue::PropertyGetter                                     | QScriptValue::PropertySetter)                                  : QScriptValue::PropertyFlag(0))                               | QScriptValue::QObjectMember                               | PROPERTY_ID);#ifndef Q_SCRIPT_NO_QMETAOBJECT_CACHE                metaCache->registerMember(nameId, *member);#endif                if (!(opt & QScriptEngine::ExcludeSuperClassProperties)                    || (index >= meta->propertyOffset())) {                    return true;                }            }        }        index = qobject->dynamicPropertyNames().indexOf(name);        if (index != -1) {            member->native(nameId, index,                           QScriptValue::QObjectMember                           | DYNAPROPERTY_ID);            // not cached because it can be removed            return true;        }        const int offset = (opt & QScriptEngine::ExcludeSuperClassMethods)                           ? meta->methodOffset() : 0;        for (index = meta->methodCount() - 1; index >= offset; --index) {            QMetaMethod method = meta->method(index);            if (hasMethodAccess(method)                && (methodName(method) == name)) {                member->native(nameId, index,                               QScriptValue::QObjectMember                               | METHOD_ID                               | MAYBE_OVERLOADED);#ifndef Q_SCRIPT_NO_QMETAOBJECT_CACHE                metaCache->registerMember(nameId, *member);#endif                return true;            }        }        if (!(opt & QScriptEngine::ExcludeChildObjects)) {            QList<QObject*> children = qobject->children();            for (index = 0; index < children.count(); ++index) {                QObject *child = children.at(index);                if (child->objectName() == memberName) {                    member->native(nameId, index,                                   QScriptValue::ReadOnly                                   | QScriptValue::Undeletable                                   | QScriptValue::SkipInEnumeration                                   | CHILD_ID);                    // not cached because it can be removed or change name                    return true;                }            }        }        if (opt & QScriptEngine::AutoCreateDynamicProperties) {            member->native(nameId, -1, DYNAPROPERTY_ID);            return true;        }        return false;     }    virtual bool get(const QScriptValueImpl &obj, const QScript::Member &member, QScriptValueImpl *result)    {        if (! member.isNativeProperty())            return false;        QScriptEnginePrivate *eng = QScriptEnginePrivate::get(obj.engine());        ExtQObject::Instance *inst = ExtQObject::Instance::get(obj, m_classInfo);        QObject *qobject = inst->value;        if (!qobject) {            QScriptContextPrivate *ctx = QScriptContextPrivate::get(eng->currentContext());            *result = ctx->throwError(                QString::fromLatin1("cannot access member `%0' of deleted QObject")                .arg(member.nameId()->s));            return true;        }        switch (member.flags() & ID_MASK) {        case PROPERTY_ID: {            const QMetaObject *meta = qobject->metaObject();            const int propertyIndex = member.id();            QMetaProperty prop = meta->property(propertyIndex);            Q_ASSERT(prop.isScriptable());            if (GeneratePropertyFunctions) {                QScriptValueImpl accessor;#ifndef Q_SCRIPT_NO_QMETAOBJECT_CACHE                QScriptMetaObject *metaCache = eng->cachedMetaObject(meta);                accessor = metaCache->findPropertyAccessor(propertyIndex);                if (!accessor.isValid()) {#endif                    accessor = eng->createFunction(new QtPropertyFunction(meta, propertyIndex));#ifndef Q_SCRIPT_NO_QMETAOBJECT_CACHE                    metaCache->registerPropertyAccessor(propertyIndex, accessor);                }#endif                *result = accessor;            } else {                QVariant v = prop.read(qobject);                *result = eng->valueFromVariant(v);            }        }   break;        case DYNAPROPERTY_ID: {            if (member.id() != -1) {                QVariant v = qobject->property(member.nameId()->s.toLatin1());                *result = eng->valueFromVariant(v);            } else {                *result = eng->undefinedValue();            }        }   break;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -