示例#1
0
QObject* QmlTypeWrapper::singletonObject() const
{
    if (!isSingleton())
        return 0;

    QQmlEngine *e = engine()->qmlEngine();
    QQmlType::SingletonInstanceInfo *siinfo = d()->type->singletonInstanceInfo();
    siinfo->init(e);
    return siinfo->qobjectApi(e);
}
示例#2
0
QVariant QmlTypeWrapper::toVariant() const
{
    if (d()->type && d()->type->isSingleton()) {
        QQmlEngine *e = engine()->qmlEngine();
        QQmlType::SingletonInstanceInfo *siinfo = d()->type->singletonInstanceInfo();
        siinfo->init(e); // note: this will also create QJSValue singleton which isn't strictly required.
        QObject *qobjectSingleton = siinfo->qobjectApi(e);
        if (qobjectSingleton) {
            return QVariant::fromValue<QObject*>(qobjectSingleton);
        }
    }

    // only QObject Singleton Type can be converted to a variant.
    return QVariant();
}
示例#3
0
    // find even more QMetaObjects by instantiating QML types and running
    // over the instances
    foreach (QQmlType *ty, QQmlMetaType::qmlTypes()) {
        if (skip.contains(ty))
            continue;
        if (ty->isExtendedType())
            continue;
        if (!ty->isCreatable())
            continue;
        if (ty->typeName() == "QQmlComponent")
            continue;

        QString tyName = ty->qmlTypeName();
        tyName = tyName.mid(tyName.lastIndexOf(QLatin1Char('/')) + 1);
        if (tyName.isEmpty())
            continue;

        inObjectInstantiation = tyName;
        QObject *object = 0;

        if (ty->isSingleton()) {
            QQmlType::SingletonInstanceInfo *siinfo = ty->singletonInstanceInfo();
            if (siinfo->qobjectCallback) {
                siinfo->init(engine);
                collectReachableMetaObjects(object, &metas);
                object = siinfo->qobjectApi(engine);
            } else {
                inObjectInstantiation.clear();
                continue; // we don't handle QJSValue singleton types.
            }
        } else {
            object = ty->create();
        }

        inObjectInstantiation.clear();

        if (object)
            collectReachableMetaObjects(object, &metas);
        else
            qWarning() << "Could not create" << tyName;
    }
