/**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtDeclarative module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include "qmldom.h" #include "qmldom_p.h" #include "qmlcompositetypedata_p.h" #include "qmlcompiler_p.h" #include "qmlengine_p.h" #include "qmlscriptparser_p.h" #include "qmlglobal_p.h" #include #include #include QT_BEGIN_NAMESPACE QmlDomDocumentPrivate::QmlDomDocumentPrivate() : root(0) { } QmlDomDocumentPrivate::~QmlDomDocumentPrivate() { if (root) root->release(); } /*! \class QmlDomDocument \internal \brief The QmlDomDocument class represents the root of a QML document A QML document is a self-contained snippet of QML, usually contained in a single file. Each document has a root object, accessible through QmlDomDocument::rootObject(). The QmlDomDocument class allows the programmer to inspect a QML document by calling QmlDomDocument::load(). The following example loads a QML file from disk, and prints out its root object type and the properties assigned in the root object. \code QFile file(inputFileName); file.open(QIODevice::ReadOnly); QByteArray xmlData = file.readAll(); QmlDomDocument document; document.load(qmlengine, xmlData); QmlDomObject rootObject = document.rootObject(); qDebug() << rootObject.objectType(); foreach(QmlDomProperty property, rootObject.properties()) qDebug() << property.propertyName(); \endcode */ /*! Construct an empty QmlDomDocument. */ QmlDomDocument::QmlDomDocument() : d(new QmlDomDocumentPrivate) { } /*! Create a copy of \a other QmlDomDocument. */ QmlDomDocument::QmlDomDocument(const QmlDomDocument &other) : d(other.d) { } /*! Destroy the QmlDomDocument */ QmlDomDocument::~QmlDomDocument() { } /*! Assign \a other to this QmlDomDocument. */ QmlDomDocument &QmlDomDocument::operator=(const QmlDomDocument &other) { d = other.d; return *this; } /*! Returns all import statements in qml. */ QList QmlDomDocument::imports() const { return d->imports; } /*! Loads a QmlDomDocument from \a data. \a data should be valid QML data. On success, true is returned. If the \a data is malformed, false is returned and QmlDomDocument::errors() contains an error description. \sa QmlDomDocument::loadError() */ bool QmlDomDocument::load(QmlEngine *engine, const QByteArray &data, const QUrl &url) { d->errors.clear(); d->imports.clear(); QmlCompiledData *component = new QmlCompiledData; QmlCompiler compiler; QmlCompositeTypeData *td = ((QmlEnginePrivate *)QmlEnginePrivate::get(engine))->typeManager.getImmediate(data, url); if(td->status == QmlCompositeTypeData::Error) { d->errors = td->errors; td->release(); component->release(); return false; } else if(td->status == QmlCompositeTypeData::Waiting || td->status == QmlCompositeTypeData::WaitingResources) { QmlError error; error.setDescription(QLatin1String("QmlDomDocument supports local types only")); d->errors << error; td->release(); component->release(); return false; } compiler.compile(engine, td, component); if (compiler.isError()) { d->errors = compiler.errors(); td->release(); component->release(); return false; } for (int i = 0; i < td->data.imports().size(); ++i) { QmlScriptParser::Import parserImport = td->data.imports().at(i); QmlDomImport domImport; domImport.d->type = static_cast(parserImport.type); domImport.d->uri = parserImport.uri; domImport.d->qualifier = parserImport.qualifier; domImport.d->version = parserImport.version; d->imports += domImport; } if (td->data.tree()) { d->root = td->data.tree(); d->root->addref(); } component->release(); return true; } /*! Returns the last load errors. The load errors will be reset after a successful call to load(). \sa load() */ QList QmlDomDocument::errors() const { return d->errors; } /*! Returns the document's root object, or an invalid QmlDomObject if the document has no root. In the sample QML below, the root object will be the QmlGraphicsItem type. \qml Item { Text { text: "Hello World" } } \endqml */ QmlDomObject QmlDomDocument::rootObject() const { QmlDomObject rv; rv.d->object = d->root; if (rv.d->object) rv.d->object->addref(); return rv; } QmlDomPropertyPrivate::QmlDomPropertyPrivate() : property(0) { } QmlDomPropertyPrivate::~QmlDomPropertyPrivate() { if (property) property->release(); } QmlDomDynamicPropertyPrivate::QmlDomDynamicPropertyPrivate(): valid(false) { } QmlDomDynamicPropertyPrivate::~QmlDomDynamicPropertyPrivate() { if (valid && property.defaultValue) property.defaultValue->release(); } /*! \class QmlDomProperty \internal \brief The QmlDomProperty class represents one property assignment in the QML DOM tree Properties in QML can be assigned QML \l {QmlDomValue}{values}. \sa QmlDomObject */ /*! Construct an invalid QmlDomProperty. */ QmlDomProperty::QmlDomProperty() : d(new QmlDomPropertyPrivate) { } /*! Create a copy of \a other QmlDomProperty. */ QmlDomProperty::QmlDomProperty(const QmlDomProperty &other) : d(other.d) { } /*! Destroy the QmlDomProperty. */ QmlDomProperty::~QmlDomProperty() { } /*! Assign \a other to this QmlDomProperty. */ QmlDomProperty &QmlDomProperty::operator=(const QmlDomProperty &other) { d = other.d; return *this; } /*! Returns true if this is a valid QmlDomProperty, false otherwise. */ bool QmlDomProperty::isValid() const { return d->property != 0; } /*! Return the name of this property. \qml Text { x: 10 y: 10 font.bold: true } \endqml As illustrated above, a property name can be a simple string, such as "x" or "y", or a more complex "dot property", such as "font.bold". In both cases the full name is returned ("x", "y" and "font.bold") by this method. For dot properties, a split version of the name can be accessed by calling QmlDomProperty::propertyNameParts(). \sa QmlDomProperty::propertyNameParts() */ QByteArray QmlDomProperty::propertyName() const { return d->propertyName; } /*! Return the name of this property, split into multiple parts in the case of dot properties. \qml Text { x: 10 y: 10 font.bold: true } \endqml For each of the properties shown above, this method would return ("x"), ("y") and ("font", "bold"). \sa QmlDomProperty::propertyName() */ QList QmlDomProperty::propertyNameParts() const { if (d->propertyName.isEmpty()) return QList(); else return d->propertyName.split('.'); } /*! Return true if this property is used as a default property in the QML document. \qml hello \endqml The above two examples return the same DOM tree, except that the second has the default property flag set on the text property. Observe that whether or not a property has isDefaultProperty set is determined by how the property is used, and not only by whether the property is the types default property. */ bool QmlDomProperty::isDefaultProperty() const { return d->property && d->property->isDefault; } /*! Returns the QmlDomValue that is assigned to this property, or an invalid QmlDomValue if no value is assigned. */ QmlDomValue QmlDomProperty::value() const { QmlDomValue rv; if (d->property) { rv.d->property = d->property; rv.d->value = d->property->values.at(0); rv.d->property->addref(); rv.d->value->addref(); } return rv; } /*! Returns the position in the input data where the property ID startd, or -1 if the property is invalid. */ int QmlDomProperty::position() const { if (d && d->property) { return d->property->location.range.offset; } else return -1; } /*! Returns the length in the input data from where the property ID started upto the end of it, or -1 if the property is invalid. */ int QmlDomProperty::length() const { if (d && d->property) return d->property->location.range.length; else return -1; } /*! Construct an invalid QmlDomDynamicProperty. */ QmlDomDynamicProperty::QmlDomDynamicProperty(): d(new QmlDomDynamicPropertyPrivate) { } /*! Create a copy of \a other QmlDomDynamicProperty. */ QmlDomDynamicProperty::QmlDomDynamicProperty(const QmlDomDynamicProperty &other): d(other.d) { } /*! Destroy the QmlDomDynamicProperty. */ QmlDomDynamicProperty::~QmlDomDynamicProperty() { } /*! Assign \a other to this QmlDomDynamicProperty. */ QmlDomDynamicProperty &QmlDomDynamicProperty::operator=(const QmlDomDynamicProperty &other) { d = other.d; return *this; } bool QmlDomDynamicProperty::isValid() const { return d && d->valid; } /*! Return the name of this dynamic property. \qml Item { property int count: 10; } \endqml As illustrated above, a dynamic property name can have a name and a default value ("10"). */ QByteArray QmlDomDynamicProperty::propertyName() const { if (isValid()) return d->property.name; else return QByteArray(); } /*! Returns the type of the dynamic property. Note that when the property is an alias property, this will return -1. Use QmlDomProperty::isAlias() to check if the property is an alias. */ int QmlDomDynamicProperty::propertyType() const { if (isValid()) { switch (d->property.type) { case QmlParser::Object::DynamicProperty::Bool: return QMetaType::type("bool"); case QmlParser::Object::DynamicProperty::Color: return QMetaType::type("QColor"); case QmlParser::Object::DynamicProperty::Date: return QMetaType::type("QDate"); case QmlParser::Object::DynamicProperty::Int: return QMetaType::type("int"); case QmlParser::Object::DynamicProperty::Real: return QMetaType::type("double"); case QmlParser::Object::DynamicProperty::String: return QMetaType::type("QString"); case QmlParser::Object::DynamicProperty::Url: return QMetaType::type("QUrl"); case QmlParser::Object::DynamicProperty::Variant: return QMetaType::type("QVariant"); default: break; } } return -1; } QByteArray QmlDomDynamicProperty::propertyTypeName() const { if (isValid()) return d->property.customType; return QByteArray(); } /*! Return true if this property is used as a default property in the QML document. \qml hello \endqml The above two examples return the same DOM tree, except that the second has the default property flag set on the text property. Observe that whether or not a property has isDefaultProperty set is determined by how the property is used, and not only by whether the property is the types default property. */ bool QmlDomDynamicProperty::isDefaultProperty() const { if (isValid()) return d->property.isDefaultProperty; else return false; } /*! Returns the default value as a QmlDomProperty. */ QmlDomProperty QmlDomDynamicProperty::defaultValue() const { QmlDomProperty rp; if (isValid() && d->property.defaultValue) { rp.d->property = d->property.defaultValue; rp.d->propertyName = propertyName(); rp.d->property->addref(); } return rp; } /*! Returns true if this dynamic property is an alias for another property, false otherwise. */ bool QmlDomDynamicProperty::isAlias() const { if (isValid()) return d->property.type == QmlParser::Object::DynamicProperty::Alias; else return false; } /*! Returns the position in the input data where the property ID startd, or 0 if the property is invalid. */ int QmlDomDynamicProperty::position() const { if (isValid()) { return d->property.location.range.offset; } else return -1; } /*! Returns the length in the input data from where the property ID started upto the end of it, or 0 if the property is invalid. */ int QmlDomDynamicProperty::length() const { if (isValid()) return d->property.location.range.length; else return -1; } QmlDomObjectPrivate::QmlDomObjectPrivate() : object(0) { } QmlDomObjectPrivate::~QmlDomObjectPrivate() { if (object) object->release(); } QmlDomObjectPrivate::Properties QmlDomObjectPrivate::properties() const { Properties rv; for (QHash::ConstIterator iter = object->properties.begin(); iter != object->properties.end(); ++iter) { rv << properties(*iter); } return rv; } QmlDomObjectPrivate::Properties QmlDomObjectPrivate::properties(QmlParser::Property *property) const { Properties rv; if (property->value) { for (QHash::ConstIterator iter = property->value->properties.begin(); iter != property->value->properties.end(); ++iter) { rv << properties(*iter); } QByteArray name(property->name + '.'); for (Properties::Iterator iter = rv.begin(); iter != rv.end(); ++iter) iter->second.prepend(name); } else { rv << qMakePair(property, property->name); } return rv; } /*! \class QmlDomObject \internal \brief The QmlDomObject class represents an object instantiation. Each object instantiated in a QML file has a corresponding QmlDomObject node in the QML DOM. In addition to the type information that determines the object to instantiate, QmlDomObject's also have a set of associated QmlDomProperty's. Each QmlDomProperty represents a QML property assignment on the instantiated object. For example, \qml QGraphicsWidget { opacity: 0.5 size: "100x100" } \endqml describes a single QmlDomObject - "QGraphicsWidget" - with two properties, "opacity" and "size". Obviously QGraphicsWidget has many more properties than just these two, but the QML DOM representation only contains those assigned values (or bindings) in the QML file. */ /*! Construct an invalid QmlDomObject. */ QmlDomObject::QmlDomObject() : d(new QmlDomObjectPrivate) { } /*! Create a copy of \a other QmlDomObject. */ QmlDomObject::QmlDomObject(const QmlDomObject &other) : d(other.d) { } /*! Destroy the QmlDomObject. */ QmlDomObject::~QmlDomObject() { } /*! Assign \a other to this QmlDomObject. */ QmlDomObject &QmlDomObject::operator=(const QmlDomObject &other) { d = other.d; return *this; } /*! Returns true if this is a valid QmlDomObject, false otherwise. */ bool QmlDomObject::isValid() const { return d->object != 0; } /*! Returns the fully-qualified type name of this object. For example, the type of this object would be "Qt/4.6/Rectangle". \qml Rectangle { } \endqml */ QByteArray QmlDomObject::objectType() const { if (d->object) return d->object->typeName; else return QByteArray(); } /*! Returns the type name as referenced in the qml file. For example, the type of this object would be "Rectangle". \qml Rectangle { } \endqml */ QByteArray QmlDomObject::objectClassName() const { if (d->object) return d->object->className; else return QByteArray(); } int QmlDomObject::objectTypeMajorVersion() const { if (d->object) return d->object->majorVersion; else return -1; } int QmlDomObject::objectTypeMinorVersion() const { if (d->object) return d->object->minorVersion; else return -1; } /*! Returns the QML id assigned to this object, or an empty QByteArray if no id has been assigned. For example, the object id of this object would be "MyText". \qml Text { id: myText } \endqml */ QString QmlDomObject::objectId() const { if (d->object) { return d->object->id; } else { return QString(); } } /*! Returns the list of assigned properties on this object. In the following example, "text" and "x" properties would be returned. \qml Text { text: "Hello world!" x: 100 } \endqml */ QList QmlDomObject::properties() const { QList rv; if (!d->object || isComponent()) return rv; QmlDomObjectPrivate::Properties properties = d->properties(); for (int ii = 0; ii < properties.count(); ++ii) { QmlDomProperty domProperty; domProperty.d->property = properties.at(ii).first; domProperty.d->property->addref(); domProperty.d->propertyName = properties.at(ii).second; rv << domProperty; } if (d->object->defaultProperty) { QmlDomProperty domProperty; domProperty.d->property = d->object->defaultProperty; domProperty.d->property->addref(); domProperty.d->propertyName = d->object->defaultProperty->name; rv << domProperty; } return rv; } /*! Returns the object's \a name property if a value has been assigned to it, or an invalid QmlDomProperty otherwise. In the example below, \c {object.property("source")} would return a valid QmlDomProperty, and \c {object.property("tile")} an invalid QmlDomProperty. \qml Image { source: "sample.jpg" } \endqml */ QmlDomProperty QmlDomObject::property(const QByteArray &name) const { QList props = properties(); for (int ii = 0; ii < props.count(); ++ii) if (props.at(ii).propertyName() == name) return props.at(ii); return QmlDomProperty(); } QList QmlDomObject::dynamicProperties() const { QList properties; for (int i = 0; i < d->object->dynamicProperties.size(); ++i) { QmlDomDynamicProperty p; p.d = new QmlDomDynamicPropertyPrivate; p.d->property = d->object->dynamicProperties.at(i); p.d->valid = true; if (p.d->property.defaultValue) p.d->property.defaultValue->addref(); properties.append(p); } return properties; } QmlDomDynamicProperty QmlDomObject::dynamicProperty(const QByteArray &name) const { QmlDomDynamicProperty p; if (!isValid()) return p; for (int i = 0; i < d->object->dynamicProperties.size(); ++i) { if (d->object->dynamicProperties.at(i).name == name) { p.d = new QmlDomDynamicPropertyPrivate; p.d->property = d->object->dynamicProperties.at(i); if (p.d->property.defaultValue) p.d->property.defaultValue->addref(); p.d->valid = true; } } return p; } /*! Returns true if this object is a custom type. Custom types are special types that allow embeddeding non-QML data, such as SVG or HTML data, directly into QML files. \note Currently this method will always return false, and is a placekeeper for future functionality. \sa QmlDomObject::customTypeData() */ bool QmlDomObject::isCustomType() const { return false; } /*! If this object represents a custom type, returns the data associated with the custom type, otherwise returns an empty QByteArray(). QmlDomObject::isCustomType() can be used to check if this object represents a custom type. */ QByteArray QmlDomObject::customTypeData() const { return QByteArray(); } /*! Returns true if this object is a sub-component object. Sub-component objects can be converted into QmlDomComponent instances by calling QmlDomObject::toComponent(). \sa QmlDomObject::toComponent() */ bool QmlDomObject::isComponent() const { return (d->object && d->object->typeName == "Qt/Component"); } /*! Returns a QmlDomComponent for this object if it is a sub-component, or an invalid QmlDomComponent if not. QmlDomObject::isComponent() can be used to check if this object represents a sub-component. \sa QmlDomObject::isComponent() */ QmlDomComponent QmlDomObject::toComponent() const { QmlDomComponent rv; if (isComponent()) rv.d = d; return rv; } /*! Returns the position in the input data where the property assignment started , or -1 if the property is invalid. */ int QmlDomObject::position() const { if (d && d->object) return d->object->location.range.offset; else return -1; } /*! Returns the length in the input data from where the property assignment star ted upto the end of it, or -1 if the property is invalid. */ int QmlDomObject::length() const { if (d && d->object) return d->object->location.range.length; else return -1; } // Returns the URL of the type, if it is an external type, or an empty URL if // not QUrl QmlDomObject::url() const { if (d && d->object) return d->object->url; else return QUrl(); } QmlDomBasicValuePrivate::QmlDomBasicValuePrivate() : value(0) { } QmlDomBasicValuePrivate::~QmlDomBasicValuePrivate() { if (value) value->release(); } /*! \class QmlDomValueLiteral \internal \brief The QmlDomValueLiteral class represents a literal value. A literal value is a simple value, written inline with the QML. In the example below, the "x", "y" and "color" properties are being assigned literal values. \qml Rectangle { x: 10 y: 10 color: "red" } \endqml */ /*! Construct an empty QmlDomValueLiteral. */ QmlDomValueLiteral::QmlDomValueLiteral(): d(new QmlDomBasicValuePrivate) { } /*! Create a copy of \a other QmlDomValueLiteral. */ QmlDomValueLiteral::QmlDomValueLiteral(const QmlDomValueLiteral &other) : d(other.d) { } /*! Destroy the QmlDomValueLiteral. */ QmlDomValueLiteral::~QmlDomValueLiteral() { } /*! Assign \a other to this QmlDomValueLiteral. */ QmlDomValueLiteral &QmlDomValueLiteral::operator=(const QmlDomValueLiteral &other) { d = other.d; return *this; } /*! Return the literal value. In the example below, the literal value will be the string "10". \qml Rectangle { x: 10 } \endqml */ QString QmlDomValueLiteral::literal() const { if (d->value) return d->value->primitive(); else return QString(); } /*! \class QmlDomValueBinding \internal \brief The QmlDomValueBinding class represents a property binding. A property binding is an ECMAScript expression assigned to a property. In the example below, the "x" property is being assigned a property binding. \qml Rectangle { x: Other.x } \endqml */ /*! Construct an empty QmlDomValueBinding. */ QmlDomValueBinding::QmlDomValueBinding(): d(new QmlDomBasicValuePrivate) { } /*! Create a copy of \a other QmlDomValueBinding. */ QmlDomValueBinding::QmlDomValueBinding(const QmlDomValueBinding &other) : d(other.d) { } /*! Destroy the QmlDomValueBinding. */ QmlDomValueBinding::~QmlDomValueBinding() { } /*! Assign \a other to this QmlDomValueBinding. */ QmlDomValueBinding &QmlDomValueBinding::operator=(const QmlDomValueBinding &other) { d = other.d; return *this; } /*! Return the binding expression. In the example below, the string "Other.x" will be returned. \qml Rectangle { x: Other.x } \endqml */ QString QmlDomValueBinding::binding() const { if (d->value) return d->value->value.asScript(); else return QString(); } /*! \class QmlDomValueValueSource \internal \brief The QmlDomValueValueSource class represents a value source assignment value. In QML, value sources are special value generating types that may be assigned to properties. Value sources inherit the QmlPropertyValueSource class. In the example below, the "x" property is being assigned the NumberAnimation value source. \qml Rectangle { x: NumberAnimation { from: 0 to: 100 repeat: true running: true } } \endqml */ /*! Construct an empty QmlDomValueValueSource. */ QmlDomValueValueSource::QmlDomValueValueSource(): d(new QmlDomBasicValuePrivate) { } /*! Create a copy of \a other QmlDomValueValueSource. */ QmlDomValueValueSource::QmlDomValueValueSource(const QmlDomValueValueSource &other) : d(other.d) { } /*! Destroy the QmlDomValueValueSource. */ QmlDomValueValueSource::~QmlDomValueValueSource() { } /*! Assign \a other to this QmlDomValueValueSource. */ QmlDomValueValueSource &QmlDomValueValueSource::operator=(const QmlDomValueValueSource &other) { d = other.d; return *this; } /*! Return the value source object. In the example below, an object representing the NumberAnimation will be returned. \qml Rectangle { x: NumberAnimation { from: 0 to: 100 repeat: true running: true } } \endqml */ QmlDomObject QmlDomValueValueSource::object() const { QmlDomObject rv; if (d->value) { rv.d->object = d->value->object; rv.d->object->addref(); } return rv; } /*! \class QmlDomValueValueInterceptor \internal \brief The QmlDomValueValueInterceptor class represents a value interceptor assignment value. In QML, value interceptor are special write-intercepting types that may be assigned to properties. Value interceptor inherit the QmlPropertyValueInterceptor class. In the example below, the "x" property is being assigned the Behavior value interceptor. \qml Rectangle { x: Behavior { NumberAnimation { duration: 500 } } } \endqml */ /*! Construct an empty QmlDomValueValueInterceptor. */ QmlDomValueValueInterceptor::QmlDomValueValueInterceptor(): d(new QmlDomBasicValuePrivate) { } /*! Create a copy of \a other QmlDomValueValueInterceptor. */ QmlDomValueValueInterceptor::QmlDomValueValueInterceptor(const QmlDomValueValueInterceptor &other) : d(other.d) { } /*! Destroy the QmlDomValueValueInterceptor. */ QmlDomValueValueInterceptor::~QmlDomValueValueInterceptor() { } /*! Assign \a other to this QmlDomValueValueInterceptor. */ QmlDomValueValueInterceptor &QmlDomValueValueInterceptor::operator=(const QmlDomValueValueInterceptor &other) { d = other.d; return *this; } /*! Return the value interceptor object. In the example below, an object representing the Behavior will be returned. \qml Rectangle { x: Behavior { NumberAnimation { duration: 500 } } } \endqml */ QmlDomObject QmlDomValueValueInterceptor::object() const { QmlDomObject rv; if (d->value) { rv.d->object = d->value->object; rv.d->object->addref(); } return rv; } QmlDomValuePrivate::QmlDomValuePrivate() : property(0), value(0) { } QmlDomValuePrivate::~QmlDomValuePrivate() { if (property) property->release(); if (value) value->release(); } /*! \class QmlDomValue \internal \brief The QmlDomValue class represents a generic Qml value. QmlDomValue's can be assigned to QML \l {QmlDomProperty}{properties}. In QML, properties can be assigned various different values, including basic literals, property bindings, property value sources, objects and lists of values. The QmlDomValue class allows a programmer to determine the specific value type being assigned and access more detailed information through a corresponding value type class. For example, in the following example, \qml Text { text: "Hello World!" y: Other.y } \endqml The text property is being assigned a literal, and the y property a property binding. To output the values assigned to the text and y properties in the above example from C++, \code QmlDomDocument document; QmlDomObject root = document.rootObject(); QmlDomProperty text = root.property("text"); if (text.value().isLiteral()) { QmlDomValueLiteral literal = text.value().toLiteral(); qDebug() << literal.literal(); } QmlDomProperty y = root.property("y"); if (y.value().isBinding()) { QmlDomValueBinding binding = y.value().toBinding(); qDebug() << binding.binding(); } \endcode */ /*! Construct an invalid QmlDomValue. */ QmlDomValue::QmlDomValue() : d(new QmlDomValuePrivate) { } /*! Create a copy of \a other QmlDomValue. */ QmlDomValue::QmlDomValue(const QmlDomValue &other) : d(other.d) { } /*! Destroy the QmlDomValue */ QmlDomValue::~QmlDomValue() { } /*! Assign \a other to this QmlDomValue. */ QmlDomValue &QmlDomValue::operator=(const QmlDomValue &other) { d = other.d; return *this; } /*! \enum QmlDomValue::Type The type of the QmlDomValue node. \value Invalid The QmlDomValue is invalid. \value Literal The QmlDomValue is a literal value assignment. Use QmlDomValue::toLiteral() to access the type instance. \value PropertyBinding The QmlDomValue is a property binding. Use QmlDomValue::toBinding() to access the type instance. \value ValueSource The QmlDomValue is a property value source. Use QmlDomValue::toValueSource() to access the type instance. \value ValueInterceptor The QmlDomValue is a property value interceptor. Use QmlDomValue::toValueInterceptor() to access the type instance. \value Object The QmlDomValue is an object assignment. Use QmlDomValue::toObject() to access the type instnace. \value List The QmlDomValue is a list of other values. Use QmlDomValue::toList() to access the type instance. */ /*! Returns the type of this QmlDomValue. */ QmlDomValue::Type QmlDomValue::type() const { if (d->property) if (QmlMetaType::isList(d->property->type) || QmlMetaType::isQmlList(d->property->type) || (d->property && d->property->values.count() > 1)) return List; QmlParser::Value *value = d->value; if (!value && !d->property) return Invalid; switch(value->type) { case QmlParser::Value::Unknown: return Invalid; case QmlParser::Value::Literal: return Literal; case QmlParser::Value::PropertyBinding: return PropertyBinding; case QmlParser::Value::ValueSource: return ValueSource; case QmlParser::Value::ValueInterceptor: return ValueInterceptor; case QmlParser::Value::CreatedObject: return Object; case QmlParser::Value::SignalObject: return Invalid; case QmlParser::Value::SignalExpression: return Literal; case QmlParser::Value::Id: return Literal; } return Invalid; } /*! Returns true if this is an invalid value, otherwise false. */ bool QmlDomValue::isInvalid() const { return type() == Invalid; } /*! Returns true if this is a literal value, otherwise false. */ bool QmlDomValue::isLiteral() const { return type() == Literal; } /*! Returns true if this is a property binding value, otherwise false. */ bool QmlDomValue::isBinding() const { return type() == PropertyBinding; } /*! Returns true if this is a value source value, otherwise false. */ bool QmlDomValue::isValueSource() const { return type() == ValueSource; } /*! Returns true if this is a value interceptor value, otherwise false. */ bool QmlDomValue::isValueInterceptor() const { return type() == ValueInterceptor; } /*! Returns true if this is an object value, otherwise false. */ bool QmlDomValue::isObject() const { return type() == Object; } /*! Returns true if this is a list value, otherwise false. */ bool QmlDomValue::isList() const { return type() == List; } /*! Returns a QmlDomValueLiteral if this value is a literal type, otherwise returns an invalid QmlDomValueLiteral. \sa QmlDomValue::type() */ QmlDomValueLiteral QmlDomValue::toLiteral() const { QmlDomValueLiteral rv; if (type() == Literal) { rv.d->value = d->value; rv.d->value->addref(); } return rv; } /*! Returns a QmlDomValueBinding if this value is a property binding type, otherwise returns an invalid QmlDomValueBinding. \sa QmlDomValue::type() */ QmlDomValueBinding QmlDomValue::toBinding() const { QmlDomValueBinding rv; if (type() == PropertyBinding) { rv.d->value = d->value; rv.d->value->addref(); } return rv; } /*! Returns a QmlDomValueValueSource if this value is a property value source type, otherwise returns an invalid QmlDomValueValueSource. \sa QmlDomValue::type() */ QmlDomValueValueSource QmlDomValue::toValueSource() const { QmlDomValueValueSource rv; if (type() == ValueSource) { rv.d->value = d->value; rv.d->value->addref(); } return rv; } /*! Returns a QmlDomValueValueInterceptor if this value is a property value interceptor type, otherwise returns an invalid QmlDomValueValueInterceptor. \sa QmlDomValue::type() */ QmlDomValueValueInterceptor QmlDomValue::toValueInterceptor() const { QmlDomValueValueInterceptor rv; if (type() == ValueInterceptor) { rv.d->value = d->value; rv.d->value->addref(); } return rv; } /*! Returns a QmlDomObject if this value is an object assignment type, otherwise returns an invalid QmlDomObject. \sa QmlDomValue::type() */ QmlDomObject QmlDomValue::toObject() const { QmlDomObject rv; if (type() == Object) { rv.d->object = d->value->object; rv.d->object->addref(); } return rv; } /*! Returns a QmlDomList if this value is a list type, otherwise returns an invalid QmlDomList. \sa QmlDomValue::type() */ QmlDomList QmlDomValue::toList() const { QmlDomList rv; if (type() == List) { rv.d = d; } return rv; } /*! Returns the position in the input data where the property value startd, or -1 if the value is invalid. */ int QmlDomValue::position() const { if (type() == Invalid) return -1; else return d->value->location.range.offset; } /*! Returns the length in the input data from where the property value started u pto the end of it, or -1 if the value is invalid. */ int QmlDomValue::length() const { if (type() == Invalid) return -1; else return d->value->location.range.length; } /*! \class QmlDomList \internal \brief The QmlDomList class represents a list of values assigned to a QML property. Lists of values can be assigned to properties. For example, the following example assigns multiple objects to Item's "children" property \qml Item { children: [ Text { }, Rectangle { } ] } \endqml Lists can also be implicitly created by assigning multiple \l {QmlDomValueValueSource}{value sources} or constants to a property. \qml Item { x: 10 x: NumberAnimation { running: false from: 0 to: 100 } } \endqml */ /*! Construct an empty QmlDomList. */ QmlDomList::QmlDomList() { } /*! Create a copy of \a other QmlDomList. */ QmlDomList::QmlDomList(const QmlDomList &other) : d(other.d) { } /*! Destroy the QmlDomList. */ QmlDomList::~QmlDomList() { } /*! Assign \a other to this QmlDomList. */ QmlDomList &QmlDomList::operator=(const QmlDomList &other) { d = other.d; return *this; } /*! Returns the list of QmlDomValue's. */ QList QmlDomList::values() const { QList rv; if (!d->property) return rv; for (int ii = 0; ii < d->property->values.count(); ++ii) { QmlDomValue v; v.d->value = d->property->values.at(ii); v.d->value->addref(); rv << v; } return rv; } /*! Returns the position in the input data where the list started, or -1 if the property is invalid. */ int QmlDomList::position() const { if (d && d->property) { return d->property->listValueRange.offset; } else return -1; } /*! Returns the length in the input data from where the list started upto the end of it, or 0 if the property is invalid. */ int QmlDomList::length() const { if (d && d->property) return d->property->listValueRange.length; else return -1; } /*! Returns a list of positions of the commas in the QML file. */ QList QmlDomList:: commaPositions() const { if (d && d->property) return d->property->listCommaPositions; else return QList(); } /*! \class QmlDomComponent \internal \brief The QmlDomComponent class represents sub-component within a QML document. Sub-components are QmlComponents defined within a QML document. The following example shows the definition of a sub-component with the id "listDelegate". \qml Item { Component { id: listDelegate Text { text: modelData.text } } } \endqml Like QmlDomDocument's, components contain a single root object. */ /*! Construct an empty QmlDomComponent. */ QmlDomComponent::QmlDomComponent() { } /*! Create a copy of \a other QmlDomComponent. */ QmlDomComponent::QmlDomComponent(const QmlDomComponent &other) : QmlDomObject(other) { } /*! Destroy the QmlDomComponent. */ QmlDomComponent::~QmlDomComponent() { } /*! Assign \a other to this QmlDomComponent. */ QmlDomComponent &QmlDomComponent::operator=(const QmlDomComponent &other) { static_cast(*this) = other; return *this; } /*! Returns the component's root object. In the example below, the root object is the "Text" object. \qml Item { Component { id: listDelegate Text { text: modelData.text } } } \endqml */ QmlDomObject QmlDomComponent::componentRoot() const { QmlDomObject rv; if (d->object) { QmlParser::Object *obj = 0; if (d->object->defaultProperty && d->object->defaultProperty->values.count() == 1 && d->object->defaultProperty->values.at(0)->object) obj = d->object->defaultProperty->values.at(0)->object; if (obj) { rv.d->object = obj; rv.d->object->addref(); } } return rv; } QmlDomImportPrivate::QmlDomImportPrivate() : type(File) { } QmlDomImportPrivate::~QmlDomImportPrivate() { } /*! \class QmlDomImport \internal \brief The QmlDomImport class represents an import statement. */ /*! Construct an empty QmlDomImport. */ QmlDomImport::QmlDomImport() : d(new QmlDomImportPrivate) { } /*! Create a copy of \a other QmlDomImport. */ QmlDomImport::QmlDomImport(const QmlDomImport &other) : d(other.d) { } /*! Destroy the QmlDomImport. */ QmlDomImport::~QmlDomImport() { } /*! Assign \a other to this QmlDomImport. */ QmlDomImport &QmlDomImport::operator=(const QmlDomImport &other) { d = other.d; return *this; } /*! Returns the type of the import. */ QmlDomImport::Type QmlDomImport::type() const { return static_cast(d->type); } /*! Returns the URI of the import (e.g. 'subdir' or 'com.nokia.Qt') */ QString QmlDomImport::uri() const { return d->uri; } /*! Returns the version specified by the import. An empty string if no version was specified. */ QString QmlDomImport::version() const { return d->version; } /*! Returns the (optional) qualifier string (the token following the 'as' keyword) of the import. */ QString QmlDomImport::qualifier() const { return d->qualifier; } QT_END_NAMESPACE