diff options
author | Qt Continuous Integration System <qt-info@nokia.com> | 2010-03-21 15:55:57 (GMT) |
---|---|---|
committer | Qt Continuous Integration System <qt-info@nokia.com> | 2010-03-21 15:55:57 (GMT) |
commit | 83f6232cadb5bfeeeec170bb17224c4032031dd7 (patch) | |
tree | d9fc3ad22afe7025d5e12114a5ade35e27cefe97 | |
parent | 9dbba618af3b505c0aac590d0b0ec32eabb76d76 (diff) | |
parent | dc6f3d03d88e8cf7b3b7940ef76ab8151f8588ce (diff) | |
download | Qt-83f6232cadb5bfeeeec170bb17224c4032031dd7.zip Qt-83f6232cadb5bfeeeec170bb17224c4032031dd7.tar.gz Qt-83f6232cadb5bfeeeec170bb17224c4032031dd7.tar.bz2 |
Merge branch '4.7' of scm.dev.nokia.troll.no:qt/qt-qml into 4.7-integration
* '4.7' of scm.dev.nokia.troll.no:qt/qt-qml:
Reduce amount of qmldir parsing
Fix local type lookup
Initialize variable.
Setting stacking order from top to bottom seems to work better.
Don't crash if an out of bounds model index is accessed.
15 files changed, 86 insertions, 60 deletions
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 <TypeName> <File> +\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/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)); } } 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) { 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.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..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) @@ -94,15 +93,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<Component> components() const; @@ -120,6 +121,9 @@ private: unsigned _isParsed: 1; }; +typedef QList<QDeclarativeDirParser::Component> QDeclarativeDirComponents; + + QT_END_NAMESPACE #endif // QDECLARATIVEDIRPARSER_P_H diff --git a/src/declarative/qml/qdeclarativeengine.cpp b/src/declarative/qml/qdeclarativeengine.cpp index 800434a..f49b17d 100644 --- a/src/declarative/qml/qdeclarativeengine.cpp +++ b/src/declarative/qml/qdeclarativeengine.cpp @@ -1361,9 +1361,10 @@ struct QDeclarativeEnginePrivate::ImportedNamespace { QList<int> majversions; QList<int> minversions; QList<bool> isLibrary; - QList<QString> qmlDirContent; + QList<QDeclarativeDirComponents> qmlDirComponents; - 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<urls.count(); ++i) { int vmaj = majversions.at(i); @@ -1383,23 +1384,22 @@ 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)) { + 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; } } @@ -1434,22 +1434,22 @@ public: QSet<QString> 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); @@ -1465,7 +1465,7 @@ public: } } } - return qmldircontent; + return qmldirParser.components(); } QString resolvedUri(const QString &dir_arg, QDeclarativeEngine *engine) @@ -1512,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()) { @@ -1566,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); @@ -1597,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; } @@ -1617,7 +1617,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 +1627,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) @@ -1970,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<QDeclarativeEnginePrivate *>(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 <QtScript/QScriptClass> #include <QtScript/QScriptValue> @@ -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, 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 &); 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" |