diff options
author | Liang Qi <liang.qi@theqtcompany.com> | 2015-11-03 13:27:13 +0100 |
---|---|---|
committer | Liang Qi <liang.qi@theqtcompany.com> | 2015-11-03 13:27:13 +0100 |
commit | f2244103ff7a9b61fc7bcb7e920d8cc6b2f5f226 (patch) | |
tree | 8fe753743c46d4a652f582a7a2a49e5709eaa6e0 /src/qml/qml | |
parent | 57430b2bdad32150e0ed8ceb6893430363ee6670 (diff) | |
parent | 164af37710e5721cbc7d79a0af20f2387181c59c (diff) |
Merge remote-tracking branch 'origin/5.6' into dev
Conflicts:
tools/qmlprofiler/qmlprofilerclient.cpp
Change-Id: I1de8832fefd0e45fea16ca072b6c7ae44fa376d4
Diffstat (limited to 'src/qml/qml')
-rw-r--r-- | src/qml/qml/qqmlengine.cpp | 4 | ||||
-rw-r--r-- | src/qml/qml/qqmlfileselector.cpp | 6 | ||||
-rw-r--r-- | src/qml/qml/qqmlfileselector_p.h | 2 | ||||
-rw-r--r-- | src/qml/qml/qqmlglobal_p.h | 10 | ||||
-rw-r--r-- | src/qml/qml/qqmlimport.cpp | 4 | ||||
-rw-r--r-- | src/qml/qml/qqmllocale_p.h | 2 | ||||
-rw-r--r-- | src/qml/qml/qqmltypeloader.cpp | 149 | ||||
-rw-r--r-- | src/qml/qml/qqmltypeloader_p.h | 11 | ||||
-rw-r--r-- | src/qml/qml/v8/qqmlbuiltinfunctions.cpp | 7 |
9 files changed, 120 insertions, 75 deletions
diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp index 56252ec1ab..ae7c0cf8fb 100644 --- a/src/qml/qml/qqmlengine.cpp +++ b/src/qml/qml/qqmlengine.cpp @@ -2437,6 +2437,8 @@ bool QQml_isFileCaseCorrect(const QString &fileName, int lengthIn /* = -1 */) Returns the QQmlEngine associated with \a object, if any. This is equivalent to QQmlEngine::contextForObject(object)->engine(), but more efficient. + \note Add \c{#include <QtQml>} to use this function. + \sa {QQmlEngine::contextForObject()}{contextForObject()}, qmlContext() */ @@ -2447,6 +2449,8 @@ bool QQml_isFileCaseCorrect(const QString &fileName, int lengthIn /* = -1 */) Returns the QQmlContext associated with \a object, if any. This is equivalent to QQmlEngine::contextForObject(object). + \note Add \c{#include <QtQml>} to use this function. + \sa {QQmlEngine::contextForObject()}{contextForObject()}, qmlEngine() */ diff --git a/src/qml/qml/qqmlfileselector.cpp b/src/qml/qml/qqmlfileselector.cpp index 8597e8a5c7..ab880b7069 100644 --- a/src/qml/qml/qqmlfileselector.cpp +++ b/src/qml/qml/qqmlfileselector.cpp @@ -123,6 +123,12 @@ QQmlFileSelectorPrivate::QQmlFileSelectorPrivate() myInstance.reset(new QQmlFileSelectorInterceptor(this)); } +QQmlFileSelectorPrivate::~QQmlFileSelectorPrivate() +{ + if (ownSelector) + delete selector; +} + /*! Sets the QFileSelector instance for use by the QQmlFileSelector to \a selector. QQmlFileSelector does not take ownership of the new QFileSelector. To reset QQmlFileSelector diff --git a/src/qml/qml/qqmlfileselector_p.h b/src/qml/qml/qqmlfileselector_p.h index 58248bf1c1..46ea027bc1 100644 --- a/src/qml/qml/qqmlfileselector_p.h +++ b/src/qml/qml/qqmlfileselector_p.h @@ -60,6 +60,8 @@ class Q_QML_PRIVATE_EXPORT QQmlFileSelectorPrivate : public QObjectPrivate Q_DECLARE_PUBLIC(QQmlFileSelector) public: QQmlFileSelectorPrivate(); + ~QQmlFileSelectorPrivate(); + QFileSelector* selector; QPointer<QQmlEngine> engine; bool ownSelector; diff --git a/src/qml/qml/qqmlglobal_p.h b/src/qml/qml/qqmlglobal_p.h index b7212648ab..23cfc24e7a 100644 --- a/src/qml/qml/qqmlglobal_p.h +++ b/src/qml/qml/qqmlglobal_p.h @@ -59,10 +59,12 @@ QT_BEGIN_NAMESPACE { \ static enum { Yes, No, Unknown } status = Unknown; \ if (status == Unknown) { \ - QByteArray v = qgetenv(#var); \ - bool value = !v.isEmpty() && v != "0" && v != "false"; \ - if (value) status = Yes; \ - else status = No; \ + status = No; \ + if (Q_UNLIKELY(!qEnvironmentVariableIsEmpty(#var))) { \ + const QByteArray v = qgetenv(#var); \ + if (v != "0" && v != "false") \ + status = Yes; \ + } \ } \ return status == Yes; \ } diff --git a/src/qml/qml/qqmlimport.cpp b/src/qml/qml/qqmlimport.cpp index d0d14d9416..c5b5947c11 100644 --- a/src/qml/qml/qqmlimport.cpp +++ b/src/qml/qml/qqmlimport.cpp @@ -1570,8 +1570,8 @@ QQmlImportDatabase::QQmlImportDatabase(QQmlEngine *e) addImportPath(installImportsPath); // env import paths - QByteArray envImportPath = qgetenv("QML2_IMPORT_PATH"); - if (!envImportPath.isEmpty()) { + if (Q_UNLIKELY(!qEnvironmentVariableIsEmpty("QML2_IMPORT_PATH"))) { + const QByteArray envImportPath = qgetenv("QML2_IMPORT_PATH"); #if defined(Q_OS_WIN) QLatin1Char pathSep(';'); #else diff --git a/src/qml/qml/qqmllocale_p.h b/src/qml/qml/qqmllocale_p.h index 0c2fbbdb14..aa6b2e8681 100644 --- a/src/qml/qml/qqmllocale_p.h +++ b/src/qml/qml/qqmllocale_p.h @@ -82,7 +82,7 @@ private: }; -class Q_AUTOTEST_EXPORT QQmlLocale +class Q_QML_PRIVATE_EXPORT QQmlLocale { Q_GADGET diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp index 270c28c399..29f1ca7959 100644 --- a/src/qml/qml/qqmltypeloader.cpp +++ b/src/qml/qml/qqmltypeloader.cpp @@ -911,97 +911,116 @@ void QQmlTypeLoader::unlock() m_thread->unlock(); } -/*! -Load the provided \a blob from the network or filesystem. +struct PlainLoader { + void loadThread(QQmlTypeLoader *loader, QQmlDataBlob *blob) const + { + loader->loadThread(blob); + } + void load(QQmlTypeLoader *loader, QQmlDataBlob *blob) const + { + loader->m_thread->load(blob); + } + void loadAsync(QQmlTypeLoader *loader, QQmlDataBlob *blob) const + { + loader->m_thread->loadAsync(blob); + } +}; -The loader must be locked. -*/ -void QQmlTypeLoader::load(QQmlDataBlob *blob, Mode mode) +struct StaticLoader { + const QByteArray &data; + StaticLoader(const QByteArray &data) : data(data) {} + + void loadThread(QQmlTypeLoader *loader, QQmlDataBlob *blob) const + { + loader->loadWithStaticDataThread(blob, data); + } + void load(QQmlTypeLoader *loader, QQmlDataBlob *blob) const + { + loader->m_thread->loadWithStaticData(blob, data); + } + void loadAsync(QQmlTypeLoader *loader, QQmlDataBlob *blob) const + { + loader->m_thread->loadWithStaticDataAsync(blob, data); + } +}; + +struct CachedLoader { + const QQmlPrivate::CachedQmlUnit *unit; + CachedLoader(const QQmlPrivate::CachedQmlUnit *unit) : unit(unit) {} + + void loadThread(QQmlTypeLoader *loader, QQmlDataBlob *blob) const + { + loader->loadWithCachedUnitThread(blob, unit); + } + void load(QQmlTypeLoader *loader, QQmlDataBlob *blob) const + { + loader->m_thread->loadWithCachedUnit(blob, unit); + } + void loadAsync(QQmlTypeLoader *loader, QQmlDataBlob *blob) const + { + loader->m_thread->loadWithCachedUnit(blob, unit); + } +}; + +template<typename Loader> +void QQmlTypeLoader::doLoad(const Loader &loader, QQmlDataBlob *blob, Mode mode) { #ifdef DATABLOB_DEBUG - qWarning("QQmlTypeLoader::load(%s): %s thread", qPrintable(blob->m_url.toString()), + qWarning("QQmlTypeLoader::doLoad(%s): %s thread", qPrintable(blob->m_url.toString()), m_thread->isThisThread()?"Compile":"Engine"); #endif blob->startLoading(); if (m_thread->isThisThread()) { unlock(); - loadThread(blob); + loader.loadThread(this, blob); lock(); - } else if (mode == PreferSynchronous) { + } else if (mode == Asynchronous) { + blob->m_data.setIsAsync(true); unlock(); - m_thread->load(blob); + loader.loadAsync(this, blob); lock(); - if (!blob->isCompleteOrError()) - blob->m_data.setIsAsync(true); } else { - Q_ASSERT(mode == Asynchronous); - blob->m_data.setIsAsync(true); unlock(); - m_thread->loadAsync(blob); + loader.load(this, blob); lock(); + if (mode == PreferSynchronous) { + if (!blob->isCompleteOrError()) + blob->m_data.setIsAsync(true); + } else { + Q_ASSERT(mode == Synchronous); + while (!blob->isCompleteOrError()) { + unlock(); + m_thread->waitForNextMessage(); + lock(); + } + } } } /*! -Load the provided \a blob with \a data. The blob's URL is not used by the data loader in this case. +Load the provided \a blob from the network or filesystem. The loader must be locked. */ -void QQmlTypeLoader::loadWithStaticData(QQmlDataBlob *blob, const QByteArray &data, Mode mode) +void QQmlTypeLoader::load(QQmlDataBlob *blob, Mode mode) { -#ifdef DATABLOB_DEBUG - qWarning("QQmlTypeLoader::loadWithStaticData(%s, data): %s thread", qPrintable(blob->m_url.toString()), - m_thread->isThisThread()?"Compile":"Engine"); -#endif + doLoad(PlainLoader(), blob, mode); +} - blob->startLoading(); +/*! +Load the provided \a blob with \a data. The blob's URL is not used by the data loader in this case. - if (m_thread->isThisThread()) { - unlock(); - loadWithStaticDataThread(blob, data); - lock(); - } else if (mode == PreferSynchronous) { - unlock(); - m_thread->loadWithStaticData(blob, data); - lock(); - if (!blob->isCompleteOrError()) - blob->m_data.setIsAsync(true); - } else { - Q_ASSERT(mode == Asynchronous); - blob->m_data.setIsAsync(true); - unlock(); - m_thread->loadWithStaticDataAsync(blob, data); - lock(); - } +The loader must be locked. +*/ +void QQmlTypeLoader::loadWithStaticData(QQmlDataBlob *blob, const QByteArray &data, Mode mode) +{ + doLoad(StaticLoader(data), blob, mode); } void QQmlTypeLoader::loadWithCachedUnit(QQmlDataBlob *blob, const QQmlPrivate::CachedQmlUnit *unit, Mode mode) { -#ifdef DATABLOB_DEBUG - qWarning("QQmlTypeLoader::loadWithUnitFcatory(%s, data): %s thread", qPrintable(blob->m_url.toString()), - m_thread->isThisThread()?"Compile":"Engine"); -#endif - - blob->startLoading(); - - if (m_thread->isThisThread()) { - unlock(); - loadWithCachedUnitThread(blob, unit); - lock(); - } else if (mode == PreferSynchronous) { - unlock(); - m_thread->loadWithCachedUnit(blob, unit); - lock(); - if (!blob->isCompleteOrError()) - blob->m_data.setIsAsync(true); - } else { - Q_ASSERT(mode == Asynchronous); - blob->m_data.setIsAsync(true); - unlock(); - m_thread->loadWithCachedUnitAsync(blob, unit); - lock(); - } + doLoad(CachedLoader(unit), blob, mode); } void QQmlTypeLoader::loadWithStaticDataThread(QQmlDataBlob *blob, const QByteArray &data) @@ -1618,7 +1637,7 @@ QQmlTypeData *QQmlTypeLoader::getType(const QUrl &url, Mode mode) } else { QQmlTypeLoader::load(typeData, mode); } - } else if ((mode == PreferSynchronous) && QQmlFile::isSynchronous(url)) { + } else if ((mode == PreferSynchronous || mode == Synchronous) && QQmlFile::isSynchronous(url)) { // this was started Asynchronous, but we need to force Synchronous // completion now (if at all possible with this type of URL). @@ -1643,12 +1662,12 @@ QQmlTypeData *QQmlTypeLoader::getType(const QUrl &url, Mode mode) Returns a QQmlTypeData for the given \a data with the provided base \a url. The QQmlTypeData will not be cached. */ -QQmlTypeData *QQmlTypeLoader::getType(const QByteArray &data, const QUrl &url) +QQmlTypeData *QQmlTypeLoader::getType(const QByteArray &data, const QUrl &url, Mode mode) { LockHolder<QQmlTypeLoader> holder(this); QQmlTypeData *typeData = new QQmlTypeData(url, this); - QQmlTypeLoader::loadWithStaticData(typeData, data); + QQmlTypeLoader::loadWithStaticData(typeData, data, mode); return typeData; } diff --git a/src/qml/qml/qqmltypeloader_p.h b/src/qml/qml/qqmltypeloader_p.h index e7b4b8f95b..6433601ba8 100644 --- a/src/qml/qml/qqmltypeloader_p.h +++ b/src/qml/qml/qqmltypeloader_p.h @@ -215,7 +215,7 @@ class Q_AUTOTEST_EXPORT QQmlTypeLoader { Q_DECLARE_TR_FUNCTIONS(QQmlTypeLoader) public: - enum Mode { PreferSynchronous, Asynchronous }; + enum Mode { PreferSynchronous, Asynchronous, Synchronous }; class Q_QML_PRIVATE_EXPORT Blob : public QQmlDataBlob { @@ -283,7 +283,7 @@ public: QQmlImportDatabase *importDatabase(); QQmlTypeData *getType(const QUrl &url, Mode mode = PreferSynchronous); - QQmlTypeData *getType(const QByteArray &, const QUrl &url); + QQmlTypeData *getType(const QByteArray &, const QUrl &url, Mode mode = PreferSynchronous); QQmlScriptBlob *getScript(const QUrl &); QQmlQmldirData *getQmldir(const QUrl &); @@ -362,6 +362,13 @@ private: QmldirCache m_qmldirCache; ImportDirCache m_importDirCache; ImportQmlDirCache m_importQmlDirCache; + + template<typename Loader> + void doLoad(const Loader &loader, QQmlDataBlob *blob, Mode mode); + + friend struct PlainLoader; + friend struct CachedLoader; + friend struct StaticLoader; }; class Q_AUTOTEST_EXPORT QQmlTypeData : public QQmlTypeLoader::Blob diff --git a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp index 89088e5b3e..3acabe390f 100644 --- a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp +++ b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp @@ -1013,8 +1013,13 @@ ReturnedValue QtObject::method_createQmlObject(CallContext *ctx) if (!parentArg) V4THROW_ERROR("Qt.createQmlObject(): Missing parent object"); + QQmlTypeData *typeData = QQmlEnginePrivate::get(engine)->typeLoader.getType( + qml.toUtf8(), url, QQmlTypeLoader::Synchronous); + Q_ASSERT(typeData->isCompleteOrError()); QQmlComponent component(engine); - component.setData(qml.toUtf8(), url); + QQmlComponentPrivate *componentPrivate = QQmlComponentPrivate::get(&component); + componentPrivate->fromTypeData(typeData); + componentPrivate->progress = 1.0; if (component.isError()) { ScopedValue v(scope, Error::create(ctx->d()->engine, component.errors())); |