示例#4
0
void QmlTypeWrapper::put(Managed *m, String *name, const Value &value)
{
    Q_ASSERT(m->as<QmlTypeWrapper>());
    QmlTypeWrapper *w = static_cast<QmlTypeWrapper *>(m);
    QV4::ExecutionEngine *v4 = w->engine();
    if (v4->hasException)
        return;

    QV4::Scope scope(v4);
    QQmlContextData *context = v4->v8Engine->callingContext();

    QQmlType *type = w->d()->type;
    if (type && !type->isSingleton() && w->d()->object) {
        QObject *object = w->d()->object;
        QObject *ao = qmlAttachedPropertiesObjectById(type->attachedPropertiesId(), object);
        if (ao)
            QV4::QObjectWrapper::setQmlProperty(v4, context, ao, name, QV4::QObjectWrapper::IgnoreRevision, value);
    } else if (type && type->isSingleton()) {
        QQmlEngine *e = scope.engine->qmlEngine();
        QQmlType::SingletonInstanceInfo *siinfo = type->singletonInstanceInfo();
        siinfo->init(e);

        QObject *qobjectSingleton = siinfo->qobjectApi(e);
        if (qobjectSingleton) {
            QV4::QObjectWrapper::setQmlProperty(v4, context, qobjectSingleton, name, QV4::QObjectWrapper::IgnoreRevision, value);
        } else if (!siinfo->scriptApi(e).isUndefined()) {
            QV4::ScopedObject apiprivate(scope, QJSValuePrivate::convertedToValue(v4, siinfo->scriptApi(e)));
            if (!apiprivate) {
                QString error = QLatin1String("Cannot assign to read-only property \"") + name->toQString() + QLatin1Char('\"');
                v4->throwError(error);
                return;
            } else {
                apiprivate->put(name, value);
            }
        }
    }
}
示例#5
0
ReturnedValue QmlTypeWrapper::get(Managed *m, String *name, bool *hasProperty)
{
    Q_ASSERT(m->as<QmlTypeWrapper>());

    QV4::ExecutionEngine *v4 = static_cast<QmlTypeWrapper *>(m)->engine();
    QV4::Scope scope(v4);

    Scoped<QmlTypeWrapper> w(scope, static_cast<QmlTypeWrapper *>(m));

    if (hasProperty)
        *hasProperty = true;

    QQmlContextData *context = v4->v8Engine->callingContext();

    QObject *object = w->d()->object;

    if (w->d()->type) {
        QQmlType *type = w->d()->type;

        // singleton types are handled differently to other types.
        if (type->isSingleton()) {
            QQmlEngine *e = v4->qmlEngine();
            QQmlType::SingletonInstanceInfo *siinfo = type->singletonInstanceInfo();
            siinfo->init(e);

            QObject *qobjectSingleton = siinfo->qobjectApi(e);
            if (qobjectSingleton) {
                // check for enum value
                if (name->startsWithUpper()) {
                    if (w->d()->mode == Heap::QmlTypeWrapper::IncludeEnums) {
                        // ### Optimize
                        QByteArray enumName = name->toQString().toUtf8();
                        const QMetaObject *metaObject = qobjectSingleton->metaObject();
                        for (int ii = metaObject->enumeratorCount() - 1; ii >= 0; --ii) {
                            QMetaEnum e = metaObject->enumerator(ii);
                            bool ok;
                            int value = e.keyToValue(enumName.constData(), &ok);
                            if (ok)
                                return QV4::Primitive::fromInt32(value).asReturnedValue();
                        }
                    }
                }

                // check for property.
                return QV4::QObjectWrapper::getQmlProperty(v4, context, qobjectSingleton, name, QV4::QObjectWrapper::IgnoreRevision, hasProperty);
            } else if (!siinfo->scriptApi(e).isUndefined()) {
                // NOTE: if used in a binding, changes will not trigger re-evaluation since non-NOTIFYable.
                QV4::ScopedObject o(scope, QJSValuePrivate::convertedToValue(v4, siinfo->scriptApi(e)));
                if (!!o)
                    return o->get(name);
            }

            // Fall through to base implementation

        } else {

            if (name->startsWithUpper()) {
                bool ok = false;
                int value = type->enumValue(name, &ok);
                if (ok)
                    return QV4::Primitive::fromInt32(value).asReturnedValue();

                // Fall through to base implementation

            } else if (w->d()->object) {
                QObject *ao = qmlAttachedPropertiesObjectById(type->attachedPropertiesId(), object);
                if (ao)
                    return QV4::QObjectWrapper::getQmlProperty(v4, context, ao, name, QV4::QObjectWrapper::IgnoreRevision, hasProperty);

                // Fall through to base implementation
            }

            // Fall through to base implementation
        }

        // Fall through to base implementation

    } else if (w->d()->typeNamespace) {
        Q_ASSERT(w->d()->importNamespace);
        QQmlTypeNameCache::Result r = w->d()->typeNamespace->query(name, w->d()->importNamespace);

        if (r.isValid()) {
            if (r.type) {
                return create(scope.engine, object, r.type, w->d()->mode);
            } else if (r.scriptIndex != -1) {
                QV4::ScopedObject scripts(scope, context->importedScripts.valueRef());
                return scripts->getIndexed(r.scriptIndex);
            } else if (r.importNamespace) {
                return create(scope.engine, object, context->imports, r.importNamespace);
            }

            return QV4::Encode::undefined();

        }

        // Fall through to base implementation

    } else {
        Q_ASSERT(!"Unreachable");
    }

    if (hasProperty)
        *hasProperty = false;
    return Object::get(m, name, hasProperty);
}