diff options
author | Liang Qi <liang.qi@nokia.com> | 2011-10-25 12:56:51 (GMT) |
---|---|---|
committer | Liang Qi <liang.qi@nokia.com> | 2011-10-25 12:56:51 (GMT) |
commit | bd0258ed73ecee28fba4c21027b2c2afd1b6af39 (patch) | |
tree | 136e780c13e0019382a315758d20e8ea43cf1c2d /src/declarative | |
parent | cb4eb590d4af9978a0d60402f3c4ab99b6f4ede4 (diff) | |
parent | ec6543371108bbe24fb8d98eb1ff057c641a0e9d (diff) | |
download | Qt-bd0258ed73ecee28fba4c21027b2c2afd1b6af39.zip Qt-bd0258ed73ecee28fba4c21027b2c2afd1b6af39.tar.gz Qt-bd0258ed73ecee28fba4c21027b2c2afd1b6af39.tar.bz2 |
Merge remote-tracking branch 'origin/4.7' into qt-4.8-from-4.7
Conflicts:
src/corelib/kernel/qeventdispatcher_symbian.cpp
src/declarative/qml/qdeclarativetypeloader.cpp
src/imports/gestures/gestures.pro
src/imports/particles/particles.pro
src/opengl/qgl.cpp
src/opengl/qgl_p.h
src/s60installs/bwins/QtGuiu.def
src/s60installs/eabi/QtGuiu.def
tests/auto/declarative/qdeclarativescriptdebugging/qdeclarativescriptdebugging.pro
tests/auto/declarative/qdeclarativewebview/qdeclarativewebview.pro
tests/auto/qaudioinput/qaudioinput.pro
tests/auto/qaudiooutput/qaudiooutput.pro
tests/auto/qchar/qchar.pro
tests/auto/qclipboard/test/test.pro
tests/auto/qsound/qsound.pro
Diffstat (limited to 'src/declarative')
-rw-r--r-- | src/declarative/graphicsitems/qdeclarativegridview.cpp | 33 | ||||
-rw-r--r-- | src/declarative/graphicsitems/qdeclarativelistview.cpp | 14 | ||||
-rw-r--r-- | src/declarative/qml/qdeclarativedirparser.cpp | 40 | ||||
-rw-r--r-- | src/declarative/qml/qdeclarativedirparser_p.h | 6 | ||||
-rw-r--r-- | src/declarative/qml/qdeclarativeimport.cpp | 112 | ||||
-rw-r--r-- | src/declarative/qml/qdeclarativeimport_p.h | 2 | ||||
-rw-r--r-- | src/declarative/qml/qdeclarativetypeloader.cpp | 94 | ||||
-rw-r--r-- | src/declarative/qml/qdeclarativetypeloader_p.h | 9 | ||||
-rw-r--r-- | src/declarative/util/qdeclarativepropertychanges.cpp | 5 |
9 files changed, 235 insertions, 80 deletions
diff --git a/src/declarative/graphicsitems/qdeclarativegridview.cpp b/src/declarative/graphicsitems/qdeclarativegridview.cpp index a7d593a..0a74910 100644 --- a/src/declarative/graphicsitems/qdeclarativegridview.cpp +++ b/src/declarative/graphicsitems/qdeclarativegridview.cpp @@ -1083,25 +1083,29 @@ void QDeclarativeGridViewPrivate::fixup(AxisData &data, qreal minExtent, qreal m tempPosition -= bias; } FxGridItem *topItem = snapItemAt(tempPosition+highlightStart); + if (!topItem && strictHighlightRange && currentItem) { + // StrictlyEnforceRange always keeps an item in range + updateHighlight(); + topItem = currentItem; + } FxGridItem *bottomItem = snapItemAt(tempPosition+highlightEnd); + if (!bottomItem && strictHighlightRange && currentItem) { + // StrictlyEnforceRange always keeps an item in range + updateHighlight(); + bottomItem = currentItem; + } qreal pos; - if (topItem && bottomItem && strictHighlightRange) { - qreal topPos = qMin(topItem->rowPos() - highlightStart, -maxExtent); - qreal bottomPos = qMax(bottomItem->rowPos() - highlightEnd, -minExtent); - pos = qAbs(data.move + topPos) < qAbs(data.move + bottomPos) ? topPos : bottomPos; - } else if (topItem) { - qreal headerPos = 0; - if (header) - headerPos = isRightToLeftTopToBottom() ? header->rowPos() + cellWidth - headerSize() : header->rowPos(); - if (topItem->index == 0 && header && tempPosition+highlightStart < headerPos+headerSize()/2 && !strictHighlightRange) { - pos = isRightToLeftTopToBottom() ? - headerPos + highlightStart - size() : headerPos - highlightStart; + bool isInBounds = -position() > maxExtent && -position() <= minExtent; + if (topItem && (isInBounds || strictHighlightRange)) { + if (topItem->index == 0 && header && tempPosition+highlightStart < header->rowPos()+headerSize()/2 && !strictHighlightRange) { + pos = isRightToLeftTopToBottom() ? - header->rowPos() + highlightStart - size() : header->rowPos() - highlightStart; } else { if (isRightToLeftTopToBottom()) pos = qMax(qMin(-topItem->rowPos() + highlightStart - size(), -maxExtent), -minExtent); else pos = qMax(qMin(topItem->rowPos() - highlightStart, -maxExtent), -minExtent); } - } else if (bottomItem) { + } else if (bottomItem && isInBounds) { if (isRightToLeftTopToBottom()) pos = qMax(qMin(-bottomItem->rowPos() + highlightEnd - size(), -maxExtent), -minExtent); else @@ -2247,9 +2251,10 @@ qreal QDeclarativeGridView::minXExtent() const qreal extent = -d->startPosition(); qreal highlightStart; qreal highlightEnd; - qreal endPositionFirstItem; + qreal endPositionFirstItem = 0; if (d->isRightToLeftTopToBottom()) { - endPositionFirstItem = d->rowPosAt(d->model->count()-1); + if (d->model && d->model->count()) + endPositionFirstItem = d->rowPosAt(d->model->count()-1); highlightStart = d->highlightRangeStartValid ? d->highlightRangeStart - (d->lastPosition()-endPositionFirstItem) : d->size() - (d->lastPosition()-endPositionFirstItem); @@ -2264,7 +2269,7 @@ qreal QDeclarativeGridView::minXExtent() const extent += d->header->item->width(); } if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) { - extent += highlightStart; + extent += d->isRightToLeftTopToBottom() ? -highlightStart : highlightStart; extent = qMax(extent, -(endPositionFirstItem - highlightEnd)); } return extent; diff --git a/src/declarative/graphicsitems/qdeclarativelistview.cpp b/src/declarative/graphicsitems/qdeclarativelistview.cpp index 44d6a1a..7638b2b 100644 --- a/src/declarative/graphicsitems/qdeclarativelistview.cpp +++ b/src/declarative/graphicsitems/qdeclarativelistview.cpp @@ -1326,10 +1326,20 @@ void QDeclarativeListViewPrivate::fixup(AxisData &data, qreal minExtent, qreal m tempPosition -= bias; } FxListItem *topItem = snapItemAt(tempPosition+highlightStart); + if (!topItem && strictHighlightRange && currentItem) { + // StrictlyEnforceRange always keeps an item in range + updateHighlight(); + topItem = currentItem; + } FxListItem *bottomItem = snapItemAt(tempPosition+highlightEnd); + if (!bottomItem && strictHighlightRange && currentItem) { + // StrictlyEnforceRange always keeps an item in range + updateHighlight(); + bottomItem = currentItem; + } qreal pos; bool isInBounds = -position() > maxExtent && -position() <= minExtent; - if (topItem && isInBounds) { + if (topItem && (isInBounds || strictHighlightRange)) { if (topItem->index == 0 && header && tempPosition+highlightStart < header->position()+header->size()/2 && !strictHighlightRange) { pos = isRightToLeft() ? - header->position() + highlightStart - size() : header->position() - highlightStart; } else { @@ -2754,7 +2764,7 @@ qreal QDeclarativeListView::minXExtent() const d->minExtent += d->header->size(); } if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) { - d->minExtent += highlightStart; + d->minExtent += d->isRightToLeft() ? -highlightStart : highlightStart; d->minExtent = qMax(d->minExtent, -(endPositionFirstItem - highlightEnd + 1)); } d->minExtentDirty = false; diff --git a/src/declarative/qml/qdeclarativedirparser.cpp b/src/declarative/qml/qdeclarativedirparser.cpp index 1d4db40..74ebda2 100644 --- a/src/declarative/qml/qdeclarativedirparser.cpp +++ b/src/declarative/qml/qdeclarativedirparser.cpp @@ -41,8 +41,10 @@ #include "private/qdeclarativedirparser_p.h" #include "qdeclarativeerror.h" +#include <private/qdeclarativeglobal_p.h> #include <QtCore/QTextStream> +#include <QtCore/QFile> #include <QtCore/QtDebug> QT_BEGIN_NAMESPACE @@ -66,6 +68,16 @@ void QDeclarativeDirParser::setUrl(const QUrl &url) _url = url; } +QString QDeclarativeDirParser::fileSource() const +{ + return _filePathSouce; +} + +void QDeclarativeDirParser::setFileSource(const QString &filePath) +{ + _filePathSouce = filePath; +} + QString QDeclarativeDirParser::source() const { return _source; @@ -92,6 +104,23 @@ bool QDeclarativeDirParser::parse() _plugins.clear(); _components.clear(); + if (_source.isEmpty() && !_filePathSouce.isEmpty()) { + QFile file(_filePathSouce); + if (!QDeclarative_isFileCaseCorrect(_filePathSouce)) { + QDeclarativeError error; + error.setDescription(QString::fromUtf8("cannot load module \"$$URI$$\": File name case mismatch for \"%1\"").arg(_filePathSouce)); + _errors.prepend(error); + return false; + } else if (file.open(QFile::ReadOnly)) { + _source = QString::fromUtf8(file.readAll()); + } else { + QDeclarativeError error; + error.setDescription(QString::fromUtf8("module \"$$URI$$\" definition \"%1\" not readable").arg(_filePathSouce)); + _errors.prepend(error); + return false; + } + } + QTextStream stream(&_source); int lineNumber = 0; @@ -224,9 +253,16 @@ bool QDeclarativeDirParser::hasError() const return false; } -QList<QDeclarativeError> QDeclarativeDirParser::errors() const +QList<QDeclarativeError> QDeclarativeDirParser::errors(const QString &uri) const { - return _errors; + QList<QDeclarativeError> errors = _errors; + for (int i = 0; i < errors.size(); ++i) { + QDeclarativeError &e = errors[i]; + QString description = e.description(); + description.replace(QLatin1String("$$URI$$"), uri); + e.setDescription(description); + } + return errors; } QList<QDeclarativeDirParser::Plugin> QDeclarativeDirParser::plugins() const diff --git a/src/declarative/qml/qdeclarativedirparser_p.h b/src/declarative/qml/qdeclarativedirparser_p.h index d40833a..273a2c7 100644 --- a/src/declarative/qml/qdeclarativedirparser_p.h +++ b/src/declarative/qml/qdeclarativedirparser_p.h @@ -73,11 +73,14 @@ public: QString source() const; void setSource(const QString &source); + QString fileSource() const; + void setFileSource(const QString &filePath); + bool isParsed() const; bool parse(); bool hasError() const; - QList<QDeclarativeError> errors() const; + QList<QDeclarativeError> errors(const QString &uri) const; struct Plugin { @@ -129,6 +132,7 @@ private: QList<QDeclarativeError> _errors; QUrl _url; QString _source; + QString _filePathSouce; QList<Component> _components; QList<Plugin> _plugins; #ifdef QT_CREATOR diff --git a/src/declarative/qml/qdeclarativeimport.cpp b/src/declarative/qml/qdeclarativeimport.cpp index c2f0086..21413ce 100644 --- a/src/declarative/qml/qdeclarativeimport.cpp +++ b/src/declarative/qml/qdeclarativeimport.cpp @@ -80,16 +80,16 @@ public: QList<QDeclarativeDirComponents> qmlDirComponents; - bool find_helper(int i, const QByteArray& type, int *vmajor, int *vminor, + bool find_helper(QDeclarativeTypeLoader *typeLoader, int i, const QByteArray& type, int *vmajor, int *vminor, QDeclarativeType** type_return, QUrl* url_return, QUrl *base = 0, bool *typeRecursionDetected = 0); - bool find(const QByteArray& type, int *vmajor, int *vminor, QDeclarativeType** type_return, + bool find(QDeclarativeTypeLoader *typeLoader, const QByteArray& type, int *vmajor, int *vminor, QDeclarativeType** type_return, QUrl* url_return, QUrl *base = 0, QString *errorString = 0); }; class QDeclarativeImportsPrivate { public: - QDeclarativeImportsPrivate(); + QDeclarativeImportsPrivate(QDeclarativeTypeLoader *loader); ~QDeclarativeImportsPrivate(); bool importExtension(const QString &absoluteFilePath, const QString &uri, @@ -112,6 +112,7 @@ public: QSet<QString> qmlDirFilesForWhichPluginsHaveBeenLoaded; QDeclarativeImportedNamespace unqualifiedset; QHash<QString,QDeclarativeImportedNamespace* > set; + QDeclarativeTypeLoader *typeLoader; }; /*! @@ -135,9 +136,12 @@ QDeclarativeImports::operator =(const QDeclarativeImports ©) return *this; } -QDeclarativeImports::QDeclarativeImports() -: d(new QDeclarativeImportsPrivate) -{ +QDeclarativeImports::QDeclarativeImports() + : d(new QDeclarativeImportsPrivate(0)){ +} + +QDeclarativeImports::QDeclarativeImports(QDeclarativeTypeLoader *typeLoader) + : d(new QDeclarativeImportsPrivate(typeLoader)){ } QDeclarativeImports::~QDeclarativeImports() @@ -269,10 +273,11 @@ bool QDeclarativeImports::resolveType(QDeclarativeImportedNamespace* ns, const Q QDeclarativeType** type_return, QUrl* url_return, int *vmaj, int *vmin) const { - return ns->find(type,vmaj,vmin,type_return,url_return); + Q_ASSERT(d->typeLoader); + return ns->find(d->typeLoader,type,vmaj,vmin,type_return,url_return); } -bool QDeclarativeImportedNamespace::find_helper(int i, const QByteArray& type, int *vmajor, int *vminor, +bool QDeclarativeImportedNamespace::find_helper(QDeclarativeTypeLoader *typeLoader, int i, const QByteArray& type, int *vmajor, int *vminor, QDeclarativeType** type_return, QUrl* url_return, QUrl *base, bool *typeRecursionDetected) { @@ -292,7 +297,6 @@ bool QDeclarativeImportedNamespace::find_helper(int i, const QByteArray& type, i return true; } - QUrl url = QUrl(urls.at(i) + QLatin1Char('/') + QString::fromUtf8(type) + QLatin1String(".qml")); QDeclarativeDirComponents qmldircomponents = qmlDirComponents.at(i); bool typeWasDeclaredInQmldir = false; @@ -304,6 +308,7 @@ bool QDeclarativeImportedNamespace::find_helper(int i, const QByteArray& type, i // importing version -1 means import ALL versions if ((vmaj == -1) || (c.majorVersion < vmaj || (c.majorVersion == vmaj && vmin >= c.minorVersion))) { + QUrl url = QUrl(urls.at(i) + QLatin1Char('/') + QString::fromUtf8(type) + QLatin1String(".qml")); QUrl candidate = url.resolved(QUrl(c.fileName)); if (c.internal && base) { if (base->resolved(QUrl(c.fileName)) != candidate) @@ -324,8 +329,9 @@ bool QDeclarativeImportedNamespace::find_helper(int i, const QByteArray& type, i if (!typeWasDeclaredInQmldir && !isLibrary.at(i)) { // XXX search non-files too! (eg. zip files, see QT-524) - QFileInfo f(QDeclarativeEnginePrivate::urlToLocalFileOrQrc(url)); - if (f.exists()) { + QUrl url = QUrl(urls.at(i) + QLatin1Char('/') + QString::fromUtf8(type) + QLatin1String(".qml")); + QString file = QDeclarativeEnginePrivate::urlToLocalFileOrQrc(url); + if (!typeLoader->absoluteFilePath(file).isEmpty()) { if (base && *base == url) { // no recursion if (typeRecursionDetected) *typeRecursionDetected = true; @@ -339,9 +345,8 @@ bool QDeclarativeImportedNamespace::find_helper(int i, const QByteArray& type, i return false; } -QDeclarativeImportsPrivate::QDeclarativeImportsPrivate() -: ref(1) -{ +QDeclarativeImportsPrivate::QDeclarativeImportsPrivate(QDeclarativeTypeLoader *loader) + : ref(1), typeLoader(loader){ } QDeclarativeImportsPrivate::~QDeclarativeImportsPrivate() @@ -354,33 +359,22 @@ bool QDeclarativeImportsPrivate::importExtension(const QString &absoluteFilePath QDeclarativeImportDatabase *database, QDeclarativeDirComponents* components, QString *errorString) { - QFile file(absoluteFilePath); - QString filecontent; - if (!QDeclarative_isFileCaseCorrect(absoluteFilePath)) { - if (errorString) - *errorString = QDeclarativeImportDatabase::tr("cannot load module \"%1\": File name case mismatch for \"%2\"").arg(uri).arg(absoluteFilePath); - return false; - } else if (file.open(QFile::ReadOnly)) { - filecontent = QString::fromUtf8(file.readAll()); - if (qmlImportTrace()) - qDebug().nospace() << "QDeclarativeImports(" << qPrintable(base.toString()) << "::importExtension: " - << "loaded " << absoluteFilePath; - } else { - if (errorString) - *errorString = QDeclarativeImportDatabase::tr("module \"%1\" definition \"%2\" not readable").arg(uri).arg(absoluteFilePath); + Q_ASSERT(typeLoader); + const QDeclarativeDirParser *qmldirParser = typeLoader->qmlDirParser(absoluteFilePath); + if (qmldirParser->hasError()) { + if (errorString) { + const QList<QDeclarativeError> qmldirErrors = qmldirParser->errors(uri); + for (int i = 0; i < qmldirErrors.size(); ++i) + *errorString += qmldirErrors.at(i).description(); + } return false; } - QDir dir = QFileInfo(file).dir(); - - QDeclarativeDirParser qmldirParser; - qmldirParser.setSource(filecontent); - qmldirParser.parse(); if (! qmlDirFilesForWhichPluginsHaveBeenLoaded.contains(absoluteFilePath)) { qmlDirFilesForWhichPluginsHaveBeenLoaded.insert(absoluteFilePath); - - foreach (const QDeclarativeDirParser::Plugin &plugin, qmldirParser.plugins()) { + QDir dir = QFileInfo(absoluteFilePath).dir(); + foreach (const QDeclarativeDirParser::Plugin &plugin, qmldirParser->plugins()) { QString resolvedFilePath = database->resolvePlugin(dir, plugin.path, plugin.name); #if defined(QT_LIBINFIX) && defined(Q_OS_SYMBIAN) @@ -405,7 +399,7 @@ bool QDeclarativeImportsPrivate::importExtension(const QString &absoluteFilePath } if (components) - *components = qmldirParser.components(); + *components = qmldirParser->components(); return true; } @@ -446,6 +440,7 @@ bool QDeclarativeImportsPrivate::add(const QDeclarativeDirComponents &qmldircomp QDeclarativeScriptParser::Import::Type importType, QDeclarativeImportDatabase *database, QString *errorString) { + Q_ASSERT(typeLoader); QDeclarativeDirComponents qmldircomponents = qmldircomponentsnetwork; QString uri = uri_arg; QDeclarativeImportedNamespace *s; @@ -463,20 +458,20 @@ bool QDeclarativeImportsPrivate::add(const QDeclarativeDirComponents &qmldircomp url.replace(QLatin1Char('.'), QLatin1Char('/')); bool found = false; QString dir; - + QString qmldir; // step 1: search for extension with fully encoded version number if (vmaj >= 0 && vmin >= 0) { foreach (const QString &p, database->fileImportPath) { dir = p+QLatin1Char('/')+url; + qmldir = dir+QString(QLatin1String(".%1.%2")).arg(vmaj).arg(vmin)+QLatin1String("/qmldir"); - QFileInfo fi(dir+QString(QLatin1String(".%1.%2")).arg(vmaj).arg(vmin)+QLatin1String("/qmldir")); - const QString absoluteFilePath = fi.absoluteFilePath(); - - if (fi.isFile()) { + QString absoluteFilePath = typeLoader->absoluteFilePath(qmldir); + if (!absoluteFilePath.isEmpty()) { found = true; - url = QUrl::fromLocalFile(fi.absolutePath()).toString(); + QString absolutePath = absoluteFilePath.left(absoluteFilePath.lastIndexOf(QLatin1Char('/'))); + url = QUrl::fromLocalFile(absolutePath).toString(); uri = resolvedUri(dir, database); if (!importExtension(absoluteFilePath, uri, database, &qmldircomponents, errorString)) return false; @@ -488,14 +483,14 @@ bool QDeclarativeImportsPrivate::add(const QDeclarativeDirComponents &qmldircomp if (vmaj >= 0 && vmin >= 0) { foreach (const QString &p, database->fileImportPath) { dir = p+QLatin1Char('/')+url; + qmldir = dir+QString(QLatin1String(".%1")).arg(vmaj)+QLatin1String("/qmldir"); - QFileInfo fi(dir+QString(QLatin1String(".%1")).arg(vmaj)+QLatin1String("/qmldir")); - const QString absoluteFilePath = fi.absoluteFilePath(); - - if (fi.isFile()) { + QString absoluteFilePath = typeLoader->absoluteFilePath(qmldir); + if (!absoluteFilePath.isEmpty()) { found = true; - url = QUrl::fromLocalFile(fi.absolutePath()).toString(); + QString absolutePath = absoluteFilePath.left(absoluteFilePath.lastIndexOf(QLatin1Char('/'))); + url = QUrl::fromLocalFile(absolutePath).toString(); uri = resolvedUri(dir, database); if (!importExtension(absoluteFilePath, uri, database, &qmldircomponents, errorString)) return false; @@ -508,14 +503,14 @@ bool QDeclarativeImportsPrivate::add(const QDeclarativeDirComponents &qmldircomp foreach (const QString &p, database->fileImportPath) { dir = p+QLatin1Char('/')+url; + qmldir = dir+QLatin1String("/qmldir"); - QFileInfo fi(dir+QLatin1String("/qmldir")); - const QString absoluteFilePath = fi.absoluteFilePath(); - - if (fi.isFile()) { + QString absoluteFilePath = typeLoader->absoluteFilePath(qmldir); + if (!absoluteFilePath.isEmpty()) { found = true; - url = QUrl::fromLocalFile(fi.absolutePath()).toString(); + QString absolutePath = absoluteFilePath.left(absoluteFilePath.lastIndexOf(QLatin1Char('/'))); + url = QUrl::fromLocalFile(absolutePath).toString(); uri = resolvedUri(dir, database); if (!importExtension(absoluteFilePath, uri, database, &qmldircomponents, errorString)) return false; @@ -553,7 +548,7 @@ bool QDeclarativeImportsPrivate::add(const QDeclarativeDirComponents &qmldircomp uri = resolvedUri(QDeclarativeEnginePrivate::urlToLocalFileOrQrc(base.resolved(QUrl(uri))), database); if (uri.endsWith(QLatin1Char('/'))) uri.chop(1); - if (QFile::exists(localFileOrQrc)) { + if (!typeLoader->absoluteFilePath(localFileOrQrc).isEmpty()) { if (!importExtension(localFileOrQrc,uri,database,&qmldircomponents,errorString)) return false; } @@ -616,6 +611,7 @@ bool QDeclarativeImportsPrivate::add(const QDeclarativeDirComponents &qmldircomp bool QDeclarativeImportsPrivate::find(const QByteArray& type, int *vmajor, int *vminor, QDeclarativeType** type_return, QUrl* url_return, QString *errorString) { + Q_ASSERT(typeLoader); QDeclarativeImportedNamespace *s = 0; int slash = type.indexOf('/'); if (slash >= 0) { @@ -637,7 +633,7 @@ bool QDeclarativeImportsPrivate::find(const QByteArray& type, int *vmajor, int * } 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, &base, errorString)) + if (s->find(typeLoader, unqualifiedtype,vmajor,vminor,type_return,url_return, &base, errorString)) return true; if (s->urls.count() == 1 && !s->isLibrary[0] && url_return && s != &unqualifiedset) { // qualified, and only 1 url @@ -654,16 +650,16 @@ QDeclarativeImportedNamespace *QDeclarativeImportsPrivate::findNamespace(const Q return set.value(type); } -bool QDeclarativeImportedNamespace::find(const QByteArray& type, int *vmajor, int *vminor, QDeclarativeType** type_return, +bool QDeclarativeImportedNamespace::find(QDeclarativeTypeLoader *typeLoader, const QByteArray& type, int *vmajor, int *vminor, QDeclarativeType** type_return, QUrl* url_return, QUrl *base, QString *errorString) { bool typeRecursionDetected = false; for (int i=0; i<urls.count(); ++i) { - if (find_helper(i, type, vmajor, vminor, type_return, url_return, base, &typeRecursionDetected)) { + if (find_helper(typeLoader, i, type, vmajor, vminor, type_return, url_return, base, &typeRecursionDetected)) { if (qmlCheckTypes()) { // check for type clashes for (int j = i+1; j<urls.count(); ++j) { - if (find_helper(j, type, vmajor, vminor, 0, 0, base)) { + if (find_helper(typeLoader, j, type, vmajor, vminor, 0, 0, base)) { if (errorString) { QString u1 = urls.at(i); QString u2 = urls.at(j); @@ -1042,7 +1038,7 @@ bool QDeclarativeImportDatabase::importPlugin(const QString &filePath, const QSt if (!engineInitialized || !typesRegistered) { if (!QDeclarative_isFileCaseCorrect(absoluteFilePath)) { if (errorString) - *errorString = tr("File name case mismatch for \"%2\"").arg(absoluteFilePath); + *errorString = tr("File name case mismatch for \"%1\"").arg(absoluteFilePath); return false; } QPluginLoader loader(absoluteFilePath); diff --git a/src/declarative/qml/qdeclarativeimport_p.h b/src/declarative/qml/qdeclarativeimport_p.h index 319e76c..d2ae9cc 100644 --- a/src/declarative/qml/qdeclarativeimport_p.h +++ b/src/declarative/qml/qdeclarativeimport_p.h @@ -68,11 +68,13 @@ class QDir; class QDeclarativeImportedNamespace; class QDeclarativeImportsPrivate; class QDeclarativeImportDatabase; +class QDeclarativeTypeLoader; class QDeclarativeImports { public: QDeclarativeImports(); + QDeclarativeImports(QDeclarativeTypeLoader *); QDeclarativeImports(const QDeclarativeImports &); ~QDeclarativeImports(); QDeclarativeImports &operator=(const QDeclarativeImports &); diff --git a/src/declarative/qml/qdeclarativetypeloader.cpp b/src/declarative/qml/qdeclarativetypeloader.cpp index 82197dc..0d8119f 100644 --- a/src/declarative/qml/qdeclarativetypeloader.cpp +++ b/src/declarative/qml/qdeclarativetypeloader.cpp @@ -50,10 +50,37 @@ #include <QtDeclarative/qdeclarativecomponent.h> #include <QtCore/qdebug.h> #include <QtCore/qdir.h> +#include <QtCore/qdiriterator.h> #include <QtCore/qfile.h> QT_BEGIN_NAMESPACE +/* +Returns the set of QML files in path (qmldir, *.qml, *.js). The caller +is responsible for deleting the returned data. +*/ +static QSet<QString> *qmlFilesInDirectory(const QString &path) +{ + QDirIterator dir(path, QDir::Files); + if (!dir.hasNext()) + return 0; + QSet<QString> *files = new QSet<QString>; + while (dir.hasNext()) { + dir.next(); + QString fileName = dir.fileName(); + if (fileName == QLatin1String("qmldir") + || fileName.endsWith(QLatin1String(".qml")) + || fileName.endsWith(QLatin1String(".js"))) { +#if defined(Q_OS_WIN32) || defined(Q_OS_WINCE) || defined(Q_OS_DARWIN) || defined(Q_OS_SYMBIAN) + fileName = fileName.toLower(); +#endif + files->insert(fileName); + } + } + return files; +} + + /*! \class QDeclarativeDataBlob \brief The QDeclarativeDataBlob encapsulates a data request that can be issued to a QDeclarativeDataLoader. @@ -727,6 +754,67 @@ QDeclarativeQmldirData *QDeclarativeTypeLoader::getQmldir(const QUrl &url) } /*! +Returns the absolute filename of path via a directory cache for files named +"qmldir", "*.qml", "*.js" +Returns a empty string if the path does not exist. +*/ +QString QDeclarativeTypeLoader::absoluteFilePath(const QString &path) +{ + if (path.isEmpty()) + return QString(); + if (path.at(0) == QLatin1Char(':')) { + // qrc resource + QFileInfo fileInfo(path); + return fileInfo.isFile() ? fileInfo.absoluteFilePath() : QString(); + } +#if defined(Q_OS_WIN32) || defined(Q_OS_WINCE) || defined(Q_OS_DARWIN) || defined(Q_OS_SYMBIAN) + QString lowPath(path.toLower()); +#else + QString lowPath(path); +#endif + int lastSlash = lowPath.lastIndexOf(QLatin1Char('/')); + QString dirPath = lowPath.left(lastSlash); + + StringSet *fileSet = 0; + QHash<QString,StringSet*>::const_iterator it = m_importDirCache.find(dirPath); + if (it == m_importDirCache.end()) { + StringSet *files = qmlFilesInDirectory(path.left(lastSlash)); + m_importDirCache.insert(dirPath, files); + fileSet = files; + } else { + fileSet = *it; + } + if (!fileSet) + return QString(); + + QString absoluteFilePath = fileSet->contains(QString(lowPath.constData()+lastSlash+1, lowPath.length()-lastSlash-1)) ? path : QString(); + if (absoluteFilePath.length() > 2 && absoluteFilePath.at(0) != QLatin1Char('/') && absoluteFilePath.at(1) != QLatin1Char(':')) + absoluteFilePath = QFileInfo(absoluteFilePath).absoluteFilePath(); + + return absoluteFilePath; +} + +/*! +Return a QDeclarativeDirParser for absoluteFilePath. The QDeclarativeDirParser may be cached. +*/ +const QDeclarativeDirParser *QDeclarativeTypeLoader::qmlDirParser(const QString &absoluteFilePath) +{ + QDeclarativeDirParser *qmldirParser; + QHash<QString,QDeclarativeDirParser*>::const_iterator it = m_importQmlDirCache.find(absoluteFilePath); + if (it == m_importQmlDirCache.end()) { + qmldirParser = new QDeclarativeDirParser; + qmldirParser->setFileSource(absoluteFilePath); + qmldirParser->setUrl(QUrl::fromLocalFile(absoluteFilePath)); + qmldirParser->parse(); + m_importQmlDirCache.insert(absoluteFilePath, qmldirParser); + } else { + qmldirParser = *it; + } + + return qmldirParser; +} + +/* Clears cached information about loaded files, including any type data, scripts and qmldir information. */ @@ -738,16 +826,20 @@ void QDeclarativeTypeLoader::clearCache() (*iter)->release(); for (QmldirCache::Iterator iter = m_qmldirCache.begin(); iter != m_qmldirCache.end(); ++iter) (*iter)->release(); + qDeleteAll(m_importDirCache); + qDeleteAll(m_importQmlDirCache); m_typeCache.clear(); m_scriptCache.clear(); m_qmldirCache.clear(); + m_importDirCache.clear(); + m_importQmlDirCache.clear(); } QDeclarativeTypeData::QDeclarativeTypeData(const QUrl &url, QDeclarativeTypeLoader::Options options, QDeclarativeTypeLoader *manager) -: QDeclarativeDataBlob(url, QmlFile), m_options(options), m_typesResolved(false), +: QDeclarativeDataBlob(url, QmlFile), m_options(options), m_imports(manager), m_typesResolved(false), m_compiledData(0), m_typeLoader(manager) { } diff --git a/src/declarative/qml/qdeclarativetypeloader_p.h b/src/declarative/qml/qdeclarativetypeloader_p.h index 56b6636..c0dce3e 100644 --- a/src/declarative/qml/qdeclarativetypeloader_p.h +++ b/src/declarative/qml/qdeclarativetypeloader_p.h @@ -198,14 +198,23 @@ public: QDeclarativeScriptData *getScript(const QUrl &); QDeclarativeQmldirData *getQmldir(const QUrl &); + + QString absoluteFilePath(const QString &path); + const QDeclarativeDirParser *qmlDirParser(const QString &absoluteFilePath); + private: typedef QHash<QUrl, QDeclarativeTypeData *> TypeCache; typedef QHash<QUrl, QDeclarativeScriptData *> ScriptCache; typedef QHash<QUrl, QDeclarativeQmldirData *> QmldirCache; + typedef QSet<QString> StringSet; + typedef QHash<QString, StringSet*> ImportDirCache; + typedef QHash<QString, QDeclarativeDirParser*> ImportQmlDirCache; TypeCache m_typeCache; ScriptCache m_scriptCache; QmldirCache m_qmldirCache; + ImportDirCache m_importDirCache; + ImportQmlDirCache m_importQmlDirCache; }; Q_DECLARE_OPERATORS_FOR_FLAGS(QDeclarativeTypeLoader::Options) diff --git a/src/declarative/util/qdeclarativepropertychanges.cpp b/src/declarative/util/qdeclarativepropertychanges.cpp index 5cdf785..f86274f 100644 --- a/src/declarative/util/qdeclarativepropertychanges.cpp +++ b/src/declarative/util/qdeclarativepropertychanges.cpp @@ -171,7 +171,8 @@ public: reverseExpression = rewindExpression; } - /*virtual void copyOriginals(QDeclarativeActionEvent *other) + virtual bool needsCopy() { return true; } + virtual void copyOriginals(QDeclarativeActionEvent *other) { QDeclarativeReplaceSignalHandler *rsh = static_cast<QDeclarativeReplaceSignalHandler*>(other); saveCurrentValues(); @@ -182,7 +183,7 @@ public: ownedExpression = rsh->ownedExpression; rsh->ownedExpression = 0; } - }*/ + } virtual void rewind() { ownedExpression = QDeclarativePropertyPrivate::setSignalExpression(property, rewindExpression); |