From dba327eec1a308e61c2bd21941ba982fb9283827 Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Tue, 30 Jun 2009 14:39:52 +1000 Subject: Add a simple folder model. --- src/declarative/extra/extra.pri | 2 + src/declarative/extra/qmlfolderlistmodel.cpp | 178 +++++++++++++++++++++++++++ src/declarative/extra/qmlfolderlistmodel.h | 100 +++++++++++++++ 3 files changed, 280 insertions(+) create mode 100644 src/declarative/extra/qmlfolderlistmodel.cpp create mode 100644 src/declarative/extra/qmlfolderlistmodel.h diff --git a/src/declarative/extra/extra.pri b/src/declarative/extra/extra.pri index 2590fbc..7244f98 100644 --- a/src/declarative/extra/extra.pri +++ b/src/declarative/extra/extra.pri @@ -2,12 +2,14 @@ SOURCES += \ extra/qnumberformat.cpp \ extra/qmlnumberformatter.cpp \ extra/qfxintegermodel.cpp \ + extra/qmlfolderlistmodel.cpp \ extra/qmltimer.cpp HEADERS += \ extra/qnumberformat.h \ extra/qmlnumberformatter.h \ extra/qfxintegermodel.h \ + extra/qmlfolderlistmodel.h \ extra/qmltimer.h contains(QT_CONFIG, xmlpatterns) { diff --git a/src/declarative/extra/qmlfolderlistmodel.cpp b/src/declarative/extra/qmlfolderlistmodel.cpp new file mode 100644 index 0000000..43ffd5c --- /dev/null +++ b/src/declarative/extra/qmlfolderlistmodel.cpp @@ -0,0 +1,178 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.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 the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "private/qobject_p.h" +#include +#include +#include "qmlfolderlistmodel.h" + +QT_BEGIN_NAMESPACE + +QT_MODULE(Declarative) + +class QmlFolderListModelPrivate : public QObjectPrivate +{ +public: + QmlFolderListModelPrivate() { + folderIndex = model.index(0,0); + } + + QDirModel model; + QString folder; + QStringList nameFilters; + QModelIndex folderIndex; +}; + +QmlFolderListModel::QmlFolderListModel(QObject *parent) + : QListModelInterface(*(new QmlFolderListModelPrivate), parent) +{ + Q_D(QmlFolderListModel); + d->model.setFilter(QDir::AllDirs | QDir::Files | QDir::Drives); + connect(&d->model, SIGNAL(rowsInserted(const QModelIndex&,int,int)) + , this, SLOT(inserted(const QModelIndex&,int,int))); +} + +QmlFolderListModel::~QmlFolderListModel() +{ +} + +QHash QmlFolderListModel::data(int index, const QList &roles) const +{ + Q_D(const QmlFolderListModel); + QHash folderData; + QModelIndex modelIndex = d->model.index(index, 0, d->folderIndex); + if (modelIndex.isValid()) { + folderData[QDirModel::FileNameRole] = d->model.data(modelIndex, QDirModel::FileNameRole); + folderData[QDirModel::FilePathRole] = d->model.data(modelIndex, QDirModel::FilePathRole); + } + + return folderData; +} + +int QmlFolderListModel::count() const +{ + Q_D(const QmlFolderListModel); + if (!d->folderIndex.isValid()) + return 0; + return d->model.rowCount(d->folderIndex); +} + +QList QmlFolderListModel::roles() const +{ + QList r; + r << QDirModel::FileNameRole; + r << QDirModel::FilePathRole; + return r; +} + +QString QmlFolderListModel::toString(int role) const +{ + switch (role) { + case QDirModel::FileNameRole: + return QLatin1String("fileName"); + case QDirModel::FilePathRole: + return QLatin1String("filePath"); + } + + return QString(); +} + +QString QmlFolderListModel::folder() const +{ + Q_D(const QmlFolderListModel); + return d->folder; +} + +void QmlFolderListModel::setFolder(const QString &folder) +{ + Q_D(QmlFolderListModel); + QModelIndex index = d->model.index(folder); + if (index.isValid() && d->model.isDir(index)) { + d->folder = folder; + QMetaObject::invokeMethod(this, "refresh", Qt::QueuedConnection); + } +} + +QStringList QmlFolderListModel::nameFilters() const +{ + Q_D(const QmlFolderListModel); + return d->nameFilters; +} + +void QmlFolderListModel::setNameFilters(const QStringList &filters) +{ + Q_D(QmlFolderListModel); + d->nameFilters = filters; + QMetaObject::invokeMethod(this, "refresh", Qt::QueuedConnection); +} + +void QmlFolderListModel::classComplete() +{ +} + +bool QmlFolderListModel::isFolder(int index) const +{ + Q_D(const QmlFolderListModel); + return d->model.isDir(d->model.index(index, 0, d->folderIndex)); +} + +void QmlFolderListModel::refresh() +{ + Q_D(QmlFolderListModel); + int prevCount = count(); + d->folderIndex = QModelIndex(); + emit itemsRemoved(0, prevCount); + d->folderIndex = d->model.index(d->folder); + emit itemsInserted(0, count()); +} + +void QmlFolderListModel::inserted(const QModelIndex &index, int start, int end) +{ + Q_D(QmlFolderListModel); + qDebug() << "inserted" << start << end; + if (index == d->folderIndex) + emit itemsInserted(start, end - start + 1); +} + +QML_DEFINE_TYPE(QmlFolderListModel,FolderListModel) + +QT_END_NAMESPACE + diff --git a/src/declarative/extra/qmlfolderlistmodel.h b/src/declarative/extra/qmlfolderlistmodel.h new file mode 100644 index 0000000..c8b605a --- /dev/null +++ b/src/declarative/extra/qmlfolderlistmodel.h @@ -0,0 +1,100 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.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 the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QMLFOLDERLISTMODEL_H +#define QMLFOLDERLISTMODEL_H + +#include +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Declarative) + +class QmlContext; +class QModelIndex; + +class QmlFolderListModelPrivate; +class Q_DECLARATIVE_EXPORT QmlFolderListModel : public QListModelInterface, public QmlParserStatus +{ + Q_OBJECT + Q_INTERFACES(QmlParserStatus) + + Q_PROPERTY(QString folder READ folder WRITE setFolder) + Q_PROPERTY(QStringList nameFilters READ nameFilters WRITE setNameFilters) + +public: + QmlFolderListModel(QObject *parent = 0); + ~QmlFolderListModel(); + + virtual QHash data(int index, const QList &roles = (QList())) const; + virtual int count() const; + virtual QList roles() const; + virtual QString toString(int role) const; + + QString folder() const; + void setFolder(const QString &folder); + + QStringList nameFilters() const; + void setNameFilters(const QStringList &filters); + + virtual void classComplete(); + + Q_INVOKABLE bool isFolder(int index) const; + +private Q_SLOTS: + void refresh(); + void inserted(const QModelIndex &index, int start, int end); + +private: + Q_DECLARE_PRIVATE(QmlFolderListModel) + Q_DISABLE_COPY(QmlFolderListModel) +}; + +QML_DECLARE_TYPE(QmlFolderListModel) + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QMLFOLDERLISTMODEL_H -- cgit v0.12 From 5732bf283683f0444dbec740cc26c995d9464de6 Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Tue, 30 Jun 2009 16:26:44 +1000 Subject: Simple QML browser/loader. --- examples/declarative/loader/loader.pro | 9 ++++++ examples/declarative/loader/loader.qml | 41 ++++++++++++++++++++++++++++ examples/declarative/loader/loader.qrc | 5 ++++ examples/declarative/loader/main.cpp | 18 ++++++++++++ src/declarative/extra/qmlfolderlistmodel.cpp | 18 +++++++++--- src/declarative/extra/qmlfolderlistmodel.h | 5 +++- 6 files changed, 91 insertions(+), 5 deletions(-) create mode 100644 examples/declarative/loader/loader.pro create mode 100644 examples/declarative/loader/loader.qml create mode 100644 examples/declarative/loader/loader.qrc create mode 100644 examples/declarative/loader/main.cpp diff --git a/examples/declarative/loader/loader.pro b/examples/declarative/loader/loader.pro new file mode 100644 index 0000000..baa5b8c --- /dev/null +++ b/examples/declarative/loader/loader.pro @@ -0,0 +1,9 @@ +SOURCES = main.cpp +RESOURCES = loader.qrc + +QT += script declarative + +target.path = $$[QT_INSTALL_EXAMPLES]/declarative/loader +sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS loader.pro +sources.path = $$[QT_INSTALL_EXAMPLES]/declarative/loader +INSTALLS += target sources diff --git a/examples/declarative/loader/loader.qml b/examples/declarative/loader/loader.qml new file mode 100644 index 0000000..4dd7a03 --- /dev/null +++ b/examples/declarative/loader/loader.qml @@ -0,0 +1,41 @@ +Rect { + id: Root + width: 300 + height: 400 + FolderListModel { + id: folders + nameFilters: [ "*.qml" ] + } + + Component { + id: FolderDelegate + Text { + id: Wrapper + width: Root.width + text: fileName + font.bold: true + font.size: 14 + MouseRegion { + anchors.fill: parent + onClicked: { + if (folders.isFolder(index)) { + folders.folder = filePath; + } else { + Root.qml = filePath; + } + } + } + } + } + + Text { id: DirText; text: folders.folder } + + ListView { + anchors.top: DirText.bottom + anchors.left: parent.left + anchors.right: parent.right + anchors.bottom: parent.bottom + model: folders + delegate: FolderDelegate + } +} diff --git a/examples/declarative/loader/loader.qrc b/examples/declarative/loader/loader.qrc new file mode 100644 index 0000000..8c80052 --- /dev/null +++ b/examples/declarative/loader/loader.qrc @@ -0,0 +1,5 @@ + + + loader.qml + + diff --git a/examples/declarative/loader/main.cpp b/examples/declarative/loader/main.cpp new file mode 100644 index 0000000..31bff07 --- /dev/null +++ b/examples/declarative/loader/main.cpp @@ -0,0 +1,18 @@ +#include +#include +#include + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + + QFxView *canvas = new QFxView; + canvas->setUrl(QUrl("qrc:/loader.qml")); + canvas->execute(); + canvas->resize(210,240); + canvas->show(); + + return app.exec(); +} + + diff --git a/src/declarative/extra/qmlfolderlistmodel.cpp b/src/declarative/extra/qmlfolderlistmodel.cpp index 43ffd5c..abec01e 100644 --- a/src/declarative/extra/qmlfolderlistmodel.cpp +++ b/src/declarative/extra/qmlfolderlistmodel.cpp @@ -52,7 +52,8 @@ class QmlFolderListModelPrivate : public QObjectPrivate { public: QmlFolderListModelPrivate() { - folderIndex = model.index(0,0); + folder = QDir::currentPath(); + nameFilters << "*"; } QDirModel model; @@ -124,10 +125,13 @@ QString QmlFolderListModel::folder() const void QmlFolderListModel::setFolder(const QString &folder) { Q_D(QmlFolderListModel); + if (folder == d->folder) + return; QModelIndex index = d->model.index(folder); if (index.isValid() && d->model.isDir(index)) { d->folder = folder; QMetaObject::invokeMethod(this, "refresh", Qt::QueuedConnection); + emit folderChanged(); } } @@ -141,11 +145,14 @@ void QmlFolderListModel::setNameFilters(const QStringList &filters) { Q_D(QmlFolderListModel); d->nameFilters = filters; - QMetaObject::invokeMethod(this, "refresh", Qt::QueuedConnection); + d->model.setNameFilters(d->nameFilters); } void QmlFolderListModel::classComplete() { + Q_D(QmlFolderListModel); + if (!d->folderIndex.isValid()) + QMetaObject::invokeMethod(this, "refresh", Qt::QueuedConnection); } bool QmlFolderListModel::isFolder(int index) const @@ -159,9 +166,12 @@ void QmlFolderListModel::refresh() Q_D(QmlFolderListModel); int prevCount = count(); d->folderIndex = QModelIndex(); - emit itemsRemoved(0, prevCount); + if (prevCount) + emit itemsRemoved(0, prevCount); d->folderIndex = d->model.index(d->folder); - emit itemsInserted(0, count()); + qDebug() << "count" << count(); + if (count()) + emit itemsInserted(0, count()); } void QmlFolderListModel::inserted(const QModelIndex &index, int start, int end) diff --git a/src/declarative/extra/qmlfolderlistmodel.h b/src/declarative/extra/qmlfolderlistmodel.h index c8b605a..a6e8526 100644 --- a/src/declarative/extra/qmlfolderlistmodel.h +++ b/src/declarative/extra/qmlfolderlistmodel.h @@ -60,7 +60,7 @@ class Q_DECLARATIVE_EXPORT QmlFolderListModel : public QListModelInterface, publ Q_OBJECT Q_INTERFACES(QmlParserStatus) - Q_PROPERTY(QString folder READ folder WRITE setFolder) + Q_PROPERTY(QString folder READ folder WRITE setFolder NOTIFY folderChanged) Q_PROPERTY(QStringList nameFilters READ nameFilters WRITE setNameFilters) public: @@ -82,6 +82,9 @@ public: Q_INVOKABLE bool isFolder(int index) const; +Q_SIGNALS: + void folderChanged(); + private Q_SLOTS: void refresh(); void inserted(const QModelIndex &index, int start, int end); -- cgit v0.12 From 7cba48bea33dcb80979975b27047d81025d054a5 Mon Sep 17 00:00:00 2001 From: Erik Verbruggen Date: Tue, 30 Jun 2009 10:38:45 +0200 Subject: First set of changes to add dynamic properties to the QML DOM. --- src/declarative/qml/qmldom.cpp | 248 +++++++++++++++++++++++++++++--- src/declarative/qml/qmldom.h | 31 ++++ src/declarative/qml/qmldom_p.h | 11 ++ src/declarative/qml/qmlparser.cpp | 3 +- src/declarative/qml/qmlparser_p.h | 1 + src/declarative/qml/qmlscriptparser.cpp | 2 + 6 files changed, 273 insertions(+), 23 deletions(-) diff --git a/src/declarative/qml/qmldom.cpp b/src/declarative/qml/qmldom.cpp index 5271dc5..d517b39 100644 --- a/src/declarative/qml/qmldom.cpp +++ b/src/declarative/qml/qmldom.cpp @@ -278,6 +278,23 @@ QmlDomPropertyPrivate::~QmlDomPropertyPrivate() if (property) property->release(); } +QmlDomDynamicPropertyPrivate::QmlDomDynamicPropertyPrivate(): + valid(false) +{ +} + +QmlDomDynamicPropertyPrivate::QmlDomDynamicPropertyPrivate(const QmlDomDynamicPropertyPrivate &other) +: QSharedData(other), valid(other.valid) +{ + property = other.property; + if (valid && property.defaultValue) property.defaultValue->addref(); +} + +QmlDomDynamicPropertyPrivate::~QmlDomDynamicPropertyPrivate() +{ + if (valid && property.defaultValue) property.defaultValue->release(); +} + /*! \class QmlDomProperty \internal @@ -322,8 +339,8 @@ QmlDomProperty &QmlDomProperty::operator=(const QmlDomProperty &other) } /*! - Return the name of this property. - + Return the name of this property. + \qml Text { x: 10 @@ -331,7 +348,7 @@ Text { 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. @@ -358,7 +375,7 @@ Text { } \endqml - For each of the properties shown above, this method would return ("x"), + For each of the properties shown above, this method would return ("x"), ("y") and ("font", "bold"). \sa QmlDomProperty::propertyName() @@ -370,7 +387,7 @@ QList QmlDomProperty::propertyNameParts() const } /*! - Return true if this property is used as a default property in the QML + Return true if this property is used as a default property in the QML document. \qml @@ -380,8 +397,8 @@ QList QmlDomProperty::propertyNameParts() const 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 + 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 @@ -415,7 +432,7 @@ void QmlDomProperty::setValue(const QmlDomValue &value) } /*! - Returns the position in the input data where the property ID startd, or 0 if + Returns the position in the input data where the property ID startd, or -1 if the property is invalid. */ int QmlDomProperty::position() const @@ -423,19 +440,174 @@ int QmlDomProperty::position() const if (d && d->property) { return d->property->location.range.offset; } else - return 0; + 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. + 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 0; + 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(); +} + +QVariant::Type QmlDomDynamicProperty::propertyType() const +{ + if (isValid()) { + switch (d->property.type) { + case QmlParser::Object::DynamicProperty::Bool: + return QVariant::Bool; + + case QmlParser::Object::DynamicProperty::Color: + return QVariant::Color; + + case QmlParser::Object::DynamicProperty::Date: + return QVariant::Date; + + case QmlParser::Object::DynamicProperty::Int: + return QVariant::Int; + + case QmlParser::Object::DynamicProperty::Real: + return QVariant::Double; + + case QmlParser::Object::DynamicProperty::String: + return QVariant::String; + + case QmlParser::Object::DynamicProperty::Url: + return QVariant::Url; + + case QmlParser::Object::DynamicProperty::Variant: + return QVariant:: + + default: + return QVariant::Invalid; + } + } else { + return QVariant::Invalid; + } +} + +/*! + 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()) { + rp.d->property = d->property.defaultValue; + rp.d->property->addref(); + } + + return rp; +} + +/*! + 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.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.range.length; + else + return -1; } QmlDomObjectPrivate::QmlDomObjectPrivate() @@ -701,6 +873,38 @@ void QmlDomObject::addProperty(const QByteArray &name, const QmlDomValue &value) qWarning("QmlDomObject::addProperty(const QByteArray &, const QmlDomValue &): Not implemented"); } +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); + if (p.d->property.defaultValue) p.d->property.defaultValue->addref(); + p.d->valid = true; + properties.append(p); + } + + return properties; +} + +QmlDomDynamicProperty QmlDomObject::dynamicProperty(const QByteArray &name) const +{ + QmlDomDynamicProperty 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, @@ -769,26 +973,26 @@ QmlDomComponent QmlDomObject::toComponent() const /*! Returns the position in the input data where the property assignment started -, or 0 if the property is invalid. +, or -1 if the property is invalid. */ int QmlDomObject::position() const { if (d && d->object) return d->object->location.range.offset; else - return 0; + return -1; } /*! Returns the length in the input data from where the property assignment star -ted upto the end of it, or 0 if the property is invalid. +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 0; + return -1; } // Returns the URL of the type, if it is an external type, or an empty URL if @@ -1323,25 +1527,25 @@ QmlDomList QmlDomValue::toList() const } /*! - Returns the position in the input data where the property value startd, or 0 + 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 0; + 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 0 if the value is invalid. +pto the end of it, or -1 if the value is invalid. */ int QmlDomValue::length() const { if (type() == Invalid) - return 0; + return -1; else return d->value->location.range.length; } @@ -1436,7 +1640,7 @@ void QmlDomList::setValues(const QList &values) } /*! - Returns the position in the input data where the list started, or 0 if + Returns the position in the input data where the list started, or -1 if the property is invalid. */ int QmlDomList::position() const @@ -1444,7 +1648,7 @@ int QmlDomList::position() const if (d && d->property) { return d->property->listValueRange.offset; } else - return 0; + return -1; } /*! @@ -1456,7 +1660,7 @@ int QmlDomList::length() const if (d && d->property) return d->property->listValueRange.length; else - return 0; + return -1; } /*! diff --git a/src/declarative/qml/qmldom.h b/src/declarative/qml/qmldom.h index ab3e39f..1dddb5f 100644 --- a/src/declarative/qml/qmldom.h +++ b/src/declarative/qml/qmldom.h @@ -44,6 +44,7 @@ #include #include +#include #include QT_BEGIN_HEADER @@ -107,9 +108,36 @@ public: private: friend class QmlDomObject; + friend class QmlDomDynamicProperty; QSharedDataPointer d; }; +class QmlDomDynamicPropertyPrivate; +class Q_DECLARATIVE_EXPORT QmlDomDynamicProperty +{ +public: + QmlDomDynamicProperty(); + QmlDomDynamicProperty(const QmlDomDynamicProperty &); + ~QmlDomDynamicProperty(); + QmlDomDynamicProperty &operator=(const QmlDomDynamicProperty &); + + bool isValid() const; + + QByteArray propertyName() const; + QVariant::Type propertyType() const; + + bool isDefaultProperty() const; + + QmlDomProperty defaultValue() const; + + int position() const; + int length() const; + +private: + friend class QmlDomObject; + QSharedDataPointer d; +}; + class QmlDomObjectPrivate; class Q_DECLARATIVE_EXPORT QmlDomObject { @@ -133,6 +161,9 @@ public: void removeProperty(const QByteArray &); void addProperty(const QByteArray &, const QmlDomValue &); + QList dynamicProperties() const; + QmlDomDynamicProperty dynamicProperty(const QByteArray &) const; + bool isCustomType() const; QByteArray customTypeData() const; void setCustomTypeData(const QByteArray &); diff --git a/src/declarative/qml/qmldom_p.h b/src/declarative/qml/qmldom_p.h index 441269c..6a7032e 100644 --- a/src/declarative/qml/qmldom_p.h +++ b/src/declarative/qml/qmldom_p.h @@ -91,6 +91,17 @@ public: QmlParser::Property *property; }; +class QmlDomDynamicPropertyPrivate : public QSharedData +{ +public: + QmlDomDynamicPropertyPrivate(); + QmlDomDynamicPropertyPrivate(const QmlDomDynamicPropertyPrivate &); + ~QmlDomDynamicPropertyPrivate(); + + bool valid; + QmlParser::Object::DynamicProperty property; +}; + class QmlDomValuePrivate : public QSharedData { public: diff --git a/src/declarative/qml/qmlparser.cpp b/src/declarative/qml/qmlparser.cpp index 5ad4a6e..6f0b0b7 100644 --- a/src/declarative/qml/qmlparser.cpp +++ b/src/declarative/qml/qmlparser.cpp @@ -113,7 +113,8 @@ QmlParser::Object::DynamicProperty::DynamicProperty(const DynamicProperty &o) : isDefaultProperty(o.isDefaultProperty), type(o.type), name(o.name), - defaultValue(o.defaultValue) + defaultValue(o.defaultValue), + range(o.range) { } diff --git a/src/declarative/qml/qmlparser_p.h b/src/declarative/qml/qmlparser_p.h index 78040da..29a9390 100644 --- a/src/declarative/qml/qmlparser_p.h +++ b/src/declarative/qml/qmlparser_p.h @@ -139,6 +139,7 @@ namespace QmlParser Type type; QByteArray name; QmlParser::Property *defaultValue; + LocationRange range; }; struct DynamicSignal { DynamicSignal(); diff --git a/src/declarative/qml/qmlscriptparser.cpp b/src/declarative/qml/qmlscriptparser.cpp index fb7492d..f1d4fd2 100644 --- a/src/declarative/qml/qmlscriptparser.cpp +++ b/src/declarative/qml/qmlscriptparser.cpp @@ -532,6 +532,8 @@ bool ProcessAST::visit(AST::UiPublicMember *node) property.isDefaultProperty = node->isDefaultMember; property.type = type; property.name = name.toUtf8(); + property.range.offset = node->firstSourceLocation().offset; + property.range.length = node->semicolonToken.end() - property.range.offset; if (node->expression) { // default value property.defaultValue = new Property; -- cgit v0.12 From 028a6a00c5653c6dc0641b215287e33b8312d7a7 Mon Sep 17 00:00:00 2001 From: Erik Verbruggen Date: Tue, 30 Jun 2009 13:17:19 +0200 Subject: Fixes for the dynamic properties in the QML DOM. --- src/declarative/qml/qmldom.cpp | 31 +++++++++++++++++-------------- src/declarative/qml/qmldom.h | 3 +-- 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/src/declarative/qml/qmldom.cpp b/src/declarative/qml/qmldom.cpp index 053ea14..9015e5c 100644 --- a/src/declarative/qml/qmldom.cpp +++ b/src/declarative/qml/qmldom.cpp @@ -512,40 +512,40 @@ QByteArray QmlDomDynamicProperty::propertyName() const return QByteArray(); } -QVariant::Type QmlDomDynamicProperty::propertyType() const +int QmlDomDynamicProperty::propertyType() const { if (isValid()) { switch (d->property.type) { case QmlParser::Object::DynamicProperty::Bool: - return QVariant::Bool; + return QMetaType::type("bool"); case QmlParser::Object::DynamicProperty::Color: - return QVariant::Color; + return QMetaType::type("QColor"); case QmlParser::Object::DynamicProperty::Date: - return QVariant::Date; + return QMetaType::type("QDateTime"); case QmlParser::Object::DynamicProperty::Int: - return QVariant::Int; + return QMetaType::type("int"); case QmlParser::Object::DynamicProperty::Real: - return QVariant::Double; + return QMetaType::type("double"); case QmlParser::Object::DynamicProperty::String: - return QVariant::String; + return QMetaType::type("QString"); case QmlParser::Object::DynamicProperty::Url: - return QVariant::Url; + return QMetaType::type("QUrl"); case QmlParser::Object::DynamicProperty::Variant: - return QVariant:: + return QMetaType::type("QVariant"); default: - return QVariant::Invalid; + break; } - } else { - return QVariant::Invalid; } + + return -1; } /*! @@ -578,7 +578,7 @@ QmlDomProperty QmlDomDynamicProperty::defaultValue() const { QmlDomProperty rp; - if (isValid()) { + if (isValid() && d->property.defaultValue) { rp.d->property = d->property.defaultValue; rp.d->property->addref(); } @@ -881,8 +881,11 @@ QList QmlDomObject::dynamicProperties() const QmlDomDynamicProperty p; 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; + + if (p.d->property.defaultValue) + p.d->property.defaultValue->addref(); + properties.append(p); } diff --git a/src/declarative/qml/qmldom.h b/src/declarative/qml/qmldom.h index 1dddb5f..170ef56 100644 --- a/src/declarative/qml/qmldom.h +++ b/src/declarative/qml/qmldom.h @@ -44,7 +44,6 @@ #include #include -#include #include QT_BEGIN_HEADER @@ -124,7 +123,7 @@ public: bool isValid() const; QByteArray propertyName() const; - QVariant::Type propertyType() const; + int propertyType() const; bool isDefaultProperty() const; -- cgit v0.12