QDeclarativeInfo::~QDeclarativeInfo()
{
    if (0 == --d->ref) {
        QList<QDeclarativeError> errors = d->errors;

        QDeclarativeEngine *engine = 0;

        if (!d->buffer.isEmpty()) {
            QDeclarativeError error;

            QObject *object = const_cast<QObject *>(d->object);

            if (object) {
                engine = qmlEngine(d->object);
                QString typeName;
                QDeclarativeType *type = QDeclarativeMetaType::qmlType(object->metaObject());
                if (type) {
                    typeName = QLatin1String(type->qmlTypeName());
                    int lastSlash = typeName.lastIndexOf(QLatin1Char('/'));
                    if (lastSlash != -1)
                        typeName = typeName.mid(lastSlash+1);
                } else {
                    typeName = QString::fromUtf8(object->metaObject()->className());
                    int marker = typeName.indexOf(QLatin1String("_QMLTYPE_"));
                    if (marker != -1)
                        typeName = typeName.left(marker);

                    marker = typeName.indexOf(QLatin1String("_QML_"));
                    if (marker != -1) {
                        typeName = typeName.left(marker) + "*";
                        type = QDeclarativeMetaType::qmlType(QMetaType::type(typeName.toLatin1()));
                        if (type) {
                            typeName = QLatin1String(type->qmlTypeName());
                            int lastSlash = typeName.lastIndexOf(QLatin1Char('/'));
                            if (lastSlash != -1)
                                typeName = typeName.mid(lastSlash+1);
                        }
                    }
                }

                d->buffer.prepend(QLatin1String("QML ") + typeName + QLatin1String(": "));

                QDeclarativeData *ddata = QDeclarativeData::get(object, false);
                if (ddata && ddata->outerContext && !ddata->outerContext->url.isEmpty()) {
                    error.setUrl(ddata->outerContext->url);
                    error.setLine(ddata->lineNumber);
                    error.setColumn(ddata->columnNumber);
                }
            }

            error.setDescription(d->buffer);

            errors.prepend(error);
        }

        QDeclarativeEnginePrivate::warning(engine, errors);

        delete d;
    }
}
Example #2
0
const QMetaObject *QDeclarativePropertyPrivate::rawMetaObjectForType(QDeclarativeEnginePrivate *engine, int userType)
{
    if (engine) {
        return engine->rawMetaObjectForType(userType);
    } else {
        QDeclarativeType *type = QDeclarativeMetaType::qmlType(userType);
        return type?type->baseMetaObject():0;
    }
}
Example #3
0
void MetaInfoPrivate::typeInfo(const QMetaObject *qMetaObject, QString *typeName, int *majorVersion, int *minorVersion) const
{
    Q_ASSERT(typeName);

    if (!qMetaObject)
        return;

    *typeName = qMetaObject->className();
    int majVersion = -1;
    int minVersion = -1;
    QDeclarativeType *qmlType = QDeclarativeMetaType::qmlType(qMetaObject);
    if (qmlType) {
        if (!qmlType->qmlTypeName().isEmpty()) {
            *typeName = qmlType->qmlTypeName();
            majVersion = qmlType->majorVersion();
            minVersion = qmlType->minorVersion();
        }
    }
    if (majorVersion)
        *majorVersion = majVersion;
    if (minorVersion)
        *minorVersion = minVersion;
}
Example #4
0
bool QDeclarativePropertyPrivate::write(QObject *object, const QDeclarativePropertyCache::Data &property, 
                                            const QVariant &value, QDeclarativeContextData *context, 
                                            WriteFlags flags)
{
    int coreIdx = property.coreIndex;
    int status = -1;    //for dbus

    if (property.flags & QDeclarativePropertyCache::Data::IsEnumType) {
        QMetaProperty prop = object->metaObject()->property(property.coreIndex);
        QVariant v = value;
        // Enum values come through the script engine as doubles
        if (value.userType() == QVariant::Double) { 
            double integral;
            double fractional = modf(value.toDouble(), &integral);
            if (qFuzzyIsNull(fractional))
                v.convert(QVariant::Int);
        }
        return writeEnumProperty(prop, coreIdx, object, v, flags);
    }

    int propertyType = property.propType;
    int variantType = value.userType();

    QDeclarativeEnginePrivate *enginePriv = QDeclarativeEnginePrivate::get(context);

    if (propertyType == QVariant::Url) {

        QUrl u;
        bool found = false;
        if (variantType == QVariant::Url) {
            u = value.toUrl();
            found = true;
        } else if (variantType == QVariant::ByteArray) {
            u = QUrl(QString::fromUtf8(value.toByteArray()));
            found = true;
        } else if (variantType == QVariant::String) {
            u = QUrl(value.toString());
            found = true;
        }

        if (!found)
            return false;

        if (context && u.isRelative() && !u.isEmpty())
            u = context->resolvedUrl(u);
        int status = -1;
        void *argv[] = { &u, 0, &status, &flags };
        QMetaObject::metacall(object, QMetaObject::WriteProperty, coreIdx, argv);

    } else if (variantType == propertyType) {

        void *a[] = { (void *)value.constData(), 0, &status, &flags };
        QMetaObject::metacall(object, QMetaObject::WriteProperty, coreIdx, a);

    } else if (qMetaTypeId<QVariant>() == propertyType) {

        void *a[] = { (void *)&value, 0, &status, &flags };
        QMetaObject::metacall(object, QMetaObject::WriteProperty, coreIdx, a);

    } else if (property.flags & QDeclarativePropertyCache::Data::IsQObjectDerived) {

        const QMetaObject *valMo = rawMetaObjectForType(enginePriv, value.userType());
        
        if (!valMo)
            return false;

        QObject *o = *(QObject **)value.constData();
        const QMetaObject *propMo = rawMetaObjectForType(enginePriv, propertyType);

        if (o) valMo = o->metaObject();

        if (canConvert(valMo, propMo)) {
            void *args[] = { &o, 0, &status, &flags };
            QMetaObject::metacall(object, QMetaObject::WriteProperty, coreIdx, 
                                  args);
        } else if (!o && canConvert(propMo, valMo)) {
            // In the case of a null QObject, we assign the null if there is 
            // any change that the null variant type could be up or down cast to 
            // the property type.
            void *args[] = { &o, 0, &status, &flags };
            QMetaObject::metacall(object, QMetaObject::WriteProperty, coreIdx, 
                                  args);
        } else {
            return false;
        }

    } else if (property.flags & QDeclarativePropertyCache::Data::IsQList) {

        const QMetaObject *listType = 0;
        if (enginePriv) {
            listType = enginePriv->rawMetaObjectForType(enginePriv->listType(property.propType));
        } else {
            QDeclarativeType *type = QDeclarativeMetaType::qmlType(QDeclarativeMetaType::listType(property.propType));
            if (!type) return false;
            listType = type->baseMetaObject();
        }
        if (!listType) return false;

        QDeclarativeListProperty<void> prop;
        void *args[] = { &prop, 0 };
        QMetaObject::metacall(object, QMetaObject::ReadProperty, coreIdx, args);

        if (!prop.clear) return false;

        prop.clear(&prop);

        if (value.userType() == qMetaTypeId<QList<QObject *> >()) {
            const QList<QObject *> &list = qvariant_cast<QList<QObject *> >(value);

            for (int ii = 0; ii < list.count(); ++ii) {
                QObject *o = list.at(ii);
                if (o && !canConvert(o->metaObject(), listType))
                    o = 0;
                prop.append(&prop, (void *)o);
            }
        } else {
            QObject *o = enginePriv?enginePriv->toQObject(value):QDeclarativeMetaType::toQObject(value);
            if (o && !canConvert(o->metaObject(), listType))
                o = 0;
            prop.append(&prop, (void *)o);
        }

    } else {
        Q_ASSERT(variantType != propertyType);

        QVariant v = value;
        if (v.convert((QVariant::Type)propertyType)) {
            void *a[] = { (void *)v.constData(), 0, &status, &flags};
            QMetaObject::metacall(object, QMetaObject::WriteProperty, coreIdx, a);
        } else if ((uint)propertyType >= QVariant::UserType && variantType == QVariant::String) {
            QDeclarativeMetaType::StringConverter con = QDeclarativeMetaType::customStringConverter(propertyType);
            if (!con)
                return false;

            QVariant v = con(value.toString());
            if (v.userType() == propertyType) {
                void *a[] = { (void *)v.constData(), 0, &status, &flags};
                QMetaObject::metacall(object, QMetaObject::WriteProperty, coreIdx, a);
            }
        } else if (variantType == QVariant::String) {
            bool ok = false;
            QVariant v = QDeclarativeStringConverters::variantFromString(value.toString(), propertyType, &ok);
            if (!ok)
                return false;

            void *a[] = { (void *)v.constData(), 0, &status, &flags};
            QMetaObject::metacall(object, QMetaObject::WriteProperty, coreIdx, a);
        } else {
            return false;
        }
    }

    return true;
}
void QJnextMainLoop::createObject(QVariantList& args, QByteArray* result) {
	uint id = idBase++;
	// this will OWN the backing char array
	QByteArray param = args.takeFirst().toByteArray();
	QByteArray ns(param);
	QByteArray ver = QtBridge::takeLastParam(ns, "@");
	if (ver.size() == 0)
		ver = "1.0";
	QByteArray cls = QtBridge::takeLastParam(ns, ".");
	QString qmlcls = QString(ns) + "/" + cls;

	QObject *& object = objects[id];
	if (object != NULL) {
		*result = "Error object already exists for id" + QByteArray::number(id);
		qWarning() << *result;
		return;
	}

#ifdef DEBUG_QJnextMainLoop
	qDebug() << "[QJnextMainLoop]\tQDeclarative" << "import " + ns + " " + ver + "; " + cls + " {}";
#endif
	QDeclarativeComponent component(declarativeEngine, this);

	component.setData(
			"import " + ns + " " + ver + "; import QtQuick 1.0; QtObject {}",
			QUrl());
	if (component.isError() || !component.isReady()) {
		qWarning() << "COMPONENT ERROR" << component.errorString();
	}

	int majorVersion = -1, minorVersion = -1;
	QDeclarativeType * dtype = NULL;
	QString scls = cls;

	QList<QDeclarativeType*> types = QDeclarativeMetaType::qmlTypes();
	foreach(QDeclarativeType* type, types)
	{
		if (ns == type->module()) {
			QString qmlType = QString::fromLatin1(type->qmlTypeName());

			if (qmlcls.compare(qmlType, Qt::CaseInsensitive) == 0) {
				if (type->majorVersion() > majorVersion
						&& type->minorVersion() > minorVersion) {
					majorVersion = type->majorVersion();
					minorVersion = type->minorVersion();
					dtype = type;
				}
			}
		}
	}
	if (dtype == NULL && ns == "bb" && cls == "Application") {
		object = bb::Application::instance();
		object->setUserData(userDataId, new QJnextUserData(id));
		goto end_createObject;
	}
	if (dtype == NULL) {
		*result = "No such Type " + cls + " in namespace " + ns;
		qWarning() << *result;
		return;
	} else if (!dtype->isCreatable()) {
		*result = "Class " + ns + "." + cls + " is not creatable: "
				+ dtype->noCreationReason().toLatin1();
		qWarning() << *result;
		return;
	}

#ifdef DEBUG_QJnextMainLoop
	qDebug() << "[QJnextMainLoop]\t" << dtype->typeId() << dtype->typeName()
			<< QString("%1.%2").arg(QString::number(dtype->majorVersion())).arg(
					QString::number(dtype->minorVersion()));
#endif
	object = dtype->create();
	if (!object) {
		qWarning() << "COMPONENT.CREATE ERROR";
		*result = "Error creating component";
		return;
	}
	object->setUserData(userDataId, new QJnextUserData(id));
	object->setParent(this);

end_createObject:
	*result = QByteArray::number(id);
#ifdef DEBUG_QJnextMainLoop
	qDebug() << "[QJnextMainLoop]\tCreated object" << id;
#endif
}
Example #6
0
void tst_QDeclarativeDebug::recursiveObjectTest(QObject *o, const QDeclarativeDebugObjectReference &oref, bool recursive) const
{
    const QMetaObject *meta = o->metaObject();

    QDeclarativeType *type = QDeclarativeMetaType::qmlType(meta);
    QString className = type ? QString(type->qmlTypeName()) : QString(meta->className());
    className = className.mid(className.lastIndexOf(QLatin1Char('/'))+1);

    QCOMPARE(oref.debugId(), QDeclarativeDebugService::idForObject(o));
    QCOMPARE(oref.name(), o->objectName());
    QCOMPARE(oref.className(), className);
    QCOMPARE(oref.contextDebugId(), QDeclarativeDebugService::idForObject(qmlContext(o)));

    const QObjectList &children = o->children();
    for (int i=0; i<children.count(); i++) {
        QObject *child = children[i];
        if (!qmlContext(child))
            continue;
        int debugId = QDeclarativeDebugService::idForObject(child);
        QVERIFY(debugId >= 0);

        QDeclarativeDebugObjectReference cref;
        foreach (const QDeclarativeDebugObjectReference &ref, oref.children()) {
            if (ref.debugId() == debugId) {
                cref = ref;
                break;
            }
        }
        QVERIFY(cref.debugId() >= 0);

        if (recursive)
            recursiveObjectTest(child, cref, true);
    }

    foreach (const QDeclarativeDebugPropertyReference &p, oref.properties()) {
        QCOMPARE(p.objectDebugId(), QDeclarativeDebugService::idForObject(o));

        // signal properties are fake - they are generated from QDeclarativeBoundSignal children
        if (p.name().startsWith("on") && p.name().length() > 2 && p.name()[2].isUpper()) {
            QVERIFY(p.value().toString().startsWith('{') && p.value().toString().endsWith('}'));
            QVERIFY(p.valueTypeName().isEmpty());
            QVERIFY(p.binding().isEmpty());
            QVERIFY(!p.hasNotifySignal());
            continue;
        }

        QMetaProperty pmeta = meta->property(meta->indexOfProperty(p.name().toUtf8().constData()));

        QCOMPARE(p.name(), QString::fromUtf8(pmeta.name()));

        if (pmeta.type() > 0 && pmeta.type() < QVariant::UserType) // TODO test complex types
            QCOMPARE(p.value(), pmeta.read(o));

        if (p.name() == "parent")
            QVERIFY(p.valueTypeName() == "QGraphicsObject*" || p.valueTypeName() == "QDeclarativeItem*");
        else
            QCOMPARE(p.valueTypeName(), QString::fromUtf8(pmeta.typeName()));

        QDeclarativeAbstractBinding *binding = 
            QDeclarativePropertyPrivate::binding(QDeclarativeProperty(o, p.name()));
        if (binding)
            QCOMPARE(binding->expression(), p.binding());

        QCOMPARE(p.hasNotifySignal(), pmeta.hasNotifySignal());

        QVERIFY(pmeta.isValid());
    }
}